Merge "Fixed bugs with starting windows when displayng forcedResized activity" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b406dd20ee
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user