summaryrefslogtreecommitdiffstats
path: root/core/java/android/app/ActivityView.java
diff options
context:
space:
mode:
authorCraig Mautner <cmautner@google.com>2014-04-17 18:39:38 -0700
committerCraig Mautner <cmautner@google.com>2014-04-21 15:28:42 -0700
commitf4c909bcb87d6f103c9f9e8255fa61bd86f4de67 (patch)
tree4bda1df837e743ddf10e33424de390571603907e /core/java/android/app/ActivityView.java
parent72eec7f6c9509fb86f46fbdb619523efacb8d02e (diff)
downloadframeworks_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.java170
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());
}
}
}