Merge "Implement Display Layer Stats V0.1"
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index c7b51c8..e3130d6 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -105,7 +105,6 @@
     { "video",      "Video",            ATRACE_TAG_VIDEO, { } },
     { "camera",     "Camera",           ATRACE_TAG_CAMERA, { } },
     { "hal",        "Hardware Modules", ATRACE_TAG_HAL, { } },
-    { "app",        "Application",      ATRACE_TAG_APP, { } },
     { "res",        "Resource Loading", ATRACE_TAG_RESOURCES, { } },
     { "dalvik",     "Dalvik VM",        ATRACE_TAG_DALVIK, { } },
     { "rs",         "RenderScript",     ATRACE_TAG_RS, { } },
diff --git a/libs/binder/ActivityManager.cpp b/libs/binder/ActivityManager.cpp
index 9adac26..2728f35 100644
--- a/libs/binder/ActivityManager.cpp
+++ b/libs/binder/ActivityManager.cpp
@@ -80,6 +80,15 @@
     }
 }
 
+bool ActivityManager::isUidActive(const uid_t uid, const String16& callingPackage)
+{
+    sp<IActivityManager> service = getService();
+    if (service != NULL) {
+        return service->isUidActive(uid, callingPackage);
+    }
+    return false;
+}
+
 status_t ActivityManager::linkToDeath(const sp<IBinder::DeathRecipient>& recipient) {
     sp<IActivityManager> service = getService();
     if (service != NULL) {
diff --git a/libs/binder/IActivityManager.cpp b/libs/binder/IActivityManager.cpp
index b7a5fd9..428db4d 100644
--- a/libs/binder/IActivityManager.cpp
+++ b/libs/binder/IActivityManager.cpp
@@ -78,6 +78,18 @@
          data.writeStrongBinder(IInterface::asBinder(observer));
          remote()->transact(UNREGISTER_UID_OBSERVER_TRANSACTION, data, &reply);
     }
+
+    virtual bool isUidActive(const uid_t uid, const String16& callingPackage)
+    {
+         Parcel data, reply;
+         data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor());
+         data.writeInt32(uid);
+         data.writeString16(callingPackage);
+         remote()->transact(IS_UID_ACTIVE_TRANSACTION, data, &reply);
+         // fail on exception
+         if (reply.readExceptionCode() != 0) return false;
+         return reply.readInt32() == 1;
+    }
 };
 
 // ------------------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/ActivityManager.h b/libs/binder/include/binder/ActivityManager.h
index 397382f..3090cae 100644
--- a/libs/binder/include/binder/ActivityManager.h
+++ b/libs/binder/include/binder/ActivityManager.h
@@ -50,6 +50,7 @@
                              const int32_t cutpoint,
                              const String16& callingPackage);
     void unregisterUidObserver(const sp<IUidObserver>& observer);
+    bool isUidActive(const uid_t uid, const String16& callingPackage);
 
     status_t linkToDeath(const sp<IBinder::DeathRecipient>& recipient);
     status_t unlinkToDeath(const sp<IBinder::DeathRecipient>& recipient);
diff --git a/libs/binder/include/binder/IActivityManager.h b/libs/binder/include/binder/IActivityManager.h
index bac2a99..6607c0e 100644
--- a/libs/binder/include/binder/IActivityManager.h
+++ b/libs/binder/include/binder/IActivityManager.h
@@ -35,11 +35,13 @@
                                      const int32_t cutpoint,
                                      const String16& callingPackage) = 0;
     virtual void unregisterUidObserver(const sp<IUidObserver>& observer) = 0;
+    virtual bool isUidActive(const uid_t uid, const String16& callingPackage) = 0;
 
     enum {
         OPEN_CONTENT_URI_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
         REGISTER_UID_OBSERVER_TRANSACTION,
-        UNREGISTER_UID_OBSERVER_TRANSACTION
+        UNREGISTER_UID_OBSERVER_TRANSACTION,
+        IS_UID_ACTIVE_TRANSACTION
     };
 };
 
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 3cf49d6..4c041bc 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -629,7 +629,7 @@
         int32_t ownerUid)
 {
     sp<SurfaceControl> sur;
-    status_t err = NO_ERROR;
+    status_t err = mStatus;
 
     if (mStatus == NO_ERROR) {
         sp<IBinder> handle;
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 66d5595..df391ed 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -58,7 +58,6 @@
 
 class SurfaceTest : public ::testing::Test {
 protected:
-
     SurfaceTest() {
         ProcessState::self()->startThreadPool();
     }
@@ -93,6 +92,16 @@
     sp<SurfaceControl> mSurfaceControl;
 };
 
+TEST_F(SurfaceTest, CreateSurfaceReturnsErrorBadClient) {
+    mComposerClient->dispose();
+    ASSERT_EQ(NO_INIT, mComposerClient->initCheck());
+
+    sp<SurfaceControl> sc;
+    status_t err = mComposerClient->createSurfaceChecked(
+            String8("Test Surface"), 32, 32, PIXEL_FORMAT_RGBA_8888, &sc, 0);
+    ASSERT_EQ(NO_INIT, err);
+}
+
 TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenVisible) {
     sp<ANativeWindow> anw(mSurface);
     int result = -123;
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 3ce5c9f..660a200 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -769,9 +769,14 @@
 
   auto s3 = p->CreateConsumer();
   EXPECT_FALSE(s3);
+  // Note that here the expected error code is EOPNOTSUPP as the socket towards
+  // ProducerChannel has been teared down.
   EXPECT_EQ(s3.error(), EOPNOTSUPP);
 
   s3 = c->CreateConsumer();
   EXPECT_FALSE(s3);
-  EXPECT_EQ(s3.error(), EOPNOTSUPP);
+  // Note that here the expected error code is EPIPE returned from
+  // ConsumerChannel::HandleMessage as the socket is still open but the producer
+  // is gone.
+  EXPECT_EQ(s3.error(), EPIPE);
 }
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 4d32ea6..5c078d3 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -105,6 +105,36 @@
     return value ? "true" : "false";
 }
 
+static std::string motionActionToString(int32_t action) {
+    // Convert MotionEvent action to string
+    switch(action & AMOTION_EVENT_ACTION_MASK) {
+        case AMOTION_EVENT_ACTION_DOWN:
+            return "DOWN";
+        case AMOTION_EVENT_ACTION_MOVE:
+            return "MOVE";
+        case AMOTION_EVENT_ACTION_UP:
+            return "UP";
+        case AMOTION_EVENT_ACTION_POINTER_DOWN:
+            return "POINTER_DOWN";
+        case AMOTION_EVENT_ACTION_POINTER_UP:
+            return "POINTER_UP";
+    }
+    return StringPrintf("%" PRId32, action);
+}
+
+static std::string keyActionToString(int32_t action) {
+    // Convert KeyEvent action to string
+    switch(action) {
+        case AKEY_EVENT_ACTION_DOWN:
+            return "DOWN";
+        case AKEY_EVENT_ACTION_UP:
+            return "UP";
+        case AKEY_EVENT_ACTION_MULTIPLE:
+            return "MULTIPLE";
+    }
+    return StringPrintf("%" PRId32, action);
+}
+
 static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
     return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
             >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
@@ -3979,11 +4009,11 @@
 }
 
 void InputDispatcher::KeyEntry::appendDescription(std::string& msg) const {
-    msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, action=%d, "
+    msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, action=%s, "
             "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
             "repeatCount=%d), policyFlags=0x%08x",
-            deviceId, source, action, flags, keyCode, scanCode, metaState,
-            repeatCount, policyFlags);
+            deviceId, source, keyActionToString(action).c_str(), flags, keyCode,
+            scanCode, metaState, repeatCount, policyFlags);
 }
 
 void InputDispatcher::KeyEntry::recycle() {
@@ -4026,11 +4056,11 @@
 
 void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
     msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
-            ", action=%d, actionButton=0x%08x, "
-            "flags=0x%08x, metaState=0x%08x, buttonState=0x%08x, "
+            ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, buttonState=0x%08x, "
             "edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, pointers=[",
-            deviceId, source, displayId, action, actionButton, flags, metaState, buttonState,
-            edgeFlags, xPrecision, yPrecision);
+            deviceId, source, displayId, motionActionToString(action).c_str(), actionButton, flags,
+            metaState, buttonState, edgeFlags, xPrecision, yPrecision);
+
     for (uint32_t i = 0; i < pointerCount; i++) {
         if (i) {
             msg += ", ";
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index a6caf29..f02c5fa 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -160,8 +160,6 @@
                          bool useIdentityTransform) const {
     ATRACE_CALL();
 
-    CompositionInfo& compositionInfo = getBE().compositionInfo;
-
     if (CC_UNLIKELY(mActiveBuffer == 0)) {
         // the texture has not been created yet, this Layer has
         // in fact never been drawn into. This happens frequently with
@@ -243,7 +241,6 @@
         mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
         mTexture.setFiltering(useFiltering);
         mTexture.setMatrix(textureMatrix);
-        compositionInfo.re.texture = mTexture;
 
         engine.setupLayerTexturing(mTexture);
     } else {
@@ -253,23 +250,6 @@
     engine.disableTexturing();
 }
 
-void BufferLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) const {
-    CompositionInfo& compositionInfo = getBE().compositionInfo;
-    auto& engine(mFlinger->getRenderEngine());
-
-    draw(renderArea, useIdentityTransform);
-
-    engine.setupLayerTexturing(compositionInfo.re.texture);
-    engine.setupLayerBlending(compositionInfo.re.preMultipliedAlpha, compositionInfo.re.opaque,
-            false, compositionInfo.re.color);
-    engine.setSourceDataSpace(compositionInfo.hwc.dataspace);
-    engine.setSourceY410BT2020(compositionInfo.re.Y410BT2020);
-    engine.drawMesh(getBE().getMesh());
-    engine.disableBlending();
-    engine.disableTexturing();
-    engine.setSourceY410BT2020(false);
-}
-
 void BufferLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
     mConsumer->setReleaseFence(releaseFence);
 }
@@ -830,17 +810,21 @@
     texCoords[2] = vec2(right, 1.0f - bottom);
     texCoords[3] = vec2(right, 1.0f - top);
 
-    getBE().compositionInfo.re.preMultipliedAlpha = mPremultipliedAlpha;
-    getBE().compositionInfo.re.opaque = isOpaque(s);
-    getBE().compositionInfo.re.disableTexture = false;
-    getBE().compositionInfo.re.color = getColor();
-    getBE().compositionInfo.hwc.dataspace = mCurrentState.dataSpace;
+    auto& engine(mFlinger->getRenderEngine());
+    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */,
+                              getColor());
+    engine.setSourceDataSpace(mCurrentState.dataSpace);
 
     if (mCurrentState.dataSpace == HAL_DATASPACE_BT2020_ITU_PQ &&
         mConsumer->getCurrentApi() == NATIVE_WINDOW_API_MEDIA &&
         getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102) {
-        getBE().compositionInfo.re.Y410BT2020 = true;
+        engine.setSourceY410BT2020(true);
     }
+
+    engine.drawMesh(getBE().mMesh);
+    engine.disableBlending();
+
+    engine.setSourceY410BT2020(false);
 }
 
 uint32_t BufferLayer::getProducerStickyTransform() const {
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index c7b09ad..6b02f8c 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -101,7 +101,6 @@
      */
     void onDraw(const RenderArea& renderArea, const Region& clip,
                 bool useIdentityTransform) const override;
-    void drawNow(const RenderArea& renderArea, bool useIdentityTransform) const;
 
     void onLayerDisplayed(const sp<Fence>& releaseFence) override;
 
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index 71975c8..911b5a1 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -46,27 +46,16 @@
                         bool useIdentityTransform) const {
     const State& s(getDrawingState());
     if (s.color.a > 0) {
-        computeGeometry(renderArea, getBE().mMesh, useIdentityTransform);
-        getBE().compositionInfo.re.preMultipliedAlpha = getPremultipledAlpha();
-        getBE().compositionInfo.re.opaque = false;
-        getBE().compositionInfo.re.disableTexture = true;
-        getBE().compositionInfo.re.color = s.color;
+        Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
+        computeGeometry(renderArea, mesh, useIdentityTransform);
+        auto& engine(mFlinger->getRenderEngine());
+        engine.setupLayerBlending(getPremultipledAlpha(), false /* opaque */,
+                                  true /* disableTexture */, s.color);
+        engine.drawMesh(mesh);
+        engine.disableBlending();
     }
 }
 
-void ColorLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) const {
-    CompositionInfo& compositionInfo = getBE().compositionInfo;
-    auto& engine(mFlinger->getRenderEngine());
-
-    draw(renderArea, useIdentityTransform);
-
-    engine.setupLayerBlending(compositionInfo.re.preMultipliedAlpha, compositionInfo.re.opaque,
-            compositionInfo.re.disableTexture, compositionInfo.re.color);
-    engine.setSourceDataSpace(compositionInfo.hwc.dataspace);
-    engine.drawMesh(getBE().getMesh());
-    engine.disableBlending();
-}
-
 bool ColorLayer::isVisible() const {
     const Layer::State& s(getDrawingState());
     return !isHiddenByPolicy() && s.color.a;
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index e8fb92d..0cde398 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -32,7 +32,6 @@
     virtual const char* getTypeId() const { return "ColorLayer"; }
     virtual void onDraw(const RenderArea& renderArea, const Region& clip,
                         bool useIdentityTransform) const;
-    void drawNow(const RenderArea& , bool ) const;
     bool isVisible() const override;
 
     void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override;
diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp
index 320c0df..f259d93 100644
--- a/services/surfaceflinger/ContainerLayer.cpp
+++ b/services/surfaceflinger/ContainerLayer.cpp
@@ -30,8 +30,6 @@
 
 void ContainerLayer::onDraw(const RenderArea&, const Region& /* clip */, bool) const {}
 
-void ContainerLayer::drawNow(const RenderArea&, bool) const {}
-
 bool ContainerLayer::isVisible() const {
     return !isHiddenByPolicy();
 }
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index 50c0191..543f60a 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -32,7 +32,6 @@
     const char* getTypeId() const override { return "ContainerLayer"; }
     void onDraw(const RenderArea& renderArea, const Region& clip,
                 bool useIdentityTransform) const override;
-    void drawNow(const RenderArea& renderArea, bool useIdentityTransform) const override;
     bool isVisible() const override;
 
     void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 43bef60..5428e2e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -625,15 +625,9 @@
         transform = Transform(invTransform) * tr * bufferOrientation;
     }
 
-    // STOPSHIP (b/72106793): If we have less than 25% scaling, HWC usually needs to use the rotator
-    // to handle it. However, there is one guaranteed frame of jank when we switch to using the
-    // rotator. In the meantime, we force GL composition instead until we have a better fix for the
-    // HWC issue.
-    bool extremeScaling = abs(t[0][0]) <= 0.25 || abs(t[1][1]) <= 0.25;
-
     // this gives us only the "orientation" component of the transform
     const uint32_t orientation = transform.getOrientation();
-    if (orientation & Transform::ROT_INVALID || extremeScaling) {
+    if (orientation & Transform::ROT_INVALID) {
         // we can only handle simple transformation
         hwcInfo.forceClientComposition = true;
     } else {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5c00833..325d93c 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -360,16 +360,6 @@
     void draw(const RenderArea& renderArea) const;
 
     /*
-     * drawNow uses the renderEngine to draw the layer.  This is different than the
-     * draw function as with the FE/BE split, the draw function runs in the FE and
-     * sets up state for the BE to do the actual drawing.  drawNow is used to tell
-     * the layer to skip the state setup and just go ahead and draw the layer.  This
-     * is used for screen captures which happens separately from the frame
-     * compositing path.
-     */
-    virtual void drawNow(const RenderArea& renderArea, bool useIdentityTransform) const = 0;
-
-    /*
      * doTransaction - process the transaction. This is a good place to figure
      * out which attributes of the surface have changed.
      */
diff --git a/services/surfaceflinger/LayerBE.cpp b/services/surfaceflinger/LayerBE.cpp
index 78330fd..5287fe1 100644
--- a/services/surfaceflinger/LayerBE.cpp
+++ b/services/surfaceflinger/LayerBE.cpp
@@ -57,8 +57,7 @@
     ALOGV("[%s]\tblackoutLayer=%d", tag, re.blackoutLayer);
     ALOGV("[%s]\tclearArea=%d", tag, re.clearArea);
     ALOGV("[%s]\tpreMultipliedAlpha=%d", tag, re.preMultipliedAlpha);
-    ALOGV("[%s]\topaque=%d", tag, re.opaque);
-    ALOGV("[%s]\tdisableTexture=%d", tag, re.disableTexture);
+    ALOGV("[%s]\topaque=%d\n", tag, re.opaque);
     ALOGV("[%s]\ttexture:name(%d), target(%d), size(%d/%d)", tag, re.texture.getTextureName(), re.texture.getTextureTarget(), (unsigned int)re.texture.getWidth(), (unsigned int)re.texture.getHeight());
     ALOGV("[%s]\tuseIdentityTransform=%d\n", tag, re.useIdentityTransform);
 }
diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h
index 854cdd6..981f756 100644
--- a/services/surfaceflinger/LayerBE.h
+++ b/services/surfaceflinger/LayerBE.h
@@ -87,11 +87,9 @@
         bool clearArea = false;
         bool preMultipliedAlpha = false;
         bool opaque = false;
-        bool disableTexture = false;
         half4 color;
         Texture texture;
         bool useIdentityTransform = false;
-        bool Y410BT2020 = false;
     } re;
 
     void dump(const char* tag) const;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e104727..b9e5d3f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3677,6 +3677,7 @@
         ALOGE("Attempting to set unknown power mode: %d\n", mode);
         getHwComposer().setPowerMode(type, mode);
     }
+    ALOGD("Finished set power mode=%d, type=%d", mode, hw->getDisplayType());
 }
 
 void SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
@@ -4818,7 +4819,7 @@
 
     traverseLayers([&](Layer* layer) {
         if (filtering) layer->setFiltering(true);
-        layer->drawNow(renderArea, useIdentityTransform);
+        layer->draw(renderArea, useIdentityTransform);
         if (filtering) layer->setFiltering(false);
     });
 }
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index e141b91..c38c12b 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -134,7 +134,6 @@
            channel_id(), buffer_id(), buffer_state_->load());
   for (auto consumer : consumer_channels_) {
     consumer->OnProducerClosed();
-    service()->SetChannel(consumer->channel_id(), nullptr);
   }
   Hangup();
 }