Merge "Rename SETSUSPEND to SETSUSPENDOPT DO NOT MERGE" into gingerbread
diff --git a/include/utils/PollLoop.h b/include/utils/PollLoop.h
index 81230e8..bc616eb 100644
--- a/include/utils/PollLoop.h
+++ b/include/utils/PollLoop.h
@@ -111,12 +111,18 @@
      * This method can be called on any thread.
      * This method may block briefly if it needs to wake the poll loop.
      */
-    void setCallback(int fd, int events, Callback callback, void* data = NULL);
+    void setCallback(int fd, int ident, int events, Callback callback, void* data = NULL);
 
     /**
+     * Convenience for above setCallback when ident is not used.  In this case
+     * the ident is set to POLL_CALLBACK.
+     */
+    void setCallback(int fd, int events, Callback callback, void* data = NULL);
+    
+    /**
      * Like setCallback(), but for the NDK callback function.
      */
-    void setLooperCallback(int fd, int events, ALooper_callbackFunc* callback,
+    void setLooperCallback(int fd, int ident, int events, ALooper_callbackFunc* callback,
             void* data);
     
     /**
@@ -153,11 +159,13 @@
     struct RequestedCallback {
         Callback callback;
         ALooper_callbackFunc* looperCallback;
+        int ident;
         void* data;
     };
 
     struct PendingCallback {
         int fd;
+        int ident;
         int events;
         Callback callback;
         ALooper_callbackFunc* looperCallback;
@@ -185,7 +193,7 @@
     void openWakePipe();
     void closeWakePipe();
 
-    void setCallbackCommon(int fd, int events, Callback callback,
+    void setCallbackCommon(int fd, int ident, int events, Callback callback,
             ALooper_callbackFunc* looperCallback, void* data);
     ssize_t getRequestIndexLocked(int fd);
     void wakeAndLock();
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
index 3396f25..7eb6da5 100644
--- a/libs/gui/SensorEventQueue.cpp
+++ b/libs/gui/SensorEventQueue.cpp
@@ -86,7 +86,7 @@
     Mutex::Autolock _l(mLock);
     if (mPollLoop == 0) {
         mPollLoop = new PollLoop(true);
-        mPollLoop->setCallback(getFd(), POLLIN, NULL, NULL);
+        mPollLoop->setCallback(getFd(), getFd(), POLLIN, NULL, NULL);
     }
     return mPollLoop;
 }
diff --git a/libs/utils/PollLoop.cpp b/libs/utils/PollLoop.cpp
index f740fa0..6d3eeee 100644
--- a/libs/utils/PollLoop.cpp
+++ b/libs/utils/PollLoop.cpp
@@ -95,6 +95,7 @@
     RequestedCallback requestedCallback;
     requestedCallback.callback = NULL;
     requestedCallback.looperCallback = NULL;
+    requestedCallback.ident = 0;
     requestedCallback.data = NULL;
     mRequestedCallbacks.insertAt(requestedCallback, 0);
 }
@@ -116,7 +117,7 @@
         mPendingFdsPos++;
         if (outEvents != NULL) *outEvents = pending.events;
         if (outData != NULL) *outData = pending.data;
-        return pending.fd;
+        return pending.ident;
     }
     
     mLock.lock();
@@ -182,6 +183,7 @@
             const RequestedCallback& requestedCallback = mRequestedCallbacks.itemAt(i);
             PendingCallback pending;
             pending.fd = requestedFd.fd;
+            pending.ident = requestedCallback.ident;
             pending.events = revents;
             pending.callback = requestedCallback.callback;
             pending.looperCallback = requestedCallback.looperCallback;
@@ -191,7 +193,7 @@
                 mPendingCallbacks.push(pending);
             } else if (pending.fd != mWakeReadPipeFd) {
                 if (result == POLL_CALLBACK) {
-                    result = pending.fd;
+                    result = pending.ident;
                     if (outEvents != NULL) *outEvents = pending.events;
                     if (outData != NULL) *outData = pending.data;
                 } else {
@@ -268,16 +270,20 @@
     return mAllowNonCallbacks;
 }
 
+void PollLoop::setCallback(int fd, int ident, int events, Callback callback, void* data) {
+    setCallbackCommon(fd, ident, events, callback, NULL, data);
+}
+
 void PollLoop::setCallback(int fd, int events, Callback callback, void* data) {
-    setCallbackCommon(fd, events, callback, NULL, data);
+    setCallbackCommon(fd, POLL_CALLBACK, events, callback, NULL, data);
 }
 
-void PollLoop::setLooperCallback(int fd, int events, ALooper_callbackFunc* callback,
+void PollLoop::setLooperCallback(int fd, int ident, int events, ALooper_callbackFunc* callback,
         void* data) {
-    setCallbackCommon(fd, events, NULL, callback, data);
+    setCallbackCommon(fd, ident, events, NULL, callback, data);
 }
 
-void PollLoop::setCallbackCommon(int fd, int events, Callback callback,
+void PollLoop::setCallbackCommon(int fd, int ident, int events, Callback callback,
         ALooper_callbackFunc* looperCallback, void* data) {
 
 #if DEBUG_CALLBACKS
@@ -305,6 +311,7 @@
     RequestedCallback requestedCallback;
     requestedCallback.callback = callback;
     requestedCallback.looperCallback = looperCallback;
+    requestedCallback.ident = ident;
     requestedCallback.data = data;
 
     ssize_t index = getRequestIndexLocked(fd);
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 2b1f490..e5ece8e 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -21,6 +21,7 @@
 #include <utils/Log.h>
 
 #include <cutils/sched_policy.h>
+#include <cutils/properties.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -57,7 +58,7 @@
 // ----------------------------------------------------------------------------
 
 /*
- * Create and run a new thead.
+ * Create and run a new thread.
  *
  * We create it "detached", so it cleans up after itself.
  */
@@ -280,6 +281,22 @@
 #endif
 }
 
+#if defined(HAVE_PTHREADS)
+static pthread_once_t gDoSchedulingGroupOnce = PTHREAD_ONCE_INIT;
+static bool gDoSchedulingGroup = true;
+
+static void checkDoSchedulingGroup(void) {
+    char buf[PROPERTY_VALUE_MAX];
+    int len = property_get("debug.sys.noschedgroups", buf, "");
+    if (len > 0) {
+        int temp;
+        if (sscanf(buf, "%d", &temp) == 1) {
+            gDoSchedulingGroup = temp == 0;
+        }
+    }
+}
+#endif
+
 int androidSetThreadSchedulingGroup(pid_t tid, int grp)
 {
     if (grp > ANDROID_TGROUP_MAX || grp < 0) { 
@@ -287,9 +304,12 @@
     }
 
 #if defined(HAVE_PTHREADS)
-    if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
-                                      SP_BACKGROUND : SP_FOREGROUND)) {
-        return PERMISSION_DENIED;
+    pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+    if (gDoSchedulingGroup) {
+        if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
+                                          SP_BACKGROUND : SP_FOREGROUND)) {
+            return PERMISSION_DENIED;
+        }
     }
 #endif
     
@@ -303,10 +323,13 @@
 #if defined(HAVE_PTHREADS)
     int lasterr = 0;
 
-    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(tid, SP_BACKGROUND);
-    } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(tid, SP_FOREGROUND);
+    pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+    if (gDoSchedulingGroup) {
+        if (pri >= ANDROID_PRIORITY_BACKGROUND) {
+            rc = set_sched_policy(tid, SP_BACKGROUND);
+        } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
+            rc = set_sched_policy(tid, SP_FOREGROUND);
+        }
     }
 
     if (rc) {