Merge "Fixed bugs with starting windows when displayng forcedResized activity" into nyc-dev

This commit is contained in:
TreeHugger Robot
2016-05-17 00:51:40 +00:00
committed by Android (Google) Code Review
9 changed files with 87 additions and 53 deletions

View File

@@ -161,10 +161,10 @@ public class ActivityOptions {
private static final String KEY_LAUNCH_TASK_ID = "android.activity.launchTaskId";
/**
* See {@link #setAvoidMoveToFront}.
* See {@link #setTaskOverlay}.
* @hide
*/
private static final String KEY_DONT_MOVE_TO_FRONT = "android.activity.dontMoveToFront";
private static final String KEY_TASK_OVERLAY = "android.activity.taskOverlay";
/**
* Where the docked stack should be positioned.
@@ -239,7 +239,7 @@ public class ActivityOptions {
private int mLaunchStackId = INVALID_STACK_ID;
private int mLaunchTaskId = -1;
private int mDockCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
private boolean mAvoidMoveToFront;
private boolean mTaskOverlay;
private AppTransitionAnimationSpec mAnimSpecs[];
/**
@@ -782,7 +782,7 @@ public class ActivityOptions {
}
mLaunchStackId = opts.getInt(KEY_LAUNCH_STACK_ID, INVALID_STACK_ID);
mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1);
mAvoidMoveToFront = opts.getBoolean(KEY_DONT_MOVE_TO_FRONT, false);
mTaskOverlay = opts.getBoolean(KEY_TASK_OVERLAY, false);
mDockCreateMode = opts.getInt(KEY_DOCK_CREATE_MODE, DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT);
if (opts.containsKey(KEY_ANIM_SPECS)) {
Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS);
@@ -961,20 +961,20 @@ public class ActivityOptions {
}
/**
* Set's whether the task should be moved to the front. This is different from
* {@link #getLaunchTaskBehind()} as we don't want to have an animation at all when launching
* an activity that shouldn't be moved to the front.
* Set's whether the activity launched with this option should be a task overlay. That is the
* activity will always be the top activity of the task and doesn't cause the task to be moved
* to the front when it is added.
* @hide
*/
public void setAvoidMoveToFront(boolean avoidMoveToFront) {
mAvoidMoveToFront = avoidMoveToFront;
public void setTaskOverlay(boolean taskOverlay) {
mTaskOverlay = taskOverlay;
}
/**
* @hide
*/
public boolean getAvoidMoveToFront() {
return mAvoidMoveToFront;
public boolean getTaskOverlay() {
return mTaskOverlay;
}
/** @hide */
@@ -1130,7 +1130,7 @@ public class ActivityOptions {
}
b.putInt(KEY_LAUNCH_STACK_ID, mLaunchStackId);
b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
b.putBoolean(KEY_DONT_MOVE_TO_FRONT, mAvoidMoveToFront);
b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay);
b.putInt(KEY_DOCK_CREATE_MODE, mDockCreateMode);
if (mAnimSpecs != null) {
b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);

View File

@@ -163,7 +163,12 @@ interface IWindowManager
IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback startedCallback,
boolean scaleUp);
void executeAppTransition();
void setAppStartingWindow(IBinder token, String pkg, int theme,
/**
* Called to set the starting window for the input token and returns true if the starting
* window was set for the token.
*/
boolean setAppStartingWindow(IBinder token, String pkg, int theme,
in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
void setAppVisibility(IBinder token, boolean visible);

View File

@@ -111,7 +111,7 @@ public class ForcedResizableInfoActivityController {
Intent intent = new Intent(mContext, ForcedResizableInfoActivity.class);
ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchTaskId(mPendingTaskIds.valueAt(i));
options.setAvoidMoveToFront(true);
options.setTaskOverlay(true);
mContext.startActivity(intent, options.toBundle());
}
mPendingTaskIds.clear();

View File

@@ -202,6 +202,7 @@ final class ActivityRecord {
static final int STARTING_WINDOW_SHOWN = 1;
static final int STARTING_WINDOW_REMOVED = 2;
int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;
boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
boolean mUpdateTaskThumbnailWhenHidden;
ActivityContainer mInitialActivityContainer;
@@ -1390,6 +1391,17 @@ final class ActivityRecord {
pendingVoiceInteractionStart = false;
}
void showStartingWindow(ActivityRecord prev, boolean createIfNeeded) {
final CompatibilityInfo compatInfo =
service.compatibilityInfoForPackageLocked(info.applicationInfo);
final boolean shown = service.mWindowManager.setAppStartingWindow(
appToken, packageName, theme, compatInfo, nonLocalizedLabel, labelRes, icon,
logo, windowFlags, prev != null ? prev.appToken : null, createIfNeeded);
if (shown) {
mStartingWindowState = STARTING_WINDOW_SHOWN;
}
}
void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
out.attribute(null, ATTR_ID, String.valueOf(createTime));
out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));

View File

@@ -2459,12 +2459,7 @@ final class ActivityStack {
next.hasBeenLaunched = true;
} else if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
mStackSupervisor.isFrontStack(lastStack)) {
mWindowManager.setAppStartingWindow(
next.appToken, next.packageName, next.theme,
mService.compatibilityInfoForPackageLocked(next.info.applicationInfo),
next.nonLocalizedLabel, next.labelRes, next.icon, next.logo,
next.windowFlags, null, true);
next.mStartingWindowState = STARTING_WINDOW_SHOWN;
next.showStartingWindow(null, true);
}
mStackSupervisor.startSpecificActivityLocked(next, true, false);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
@@ -2490,14 +2485,7 @@ final class ActivityStack {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
mWindowManager.setAppStartingWindow(
next.appToken, next.packageName, next.theme,
mService.compatibilityInfoForPackageLocked(
next.info.applicationInfo),
next.nonLocalizedLabel,
next.labelRes, next.icon, next.logo, next.windowFlags,
null, true);
next.mStartingWindowState = STARTING_WINDOW_SHOWN;
next.showStartingWindow(null, true);
}
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
@@ -2712,7 +2700,7 @@ final class ActivityStack {
// "has the same starting icon" as the next one. This allows the
// window manager to keep the previous window it had previously
// created, if it still had one.
ActivityRecord prev = mResumedActivity;
ActivityRecord prev = r.task.topRunningActivityWithStartingWindowLocked();
if (prev != null) {
// We don't want to reuse the previous starting preview if:
// (1) The current activity is in a different task.
@@ -2724,13 +2712,7 @@ final class ActivityStack {
prev = null;
}
}
mWindowManager.setAppStartingWindow(
r.appToken, r.packageName, r.theme,
mService.compatibilityInfoForPackageLocked(
r.info.applicationInfo), r.nonLocalizedLabel,
r.labelRes, r.icon, r.logo, r.windowFlags,
prev != null ? prev.appToken : null, showStartingIcon);
r.mStartingWindowState = STARTING_WINDOW_SHOWN;
r.showStartingWindow(prev, showStartingIcon);
}
} else {
// If this is the first activity, don't do any fancy animations,

View File

@@ -1120,17 +1120,22 @@ class ActivityStarter {
// activity.
mService.setFocusedActivityLocked(mStartActivity, "startedActivity");
}
if (mTargetStack.isFocusable()) {
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
} else {
final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay)) {
// If the activity is not focusable, we can't resume it, but still would like to
// make sure it becomes visible as it starts (this will also trigger entry
// animation). An example of this are PIP activities.
// Also, we don't want to resume activities in a task that currently has an overlay
// as the starting activity just needs to be in the visible paused state until the
// over is removed.
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mWindowManager.executeAppTransition();
} else {
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
@@ -1197,7 +1202,8 @@ class ActivityStarter {
mDoResume = false;
}
if (mOptions != null && mOptions.getLaunchTaskId() != -1 && mOptions.getAvoidMoveToFront()) {
if (mOptions != null && mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
r.mTaskOverlay = true;
final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
final ActivityRecord top = task != null ? task.getTopActivity() : null;
if (top != null && !top.visible) {

View File

@@ -88,6 +88,7 @@ import static com.android.server.am.ActivityManagerService.LOCK_SCREEN_SHOWN;
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
final class TaskRecord {
private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
@@ -685,6 +686,20 @@ final class TaskRecord {
return null;
}
ActivityRecord topRunningActivityWithStartingWindowLocked() {
if (stack != null) {
for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
ActivityRecord r = mActivities.get(activityNdx);
if (r.mStartingWindowState != STARTING_WINDOW_SHOWN
|| r.finishing || !stack.okToShowLocked(r)) {
continue;
}
return r;
}
}
return null;
}
void setFrontOfTask() {
setFrontOfTask(null);
}
@@ -760,6 +775,18 @@ final class TaskRecord {
// Otherwise make all added activities match this one.
r.mActivityType = taskType;
}
final int size = mActivities.size();
if (index == size && size > 0) {
final ActivityRecord top = mActivities.get(size - 1);
if (top.mTaskOverlay) {
// Place below the task overlay activity since the overlay activity should always
// be on top.
index--;
}
}
mActivities.add(index, r);
updateEffectiveIntent();
if (r.isPersistable()) {

View File

@@ -4032,7 +4032,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
public void setAppStartingWindow(IBinder token, String pkg,
public boolean setAppStartingWindow(IBinder token, String pkg,
int theme, CompatibilityInfo compatInfo,
CharSequence nonLocalizedLabel, int labelRes, int icon, int logo,
int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
@@ -4049,18 +4049,18 @@ public class WindowManagerService extends IWindowManager.Stub
AppWindowToken wtoken = findAppWindowToken(token);
if (wtoken == null) {
Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + token);
return;
return false;
}
// If the display is frozen, we won't do anything until the
// actual window is displayed so there is no reason to put in
// the starting window.
if (!okToDisplay()) {
return;
return false;
}
if (wtoken.startingData != null) {
return;
return false;
}
// If this is a translucent window, then don't
@@ -4075,7 +4075,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (ent == null) {
// Whoops! App doesn't exist. Um. Okay. We'll just
// pretend like we didn't see that.
return;
return false;
}
final boolean windowIsTranslucent = ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowIsTranslucent, false);
@@ -4089,33 +4089,33 @@ public class WindowManagerService extends IWindowManager.Stub
+ " Floating=" + windowIsFloating
+ " ShowWallpaper=" + windowShowWallpaper);
if (windowIsTranslucent) {
return;
return false;
}
if (windowIsFloating || windowDisableStarting) {
return;
return false;
}
if (windowShowWallpaper) {
if (mWallpaperControllerLocked.getWallpaperTarget() == null) {
// If this theme is requesting a wallpaper, and the wallpaper
// is not curently visible, then this effectively serves as
// is not currently visible, then this effectively serves as
// an opaque window and our starting window transition animation
// can still work. We just need to make sure the starting window
// is also showing the wallpaper.
windowFlags |= FLAG_SHOW_WALLPAPER;
} else {
return;
return false;
}
}
}
if (transferStartingWindow(transferFrom, wtoken)) {
return;
return true;
}
// There is no existing starting window, and the caller doesn't
// want us to create one, so that's it!
if (!createIfNeeded) {
return;
return false;
}
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating StartingData");
@@ -4128,6 +4128,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING");
mH.sendMessageAtFrontOfQueue(m);
}
return true;
}
private boolean transferStartingWindow(IBinder transferFrom, AppWindowToken wtoken) {

View File

@@ -336,10 +336,11 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
public void setAppStartingWindow(IBinder arg0, String arg1, int arg2, CompatibilityInfo arg3,
public boolean setAppStartingWindow(IBinder arg0, String arg1, int arg2, CompatibilityInfo arg3,
CharSequence arg4, int arg5, int arg6, int arg7, int arg8, IBinder arg9, boolean arg10)
throws RemoteException {
// TODO Auto-generated method stub
return false;
}
@Override