Merge "Cleanup after ActivityView" into klp-modular-dev

This commit is contained in:
Craig Mautner
2014-01-16 01:49:23 +00:00
committed by Android (Google) Code Review
5 changed files with 143 additions and 80 deletions

View File

@@ -24,6 +24,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
@@ -31,12 +32,15 @@ import android.view.ViewGroup;
import android.view.WindowManager;
public class ActivityView extends ViewGroup {
private final String TAG = "ActivityView";
private final TextureView mTextureView;
private IActivityContainer mActivityContainer;
private Activity mActivity;
private boolean mAttached;
private int mWidth;
private int mHeight;
private Surface mSurface;
public ActivityView(Context context) {
this(context, null);
@@ -83,20 +87,18 @@ public class ActivityView extends ViewGroup {
final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
if (surfaceTexture != null) {
createActivityView(surfaceTexture);
attachToSurface(surfaceTexture);
}
}
@Override
protected void onDetachedFromWindow() {
if (mActivityContainer != null) {
try {
mActivityContainer.deleteActivityView();
} catch (RemoteException e) {
}
mActivityContainer = null;
}
mAttached = false;
detachFromSurface();
}
@Override
public boolean isAttachedToWindow() {
return mAttached;
}
public void startActivity(Intent intent) {
@@ -110,22 +112,41 @@ public class ActivityView extends ViewGroup {
}
/** Call when both mActivityContainer and mTextureView's SurfaceTexture are not null */
private void createActivityView(SurfaceTexture surfaceTexture) {
private void attachToSurface(SurfaceTexture surfaceTexture) {
WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
mSurface = new Surface(surfaceTexture);
try {
mActivityContainer.createActivityView(new Surface(surfaceTexture), mWidth, mHeight,
mActivityContainer.attachToSurface(mSurface, mWidth, mHeight,
metrics.densityDpi);
} catch (RemoteException e) {
mActivityContainer = null;
mSurface.release();
mSurface = null;
mAttached = false;
throw new IllegalStateException(
"ActivityView: Unable to create ActivityContainer. " + e);
}
mAttached = true;
}
private void detachFromSurface() {
if (mActivityContainer != null) {
try {
mActivityContainer.detachFromDisplay();
} catch (RemoteException e) {
}
mActivityContainer = null;
}
if (mSurface != null) {
mSurface.release();
mSurface = null;
}
mAttached = false;
}
private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width,
@@ -133,30 +154,26 @@ public class ActivityView extends ViewGroup {
mWidth = width;
mHeight = height;
if (mActivityContainer != null) {
createActivityView(surfaceTexture);
attachToSurface(surfaceTexture);
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width,
int height) {
Log.d(TAG, "onSurfaceTextureSizeChanged: w=" + width + " h=" + height);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
try {
mActivityContainer.deleteActivityView();
// TODO: Add binderDied to handle this nullification.
mActivityContainer = null;
} catch (RemoteException r) {
}
mAttached = false;
return false;
Log.d(TAG, "onSurfaceTextureDestroyed");
detachFromSurface();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
// Log.d(TAG, "onSurfaceTextureUpdated");
}
}

View File

@@ -24,9 +24,8 @@ import android.view.Surface;
/** @hide */
interface IActivityContainer {
void attachToDisplay(int displayId);
int getDisplayId();
void attachToSurface(in Surface surface, int width, int height, int density);
void detachFromDisplay();
int startActivity(in Intent intent);
void createActivityView(in Surface surface, int width, int height, int density);
void deleteActivityView();
int getDisplayId();
}

View File

@@ -322,7 +322,7 @@ final class ActivityStack {
}
}
private int numActivities() {
int numActivities() {
int count = 0;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
count += mTaskHistory.get(taskNdx).mActivities.size();
@@ -2675,6 +2675,7 @@ final class ActivityStack {
}
private void removeActivityFromHistoryLocked(ActivityRecord r) {
mStackSupervisor.removeChildActivityContainers(r);
finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
r.makeFinishing();
if (DEBUG_ADD_REMOVE) {
@@ -3318,6 +3319,8 @@ final class ActivityStack {
r.startFreezingScreenLocked(r.app, 0);
mStackSupervisor.removeChildActivityContainers(r);
try {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG,
(andResume ? "Relaunching to RESUMED " : "Relaunching to PAUSED ")
@@ -3350,14 +3353,20 @@ final class ActivityStack {
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
if (r.appToken == token) {
return true;
return true;
}
if (r.fullscreen && !r.finishing) {
return false;
}
}
}
return true;
final ActivityRecord r = ActivityRecord.forToken(token);
if (r == null) {
return false;
}
if (r.finishing) Slog.e(TAG, "willActivityBeVisibleLocked: Returning false,"
+ " would have returned true for r=" + r);
return !r.finishing;
}
void closeSystemDialogsLocked() {

View File

@@ -417,11 +417,13 @@ public final class ActivityStackSupervisor implements DisplayListener {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFrontStack(stack)) {
if (!isFrontStack(stack) || stack.numActivities() == 0) {
continue;
}
final ActivityRecord resumedActivity = stack.mResumedActivity;
if (resumedActivity == null || !resumedActivity.idle) {
if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack="
+ stack.mStackId + " " + resumedActivity + " not idle");
return false;
}
}
@@ -2130,6 +2132,28 @@ public final class ActivityStackSupervisor implements DisplayListener {
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 removal");
}
mActivityContainers.removeAt(ndx);
container.detachLocked();
}
}
private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
if (activityDisplay == null) {
@@ -2683,7 +2707,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
final void scheduleResumeTopActivities() {
mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
}
}
void removeSleepTimeouts() {
@@ -2731,7 +2757,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
if (activityDisplay != null) {
ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
activityDisplay.detachActivitiesLocked(stacks.get(stackNdx));
stacks.get(stackNdx).mActivityContainer.detachLocked();
}
mActivityDisplays.remove(displayId);
}
@@ -2872,6 +2898,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
final IActivityContainerCallback mCallback;
final ActivityStack mStack;
final ActivityRecord mParentActivity;
final String mIdString;
/** Display this ActivityStack is currently on. Null if not attached to a Display. */
ActivityDisplay mActivityDisplay;
@@ -2883,10 +2910,14 @@ public final class ActivityStackSupervisor implements DisplayListener {
mStack = new ActivityStack(this);
mParentActivity = parentActivity;
mCallback = callback;
mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
}
}
void attachToDisplayLocked(ActivityDisplay activityDisplay) {
if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
+ " to display=" + activityDisplay);
mActivityDisplay = activityDisplay;
mStack.mDisplayId = activityDisplay.mDisplayId;
mStack.mStacks = activityDisplay.mStacks;
@@ -2914,7 +2945,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
return -1;
}
void detachLocked() {
private void detachLocked() {
if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
+ mActivityDisplay + " Callers=" + Debug.getCallers(2));
if (mActivityDisplay != null) {
mActivityDisplay.detachActivitiesLocked(mStack);
mActivityDisplay = null;
@@ -2951,45 +2984,15 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
@Override
public void createActivityView(Surface surface, int width, int height, int density) {
DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
VirtualDisplay virtualDisplay;
long ident = Binder.clearCallingIdentity();
try {
virtualDisplay = 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);
}
final Display display = virtualDisplay.getDisplay();
final int displayId = display.getDisplayId();
mWindowManager.handleDisplayAdded(displayId);
public void attachToSurface(Surface surface, int width, int height, int density) {
synchronized (mService) {
ActivityDisplay activityDisplay = new ActivityDisplay(display);
mActivityDisplays.put(displayId, activityDisplay);
ActivityDisplay activityDisplay =
new ActivityDisplay(surface, width, height, density);
mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
attachToDisplayLocked(activityDisplay);
activityDisplay.mVirtualDisplay = virtualDisplay;
}
}
@Override
public void deleteActivityView() {
synchronized (mService) {
if (!isAttached()) {
return;
}
VirtualDisplay virtualDisplay = mActivityDisplay.mVirtualDisplay;
if (virtualDisplay != null) {
virtualDisplay.release();
mActivityDisplay.mVirtualDisplay = null;
}
detachLocked();
}
if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
+ mActivityDisplay);
}
ActivityStackSupervisor getOuter() {
@@ -3007,15 +3010,21 @@ public final class ActivityStackSupervisor implements DisplayListener {
outBounds.set(0, 0);
}
}
@Override
public String toString() {
return mIdString + (mActivityDisplay == null ? "N" : "A");
}
}
/** Exactly one of these classes per Display in the system. Capable of holding zero or more
* attached {@link ActivityStack}s */
final class ActivityDisplay {
/** Actual Display this object tracks. */
final int mDisplayId;
final Display mDisplay;
final DisplayInfo mDisplayInfo = new DisplayInfo();
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 */
@@ -3026,10 +3035,32 @@ public final class ActivityStackSupervisor implements DisplayListener {
VirtualDisplay mVirtualDisplay;
ActivityDisplay(int displayId) {
this(mDisplayManager.getDisplay(displayId));
init(mDisplayManager.getDisplay(displayId));
}
ActivityDisplay(Display display) {
init(display);
}
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) {
mDisplay = display;
mDisplayId = display.getDisplayId();
mDisplay.getDisplayInfo(mDisplayInfo);
@@ -3042,9 +3073,14 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
void detachActivitiesLocked(ActivityStack stack) {
if (DEBUG_STACK) Slog.v(TAG, "attachActivities: detaching " + stack
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) {
@@ -3052,5 +3088,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
bounds.x = mDisplayInfo.appWidth;
bounds.y = mDisplayInfo.appHeight;
}
@Override
public String toString() {
return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
+ " numStacks=" + mStacks.size() + "}";
}
}
}

View File

@@ -18,8 +18,6 @@ package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.*;
import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import android.app.AppOpsManager;
@@ -3622,7 +3620,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (freezeThisOneIfNeeded != null) {
AppWindowToken atoken = findAppWindowToken(freezeThisOneIfNeeded);
if (atoken != null) {
startAppFreezingScreenLocked(atoken, ActivityInfo.CONFIG_ORIENTATION);
startAppFreezingScreenLocked(atoken);
}
}
config = computeNewConfigurationLocked();
@@ -4395,8 +4393,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
public void startAppFreezingScreenLocked(AppWindowToken wtoken,
int configChanges) {
private void startAppFreezingScreenLocked(AppWindowToken wtoken) {
if (DEBUG_ORIENTATION) {
RuntimeException e = null;
if (!HIDE_STACK_CRAWLS) {
@@ -4445,7 +4442,7 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
final long origId = Binder.clearCallingIdentity();
startAppFreezingScreenLocked(wtoken, configChanges);
startAppFreezingScreenLocked(wtoken);
Binder.restoreCallingIdentity(origId);
}
}
@@ -8313,8 +8310,7 @@ public class WindowManagerService extends IWindowManager.Stub
// it frozen/off until this window draws at its new
// orientation.
if (!okToDisplay()) {
if (DEBUG_ORIENTATION) Slog.v(TAG,
"Changing surface while display frozen: " + w);
if (DEBUG_ORIENTATION) Slog.v(TAG, "Changing surface while display frozen: " + w);
w.mOrientationChanging = true;
w.mLastFreezeDuration = 0;
mInnerFields.mOrientationChangeComplete = false;