OSDN Git Service

SurfaceFlinger: add support for secure displays
authorJamie Gennis <jgennis@google.com>
Sat, 20 Oct 2012 01:19:11 +0000 (18:19 -0700)
committerJamie Gennis <jgennis@google.com>
Mon, 22 Oct 2012 20:41:21 +0000 (13:41 -0700)
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

12 files changed:
include/gui/ISurfaceComposer.h
include/gui/SurfaceComposerClient.h
include/ui/DisplayInfo.h
libs/gui/ISurfaceComposer.cpp
libs/gui/SurfaceComposerClient.cpp
services/surfaceflinger/DisplayDevice.cpp
services/surfaceflinger/DisplayDevice.h
services/surfaceflinger/Layer.cpp
services/surfaceflinger/LayerScreenshot.cpp
services/surfaceflinger/LayerScreenshot.h
services/surfaceflinger/SurfaceFlinger.cpp
services/surfaceflinger/SurfaceFlinger.h

index 002aafc..6500ad5 100644 (file)
@@ -69,7 +69,8 @@ public:
     /* create a display
      * requires ACCESS_SURFACE_FLINGER permission.
      */
-    virtual sp<IBinder> createDisplay(const String8& displayName) = 0;
+    virtual sp<IBinder> createDisplay(const String8& displayName,
+            bool secure) = 0;
 
     /* get the token for the existing default displays. possible values
      * for id are eDisplayIdMain and eDisplayIdHdmi.
@@ -108,9 +109,6 @@ public:
     /* returns information about a display
      * intended to be used to get information about built-in displays */
     virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) = 0;
-
-    /* connects to an external display */
-    virtual void connectDisplay(const sp<ISurfaceTexture>& display) = 0;
 };
 
 // ----------------------------------------------------------------------------
index 21d16a9..ae5d69a 100644 (file)
@@ -86,7 +86,7 @@ public:
     );
 
     //! Create a display
-    static sp<IBinder> createDisplay(const String8& displayName);
+    static sp<IBinder> createDisplay(const String8& displayName, bool secure);
 
     //! Get the token for the existing default displays.
     //! Possible values for id are eDisplayIdMain and eDisplayIdHdmi.
index c7dc354..c3a4d6b 100644 (file)
@@ -32,7 +32,8 @@ struct DisplayInfo {
     float fps;
     float density;
     uint8_t orientation;
-    uint8_t reserved[3];
+    bool secure;
+    uint8_t reserved[2];
     // TODO: this needs to go away (currently needed only by webkit)
     PixelFormatInfo pixelFormatInfo;
 };
index aff1b45..85a9488 100644 (file)
@@ -179,11 +179,12 @@ public:
         return result;
     }
 
-    virtual sp<IBinder> createDisplay(const String8& displayName)
+    virtual sp<IBinder> createDisplay(const String8& displayName, bool secure)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeString8(displayName);
+        data.writeInt32(secure ? 1 : 0);
         remote()->transact(BnSurfaceComposer::CREATE_DISPLAY, data, &reply);
         return reply.readStrongBinder();
     }
@@ -222,14 +223,6 @@ public:
         memcpy(info, reply.readInplace(sizeof(DisplayInfo)), sizeof(DisplayInfo));
         return reply.readInt32();
     }
-
-
-    virtual void connectDisplay(const sp<ISurfaceTexture>& display) {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        data.writeStrongBinder(display->asBinder());
-        remote()->transact(BnSurfaceComposer::CONNECT_DISPLAY, data, &reply);
-    }
 };
 
 IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
@@ -309,7 +302,8 @@ status_t BnSurfaceComposer::onTransact(
         case CREATE_DISPLAY: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             String8 displayName = data.readString8();
-            sp<IBinder> display(createDisplay(displayName));
+            bool secure = bool(data.readInt32());
+            sp<IBinder> display(createDisplay(displayName, secure));
             reply->writeStrongBinder(display);
             return NO_ERROR;
         } break;
@@ -338,12 +332,6 @@ status_t BnSurfaceComposer::onTransact(
             memcpy(reply->writeInplace(sizeof(DisplayInfo)), &info, sizeof(DisplayInfo));
             reply->writeInt32(result);
         } break;
-        case CONNECT_DISPLAY: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            sp<ISurfaceTexture> surfaceTexture =
-                    interface_cast<ISurfaceTexture>(data.readStrongBinder());
-            connectDisplay(surfaceTexture);
-        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
index 8586ed2..80dd6ee 100644 (file)
@@ -131,7 +131,7 @@ class Composer : public Singleton<Composer>
     DisplayState& getDisplayStateLocked(const sp<IBinder>& token);
 
 public:
-    sp<IBinder> createDisplay(const String8& displayName);
+    sp<IBinder> createDisplay(const String8& displayName, bool secure);
     sp<IBinder> getBuiltInDisplay(int32_t id);
 
     status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
@@ -175,8 +175,9 @@ ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
 
 // ---------------------------------------------------------------------------
 
-sp<IBinder> Composer::createDisplay(const String8& displayName) {
-    return ComposerService::getComposerService()->createDisplay(displayName);
+sp<IBinder> Composer::createDisplay(const String8& displayName, bool secure) {
+    return ComposerService::getComposerService()->createDisplay(displayName,
+            secure);
 }
 
 sp<IBinder> Composer::getBuiltInDisplay(int32_t id) {
@@ -459,8 +460,9 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface(
     return result;
 }
 
-sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName) {
-    return Composer::getInstance().createDisplay(displayName);
+sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName,
+        bool secure) {
+    return Composer::getInstance().createDisplay(displayName, secure);
 }
 
 sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) {
index 40631ee..ce98b67 100644 (file)
@@ -69,7 +69,9 @@ void checkGLErrors()
 
 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 @@ DisplayDevice::DisplayDevice(
       mDisplayWidth(), mDisplayHeight(), mFormat(),
       mFlags(),
       mPageFlipCount(),
+      mIsSecure(isSecure),
       mSecureLayerVisible(false),
       mScreenAcquired(false),
       mLayerStack(0),
@@ -431,13 +434,13 @@ void DisplayDevice::dump(String8& result, char* buffer, size_t SIZE) const {
     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],
index 058680b..d6da422 100644 (file)
@@ -67,7 +67,9 @@ public:
 
     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 @@ public:
     // 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 @@ private:
     uint32_t        mFlags;
     mutable uint32_t mPageFlipCount;
     String8         mDisplayName;
+    bool            mIsSecure;
 
     /*
      * Can only accessed from the main thread, these members
index c2da238..064f689 100644 (file)
@@ -253,6 +253,10 @@ void Layer::setGeometry(
         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 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
         // 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();
 
index 0fd744f..f8009b3 100644 (file)
@@ -37,7 +37,7 @@ namespace android {
 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 @@ status_t LayerScreenshot::captureLocked(int32_t layerStack) {
         return result;
     }
     initTexture(u, v);
+
+    // Currently screenshot always comes from the default display
+    mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible();
+
     return NO_ERROR;
 }
 
@@ -66,6 +70,10 @@ status_t LayerScreenshot::capture() {
         return result;
     }
     initTexture(u, v);
+
+    // Currently screenshot always comes from the default display
+    mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible();
+    
     return NO_ERROR;
 }
 
@@ -84,6 +92,10 @@ void LayerScreenshot::initStates(uint32_t w, uint32_t h, uint32_t flags) {
     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 @@ void LayerScreenshot::onDraw(const sp<const DisplayDevice>& hw, const Region& cl
             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 @@ void LayerScreenshot::onDraw(const sp<const DisplayDevice>& hw, const Region& cl
         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);
index 7807ffc..38cbd88 100644 (file)
@@ -34,6 +34,7 @@ class LayerScreenshot : public LayerBaseClient
     GLuint mTextureName;
     GLfloat mTexCoords[8];
     sp<SurfaceFlinger> mFlinger;
+    bool mIsSecure;
 public:    
             LayerScreenshot(SurfaceFlinger* flinger, const sp<Client>& client);
         virtual ~LayerScreenshot();
@@ -44,7 +45,7 @@ public:
     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"; }
index 8e569be..38e02f1 100644 (file)
@@ -163,7 +163,8 @@ sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
     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 @@ sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName)
     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 @@ status_t SurfaceFlinger::readyToRun()
 
         // 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 @@ status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo*
     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 @@ sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
     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 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
             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 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                                 "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);
index de97167..b0d3bac 100644 (file)
@@ -140,6 +140,7 @@ private:
     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 @@ private:
         Rect frame;
         uint8_t orientation;
         String8 displayName;
+        bool isSecure;
     };
 
     struct State {
@@ -187,7 +189,7 @@ private:
      */
     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 @@ private:
     // 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