Merge "Add dataSpace to buffer queues; remove old format enums."
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index f37427a..df46a60 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -169,28 +169,26 @@
 
 uint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, uid_t uid, pid_t spid)
 {
-    struct svcinfo *si;
+    struct svcinfo *si = find_svc(s, len);
+
+    if (!si || !si->handle) {
+        return 0;
+    }
+
+    if (!si->allow_isolated) {
+        // If this service doesn't allow access from isolated processes,
+        // then check the uid to see if it is isolated.
+        uid_t appid = uid % AID_USER;
+        if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
+            return 0;
+        }
+    }
 
     if (!svc_can_find(s, len, spid)) {
-        ALOGE("find_service('%s') uid=%d - PERMISSION DENIED\n",
-             str8(s, len), uid);
         return 0;
     }
-    si = find_svc(s, len);
-    //ALOGI("check_service('%s') handle = %x\n", str8(s, len), si ? si->handle : 0);
-    if (si && si->handle) {
-        if (!si->allow_isolated) {
-            // If this service doesn't allow access from isolated processes,
-            // then check the uid to see if it is isolated.
-            uid_t appid = uid % AID_USER;
-            if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
-                return 0;
-            }
-        }
-        return si->handle;
-    } else {
-        return 0;
-    }
+
+    return si->handle;
 }
 
 int do_add_service(struct binder_state *bs,
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index a146723..40e2fc1 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -158,6 +158,7 @@
 
     virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer);
 
+    virtual int connect(int api, const sp<IProducerListener>& listener);
     virtual int connect(int api);
     virtual int disconnect(int api);
     virtual int setBufferCount(int bufferCount);
diff --git a/include/media/drm/DrmAPI.h b/include/media/drm/DrmAPI.h
index 49939fd..6e84ab4 100644
--- a/include/media/drm/DrmAPI.h
+++ b/include/media/drm/DrmAPI.h
@@ -80,7 +80,8 @@
             kDrmPluginEventProvisionRequired = 1,
             kDrmPluginEventKeyNeeded,
             kDrmPluginEventKeyExpired,
-            kDrmPluginEventVendorDefined
+            kDrmPluginEventVendorDefined,
+            kDrmPluginEventSessionReclaimed
         };
 
         // Drm keys can be for offline content or for online streaming.
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 59288d8..21bb4c4 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -899,14 +899,14 @@
 
         // The crop is too wide
         if (newWidth < currentWidth) {
-            uint32_t dw = (newWidth - currentWidth) / 2;
-            outCrop.left -=dw;
-            outCrop.right += dw;
+            uint32_t dw = (currentWidth - newWidth) / 2;
+            outCrop.left += dw;
+            outCrop.right -= dw;
         // The crop is too tall
         } else if (newHeight < currentHeight) {
-            uint32_t dh = (newHeight - currentHeight) / 2;
-            outCrop.top -= dh;
-            outCrop.bottom += dh;
+            uint32_t dh = (currentHeight - newHeight) / 2;
+            outCrop.top += dh;
+            outCrop.bottom -= dh;
         }
 
         GLC_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]",
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 3f94f6a..aa6f97e 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -557,9 +557,13 @@
 }
 
 int Surface::connect(int api) {
+    static sp<IProducerListener> listener = new DummyProducerListener();
+    return connect(api, listener);
+}
+
+int Surface::connect(int api, const sp<IProducerListener>& listener) {
     ATRACE_CALL();
     ALOGV("Surface::connect");
-    static sp<IProducerListener> listener = new DummyProducerListener();
     Mutex::Autolock lock(mMutex);
     IGraphicBufferProducer::QueueBufferOutput output;
     int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3419295..d01b945 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -148,7 +148,11 @@
         mPrimaryHWVsyncEnabled(false),
         mHWVsyncAvailable(false),
         mDaltonize(false),
-        mHasColorMatrix(false)
+        mHasColorMatrix(false),
+        mHasPoweredOff(false),
+        mFrameBuckets(),
+        mTotalTime(0),
+        mLastSwapTime(0)
 {
     ALOGI("SurfaceFlinger is starting");
 
@@ -949,8 +953,8 @@
         }
     }
 
+    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
     if (kIgnorePresentFences) {
-        const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
         if (hw->isDisplayOn()) {
             enableHardwareVsync();
         }
@@ -969,6 +973,26 @@
         }
         mAnimFrameTracker.advanceFrame();
     }
+
+    if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
+        return;
+    }
+
+    nsecs_t currentTime = systemTime();
+    if (mHasPoweredOff) {
+        mHasPoweredOff = false;
+    } else {
+        nsecs_t period = mPrimaryDispSync.getPeriod();
+        nsecs_t elapsedTime = currentTime - mLastSwapTime;
+        size_t numPeriods = static_cast<size_t>(elapsedTime / period);
+        if (numPeriods < NUM_BUCKETS - 1) {
+            mFrameBuckets[numPeriods] += elapsedTime;
+        } else {
+            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
+        }
+        mTotalTime += elapsedTime;
+    }
+    mLastSwapTime = currentTime;
 }
 
 void SurfaceFlinger::rebuildLayerStacks() {
@@ -2345,6 +2369,7 @@
         }
 
         mVisibleRegionsDirty = true;
+        mHasPoweredOff = true;
         repaintEverything();
     } else if (mode == HWC_POWER_MODE_OFF) {
         if (type == DisplayDevice::DISPLAY_PRIMARY) {
@@ -2445,6 +2470,13 @@
                 mPrimaryDispSync.dump(result);
                 dumpAll = false;
             }
+
+            if ((index < numArgs) &&
+                    (args[index] == String16("--static-screen"))) {
+                index++;
+                dumpStaticScreenStats(result);
+                dumpAll = false;
+            }
         }
 
         if (dumpAll) {
@@ -2548,6 +2580,23 @@
     result.append(config);
 }
 
+void SurfaceFlinger::dumpStaticScreenStats(String8& result) const
+{
+    result.appendFormat("Static screen stats:\n");
+    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
+        float bucketTimeSec = mFrameBuckets[b] / 1e9;
+        float percent = 100.0f *
+                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
+        result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
+                b + 1, bucketTimeSec, percent);
+    }
+    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
+    float percent = 100.0f *
+            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
+    result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
+            NUM_BUCKETS - 1, bucketTimeSec, percent);
+}
+
 void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
         String8& result) const
 {
@@ -2594,6 +2643,11 @@
         mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY));
     result.append("\n");
 
+    // Dump static screen stats
+    result.append("\n");
+    dumpStaticScreenStats(result);
+    result.append("\n");
+
     /*
      * Dump the visible layer list
      */
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 4deb815..34f0aaa 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -416,6 +416,8 @@
 
     void logFrameStats();
 
+    void dumpStaticScreenStats(String8& result) const;
+
     /* ------------------------------------------------------------------------
      * Attributes
      */
@@ -493,6 +495,13 @@
 
     mat4 mColorMatrix;
     bool mHasColorMatrix;
+
+    // Static screen stats
+    bool mHasPoweredOff;
+    static const size_t NUM_BUCKETS = 8; // < 1-7, 7+
+    nsecs_t mFrameBuckets[NUM_BUCKETS];
+    nsecs_t mTotalTime;
+    nsecs_t mLastSwapTime;
 };
 
 }; // namespace android