diff options
author | Craig Mautner <cmautner@google.com> | 2014-04-17 18:39:38 -0700 |
---|---|---|
committer | Craig Mautner <cmautner@google.com> | 2014-04-21 15:28:42 -0700 |
commit | f4c909bcb87d6f103c9f9e8255fa61bd86f4de67 (patch) | |
tree | 4bda1df837e743ddf10e33424de390571603907e /core/java/android/app/ActivityView.java | |
parent | 72eec7f6c9509fb86f46fbdb619523efacb8d02e (diff) | |
download | frameworks_base-f4c909bcb87d6f103c9f9e8255fa61bd86f4de67.zip frameworks_base-f4c909bcb87d6f103c9f9e8255fa61bd86f4de67.tar.gz frameworks_base-f4c909bcb87d6f103c9f9e8255fa61bd86f4de67.tar.bz2 |
Fix ActivityView lifecycle
Major changes to maintain the VirtualDisplay across repeated
attach/detach cycles of an ActivityView. This keeps the activities
and VirtualDisplays in the ActivityView from getting into bad states.
Fixes bug 14107002.
Change-Id: Idc2aaf85ac496eab0eeb436736cb10a2020040e8
Diffstat (limited to 'core/java/android/app/ActivityView.java')
-rw-r--r-- | core/java/android/app/ActivityView.java | 170 |
1 files changed, 95 insertions, 75 deletions
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 51cb12a..a4ea17b 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -33,15 +33,18 @@ import android.view.MotionEvent; import android.view.Surface; import android.view.TextureView; import android.view.TextureView.SurfaceTextureListener; -import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import dalvik.system.CloseGuard; + +import java.lang.ref.WeakReference; /** @hide */ public class ActivityView extends ViewGroup { - private final String TAG = "ActivityView"; - private final boolean DEBUG = false; + private static final String TAG = "ActivityView"; + private static final boolean DEBUG = false; + DisplayMetrics mMetrics; private final TextureView mTextureView; private IActivityContainer mActivityContainer; private Activity mActivity; @@ -53,6 +56,8 @@ public class ActivityView extends ViewGroup { IIntentSender mQueuedPendingIntent; Intent mQueuedIntent; + private final CloseGuard mGuard = CloseGuard.get(); + public ActivityView(Context context) { this(context, null); } @@ -75,60 +80,30 @@ public class ActivityView extends ViewGroup { throw new IllegalStateException("The ActivityView's Context is not an Activity."); } - mTextureView = new TextureView(context); - mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener()); - addView(mTextureView); - if (DEBUG) Log.v(TAG, "ctor()"); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - mTextureView.layout(0, 0, r - l, b - t); - } - - @Override - protected void onAttachedToWindow() { - if (DEBUG) Log.v(TAG, "onAttachedToWindow()"); - super.onAttachedToWindow(); try { - final IBinder token = mActivity.getActivityToken(); - mActivityContainer = ActivityManagerNative.getDefault().createActivityContainer(token, - new ActivityContainerCallback()); + mActivityContainer = ActivityManagerNative.getDefault().createActivityContainer( + mActivity.getActivityToken(), new ActivityContainerCallback(this)); } catch (RemoteException e) { throw new IllegalStateException("ActivityView: Unable to create ActivityContainer. " + e); } - attachToSurfaceWhenReady(); - } + mTextureView = new TextureView(context); + mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener()); + addView(mTextureView); - @Override - protected void onDetachedFromWindow() { - if (DEBUG) Log.v(TAG, "onDetachedFromWindow(): mActivityContainer=" + mActivityContainer); - super.onDetachedFromWindow(); - if (mActivityContainer != null) { - detach(); - try { - ActivityManagerNative.getDefault().deleteActivityContainer(mActivityContainer); - } catch (RemoteException e) { - } - mActivityContainer = null; - } + WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE); + mMetrics = new DisplayMetrics(); + wm.getDefaultDisplay().getMetrics(mMetrics); + + mGuard.open("release"); + + if (DEBUG) Log.v(TAG, "ctor()"); } @Override - protected void onWindowVisibilityChanged(int visibility) { - if (DEBUG) Log.v(TAG, "onWindowVisibilityChanged(): visibility=" + visibility); - super.onWindowVisibilityChanged(visibility); - switch (visibility) { - case View.VISIBLE: - attachToSurfaceWhenReady(); - break; - case View.INVISIBLE: - break; - case View.GONE: - break; - } + protected void onLayout(boolean changed, int l, int t, int r, int b) { + mTextureView.layout(0, 0, r - l, b - t); } private boolean injectInputEvent(InputEvent event) { @@ -159,6 +134,9 @@ public class ActivityView extends ViewGroup { } public void startActivity(Intent intent) { + if (mActivityContainer == null) { + throw new IllegalStateException("Attempt to call startActivity after release"); + } if (DEBUG) Log.v(TAG, "startActivity(): intent=" + intent + " " + (isAttachedToDisplay() ? "" : "not") + " attached"); if (mSurface != null) { @@ -183,6 +161,9 @@ public class ActivityView extends ViewGroup { } public void startActivity(IntentSender intentSender) { + if (mActivityContainer == null) { + throw new IllegalStateException("Attempt to call startActivity after release"); + } if (DEBUG) Log.v(TAG, "startActivityIntentSender(): intentSender=" + intentSender + " " + (isAttachedToDisplay() ? "" : "not") + " attached"); final IIntentSender iIntentSender = intentSender.getTarget(); @@ -195,6 +176,9 @@ public class ActivityView extends ViewGroup { } public void startActivity(PendingIntent pendingIntent) { + if (mActivityContainer == null) { + throw new IllegalStateException("Attempt to call startActivity after release"); + } if (DEBUG) Log.v(TAG, "startActivityPendingIntent(): PendingIntent=" + pendingIntent + " " + (isAttachedToDisplay() ? "" : "not") + " attached"); final IIntentSender iIntentSender = pendingIntent.getTarget(); @@ -206,24 +190,54 @@ public class ActivityView extends ViewGroup { } } + public void release() { + if (DEBUG) Log.v(TAG, "release()"); + if (mActivityContainer == null) { + Log.e(TAG, "Duplicate call to release"); + return; + } + try { + mActivityContainer.release(); + } catch (RemoteException e) { + } + mActivityContainer = null; + + if (mSurface != null) { + mSurface.release(); + mSurface = null; + } + + mTextureView.setSurfaceTextureListener(null); + + mGuard.close(); + } + + @Override + protected void finalize() throws Throwable { + try { + if (mGuard != null) { + mGuard.warnIfOpen(); + release(); + } + } finally { + super.finalize(); + } + } + private void attachToSurfaceWhenReady() { final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture(); - if (mActivityContainer == null || surfaceTexture == null || mSurface != null) { + if (surfaceTexture == null || mSurface != null) { // Either not ready to attach, or already attached. return; } - WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE); - DisplayMetrics metrics = new DisplayMetrics(); - wm.getDefaultDisplay().getMetrics(metrics); - mSurface = new Surface(surfaceTexture); try { - mActivityContainer.attachToSurface(mSurface, mWidth, mHeight, metrics.densityDpi); + mActivityContainer.setSurface(mSurface, mWidth, mHeight, mMetrics.densityDpi); } catch (RemoteException e) { mSurface.release(); mSurface = null; - throw new IllegalStateException( + throw new RuntimeException( "ActivityView: Unable to create ActivityContainer. " + e); } @@ -238,41 +252,43 @@ public class ActivityView extends ViewGroup { } } - private void detach() { - if (DEBUG) Log.d(TAG, "detach: attached=" + isAttachedToDisplay()); - if (mSurface != null) { - try { - mActivityContainer.detachFromDisplay(); - } catch (RemoteException e) { - } - mSurface.release(); - mSurface = null; - } - } - private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener { @Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { + if (mActivityContainer == null) { + return; + } if (DEBUG) Log.d(TAG, "onSurfaceTextureAvailable: width=" + width + " height=" + height); mWidth = width; mHeight = height; - if (mActivityContainer != null) { - attachToSurfaceWhenReady(); - } + attachToSurfaceWhenReady(); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) { + if (mActivityContainer == null) { + return; + } if (DEBUG) Log.d(TAG, "onSurfaceTextureSizeChanged: w=" + width + " h=" + height); } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { + if (mActivityContainer == null) { + return true; + } if (DEBUG) Log.d(TAG, "onSurfaceTextureDestroyed"); - detach(); + mSurface.release(); + mSurface = null; + try { + mActivityContainer.setSurface(null, mWidth, mHeight, mMetrics.densityDpi); + } catch (RemoteException e) { + throw new RuntimeException( + "ActivityView: Unable to set surface of ActivityContainer. " + e); + } return true; } @@ -283,13 +299,17 @@ public class ActivityView extends ViewGroup { } - private class ActivityContainerCallback extends IActivityContainerCallback.Stub { + private static class ActivityContainerCallback extends IActivityContainerCallback.Stub { + private final WeakReference<ActivityView> mActivityViewWeakReference; + + ActivityContainerCallback(ActivityView activityView) { + mActivityViewWeakReference = new WeakReference<ActivityView>(activityView); + } + @Override public void setVisible(IBinder container, boolean visible) { - if (DEBUG) Log.v(TAG, "setVisible(): container=" + container + " visible=" + visible); - if (visible) { - } else { - } + if (DEBUG) Log.v(TAG, "setVisible(): container=" + container + " visible=" + visible + + " ActivityView=" + mActivityViewWeakReference.get()); } } } |