summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityOptions.java24
-rw-r--r--core/java/android/view/IWindowManager.aidl7
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java2
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityRecord.java12
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java26
-rw-r--r--services/core/java/com/android/server/am/ActivityStarter.java16
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java27
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java23
-rw-r--r--tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java3
9 files changed, 87 insertions, 53 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index a30f6299a4d9..4c8ddc7eb6b1 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -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);
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 4ba97d5f8bea..f8a6a17a0f57 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -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);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
index 34a37ba51bf1..5f083d57f9ae 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -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();
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index fa69b4a857df..3ccac9e2f1e4 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -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));
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 62d114d1257a..893bd371a1bf 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -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,
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 64bd14c3c0b5..fbb4b7773c03 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1149,17 +1149,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);
@@ -1226,7 +1231,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) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index af7740f8083a..729d32fbfc4f 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -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()) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 11327582a481..5ea4e9ef7051 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4023,7 +4023,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) {
@@ -4040,18 +4040,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
@@ -4066,7 +4066,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);
@@ -4080,33 +4080,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");
@@ -4119,6 +4119,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) {
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index f9e008e1cf92..ceebdd50021a 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -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