* commit '7ad27288f1b66733a4fcb2bdcb17dd5db6c6423d': Fix ActivityView lifecycle
This commit is contained in:
@@ -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,9 +80,24 @@ public class ActivityView extends ViewGroup {
|
||||
throw new IllegalStateException("The ActivityView's Context is not an Activity.");
|
||||
}
|
||||
|
||||
try {
|
||||
mActivityContainer = ActivityManagerNative.getDefault().createActivityContainer(
|
||||
mActivity.getActivityToken(), new ActivityContainerCallback(this));
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException("ActivityView: Unable to create ActivityContainer. "
|
||||
+ e);
|
||||
}
|
||||
|
||||
mTextureView = new TextureView(context);
|
||||
mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener());
|
||||
addView(mTextureView);
|
||||
|
||||
WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
|
||||
mMetrics = new DisplayMetrics();
|
||||
wm.getDefaultDisplay().getMetrics(mMetrics);
|
||||
|
||||
mGuard.open("release");
|
||||
|
||||
if (DEBUG) Log.v(TAG, "ctor()");
|
||||
}
|
||||
|
||||
@@ -86,51 +106,6 @@ public class ActivityView extends ViewGroup {
|
||||
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());
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException("ActivityView: Unable to create ActivityContainer. "
|
||||
+ e);
|
||||
}
|
||||
|
||||
attachToSurfaceWhenReady();
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean injectInputEvent(InputEvent event) {
|
||||
try {
|
||||
return mActivityContainer != null && mActivityContainer.injectEvent(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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,10 @@ import android.view.Surface;
|
||||
/** @hide */
|
||||
interface IActivityContainer {
|
||||
void attachToDisplay(int displayId);
|
||||
void attachToSurface(in Surface surface, int width, int height, int density);
|
||||
void detachFromDisplay();
|
||||
void setSurface(in Surface surface, int width, int height, int density);
|
||||
int startActivity(in Intent intent);
|
||||
int startActivityIntentSender(in IIntentSender intentSender);
|
||||
int getDisplayId();
|
||||
boolean injectEvent(in InputEvent event);
|
||||
void release();
|
||||
}
|
||||
|
||||
@@ -7240,6 +7240,9 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
if (r == null) {
|
||||
return null;
|
||||
}
|
||||
if (callback == null) {
|
||||
throw new IllegalArgumentException("callback must not be null");
|
||||
}
|
||||
return mStackSupervisor.createActivityContainer(r, callback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ final class ActivityRecord {
|
||||
boolean forceNewConfig; // force re-create with new config next time
|
||||
int launchCount; // count of launches since last state
|
||||
long lastLaunchTime; // time of last lauch of this activity
|
||||
ArrayList<ActivityStack> mChildContainers = new ArrayList<ActivityStack>();
|
||||
ArrayList<ActivityContainer> mChildContainers = new ArrayList<ActivityContainer>();
|
||||
|
||||
String stringName; // for caching of toString().
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ import static com.android.server.am.ActivityStackSupervisor.DEBUG_SAVED_STATE;
|
||||
import static com.android.server.am.ActivityStackSupervisor.DEBUG_STATES;
|
||||
import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
|
||||
|
||||
import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.CONTAINER_STATE_HAS_SURFACE;
|
||||
|
||||
import com.android.internal.os.BatteryStatsImpl;
|
||||
import com.android.server.Watchdog;
|
||||
import com.android.server.am.ActivityManagerService.ItemMatcher;
|
||||
@@ -1066,9 +1068,9 @@ final class ActivityStack {
|
||||
private void setVisibile(ActivityRecord r, boolean visible) {
|
||||
r.visible = visible;
|
||||
mWindowManager.setAppVisibility(r.appToken, visible);
|
||||
final ArrayList<ActivityStack> containers = r.mChildContainers;
|
||||
final ArrayList<ActivityContainer> containers = r.mChildContainers;
|
||||
for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) {
|
||||
ActivityContainer container = containers.get(containerNdx).mActivityContainer;
|
||||
ActivityContainer container = containers.get(containerNdx);
|
||||
container.setVisible(visible);
|
||||
}
|
||||
}
|
||||
@@ -1336,7 +1338,8 @@ final class ActivityStack {
|
||||
if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
|
||||
|
||||
ActivityRecord parent = mActivityContainer.mParentActivity;
|
||||
if (parent != null && parent.state != ActivityState.RESUMED) {
|
||||
if ((parent != null && parent.state != ActivityState.RESUMED) ||
|
||||
mActivityContainer.mContainerState != CONTAINER_STATE_HAS_SURFACE) {
|
||||
// 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;
|
||||
@@ -2624,6 +2627,20 @@ final class ActivityStack {
|
||||
return r;
|
||||
}
|
||||
|
||||
void finishAllActivitiesLocked() {
|
||||
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
|
||||
final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
|
||||
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
|
||||
final ActivityRecord r = activities.get(activityNdx);
|
||||
if (r.finishing) {
|
||||
continue;
|
||||
}
|
||||
Slog.d(TAG, "finishAllActivitiesLocked: finishing " + r);
|
||||
finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final boolean navigateUpToLocked(IBinder token, Intent destIntent, int resultCode,
|
||||
Intent resultData) {
|
||||
final ActivityRecord srec = ActivityRecord.forToken(token);
|
||||
@@ -2862,7 +2879,6 @@ final class ActivityStack {
|
||||
}
|
||||
if (activityRemoved) {
|
||||
mStackSupervisor.resumeTopActivitiesLocked();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,6 @@ import com.android.server.wm.WindowManagerService;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -225,11 +224,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
|
||||
// TODO: Add listener for removal of references.
|
||||
/** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
|
||||
SparseArray<WeakReference<ActivityContainer>> mActivityContainers =
|
||||
new SparseArray<WeakReference<ActivityContainer>>();
|
||||
SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>();
|
||||
|
||||
/** Mapping from displayId to display current state */
|
||||
private SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<ActivityDisplay>();
|
||||
private final SparseArray<ActivityDisplay> mActivityDisplays =
|
||||
new SparseArray<ActivityDisplay>();
|
||||
|
||||
InputManagerInternal mInputManagerInternal;
|
||||
|
||||
@@ -265,7 +264,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
mActivityDisplays.put(displayId, activityDisplay);
|
||||
}
|
||||
|
||||
createStackOnDisplay(null, HOME_STACK_ID, Display.DEFAULT_DISPLAY);
|
||||
createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);
|
||||
mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
|
||||
|
||||
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
|
||||
@@ -1386,7 +1385,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
}
|
||||
|
||||
// Need to create an app stack for this user.
|
||||
int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY);
|
||||
int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
|
||||
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
|
||||
" stackId=" + stackId);
|
||||
mFocusedStack = getStack(stackId);
|
||||
@@ -2154,14 +2153,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
}
|
||||
|
||||
ActivityStack getStack(int stackId) {
|
||||
WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
|
||||
if (weakReference != null) {
|
||||
ActivityContainer activityContainer = weakReference.get();
|
||||
if (activityContainer != null) {
|
||||
return activityContainer.mStack;
|
||||
} else {
|
||||
mActivityContainers.remove(stackId);
|
||||
}
|
||||
ActivityContainer activityContainer = mActivityContainers.get(stackId);
|
||||
if (activityContainer != null) {
|
||||
return activityContainer.mStack;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -2191,49 +2185,26 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
return null;
|
||||
}
|
||||
|
||||
ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
|
||||
ActivityContainer createActivityContainer(ActivityRecord parentActivity,
|
||||
IActivityContainerCallback callback) {
|
||||
ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
|
||||
callback);
|
||||
mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
|
||||
if (parentActivity != null) {
|
||||
parentActivity.mChildContainers.add(activityContainer.mStack);
|
||||
}
|
||||
ActivityContainer activityContainer = new VirtualActivityContainer(parentActivity, callback);
|
||||
mActivityContainers.put(activityContainer.mStackId, activityContainer);
|
||||
parentActivity.mChildContainers.add(activityContainer);
|
||||
return activityContainer;
|
||||
}
|
||||
|
||||
ActivityContainer createActivityContainer(ActivityRecord parentActivity,
|
||||
IActivityContainerCallback callback) {
|
||||
return createActivityContainer(parentActivity, getNextStackId(), callback);
|
||||
}
|
||||
|
||||
void removeChildActivityContainers(ActivityRecord parentActivity) {
|
||||
for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
|
||||
final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
|
||||
if (container == null) {
|
||||
mActivityContainers.removeAt(ndx);
|
||||
continue;
|
||||
}
|
||||
if (container.mParentActivity != parentActivity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ActivityStack stack = container.mStack;
|
||||
ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
|
||||
if (top != null) {
|
||||
// TODO: Make sure the next activity doesn't start up when top is destroyed.
|
||||
stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
|
||||
}
|
||||
mActivityContainers.removeAt(ndx);
|
||||
container.detachLocked();
|
||||
final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
|
||||
for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
|
||||
ActivityContainer container = childStacks.remove(containerNdx);
|
||||
container.release();
|
||||
}
|
||||
}
|
||||
|
||||
void deleteActivityContainer(IActivityContainer container) {
|
||||
ActivityContainer activityContainer = (ActivityContainer)container;
|
||||
if (activityContainer != null) {
|
||||
activityContainer.mStack.destroyActivitiesLocked(null, true,
|
||||
"deleteActivityContainer");
|
||||
activityContainer.mStack.finishAllActivitiesLocked();
|
||||
final ActivityRecord parent = activityContainer.mParentActivity;
|
||||
if (parent != null) {
|
||||
parent.mChildContainers.remove(activityContainer);
|
||||
@@ -2244,14 +2215,14 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
}
|
||||
}
|
||||
|
||||
private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
|
||||
private int createStackOnDisplay(int stackId, int displayId) {
|
||||
ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
|
||||
if (activityDisplay == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ActivityContainer activityContainer =
|
||||
createActivityContainer(parentActivity, stackId, null);
|
||||
ActivityContainer activityContainer = new ActivityContainer(stackId);
|
||||
mActivityContainers.put(stackId, activityContainer);
|
||||
activityContainer.attachToDisplayLocked(activityDisplay);
|
||||
return stackId;
|
||||
}
|
||||
@@ -2334,9 +2305,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
}
|
||||
|
||||
boolean shutdownLocked(int timeout) {
|
||||
boolean timedout = false;
|
||||
goingToSleepLocked();
|
||||
|
||||
boolean timedout = false;
|
||||
final long endTime = System.currentTimeMillis() + timeout;
|
||||
while (true) {
|
||||
boolean cantShutdown = false;
|
||||
@@ -3030,24 +3001,26 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
|
||||
class ActivityContainer extends IActivityContainer.Stub {
|
||||
final int mStackId;
|
||||
final IActivityContainerCallback mCallback;
|
||||
IActivityContainerCallback mCallback = null;
|
||||
final ActivityStack mStack;
|
||||
final ActivityRecord mParentActivity;
|
||||
final String mIdString;
|
||||
ActivityRecord mParentActivity = null;
|
||||
String mIdString;
|
||||
|
||||
boolean mVisible = true;
|
||||
|
||||
/** Display this ActivityStack is currently on. Null if not attached to a Display. */
|
||||
ActivityDisplay mActivityDisplay;
|
||||
|
||||
ActivityContainer(ActivityRecord parentActivity, int stackId,
|
||||
IActivityContainerCallback callback) {
|
||||
final static int CONTAINER_STATE_HAS_SURFACE = 0;
|
||||
final static int CONTAINER_STATE_NO_SURFACE = 1;
|
||||
final static int CONTAINER_STATE_FINISHING = 2;
|
||||
int mContainerState = CONTAINER_STATE_HAS_SURFACE;
|
||||
|
||||
ActivityContainer(int stackId) {
|
||||
synchronized (mService) {
|
||||
mStackId = stackId;
|
||||
mStack = new ActivityStack(this);
|
||||
mParentActivity = parentActivity;
|
||||
mCallback = callback;
|
||||
mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
|
||||
mIdString = "ActivtyContainer{" + mStackId + "}";
|
||||
if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
|
||||
}
|
||||
}
|
||||
@@ -3097,6 +3070,14 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
mContainerState = CONTAINER_STATE_FINISHING;
|
||||
mStack.finishAllActivitiesLocked();
|
||||
detachLocked();
|
||||
mWindowManager.removeStack(mStackId);
|
||||
}
|
||||
|
||||
private void detachLocked() {
|
||||
if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
|
||||
+ mActivityDisplay + " Callers=" + Debug.getCallers(2));
|
||||
@@ -3109,13 +3090,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detachFromDisplay() {
|
||||
synchronized (mService) {
|
||||
detachLocked();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int startActivity(Intent intent) {
|
||||
mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
|
||||
@@ -3149,23 +3123,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachToSurface(Surface surface, int width, int height, int density) {
|
||||
public void setSurface(Surface surface, int width, int height, int density) {
|
||||
mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
|
||||
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mService) {
|
||||
ActivityDisplay activityDisplay =
|
||||
new ActivityDisplay(surface, width, height, density);
|
||||
mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
|
||||
attachToDisplayLocked(activityDisplay);
|
||||
mStack.resumeTopActivityLocked(null);
|
||||
}
|
||||
if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
|
||||
+ mActivityDisplay);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
}
|
||||
|
||||
ActivityStackSupervisor getOuter() {
|
||||
@@ -3200,46 +3159,87 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
}
|
||||
}
|
||||
|
||||
private class VirtualActivityContainer extends ActivityContainer {
|
||||
Surface mSurface;
|
||||
|
||||
VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
|
||||
super(getNextStackId());
|
||||
mParentActivity = parent;
|
||||
mCallback = callback;
|
||||
mContainerState = CONTAINER_STATE_NO_SURFACE;
|
||||
mIdString = "VirtualActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSurface(Surface surface, int width, int height, int density) {
|
||||
super.setSurface(surface, width, height, density);
|
||||
|
||||
synchronized (mService) {
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
setSurfaceLocked(surface, width, height, density);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setSurfaceLocked(Surface surface, int width, int height, int density) {
|
||||
if (mContainerState == CONTAINER_STATE_FINISHING) {
|
||||
return;
|
||||
}
|
||||
VirtualActivityDisplay virtualActivityDisplay =
|
||||
(VirtualActivityDisplay) mActivityDisplay;
|
||||
if (virtualActivityDisplay == null) {
|
||||
virtualActivityDisplay =
|
||||
new VirtualActivityDisplay(surface, width, height, density);
|
||||
mActivityDisplay = virtualActivityDisplay;
|
||||
mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
|
||||
attachToDisplayLocked(virtualActivityDisplay);
|
||||
}
|
||||
|
||||
if (mSurface != null) {
|
||||
mSurface.release();
|
||||
mSurface = null;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
|
||||
+ virtualActivityDisplay);
|
||||
|
||||
virtualActivityDisplay.setSurface(surface);
|
||||
}
|
||||
}
|
||||
|
||||
/** Exactly one of these classes per Display in the system. Capable of holding zero or more
|
||||
* attached {@link ActivityStack}s */
|
||||
final class ActivityDisplay {
|
||||
class ActivityDisplay {
|
||||
/** Actual Display this object tracks. */
|
||||
int mDisplayId;
|
||||
Display mDisplay;
|
||||
DisplayInfo mDisplayInfo = new DisplayInfo();
|
||||
Surface mSurface;
|
||||
|
||||
/** All of the stacks on this display. Order matters, topmost stack is in front of all other
|
||||
* stacks, bottommost behind. Accessed directly by ActivityManager package classes */
|
||||
final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
|
||||
|
||||
/** If this display is for an ActivityView then the VirtualDisplay created for it is stored
|
||||
* here. */
|
||||
VirtualDisplay mVirtualDisplay;
|
||||
ActivityDisplay() {
|
||||
}
|
||||
|
||||
ActivityDisplay(int displayId) {
|
||||
init(mDisplayManager.getDisplay(displayId));
|
||||
}
|
||||
|
||||
ActivityDisplay(Surface surface, int width, int height, int density) {
|
||||
DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
|
||||
VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
|
||||
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
|
||||
DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
|
||||
init(mVirtualDisplay.getDisplay());
|
||||
mSurface = surface;
|
||||
|
||||
mWindowManager.handleDisplayAdded(mDisplayId);
|
||||
}
|
||||
|
||||
private void init(Display display) {
|
||||
void init(Display display) {
|
||||
mDisplay = display;
|
||||
mDisplayId = display.getDisplayId();
|
||||
mDisplay.getDisplayInfo(mDisplayInfo);
|
||||
@@ -3255,11 +3255,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
|
||||
+ " from displayId=" + mDisplayId);
|
||||
mStacks.remove(stack);
|
||||
if (mStacks.isEmpty() && mVirtualDisplay != null) {
|
||||
mVirtualDisplay.release();
|
||||
mVirtualDisplay = null;
|
||||
}
|
||||
mSurface.release();
|
||||
}
|
||||
|
||||
void getBounds(Point bounds) {
|
||||
@@ -3270,8 +3265,42 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
|
||||
+ " numStacks=" + mStacks.size() + "}";
|
||||
return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
|
||||
}
|
||||
}
|
||||
|
||||
class VirtualActivityDisplay extends ActivityDisplay {
|
||||
VirtualDisplay mVirtualDisplay;
|
||||
|
||||
VirtualActivityDisplay(Surface surface, 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 |
|
||||
DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
|
||||
|
||||
init(mVirtualDisplay.getDisplay());
|
||||
|
||||
mWindowManager.handleDisplayAdded(mDisplayId);
|
||||
}
|
||||
|
||||
void setSurface(Surface surface) {
|
||||
if (mVirtualDisplay != null) {
|
||||
mVirtualDisplay.setSurface(surface);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void detachActivitiesLocked(ActivityStack stack) {
|
||||
super.detachActivitiesLocked(stack);
|
||||
if (mVirtualDisplay != null) {
|
||||
mVirtualDisplay.release();
|
||||
mVirtualDisplay = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VirtualActivityDisplay={" + mDisplayId + "}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user