SurfaceFlinger: add support for secure displays

This change adds support for displays that are not allowed to display surfaces
with the eSecure flag set.  All non-virtual displays are considered secure,
while virtual displays have their secure-ness specified at creation time.

Bug: 7368436
Change-Id: I81ad535d2d1e5a7ff78269017e85b111f0098500
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 40631ee..ce98b67 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -69,7 +69,9 @@
 
 DisplayDevice::DisplayDevice(
         const sp<SurfaceFlinger>& flinger,
-        DisplayType type, const wp<IBinder>& displayToken,
+        DisplayType type,
+        bool isSecure,
+        const wp<IBinder>& displayToken,
         const sp<ANativeWindow>& nativeWindow,
         const sp<FramebufferSurface>& framebufferSurface,
         EGLConfig config)
@@ -83,6 +85,7 @@
       mDisplayWidth(), mDisplayHeight(), mFormat(),
       mFlags(),
       mPageFlipCount(),
+      mIsSecure(isSecure),
       mSecureLayerVisible(false),
       mScreenAcquired(false),
       mLayerStack(0),
@@ -431,13 +434,13 @@
     snprintf(buffer, SIZE,
         "+ DisplayDevice: %s\n"
         "   type=%x, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
-        "flips=%u, secure=%d, acquired=%d, numLayers=%u\n"
+        "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%u\n"
         "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], "
         "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
         mDisplayName.string(), mType,
         mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
         mOrientation, tr.getType(), getPageFlipCount(),
-        mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
+        mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
         mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
         mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
         tr[0][0], tr[1][0], tr[2][0],
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 058680b..d6da422 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -67,7 +67,9 @@
 
     DisplayDevice(
             const sp<SurfaceFlinger>& flinger,
-            DisplayType type, const wp<IBinder>& displayToken,
+            DisplayType type,
+            bool isSecure,
+            const wp<IBinder>& displayToken,
             const sp<ANativeWindow>& nativeWindow,
             const sp<FramebufferSurface>& framebufferSurface,
             EGLConfig config);
@@ -78,6 +80,10 @@
     // when an non existing id is requested
     bool isValid() const;
 
+    // isSecure indicates whether this display can be trusted to display
+    // secure surfaces.
+    bool isSecure() const { return mIsSecure; }
+
     // Flip the front and back buffers if the back buffer is "dirty".  Might
     // be instantaneous, might involve copying the frame buffer around.
     void flip(const Region& dirty) const;
@@ -167,6 +173,7 @@
     uint32_t        mFlags;
     mutable uint32_t mPageFlipCount;
     String8         mDisplayName;
+    bool            mIsSecure;
 
     /*
      * Can only accessed from the main thread, these members
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c2da238..064f689 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -253,6 +253,10 @@
         layer.setSkip(true);
     }
 
+    if (isSecure() && !hw->isSecure()) {
+        layer.setSkip(true);
+    }
+
     /*
      * Transformations are applied in this order:
      * 1) buffer orientation/flip/mirror
@@ -342,7 +346,9 @@
         // is probably going to have something visibly wrong.
     }
 
-    if (!isProtected()) {
+    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
+
+    if (!blackOutLayer) {
         // TODO: we could be more subtle with isFixedSize()
         const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
 
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
index 0fd744f..f8009b3 100644
--- a/services/surfaceflinger/LayerScreenshot.cpp
+++ b/services/surfaceflinger/LayerScreenshot.cpp
@@ -37,7 +37,7 @@
 LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger,
         const sp<Client>& client)
     : LayerBaseClient(flinger, client),
-      mTextureName(0), mFlinger(flinger)
+      mTextureName(0), mFlinger(flinger), mIsSecure(false)
 {
 }
 
@@ -56,6 +56,10 @@
         return result;
     }
     initTexture(u, v);
+
+    // Currently screenshot always comes from the default display
+    mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible();
+
     return NO_ERROR;
 }
 
@@ -66,6 +70,10 @@
         return result;
     }
     initTexture(u, v);
+
+    // Currently screenshot always comes from the default display
+    mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible();
+    
     return NO_ERROR;
 }
 
@@ -84,6 +92,10 @@
     if (!(flags & ISurfaceComposerClient::eHidden)) {
         capture();
     }
+    if (flags & ISurfaceComposerClient::eSecure) {
+        ALOGW("ignoring surface flag eSecure - LayerScreenshot is considered "
+                "secure iff it captures the contents of a secure surface.");
+    }
 }
 
 uint32_t LayerScreenshot::doTransaction(uint32_t flags)
@@ -125,6 +137,11 @@
             glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
         }
 
+        GLuint texName = mTextureName;
+        if (isSecure() && !hw->isSecure()) {
+            texName = mFlinger->getProtectedTexName();
+        }
+
         LayerMesh mesh;
         computeGeometry(hw, &mesh);
 
@@ -133,7 +150,7 @@
         glDisable(GL_TEXTURE_EXTERNAL_OES);
         glEnable(GL_TEXTURE_2D);
 
-        glBindTexture(GL_TEXTURE_2D, mTextureName);
+        glBindTexture(GL_TEXTURE_2D, texName);
         glMatrixMode(GL_TEXTURE);
         glLoadIdentity();
         glMatrixMode(GL_MODELVIEW);
diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h
index 7807ffc..38cbd88 100644
--- a/services/surfaceflinger/LayerScreenshot.h
+++ b/services/surfaceflinger/LayerScreenshot.h
@@ -34,6 +34,7 @@
     GLuint mTextureName;
     GLfloat mTexCoords[8];
     sp<SurfaceFlinger> mFlinger;
+    bool mIsSecure;
 public:    
             LayerScreenshot(SurfaceFlinger* flinger, const sp<Client>& client);
         virtual ~LayerScreenshot();
@@ -44,7 +45,7 @@
     virtual uint32_t doTransaction(uint32_t flags);
     virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
     virtual bool isOpaque() const         { return false; }
-    virtual bool isSecure() const         { return false; }
+    virtual bool isSecure() const         { return mIsSecure; }
     virtual bool isProtectedByApp() const { return false; }
     virtual bool isProtectedByDRM() const { return false; }
     virtual const char* getTypeId() const { return "LayerScreenshot"; }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8e569be..38e02f1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -163,7 +163,8 @@
     return bclient;
 }
 
-sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName)
+sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
+        bool secure)
 {
     class DisplayToken : public BBinder {
         sp<SurfaceFlinger> flinger;
@@ -184,6 +185,7 @@
     Mutex::Autolock _l(mStateLock);
     DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
     info.displayName = displayName;
+    info.isSecure = secure;
     mCurrentState.displays.add(token, info);
 
     return token;
@@ -485,12 +487,14 @@
 
         // set-up the displays that are already connected
         if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
+            // All non-virtual displays are currently considered secure.
+            bool isSecure = true;
             mCurrentState.displays.add(token, DisplayDeviceState(type));
             sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i);
             sp<SurfaceTextureClient> stc = new SurfaceTextureClient(
                         static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
             sp<DisplayDevice> hw = new DisplayDevice(this,
-                    type, token, stc, fbs, mEGLConfig);
+                    type, isSecure, token, stc, fbs, mEGLConfig);
             if (i > DisplayDevice::DISPLAY_PRIMARY) {
                 // FIXME: currently we don't get blank/unblank requests
                 // for displays other than the main display, so we always
@@ -666,6 +670,10 @@
     info->xdpi = xdpi;
     info->ydpi = ydpi;
     info->fps = float(1e9 / hwc.getRefreshPeriod(type));
+
+    // All non-virtual displays are currently considered secure.
+    info->secure = true;
+
     return NO_ERROR;
 }
 
@@ -675,34 +683,6 @@
     return mEventThread->createEventConnection();
 }
 
-void SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture>& surface) {
-
-    sp<IBinder> token;
-    { // scope for the lock
-        Mutex::Autolock _l(mStateLock);
-        token = mExtDisplayToken;
-    }
-
-    if (token == 0) {
-        token = createDisplay(String8("Display from connectDisplay"));
-    }
-
-    { // scope for the lock
-        Mutex::Autolock _l(mStateLock);
-        if (surface == 0) {
-            // release our current display. we're guarantee to have
-            // a reference to it (token), while we hold the lock
-            mExtDisplayToken = 0;
-        } else {
-            mExtDisplayToken = token;
-        }
-
-        DisplayDeviceState& info(mCurrentState.displays.editValueFor(token));
-        info.surface = surface;
-        setTransactionFlags(eDisplayTransactionNeeded);
-    }
-}
-
 // ----------------------------------------------------------------------------
 
 void SurfaceFlinger::waitForEvent() {
@@ -1183,6 +1163,7 @@
             for (size_t i=0 ; i<cc ; i++) {
                 if (draw.indexOfKey(curr.keyAt(i)) < 0) {
                     const DisplayDeviceState& state(curr[i]);
+                    bool isSecure = false;
 
                     sp<FramebufferSurface> fbs;
                     sp<SurfaceTextureClient> stc;
@@ -1193,21 +1174,28 @@
                                 "surface is provided (%p), ignoring it",
                                 state.surface.get());
 
+                        // All non-virtual displays are currently considered
+                        // secure.
+                        isSecure = true;
+
                         // for supported (by hwc) displays we provide our
                         // own rendering surface
                         fbs = new FramebufferSurface(*mHwc, state.type);
                         stc = new SurfaceTextureClient(
-                                static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
+                                static_cast< sp<ISurfaceTexture> >(
+                                        fbs->getBufferQueue()));
                     } else {
                         if (state.surface != NULL) {
                             stc = new SurfaceTextureClient(state.surface);
                         }
+                        isSecure = state.isSecure;
                     }
 
                     const wp<IBinder>& display(curr.keyAt(i));
                     if (stc != NULL) {
                         sp<DisplayDevice> hw = new DisplayDevice(this,
-                                state.type, display, stc, fbs, mEGLConfig);
+                                state.type, isSecure, display, stc, fbs,
+                                mEGLConfig);
                         hw->setLayerStack(state.layerStack);
                         hw->setProjection(state.orientation,
                                 state.viewport, state.frame);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index de97167..b0d3bac 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -140,6 +140,7 @@
     friend class LayerBase;
     friend class LayerBaseClient;
     friend class Layer;
+    friend class LayerScreenshot;
 
     // We're reference counted, never destroy SurfaceFlinger directly
     virtual ~SurfaceFlinger();
@@ -168,6 +169,7 @@
         Rect frame;
         uint8_t orientation;
         String8 displayName;
+        bool isSecure;
     };
 
     struct State {
@@ -187,7 +189,7 @@
      */
     virtual sp<ISurfaceComposerClient> createConnection();
     virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc();
-    virtual sp<IBinder> createDisplay(const String8& displayName);
+    virtual sp<IBinder> createDisplay(const String8& displayName, bool secure);
     virtual sp<IBinder> getBuiltInDisplay(int32_t id);
     virtual void setTransactionState(const Vector<ComposerState>& state,
             const Vector<DisplayState>& displays, uint32_t flags);
@@ -204,7 +206,6 @@
     // called when screen is turning back on
     virtual void unblank(const sp<IBinder>& display);
     virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info);
-    virtual void connectDisplay(const sp<ISurfaceTexture>& display);
 
     /* ------------------------------------------------------------------------
      * DeathRecipient interface