OSDN Git Service

Fix black ActivityView
authorCraig Mautner <cmautner@google.com>
Mon, 21 Apr 2014 22:22:06 +0000 (15:22 -0700)
committerCraig Mautner <cmautner@google.com>
Mon, 21 Apr 2014 22:28:43 +0000 (15:28 -0700)
Don't add the surface to the VirtualDisplay until the activity
has drawn. That will keep the TextureView from turning black.

Fixes bug 12821632.

Change-Id: Ia06e9f91be3e14ad724f735ae4e201ac798863a2

core/java/android/app/ActivityView.java
services/core/java/com/android/server/am/ActivityStack.java
services/core/java/com/android/server/am/ActivityStackSupervisor.java

index f6c4c8e..edf21dd 100644 (file)
@@ -83,7 +83,7 @@ public class ActivityView extends ViewGroup {
                     ActivityManagerNative.getDefault().createActivityContainer(
                             mActivity.getActivityToken(), new ActivityContainerCallback(this)));
         } catch (RemoteException e) {
-            throw new IllegalStateException("ActivityView: Unable to create ActivityContainer. "
+            throw new RuntimeException("ActivityView: Unable to create ActivityContainer. "
                     + e);
         }
 
@@ -122,6 +122,18 @@ public class ActivityView extends ViewGroup {
         return super.onGenericMotionEvent(event);
     }
 
+    @Override
+    public void onAttachedToWindow() {
+        if (DEBUG) Log.v(TAG, "onAttachedToWindow(): mActivityContainer=" + mActivityContainer +
+                " mSurface=" + mSurface);
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        if (DEBUG) Log.v(TAG, "onDetachedFromWindow(): mActivityContainer=" + mActivityContainer +
+                " mSurface=" + mSurface);
+    }
+
     public boolean isAttachedToDisplay() {
         return mSurface != null;
     }
@@ -171,7 +183,8 @@ public class ActivityView extends ViewGroup {
     }
 
     public void release() {
-        if (DEBUG) Log.v(TAG, "release()");
+        if (DEBUG) Log.v(TAG, "release() mActivityContainer=" + mActivityContainer +
+                " mSurface=" + mSurface);
         if (mActivityContainer == null) {
             Log.e(TAG, "Duplicate call to release");
             return;
@@ -200,14 +213,13 @@ public class ActivityView extends ViewGroup {
         } catch (RemoteException e) {
             mSurface.release();
             mSurface = null;
-            throw new RuntimeException(
-                    "ActivityView: Unable to create ActivityContainer. " + e);
+            throw new RuntimeException("ActivityView: Unable to create ActivityContainer. " + e);
         }
 
         if (DEBUG) Log.v(TAG, "attachToSurfaceWhenReady: " + (mQueuedIntent != null ||
                 mQueuedPendingIntent != null ? "" : "no") + " queued intent");
         if (mQueuedIntent != null) {
-            startActivity(mQueuedIntent);
+            mActivityContainer.startActivity(mQueuedIntent);
             mQueuedIntent = null;
         } else if (mQueuedPendingIntent != null) {
             mActivityContainer.startActivityIntentSender(mQueuedPendingIntent);
@@ -301,7 +313,7 @@ public class ActivityView extends ViewGroup {
             try {
                 return mIActivityContainer.startActivity(intent);
             } catch (RemoteException e) {
-                throw new IllegalStateException("ActivityView: Unable to startActivity. " + e);
+                throw new RuntimeException("ActivityView: Unable to startActivity. " + e);
             }
         }
 
@@ -309,7 +321,7 @@ public class ActivityView extends ViewGroup {
             try {
                 return mIActivityContainer.startActivityIntentSender(intentSender);
             } catch (RemoteException e) {
-                throw new IllegalStateException(
+                throw new RuntimeException(
                         "ActivityView: Unable to startActivity from IntentSender. " + e);
             }
         }
index f4f39e2..e4b196e 100755 (executable)
@@ -1233,6 +1233,7 @@ final class ActivityStack {
      * occurred and the activity will be notified immediately.
      */
     void notifyActivityDrawnLocked(ActivityRecord r) {
+        mActivityContainer.setDrawn();
         if ((r == null)
                 || (mUndrawnActivitiesBelowTopTranslucent.remove(r) &&
                         mUndrawnActivitiesBelowTopTranslucent.isEmpty())) {
@@ -1274,7 +1275,7 @@ final class ActivityStack {
 
         ActivityRecord parent = mActivityContainer.mParentActivity;
         if ((parent != null && parent.state != ActivityState.RESUMED) ||
-                mActivityContainer.mContainerState != CONTAINER_STATE_HAS_SURFACE) {
+                !mActivityContainer.isAttached()) {
             // Do not resume this stack if its parent is not resumed.
             // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
             return false;
index a316336..71924b0 100644 (file)
@@ -3080,6 +3080,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
             }
         }
 
+        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
         void setVisible(boolean visible) {
             if (mVisible != visible) {
                 mVisible = visible;
@@ -3090,6 +3091,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
             }
         }
 
+        void setDrawn() {
+        }
+
         @Override
         public String toString() {
             return mIdString + (mActivityDisplay == null ? "N" : "A");
@@ -3098,6 +3102,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
 
     private class VirtualActivityContainer extends ActivityContainer {
         Surface mSurface;
+        boolean mDrawn = false;
 
         VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
             super(getNextStackId());
@@ -3129,7 +3134,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
                     (VirtualActivityDisplay) mActivityDisplay;
             if (virtualActivityDisplay == null) {
                 virtualActivityDisplay =
-                        new VirtualActivityDisplay(surface, width, height, density);
+                        new VirtualActivityDisplay(width, height, density);
                 mActivityDisplay = virtualActivityDisplay;
                 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
                 attachToDisplayLocked(virtualActivityDisplay);
@@ -3137,23 +3142,40 @@ public final class ActivityStackSupervisor implements DisplayListener {
 
             if (mSurface != null) {
                 mSurface.release();
-                mSurface = null;
             }
 
+            mSurface = surface;
             if (surface != null) {
-                mContainerState = CONTAINER_STATE_HAS_SURFACE;
-                mSurface = surface;
                 mStack.resumeTopActivityLocked(null);
             } else {
                 mContainerState = CONTAINER_STATE_NO_SURFACE;
-                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
-                    mStack.startPausingLocked(false, true);
-                }
+                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
+//                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
+//                    mStack.startPausingLocked(false, true);
+//                }
             }
+
+            setSurfaceIfReady();
+
             if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
                     + virtualActivityDisplay);
+        }
 
-            virtualActivityDisplay.setSurface(surface);
+        @Override
+        void setDrawn() {
+            synchronized (mService) {
+                mDrawn = true;
+                setSurfaceIfReady();
+            }
+        }
+
+        private void setSurfaceIfReady() {
+            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReady: mDrawn=" + mDrawn +
+                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
+            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
+                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
+                mContainerState = CONTAINER_STATE_HAS_SURFACE;
+            }
         }
     }
 
@@ -3209,10 +3231,10 @@ public final class ActivityStackSupervisor implements DisplayListener {
     class VirtualActivityDisplay extends ActivityDisplay {
         VirtualDisplay mVirtualDisplay;
 
-        VirtualActivityDisplay(Surface surface, int width, int height, int density) {
+        VirtualActivityDisplay(int width, int height, int density) {
             DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
             mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME,
-                    width, height, density, surface, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
+                    width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
                     DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
 
             init(mVirtualDisplay.getDisplay());