am 7ad27288: am c00c89b1: am f4c909bc: Fix ActivityView lifecycle

* commit '7ad27288f1b66733a4fcb2bdcb17dd5db6c6423d':
  Fix ActivityView lifecycle
This commit is contained in:
Craig Mautner
2014-04-22 13:39:20 +00:00
committed by Android Git Automerger
6 changed files with 263 additions and 195 deletions

View File

@@ -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());
}
}
}

View File

@@ -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();
}

View File

@@ -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);
}
}

View File

@@ -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().

View File

@@ -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();
}
}

View File

@@ -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 + "}";
}
}
}