Merge "add a parameter for PCM limiter enable" into lmp-dev
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 57c4638..dd04dcf 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -1037,10 +1037,13 @@
             
             const pid_t origPid = mCallingPid;
             const uid_t origUid = mCallingUid;
-            
+            const int32_t origStrictModePolicy = mStrictModePolicy;
+            const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
+
             mCallingPid = tr.sender_pid;
             mCallingUid = tr.sender_euid;
-            
+            mLastTransactionBinderFlags = tr.flags;
+
             int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
             if (gDisableBackgroundScheduling) {
                 if (curPrio > ANDROID_PRIORITY_NORMAL) {
@@ -1062,8 +1065,9 @@
             }
 
             //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
-            
+
             Parcel reply;
+            status_t error;
             IF_LOG_TRANSACTIONS() {
                 TextOutput::Bundle _b(alog);
                 alog << "BR_TRANSACTION thr " << (void*)pthread_self()
@@ -1077,19 +1081,18 @@
             }
             if (tr.target.ptr) {
                 sp<BBinder> b((BBinder*)tr.cookie);
-                const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
-                if (error < NO_ERROR) reply.setError(error);
+                error = b->transact(tr.code, buffer, &reply, tr.flags);
 
             } else {
-                const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
-                if (error < NO_ERROR) reply.setError(error);
+                error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
             }
-            
+
             //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);
                 sendReply(reply, 0);
             } else {
                 LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
@@ -1097,6 +1100,8 @@
             
             mCallingPid = origPid;
             mCallingUid = origUid;
+            mStrictModePolicy = origStrictModePolicy;
+            mLastTransactionBinderFlags = origTransactionBinderFlags;
 
             IF_LOG_TRANSACTIONS() {
                 TextOutput::Bundle _b(alog);
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 67fbae5..7c70fa0 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -330,12 +330,26 @@
     return res;
 }
 
+static pthread_mutex_t sLogPrintMutex = PTHREAD_MUTEX_INITIALIZER;
+static nsecs_t sLogPrintTime = 0;
+#define NSECS_DURATION 1000000000
+
 void gl_unimplemented() {
-    ALOGE("called unimplemented OpenGL ES API");
-    char value[PROPERTY_VALUE_MAX];
-    property_get("debug.egl.callstack", value, "0");
-    if (atoi(value)) {
-        CallStack stack(LOG_TAG);
+    bool printLog = false;
+    nsecs_t now = systemTime();
+    pthread_mutex_lock(&sLogPrintMutex);
+    if ((now - sLogPrintTime) > NSECS_DURATION) {
+        sLogPrintTime = now;
+        printLog = true;
+    }
+    pthread_mutex_unlock(&sLogPrintMutex);
+    if (printLog) {
+        ALOGE("called unimplemented OpenGL ES API");
+        char value[PROPERTY_VALUE_MAX];
+        property_get("debug.egl.callstack", value, "0");
+        if (atoi(value)) {
+            CallStack stack(LOG_TAG);
+        }
     }
 }
 
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index ce14f99..2b5e744 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -653,8 +653,8 @@
     KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
 
     // Reuse the repeated key entry if it is otherwise unreferenced.
-    uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
-            | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
+    uint32_t policyFlags = entry->policyFlags &
+            (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
     if (entry->refCount == 1) {
         entry->recycle();
         entry->eventTime = currentTime;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index f953a96..7c57957 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -398,6 +398,24 @@
         for (int i = 0; i < count; i++) {
              mSensorEventBuffer[i].flags = 0;
         }
+
+        // Make a copy of the connection vector as some connections may be removed during the
+        // course of this loop (especially when one-shot sensor events are present in the
+        // sensor_event buffer). Promote all connections to StrongPointers before the lock is
+        // acquired. If the destructor of the sp gets called when the lock is acquired, it may
+        // result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for
+        // cleanup. So copy all the strongPointers to a vector before the lock is acquired.
+        SortedVector< sp<SensorEventConnection> > activeConnections;
+        {
+            Mutex::Autolock _l(mLock);
+            for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
+                sp<SensorEventConnection> connection(mActiveConnections[i].promote());
+                if (connection != 0) {
+                    activeConnections.add(connection);
+                }
+            }
+        }
+
         Mutex::Autolock _l(mLock);
         // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
         // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
@@ -487,21 +505,17 @@
         // Send our events to clients. Check the state of wake lock for each client and release the
         // lock if none of the clients need it.
         bool needsWakeLock = false;
-        // Make a copy of the connection vector as some connections may be removed during the
-        // course of this loop (especially when one-shot sensor events are present in the
-        // sensor_event buffer).
-        const SortedVector< wp<SensorEventConnection> > activeConnections(mActiveConnections);
         size_t numConnections = activeConnections.size();
         for (size_t i=0 ; i < numConnections; ++i) {
-            sp<SensorEventConnection> connection(activeConnections[i].promote());
-            if (connection != 0) {
-                connection->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
+            if (activeConnections[i] != 0) {
+                activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
                         mMapFlushEventsToConnections);
-                needsWakeLock |= connection->needsWakeLock();
+                needsWakeLock |= activeConnections[i]->needsWakeLock();
                 // If the connection has one-shot sensors, it may be cleaned up after first trigger.
                 // Early check for one-shot sensors.
-                if (connection->hasOneShotSensors()) {
-                    cleanupAutoDisabledSensorLocked(connection, mSensorEventBuffer, count);
+                if (activeConnections[i]->hasOneShotSensors()) {
+                    cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
+                            count);
                 }
             }
         }
@@ -985,10 +999,10 @@
 
 SensorService::SensorEventConnection::~SensorEventConnection() {
     ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
+    mService->cleanupConnection(this);
     if (mEventCache != NULL) {
         delete mEventCache;
     }
-    mService->cleanupConnection(this);
 }
 
 void SensorService::SensorEventConnection::onFirstRef() {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 6302053..edfed49 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -314,9 +314,17 @@
     mEventHandler.onHotplugReceived(disp, bool(connected));
 }
 
-static float getDefaultDensity(uint32_t height) {
-    if (height >= 1080) return ACONFIGURATION_DENSITY_XHIGH;
-    else                return ACONFIGURATION_DENSITY_TV;
+static float getDefaultDensity(uint32_t width, uint32_t height) {
+    // Default density is based on TVs: 1080p displays get XHIGH density,
+    // lower-resolution displays get TV density. Maybe eventually we'll need
+    // to update it for 4K displays, though hopefully those just report
+    // accurate DPI information to begin with. This is also used for virtual
+    // displays and even primary displays with older hwcomposers, so be
+    // careful about orientation.
+
+    uint32_t h = width < height ? width : height;
+    if (h >= 1080) return ACONFIGURATION_DENSITY_XHIGH;
+    else           return ACONFIGURATION_DENSITY_TV;
 }
 
 static const uint32_t DISPLAY_ATTRIBUTES[] = {
@@ -383,7 +391,7 @@
         }
 
         if (config.xdpi == 0.0f || config.ydpi == 0.0f) {
-            float dpi = getDefaultDensity(config.height);
+            float dpi = getDefaultDensity(config.width, config.height);
             config.xdpi = dpi;
             config.ydpi = dpi;
         }
@@ -408,7 +416,7 @@
     DisplayConfig& config = mDisplayData[id].configs.editItemAt(configId);
     config.width = w;
     config.height = h;
-    config.xdpi = config.ydpi = getDefaultDensity(h);
+    config.xdpi = config.ydpi = getDefaultDensity(w, h);
     return NO_ERROR;
 }
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index a36ddd9..fa07656 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1042,6 +1042,10 @@
     if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
         // mSidebandStreamChanged was true
         mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
+        recomputeVisibleRegions = true;
+
+        const State& s(getDrawingState());
+        return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
     }
 
     Region outDirtyRegion;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index e712523..f0fe58a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -284,7 +284,7 @@
     /*
      * Returns if a frame is queued.
      */
-    bool hasQueuedFrame() const { return mQueuedFrames > 0; }
+    bool hasQueuedFrame() const { return mQueuedFrames > 0 || mSidebandStreamChanged; }
 
     // -----------------------------------------------------------------------