merge in nyc-mr2-release history after reset to f1bc21c734d1bef1ee65f687d0989ee7e6085a08
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index 7b826d6..1853cff 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -115,6 +115,7 @@
                                            void* cookie);
     
     const   sp<ProcessState>    mProcess;
+    const   pid_t               mMyThreadId;
             Vector<BBinder*>    mPendingStrongDerefs;
             Vector<RefBase::weakref_type*> mPendingWeakDerefs;
 
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index eccc400..d90798f 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -46,7 +46,6 @@
 #define IF_LOG_COMMANDS() if (false)
 #define LOG_REMOTEREFS(...) 
 #define IF_LOG_REMOTEREFS() if (false)
-
 #define LOG_THREADPOOL(...) 
 #define LOG_ONEWAY(...) 
 
@@ -153,7 +152,7 @@
         return cmd;
     }
     out << kReturnStrings[cmdIndex];
-
+    
     switch (code) {
         case BR_TRANSACTION:
         case BR_REPLY: {
@@ -161,12 +160,12 @@
             cmd = (const int32_t *)printBinderTransactionData(out, cmd);
             out << dedent;
         } break;
-
+        
         case BR_ACQUIRE_RESULT: {
             const int32_t res = *cmd++;
             out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
         } break;
-
+        
         case BR_INCREFS:
         case BR_ACQUIRE:
         case BR_RELEASE:
@@ -175,7 +174,7 @@
             const int32_t c = *cmd++;
             out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
         } break;
-
+    
         case BR_ATTEMPT_ACQUIRE: {
             const int32_t p = *cmd++;
             const int32_t b = *cmd++;
@@ -195,7 +194,7 @@
             // BR_TRANSACTION_COMPLETE, BR_FINISHED
             break;
     }
-
+    
     out << endl;
     return cmd;
 }
@@ -220,17 +219,17 @@
             cmd = (const int32_t *)printBinderTransactionData(out, cmd);
             out << dedent;
         } break;
-
+        
         case BC_ACQUIRE_RESULT: {
             const int32_t res = *cmd++;
             out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
         } break;
-
+        
         case BC_FREE_BUFFER: {
             const int32_t buf = *cmd++;
             out << ": buffer=" << (void*)(long)buf;
         } break;
-
+        
         case BC_INCREFS:
         case BC_ACQUIRE:
         case BC_RELEASE:
@@ -238,20 +237,20 @@
             const int32_t d = *cmd++;
             out << ": desc=" << d;
         } break;
-
+    
         case BC_INCREFS_DONE:
         case BC_ACQUIRE_DONE: {
             const int32_t b = *cmd++;
             const int32_t c = *cmd++;
             out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
         } break;
-
+        
         case BC_ATTEMPT_ACQUIRE: {
             const int32_t p = *cmd++;
             const int32_t d = *cmd++;
             out << ": desc=" << d << ", pri=" << p;
         } break;
-
+        
         case BC_REQUEST_DEATH_NOTIFICATION:
         case BC_CLEAR_DEATH_NOTIFICATION: {
             const int32_t h = *cmd++;
@@ -269,7 +268,7 @@
             // BC_EXIT_LOOPER
             break;
     }
-
+    
     out << endl;
     return cmd;
 }
@@ -289,12 +288,12 @@
         if (st) return st;
         return new IPCThreadState;
     }
-
+    
     if (gShutdown) {
         ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
         return NULL;
     }
-
+    
     pthread_mutex_lock(&gTLSMutex);
     if (!gHaveTLS) {
         int key_create_value = pthread_key_create(&gTLS, threadDestructor);
@@ -323,7 +322,7 @@
 void IPCThreadState::shutdown()
 {
     gShutdown = true;
-
+    
     if (gHaveTLS) {
         // XXX Need to wait for all thread pool threads to exit!
         IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
@@ -458,6 +457,15 @@
         }
         pthread_cond_broadcast(&mProcess->mThreadCountDecrement);
         pthread_mutex_unlock(&mProcess->mThreadCountLock);
+
+        // After executing the command, ensure that the thread is returned to the
+        // foreground cgroup before rejoining the pool.  The driver takes care of
+        // restoring the priority, but doesn't do anything with cgroups so we
+        // need to take care of that here in userspace.  Note that we do make
+        // sure to go in the foreground after executing a transaction, but
+        // there are other callbacks into user code that could have changed
+        // our group so we want to make absolutely sure it is put back.
+        set_sched_policy(mMyThreadId, SP_FOREGROUND);
     }
 
     return result;
@@ -492,7 +500,12 @@
     LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
 
     mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
-
+    
+    // This thread may have been spawned by a thread that was in the background
+    // scheduling group, so first we will make sure it is in the foreground
+    // one to avoid performing an initial transaction in the background.
+    set_sched_policy(mMyThreadId, SP_FOREGROUND);
+        
     status_t result;
     do {
         processPendingDerefs();
@@ -504,7 +517,7 @@
                   mProcess->mDriverFD, result);
             abort();
         }
-
+        
         // Let this thread exit the thread pool if it is no longer
         // needed and it is not the main process thread.
         if(result == TIMED_OUT && !isMain) {
@@ -567,18 +580,18 @@
             << handle << " / code " << TypeCode(code) << ": "
             << indent << data << dedent << endl;
     }
-
+    
     if (err == NO_ERROR) {
         LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
             (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
         err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
     }
-
+    
     if (err != NO_ERROR) {
         if (reply) reply->setError(err);
         return (mLastError = err);
     }
-
+    
     if ((flags & TF_ONE_WAY) == 0) {
         #if 0
         if (code == 4) { // relayout
@@ -600,7 +613,7 @@
             ALOGI("<<<<<< RETURNING transaction %d", code);
         }
         #endif
-
+        
         IF_LOG_TRANSACTIONS() {
             TextOutput::Bundle _b(alog);
             alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
@@ -611,7 +624,7 @@
     } else {
         err = waitForResponse(NULL, NULL);
     }
-
+    
     return err;
 }
 
@@ -651,14 +664,14 @@
     mOut.writeInt32(0); // xxx was thread priority
     mOut.writeInt32(handle);
     status_t result = UNKNOWN_ERROR;
-
+    
     waitForResponse(NULL, &result);
-
+    
 #if LOG_REFCOUNTS
     printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
         handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
 #endif
-
+    
     return result;
 #else
     (void)handle;
@@ -693,6 +706,7 @@
 
 IPCThreadState::IPCThreadState()
     : mProcess(ProcessState::self()),
+      mMyThreadId(gettid()),
       mStrictModePolicy(0),
       mLastTransactionBinderFlags(0)
 {
@@ -712,7 +726,7 @@
     status_t statusBuffer;
     err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
     if (err < NO_ERROR) return err;
-
+    
     return waitForResponse(NULL, NULL);
 }
 
@@ -726,9 +740,9 @@
         err = mIn.errorCheck();
         if (err < NO_ERROR) break;
         if (mIn.dataAvail() == 0) continue;
-
+        
         cmd = (uint32_t)mIn.readInt32();
-
+        
         IF_LOG_COMMANDS() {
             alog << "Processing waitForResponse Command: "
                 << getReturnString(cmd) << endl;
@@ -738,7 +752,7 @@
         case BR_TRANSACTION_COMPLETE:
             if (!reply && !acquireResult) goto finish;
             break;
-
+        
         case BR_DEAD_REPLY:
             err = DEAD_OBJECT;
             goto finish;
@@ -746,7 +760,7 @@
         case BR_FAILED_REPLY:
             err = FAILED_TRANSACTION;
             goto finish;
-
+        
         case BR_ACQUIRE_RESULT:
             {
                 ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
@@ -755,7 +769,7 @@
                 *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
             }
             goto finish;
-
+        
         case BR_REPLY:
             {
                 binder_transaction_data tr;
@@ -803,7 +817,7 @@
         if (reply) reply->setError(err);
         mLastError = err;
     }
-
+    
     return err;
 }
 
@@ -812,17 +826,17 @@
     if (mProcess->mDriverFD <= 0) {
         return -EBADF;
     }
-
+    
     binder_write_read bwr;
-
+    
     // Is the read buffer empty?
     const bool needRead = mIn.dataPosition() >= mIn.dataSize();
-
+    
     // We don't want to write anything if we are still reading
     // from data left in the input buffer and the caller
     // has requested to read the next data.
     const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
-
+    
     bwr.write_size = outAvail;
     bwr.write_buffer = (uintptr_t)mOut.data();
 
@@ -848,7 +862,7 @@
         alog << "Size of receive buffer: " << bwr.read_size
             << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
     }
-
+    
     // Return immediately if there is nothing to do.
     if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
 
@@ -904,7 +918,7 @@
         }
         return NO_ERROR;
     }
-
+    
     return err;
 }
 
@@ -920,7 +934,7 @@
     tr.cookie = 0;
     tr.sender_pid = 0;
     tr.sender_euid = 0;
-
+    
     const status_t err = data.errorCheck();
     if (err == NO_ERROR) {
         tr.data_size = data.ipcDataSize();
@@ -937,10 +951,10 @@
     } else {
         return (mLastError = err);
     }
-
+    
     mOut.writeInt32(cmd);
     mOut.write(&tr, sizeof(tr));
-
+    
     return NO_ERROR;
 }
 
@@ -956,15 +970,15 @@
     BBinder* obj;
     RefBase::weakref_type* refs;
     status_t result = NO_ERROR;
-
+    
     switch ((uint32_t)cmd) {
     case BR_ERROR:
         result = mIn.readInt32();
         break;
-
+        
     case BR_OK:
         break;
-
+        
     case BR_ACQUIRE:
         refs = (RefBase::weakref_type*)mIn.readPointer();
         obj = (BBinder*)mIn.readPointer();
@@ -980,7 +994,7 @@
         mOut.writePointer((uintptr_t)refs);
         mOut.writePointer((uintptr_t)obj);
         break;
-
+        
     case BR_RELEASE:
         refs = (RefBase::weakref_type*)mIn.readPointer();
         obj = (BBinder*)mIn.readPointer();
@@ -993,7 +1007,7 @@
         }
         mPendingStrongDerefs.push(obj);
         break;
-
+        
     case BR_INCREFS:
         refs = (RefBase::weakref_type*)mIn.readPointer();
         obj = (BBinder*)mIn.readPointer();
@@ -1002,7 +1016,7 @@
         mOut.writePointer((uintptr_t)refs);
         mOut.writePointer((uintptr_t)obj);
         break;
-
+        
     case BR_DECREFS:
         refs = (RefBase::weakref_type*)mIn.readPointer();
         obj = (BBinder*)mIn.readPointer();
@@ -1014,22 +1028,22 @@
         //           refs, obj, refs->refBase());
         mPendingWeakDerefs.push(refs);
         break;
-
+        
     case BR_ATTEMPT_ACQUIRE:
         refs = (RefBase::weakref_type*)mIn.readPointer();
         obj = (BBinder*)mIn.readPointer();
-
+         
         {
             const bool success = refs->attemptIncStrong(mProcess.get());
             ALOG_ASSERT(success && refs->refBase() == obj,
                        "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
                        refs, obj, refs->refBase());
-
+            
             mOut.writeInt32(BC_ACQUIRE_RESULT);
             mOut.writeInt32((int32_t)success);
         }
         break;
-
+    
     case BR_TRANSACTION:
         {
             binder_transaction_data tr;
@@ -1037,14 +1051,14 @@
             ALOG_ASSERT(result == NO_ERROR,
                 "Not enough command data for brTRANSACTION");
             if (result != NO_ERROR) break;
-
+            
             Parcel buffer;
             buffer.ipcSetDataReference(
                 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                 tr.data_size,
                 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                 tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
-
+            
             const pid_t origPid = mCallingPid;
             const uid_t origUid = mCallingUid;
             const int32_t origStrictModePolicy = mStrictModePolicy;
@@ -1054,6 +1068,26 @@
             mCallingUid = tr.sender_euid;
             mLastTransactionBinderFlags = tr.flags;
 
+            int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
+            if (gDisableBackgroundScheduling) {
+                if (curPrio > ANDROID_PRIORITY_NORMAL) {
+                    // We have inherited a reduced priority from the caller, but do not
+                    // want to run in that state in this process.  The driver set our
+                    // priority already (though not our scheduling class), so bounce
+                    // it back to the default before invoking the transaction.
+                    setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
+                }
+            } else {
+                if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
+                    // We want to use the inherited priority from the caller.
+                    // Ensure this thread is in the background scheduling class,
+                    // since the driver won't modify scheduling classes for us.
+                    // The scheduling group is reset to default by the caller
+                    // once this method returns after the transaction is complete.
+                    set_sched_policy(mMyThreadId, SP_BACKGROUND);
+                }
+            }
+
             //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
 
             Parcel reply;
@@ -1087,7 +1121,7 @@
 
             //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
             //     mCallingPid, origPid, origUid);
-
+            
             if ((tr.flags & TF_ONE_WAY) == 0) {
                 LOG_ONEWAY("Sending reply to %d!", mCallingPid);
                 if (error < NO_ERROR) reply.setError(error);
@@ -1095,7 +1129,7 @@
             } else {
                 LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
             }
-
+            
             mCallingPid = origPid;
             mCallingUid = origUid;
             mStrictModePolicy = origStrictModePolicy;
@@ -1106,10 +1140,10 @@
                 alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
                     << tr.target.ptr << ": " << indent << reply << dedent << endl;
             }
-
+            
         }
         break;
-
+    
     case BR_DEAD_BINDER:
         {
             BpBinder *proxy = (BpBinder*)mIn.readPointer();
@@ -1117,24 +1151,24 @@
             mOut.writeInt32(BC_DEAD_BINDER_DONE);
             mOut.writePointer((uintptr_t)proxy);
         } break;
-
+        
     case BR_CLEAR_DEATH_NOTIFICATION_DONE:
         {
             BpBinder *proxy = (BpBinder*)mIn.readPointer();
             proxy->getWeakRefs()->decWeak(proxy);
         } break;
-
+        
     case BR_FINISHED:
         result = TIMED_OUT;
         break;
-
+        
     case BR_NOOP:
         break;
-
+        
     case BR_SPAWN_LOOPER:
         mProcess->spawnPooledThread(false);
         break;
-
+        
     default:
         printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
         result = UNKNOWN_ERROR;
@@ -1144,7 +1178,7 @@
     if (result != NO_ERROR) {
         mLastError = result;
     }
-
+    
     return result;
 }