Merge changes from topic "stack-gone"
* changes: HOME_STACK_ID, ASSISTANT_STACK_ID, and RECENTS_STACK_ID be gone! Ability to getOrCreateStack by windowingMode/activityType in AM.
This commit is contained in:
committed by
Android (Google) Code Review
commit
d562d535af
@@ -3864,6 +3864,8 @@ package android.app {
|
||||
method public void moveTaskToFront(int, int);
|
||||
method public void moveTaskToFront(int, int, android.os.Bundle);
|
||||
method public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
|
||||
method public void removeStacksInWindowingModes(int[]) throws java.lang.SecurityException;
|
||||
method public void removeStacksWithActivityTypes(int[]) throws java.lang.SecurityException;
|
||||
method public deprecated void restartPackage(java.lang.String);
|
||||
method public static void setVrThread(int);
|
||||
method public void setWatchHeapLimit(long);
|
||||
@@ -4017,14 +4019,11 @@ package android.app {
|
||||
}
|
||||
|
||||
public static class ActivityManager.StackId {
|
||||
field public static final int ASSISTANT_STACK_ID = 6; // 0x6
|
||||
field public static final int DOCKED_STACK_ID = 3; // 0x3
|
||||
field public static final int FREEFORM_WORKSPACE_STACK_ID = 2; // 0x2
|
||||
field public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1; // 0x1
|
||||
field public static final int HOME_STACK_ID = 0; // 0x0
|
||||
field public static final int INVALID_STACK_ID = -1; // 0xffffffff
|
||||
field public static final int PINNED_STACK_ID = 4; // 0x4
|
||||
field public static final int RECENTS_STACK_ID = 5; // 0x5
|
||||
}
|
||||
|
||||
public static class ActivityManager.TaskDescription implements android.os.Parcelable {
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
|
||||
package android.app;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
@@ -46,6 +42,7 @@ import android.content.pm.IPackageDataObserver;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
@@ -675,10 +672,7 @@ public class ActivityManager {
|
||||
|
||||
/** First static stack ID.
|
||||
* @hide */
|
||||
public static final int FIRST_STATIC_STACK_ID = 0;
|
||||
|
||||
/** Home activity stack ID. */
|
||||
public static final int HOME_STACK_ID = FIRST_STATIC_STACK_ID;
|
||||
private static final int FIRST_STATIC_STACK_ID = 0;
|
||||
|
||||
/** ID of stack where fullscreen activities are normally launched into. */
|
||||
public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1;
|
||||
@@ -692,15 +686,9 @@ public class ActivityManager {
|
||||
/** ID of stack that always on top (always visible) when it exist. */
|
||||
public static final int PINNED_STACK_ID = DOCKED_STACK_ID + 1;
|
||||
|
||||
/** ID of stack that contains the Recents activity. */
|
||||
public static final int RECENTS_STACK_ID = PINNED_STACK_ID + 1;
|
||||
|
||||
/** ID of stack that contains activities launched by the assistant. */
|
||||
public static final int ASSISTANT_STACK_ID = RECENTS_STACK_ID + 1;
|
||||
|
||||
/** Last static stack stack ID.
|
||||
* @hide */
|
||||
public static final int LAST_STATIC_STACK_ID = ASSISTANT_STACK_ID;
|
||||
private static final int LAST_STATIC_STACK_ID = PINNED_STACK_ID;
|
||||
|
||||
/** Start of ID range used by stacks that are created dynamically.
|
||||
* @hide */
|
||||
@@ -719,15 +707,6 @@ public class ActivityManager {
|
||||
return stackId >= FIRST_DYNAMIC_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if dynamic stacks are allowed to be visible behind the input stack.
|
||||
* @hide
|
||||
*/
|
||||
// TODO: Figure-out a way to remove.
|
||||
public static boolean isDynamicStacksVisibleBehindAllowed(int stackId) {
|
||||
return stackId == PINNED_STACK_ID || stackId == ASSISTANT_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if we try to maintain focus in the current stack when the top activity
|
||||
* finishes.
|
||||
@@ -739,15 +718,6 @@ public class ActivityManager {
|
||||
|| stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the input stack is affected by drag resizing.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isStackAffectedByDragResizing(int stackId) {
|
||||
return isStaticStack(stackId) && stackId != PINNED_STACK_ID
|
||||
&& stackId != ASSISTANT_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the windows of tasks being moved to the target stack from the source
|
||||
* stack should be replaced, meaning that window manager will keep the old window around
|
||||
@@ -759,26 +729,6 @@ public class ActivityManager {
|
||||
|| targetStackId == FREEFORM_WORKSPACE_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a stackId is a stack that be a backdrop to a translucent activity. These
|
||||
* are generally fullscreen stacks.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isBackdropToTranslucentActivity(int stackId) {
|
||||
return stackId == FULLSCREEN_WORKSPACE_STACK_ID
|
||||
|| stackId == ASSISTANT_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if activities from stasks in the given {@param stackId} are allowed to
|
||||
* enter picture-in-picture.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isAllowedToEnterPictureInPicture(int stackId) {
|
||||
return stackId != HOME_STACK_ID && stackId != ASSISTANT_STACK_ID &&
|
||||
stackId != RECENTS_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the top task in the task is allowed to return home when finished and
|
||||
* there are other tasks in the stack.
|
||||
@@ -810,34 +760,18 @@ public class ActivityManager {
|
||||
&& stackId != DOCKED_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the input stack id should only be present on a device that supports
|
||||
* multi-window mode.
|
||||
* @see android.app.ActivityManager#supportsMultiWindow
|
||||
* @hide
|
||||
*/
|
||||
// TODO: What about the other side of docked stack if we move this to WindowConfiguration?
|
||||
public static boolean isMultiWindowStack(int stackId) {
|
||||
return stackId == PINNED_STACK_ID || stackId == FREEFORM_WORKSPACE_STACK_ID
|
||||
|| stackId == DOCKED_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the input {@param stackId} is HOME_STACK_ID or RECENTS_STACK_ID
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isHomeOrRecentsStack(int stackId) {
|
||||
return stackId == HOME_STACK_ID || stackId == RECENTS_STACK_ID;
|
||||
}
|
||||
|
||||
/** Returns true if the input stack and its content can affect the device orientation.
|
||||
/** Returns the stack id for the input windowing mode.
|
||||
* @hide */
|
||||
public static boolean canSpecifyOrientation(int stackId) {
|
||||
return stackId == HOME_STACK_ID
|
||||
|| stackId == RECENTS_STACK_ID
|
||||
|| stackId == FULLSCREEN_WORKSPACE_STACK_ID
|
||||
|| stackId == ASSISTANT_STACK_ID
|
||||
|| isDynamicStack(stackId);
|
||||
// TODO: To be removed once we are not using stack id for stuff...
|
||||
public static int getStackIdForWindowingMode(int windowingMode) {
|
||||
switch (windowingMode) {
|
||||
case WINDOWING_MODE_PINNED: return PINNED_STACK_ID;
|
||||
case WINDOWING_MODE_FREEFORM: return FREEFORM_WORKSPACE_STACK_ID;
|
||||
case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY: return DOCKED_STACK_ID;
|
||||
case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY: return FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
case WINDOWING_MODE_FULLSCREEN: return FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
default: return INVALID_STACK_ID;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the windowing mode that should be used for this input stack id.
|
||||
@@ -847,14 +781,9 @@ public class ActivityManager {
|
||||
final int windowingMode;
|
||||
switch (stackId) {
|
||||
case FULLSCREEN_WORKSPACE_STACK_ID:
|
||||
case HOME_STACK_ID:
|
||||
case RECENTS_STACK_ID:
|
||||
windowingMode = inSplitScreenMode
|
||||
? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY : WINDOWING_MODE_FULLSCREEN;
|
||||
break;
|
||||
case ASSISTANT_STACK_ID:
|
||||
windowingMode = WINDOWING_MODE_FULLSCREEN;
|
||||
break;
|
||||
case PINNED_STACK_ID:
|
||||
windowingMode = WINDOWING_MODE_PINNED;
|
||||
break;
|
||||
@@ -869,51 +798,6 @@ public class ActivityManager {
|
||||
}
|
||||
return windowingMode;
|
||||
}
|
||||
|
||||
/** Returns the stack id for the input windowing mode.
|
||||
* @hide */
|
||||
// TODO: To be removed once we are not using stack id for stuff...
|
||||
public static int getStackIdForWindowingMode(int windowingMode) {
|
||||
switch (windowingMode) {
|
||||
case WINDOWING_MODE_PINNED: return PINNED_STACK_ID;
|
||||
case WINDOWING_MODE_FREEFORM: return FREEFORM_WORKSPACE_STACK_ID;
|
||||
case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY: return DOCKED_STACK_ID;
|
||||
default: return INVALID_STACK_ID;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the activity type that should be used for this input stack id.
|
||||
* @hide */
|
||||
// TODO: To be removed once we are not using stack id for stuff...
|
||||
public static int getActivityTypeForStackId(int stackId) {
|
||||
final int activityType;
|
||||
switch (stackId) {
|
||||
case HOME_STACK_ID:
|
||||
activityType = ACTIVITY_TYPE_HOME;
|
||||
break;
|
||||
case RECENTS_STACK_ID:
|
||||
activityType = ACTIVITY_TYPE_RECENTS;
|
||||
break;
|
||||
case ASSISTANT_STACK_ID:
|
||||
activityType = ACTIVITY_TYPE_ASSISTANT;
|
||||
break;
|
||||
default :
|
||||
activityType = ACTIVITY_TYPE_STANDARD;
|
||||
}
|
||||
return activityType;
|
||||
}
|
||||
|
||||
/** Returns the stack id for the input activity type.
|
||||
* @hide */
|
||||
// TODO: To be removed once we are not using stack id for stuff...
|
||||
public static int getStackIdForActivityType(int activityType) {
|
||||
switch (activityType) {
|
||||
case ACTIVITY_TYPE_HOME: return HOME_STACK_ID;
|
||||
case ACTIVITY_TYPE_RECENTS: return RECENTS_STACK_ID;
|
||||
case ACTIVITY_TYPE_ASSISTANT: return ASSISTANT_STACK_ID;
|
||||
default: return INVALID_STACK_ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1910,6 +1794,12 @@ public class ActivityManager {
|
||||
*/
|
||||
public int resizeMode;
|
||||
|
||||
/**
|
||||
* The full configuration the task is currently running in.
|
||||
* @hide
|
||||
*/
|
||||
public Configuration configuration = new Configuration();
|
||||
|
||||
public RunningTaskInfo() {
|
||||
}
|
||||
|
||||
@@ -1934,6 +1824,7 @@ public class ActivityManager {
|
||||
dest.writeInt(numRunning);
|
||||
dest.writeInt(supportsSplitScreenMultiWindow ? 1 : 0);
|
||||
dest.writeInt(resizeMode);
|
||||
configuration.writeToParcel(dest, flags);
|
||||
}
|
||||
|
||||
public void readFromParcel(Parcel source) {
|
||||
@@ -1951,6 +1842,7 @@ public class ActivityManager {
|
||||
numRunning = source.readInt();
|
||||
supportsSplitScreenMultiWindow = source.readInt() != 0;
|
||||
resizeMode = source.readInt();
|
||||
configuration.readFromParcel(source);
|
||||
}
|
||||
|
||||
public static final Creator<RunningTaskInfo> CREATOR = new Creator<RunningTaskInfo>() {
|
||||
@@ -2132,6 +2024,35 @@ public class ActivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes stacks in the windowing modes from the system if they are of activity type
|
||||
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public void removeStacksInWindowingModes(int[] windowingModes) throws SecurityException {
|
||||
try {
|
||||
getService().removeStacksInWindowingModes(windowingModes);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes stack of the activity types from the system.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public void removeStacksWithActivityTypes(int[] activityTypes) throws SecurityException {
|
||||
try {
|
||||
getService().removeStacksWithActivityTypes(activityTypes);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a task snapshot.
|
||||
* @hide
|
||||
@@ -2610,6 +2531,11 @@ public class ActivityManager {
|
||||
public boolean visible;
|
||||
// Index of the stack in the display's stack list, can be used for comparison of stack order
|
||||
public int position;
|
||||
/**
|
||||
* The full configuration the stack is currently running in.
|
||||
* @hide
|
||||
*/
|
||||
public Configuration configuration = new Configuration();
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
@@ -2644,6 +2570,7 @@ public class ActivityManager {
|
||||
} else {
|
||||
dest.writeInt(0);
|
||||
}
|
||||
configuration.writeToParcel(dest, flags);
|
||||
}
|
||||
|
||||
public void readFromParcel(Parcel source) {
|
||||
@@ -2671,6 +2598,7 @@ public class ActivityManager {
|
||||
if (source.readInt() > 0) {
|
||||
topActivity = ComponentName.readFromParcel(source);
|
||||
}
|
||||
configuration.readFromParcel(source);
|
||||
}
|
||||
|
||||
public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() {
|
||||
@@ -2698,6 +2626,8 @@ public class ActivityManager {
|
||||
sb.append(" displayId="); sb.append(displayId);
|
||||
sb.append(" userId="); sb.append(userId);
|
||||
sb.append("\n");
|
||||
sb.append(" configuration="); sb.append(configuration);
|
||||
sb.append("\n");
|
||||
prefix = prefix + " ";
|
||||
for (int i = 0; i < taskIds.length; ++i) {
|
||||
sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]);
|
||||
|
||||
@@ -380,7 +380,8 @@ interface IActivityManager {
|
||||
boolean preserveWindows, boolean animate, int animationDuration);
|
||||
List<ActivityManager.StackInfo> getAllStackInfos();
|
||||
void setFocusedStack(int stackId);
|
||||
ActivityManager.StackInfo getStackInfo(int stackId);
|
||||
ActivityManager.StackInfo getFocusedStackInfo();
|
||||
ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType);
|
||||
boolean convertFromTranslucent(in IBinder token);
|
||||
boolean convertToTranslucent(in IBinder token, in Bundle options);
|
||||
void notifyActivityDrawn(in IBinder token);
|
||||
@@ -440,7 +441,6 @@ interface IActivityManager {
|
||||
// Start of M transactions
|
||||
void notifyCleartextNetwork(int uid, in byte[] firstPacket);
|
||||
int createStackOnDisplay(int displayId);
|
||||
int getFocusedStackId();
|
||||
void setTaskResizeable(int taskId, int resizeableMode);
|
||||
boolean requestAssistContextExtras(int requestType, in IResultReceiver receiver,
|
||||
in Bundle receiverExtras, in IBinder activityToken,
|
||||
@@ -540,6 +540,13 @@ interface IActivityManager {
|
||||
void notifyPinnedStackAnimationStarted();
|
||||
void notifyPinnedStackAnimationEnded();
|
||||
void removeStack(int stackId);
|
||||
/**
|
||||
* Removes stacks in the input windowing modes from the system if they are of activity type
|
||||
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
|
||||
*/
|
||||
void removeStacksInWindowingModes(in int[] windowingModes);
|
||||
/** Removes stack of the activity types from the system. */
|
||||
void removeStacksWithActivityTypes(in int[] activityTypes);
|
||||
void makePackageIdle(String packageName, int userId);
|
||||
int getMemoryTrimLevel();
|
||||
/**
|
||||
|
||||
@@ -500,10 +500,15 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
|
||||
* @hide
|
||||
*/
|
||||
public boolean supportSplitScreenWindowingMode() {
|
||||
if (mActivityType == ACTIVITY_TYPE_ASSISTANT) {
|
||||
return supportSplitScreenWindowingMode(mWindowingMode, mActivityType);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean supportSplitScreenWindowingMode(int windowingMode, int activityType) {
|
||||
if (activityType == ACTIVITY_TYPE_ASSISTANT) {
|
||||
return false;
|
||||
}
|
||||
return mWindowingMode != WINDOWING_MODE_FREEFORM && mWindowingMode != WINDOWING_MODE_PINNED;
|
||||
return windowingMode != WINDOWING_MODE_FREEFORM && windowingMode != WINDOWING_MODE_PINNED;
|
||||
}
|
||||
|
||||
private static String windowingModeToString(@WindowingMode int windowingMode) {
|
||||
|
||||
@@ -358,10 +358,10 @@ interface IWindowManager
|
||||
* Updates the dim layer used while resizing.
|
||||
*
|
||||
* @param visible Whether the dim layer should be visible.
|
||||
* @param targetStackId The id of the task stack the dim layer should be placed on.
|
||||
* @param targetWindowingMode The windowing mode of the stack the dim layer should be placed on.
|
||||
* @param alpha The translucency of the dim layer, between 0 and 1.
|
||||
*/
|
||||
void setResizeDimLayer(boolean visible, int targetStackId, float alpha);
|
||||
void setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha);
|
||||
|
||||
/**
|
||||
* Requests Keyboard Shortcuts from the displayed window.
|
||||
|
||||
@@ -592,9 +592,10 @@ public interface WindowManagerPolicy {
|
||||
int getDockedDividerInsetsLw();
|
||||
|
||||
/**
|
||||
* Retrieves the {@param outBounds} from the stack with id {@param stackId}.
|
||||
* Retrieves the {@param outBounds} from the stack matching the {@param windowingMode} and
|
||||
* {@param activityType}.
|
||||
*/
|
||||
void getStackBounds(int stackId, Rect outBounds);
|
||||
void getStackBounds(int windowingMode, int activityType, Rect outBounds);
|
||||
|
||||
/**
|
||||
* Notifies window manager that {@link #isShowingDreamLw} has changed.
|
||||
|
||||
@@ -1873,11 +1873,11 @@
|
||||
|
||||
<!-- @SystemApi @hide Allows an application to create/manage/remove stacks -->
|
||||
<permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"
|
||||
android:protectionLevel="signature|privileged" />
|
||||
android:protectionLevel="signature|privileged|development" />
|
||||
|
||||
<!-- @SystemApi @hide Allows an application to embed other activities -->
|
||||
<permission android:name="android.permission.ACTIVITY_EMBEDDING"
|
||||
android:protectionLevel="signature|privileged" />
|
||||
android:protectionLevel="signature|privileged|development" />
|
||||
|
||||
<!-- Allows an application to start any activity, regardless of permission
|
||||
protection or exported state.
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.keyguard;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.Intent.ACTION_USER_UNLOCKED;
|
||||
import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
|
||||
import static android.os.BatteryManager.BATTERY_STATUS_FULL;
|
||||
@@ -1774,7 +1776,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
public void onTaskStackChangedBackground() {
|
||||
try {
|
||||
ActivityManager.StackInfo info = ActivityManager.getService().getStackInfo(
|
||||
ActivityManager.StackId.ASSISTANT_STACK_ID);
|
||||
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
|
||||
if (info == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.systemui.pip.phone;
|
||||
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
@@ -199,7 +201,8 @@ public class PipManager implements BasePipManager {
|
||||
public final void onBusEvent(ExpandPipEvent event) {
|
||||
if (event.clearThumbnailWindows) {
|
||||
try {
|
||||
StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
|
||||
StackInfo stackInfo = mActivityManager.getStackInfo(
|
||||
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
|
||||
if (stackInfo != null && stackInfo.taskIds != null) {
|
||||
SystemServicesProxy ssp = SystemServicesProxy.getInstance(mContext);
|
||||
for (int taskId : stackInfo.taskIds) {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.systemui.pip.phone;
|
||||
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
|
||||
import android.app.ActivityManager.StackInfo;
|
||||
import android.app.ActivityOptions;
|
||||
@@ -383,7 +385,8 @@ public class PipMenuActivityController {
|
||||
private void startMenuActivity(int menuState, Rect stackBounds, Rect movementBounds,
|
||||
boolean allowMenuTimeout, boolean willResizeMenu) {
|
||||
try {
|
||||
StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
|
||||
StackInfo pinnedStackInfo = mActivityManager.getStackInfo(
|
||||
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
|
||||
if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null &&
|
||||
pinnedStackInfo.taskIds.length > 0) {
|
||||
Intent intent = new Intent(mContext, PipMenuActivity.class);
|
||||
@@ -421,7 +424,8 @@ public class PipMenuActivityController {
|
||||
// Fetch the pinned stack bounds
|
||||
Rect stackBounds = null;
|
||||
try {
|
||||
StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
|
||||
StackInfo pinnedStackInfo = mActivityManager.getStackInfo(
|
||||
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
|
||||
if (pinnedStackInfo != null) {
|
||||
stackBounds = pinnedStackInfo.bounds;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.systemui.pip.phone;
|
||||
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static com.android.systemui.Interpolators.FAST_OUT_LINEAR_IN;
|
||||
import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN;
|
||||
import static com.android.systemui.Interpolators.LINEAR_OUT_SLOW_IN;
|
||||
@@ -121,7 +123,8 @@ public class PipMotionHelper implements Handler.Callback {
|
||||
void synchronizePinnedStackBounds() {
|
||||
cancelAnimations();
|
||||
try {
|
||||
StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
|
||||
StackInfo stackInfo =
|
||||
mActivityManager.getStackInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
|
||||
if (stackInfo != null) {
|
||||
mBounds.set(stackInfo.bounds);
|
||||
}
|
||||
@@ -529,7 +532,8 @@ public class PipMotionHelper implements Handler.Callback {
|
||||
Rect toBounds = (Rect) args.arg1;
|
||||
int duration = args.argi1;
|
||||
try {
|
||||
StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
|
||||
StackInfo stackInfo = mActivityManager.getStackInfo(
|
||||
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
|
||||
if (stackInfo == null) {
|
||||
// In the case where we've already re-expanded or dismissed the PiP, then
|
||||
// just skip the resize
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.systemui.pip.phone;
|
||||
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
|
||||
import android.app.ActivityManager.StackInfo;
|
||||
import android.app.IActivityManager;
|
||||
@@ -38,7 +40,8 @@ public class PipUtils {
|
||||
IActivityManager activityManager) {
|
||||
try {
|
||||
final String sysUiPackageName = context.getPackageName();
|
||||
final StackInfo pinnedStackInfo = activityManager.getStackInfo(PINNED_STACK_ID);
|
||||
final StackInfo pinnedStackInfo =
|
||||
activityManager.getStackInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
|
||||
if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null &&
|
||||
pinnedStackInfo.taskIds.length > 0) {
|
||||
for (int i = pinnedStackInfo.taskNames.length - 1; i >= 0; i--) {
|
||||
|
||||
@@ -54,6 +54,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
|
||||
/**
|
||||
@@ -502,7 +504,8 @@ public class PipManager implements BasePipManager {
|
||||
private StackInfo getPinnedStackInfo() {
|
||||
StackInfo stackInfo = null;
|
||||
try {
|
||||
stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
|
||||
stackInfo = mActivityManager.getStackInfo(
|
||||
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "getStackInfo failed", e);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.systemui.recents;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
@@ -437,9 +440,12 @@ public class Recents extends SystemUI
|
||||
int currentUser = sSystemServicesProxy.getCurrentUser();
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
|
||||
final int activityType = runningTask != null
|
||||
? runningTask.configuration.windowConfiguration.getActivityType()
|
||||
: ACTIVITY_TYPE_UNDEFINED;
|
||||
boolean screenPinningActive = ssp.isScreenPinningActive();
|
||||
boolean isRunningTaskInHomeOrRecentsStack = runningTask != null &&
|
||||
ActivityManager.StackId.isHomeOrRecentsStack(runningTask.stackId);
|
||||
boolean isRunningTaskInHomeOrRecentsStack =
|
||||
activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS;
|
||||
if (runningTask != null && !isRunningTaskInHomeOrRecentsStack && !screenPinningActive) {
|
||||
logDockAttempt(mContext, runningTask.topActivity, runningTask.resizeMode);
|
||||
if (runningTask.supportsSplitScreenMultiWindow) {
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package com.android.systemui.recents;
|
||||
|
||||
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.isHomeOrRecentsStack;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.view.View.MeasureSpec;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
@@ -533,7 +533,9 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
if (runningTask == null) return;
|
||||
|
||||
// Find the task in the recents list
|
||||
boolean isRunningTaskInHomeStack = SystemServicesProxy.isHomeStack(runningTask.stackId);
|
||||
boolean isRunningTaskInHomeStack =
|
||||
runningTask.configuration.windowConfiguration.getActivityType()
|
||||
== ACTIVITY_TYPE_HOME;
|
||||
ArrayList<Task> tasks = focusedStack.getStackTasks();
|
||||
Task toTask = null;
|
||||
ActivityOptions launchOpts = null;
|
||||
@@ -583,9 +585,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
|
||||
// Return early if there is no running task (can't determine affiliated tasks in this case)
|
||||
ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
|
||||
final int activityType = runningTask.configuration.windowConfiguration.getActivityType();
|
||||
if (runningTask == null) return;
|
||||
// Return early if the running task is in the home/recents stack (optimization)
|
||||
if (isHomeOrRecentsStack(runningTask.stackId)) return;
|
||||
if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) return;
|
||||
|
||||
// Find the task in the recents list
|
||||
ArrayList<Task> tasks = focusedStack.getStackTasks();
|
||||
|
||||
@@ -18,12 +18,12 @@ package com.android.systemui.recents.misc;
|
||||
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
@@ -38,6 +38,7 @@ import android.app.ActivityOptions;
|
||||
import android.app.AppGlobals;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.KeyguardManager;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
@@ -486,16 +487,22 @@ public class SystemServicesProxy {
|
||||
public ActivityManager.RunningTaskInfo getRunningTask() {
|
||||
// Note: The set of running tasks from the system is ordered by recency
|
||||
List<ActivityManager.RunningTaskInfo> tasks = mAm.getRunningTasks(10);
|
||||
if (tasks != null && !tasks.isEmpty()) {
|
||||
// Find the first task in a valid stack, we ignore everything from the Recents and PiP
|
||||
// stacks
|
||||
for (int i = 0; i < tasks.size(); i++) {
|
||||
ActivityManager.RunningTaskInfo task = tasks.get(i);
|
||||
int stackId = task.stackId;
|
||||
if (stackId != RECENTS_STACK_ID && stackId != PINNED_STACK_ID) {
|
||||
return task;
|
||||
}
|
||||
if (tasks == null || tasks.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Find the first task in a valid stack, we ignore everything from the Recents and PiP
|
||||
// stacks
|
||||
for (int i = 0; i < tasks.size(); i++) {
|
||||
final ActivityManager.RunningTaskInfo task = tasks.get(i);
|
||||
final WindowConfiguration winConfig = task.configuration.windowConfiguration;
|
||||
if (winConfig.getActivityType() == ACTIVITY_TYPE_RECENTS) {
|
||||
continue;
|
||||
}
|
||||
if (winConfig.getWindowingMode() == WINDOWING_MODE_PINNED) {
|
||||
continue;
|
||||
}
|
||||
return task;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -522,12 +529,17 @@ public class SystemServicesProxy {
|
||||
ActivityManager.StackInfo fullscreenStackInfo = null;
|
||||
ActivityManager.StackInfo recentsStackInfo = null;
|
||||
for (int i = 0; i < stackInfos.size(); i++) {
|
||||
StackInfo stackInfo = stackInfos.get(i);
|
||||
if (stackInfo.stackId == HOME_STACK_ID) {
|
||||
final StackInfo stackInfo = stackInfos.get(i);
|
||||
final WindowConfiguration winConfig = stackInfo.configuration.windowConfiguration;
|
||||
final int activityType = winConfig.getActivityType();
|
||||
final int windowingMode = winConfig.getWindowingMode();
|
||||
if (activityType == ACTIVITY_TYPE_HOME) {
|
||||
homeStackInfo = stackInfo;
|
||||
} else if (stackInfo.stackId == FULLSCREEN_WORKSPACE_STACK_ID) {
|
||||
} else if (activityType == ACTIVITY_TYPE_STANDARD
|
||||
&& (windowingMode == WINDOWING_MODE_FULLSCREEN
|
||||
|| windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)) {
|
||||
fullscreenStackInfo = stackInfo;
|
||||
} else if (stackInfo.stackId == RECENTS_STACK_ID) {
|
||||
} else if (activityType == ACTIVITY_TYPE_RECENTS) {
|
||||
recentsStackInfo = stackInfo;
|
||||
}
|
||||
}
|
||||
@@ -605,27 +617,6 @@ public class SystemServicesProxy {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given stack id is the home stack id.
|
||||
*/
|
||||
public static boolean isHomeStack(int stackId) {
|
||||
return stackId == HOME_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given stack id is the pinned stack id.
|
||||
*/
|
||||
public static boolean isPinnedStack(int stackId){
|
||||
return stackId == PINNED_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given stack id is the docked stack id.
|
||||
*/
|
||||
public static boolean isDockedStack(int stackId) {
|
||||
return stackId == DOCKED_STACK_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given stack id is the freeform workspace stack id.
|
||||
*/
|
||||
@@ -641,7 +632,8 @@ public class SystemServicesProxy {
|
||||
|
||||
ActivityManager.StackInfo stackInfo = null;
|
||||
try {
|
||||
stackInfo = mIam.getStackInfo(DOCKED_STACK_ID);
|
||||
stackInfo =
|
||||
mIam.getStackInfo(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -1106,9 +1098,10 @@ public class SystemServicesProxy {
|
||||
|
||||
try {
|
||||
// Use the recents stack bounds, fallback to fullscreen stack if it is null
|
||||
ActivityManager.StackInfo stackInfo = mIam.getStackInfo(RECENTS_STACK_ID);
|
||||
ActivityManager.StackInfo stackInfo =
|
||||
mIam.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS);
|
||||
if (stackInfo == null) {
|
||||
stackInfo = mIam.getStackInfo(FULLSCREEN_WORKSPACE_STACK_ID);
|
||||
stackInfo = mIam.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD);
|
||||
}
|
||||
if (stackInfo != null) {
|
||||
windowRect.set(stackInfo.bounds);
|
||||
|
||||
@@ -16,11 +16,6 @@
|
||||
|
||||
package com.android.systemui.recents.views;
|
||||
|
||||
import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
@@ -32,7 +27,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECOND
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager.StackId;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.ActivityOptions.OnAnimationStartedListener;
|
||||
import android.content.Context;
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.systemui.stackdivider;
|
||||
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
|
||||
import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
|
||||
|
||||
@@ -23,7 +26,6 @@ import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager.StackId;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
@@ -36,8 +38,6 @@ import android.util.AttributeSet;
|
||||
import android.view.Choreographer;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.PointerIcon;
|
||||
import android.view.VelocityTracker;
|
||||
@@ -62,7 +62,6 @@ import com.android.internal.policy.DockedDividerUtils;
|
||||
import com.android.internal.view.SurfaceFlingerVsyncChoreographer;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
|
||||
import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
|
||||
@@ -662,7 +661,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
} else {
|
||||
mWindowManagerProxy.maximizeDockedStack();
|
||||
}
|
||||
mWindowManagerProxy.setResizeDimLayer(false, -1, 0f);
|
||||
mWindowManagerProxy.setResizeDimLayer(false, WINDOWING_MODE_UNDEFINED, 0f);
|
||||
}
|
||||
|
||||
private void liftBackground() {
|
||||
@@ -998,8 +997,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
SnapTarget closestDismissTarget = getSnapAlgorithm().getClosestDismissTarget(position);
|
||||
float dimFraction = getDimFraction(position, closestDismissTarget);
|
||||
mWindowManagerProxy.setResizeDimLayer(dimFraction != 0f,
|
||||
getStackIdForDismissTarget(closestDismissTarget),
|
||||
dimFraction);
|
||||
getWindowingModeForDismissTarget(closestDismissTarget), dimFraction);
|
||||
}
|
||||
|
||||
private void applyExitAnimationParallax(Rect taskRect, int position) {
|
||||
@@ -1133,13 +1131,13 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
}
|
||||
}
|
||||
|
||||
private int getStackIdForDismissTarget(SnapTarget dismissTarget) {
|
||||
private int getWindowingModeForDismissTarget(SnapTarget dismissTarget) {
|
||||
if ((dismissTarget.flag == SnapTarget.FLAG_DISMISS_START && dockSideTopLeft(mDockSide))
|
||||
|| (dismissTarget.flag == SnapTarget.FLAG_DISMISS_END
|
||||
&& dockSideBottomRight(mDockSide))) {
|
||||
return StackId.DOCKED_STACK_ID;
|
||||
return WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
} else {
|
||||
return StackId.RECENTS_STACK_ID;
|
||||
return WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public class WindowManagerProxy {
|
||||
private final Rect mTouchableRegion = new Rect();
|
||||
|
||||
private boolean mDimLayerVisible;
|
||||
private int mDimLayerTargetStack;
|
||||
private int mDimLayerTargetWindowingMode;
|
||||
private float mDimLayerAlpha;
|
||||
|
||||
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
|
||||
@@ -113,7 +113,7 @@ public class WindowManagerProxy {
|
||||
public void run() {
|
||||
try {
|
||||
WindowManagerGlobal.getWindowManagerService().setResizeDimLayer(mDimLayerVisible,
|
||||
mDimLayerTargetStack, mDimLayerAlpha);
|
||||
mDimLayerTargetWindowingMode, mDimLayerAlpha);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to resize stack: " + e);
|
||||
}
|
||||
@@ -200,9 +200,9 @@ public class WindowManagerProxy {
|
||||
return DOCKED_INVALID;
|
||||
}
|
||||
|
||||
public void setResizeDimLayer(boolean visible, int targetStackId, float alpha) {
|
||||
public void setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha) {
|
||||
mDimLayerVisible = visible;
|
||||
mDimLayerTargetStack = targetStackId;
|
||||
mDimLayerTargetWindowingMode = targetWindowingMode;
|
||||
mDimLayerAlpha = alpha;
|
||||
mExecutor.execute(mDimLayerRunnable);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
|
||||
import android.app.ActivityManager.StackId;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -107,7 +107,7 @@ class CarNavigationBarController {
|
||||
}
|
||||
}
|
||||
|
||||
public void taskChanged(String packageName, int stackId) {
|
||||
public void taskChanged(String packageName, ActivityManager.RunningTaskInfo taskInfo) {
|
||||
// If the package name belongs to a filter, then highlight appropriate button in
|
||||
// the navigation bar.
|
||||
if (mFacetPackageMap.containsKey(packageName)) {
|
||||
@@ -121,8 +121,9 @@ class CarNavigationBarController {
|
||||
}
|
||||
|
||||
// Set up the persistent docked task if needed.
|
||||
if (mPersistentTaskIntent != null && !mStatusBar.hasDockedTask()
|
||||
&& stackId != StackId.HOME_STACK_ID) {
|
||||
boolean isHomeTask =
|
||||
taskInfo.configuration.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME;
|
||||
if (mPersistentTaskIntent != null && !mStatusBar.hasDockedTask() && !isHomeTask) {
|
||||
mStatusBar.startActivityOnStack(mPersistentTaskIntent,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ public class CarStatusBar extends StatusBar implements
|
||||
ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getRunningTask();
|
||||
if (runningTaskInfo != null && runningTaskInfo.baseActivity != null) {
|
||||
mController.taskChanged(runningTaskInfo.baseActivity.getPackageName(),
|
||||
runningTaskInfo.stackId);
|
||||
runningTaskInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,12 @@
|
||||
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.StackId;
|
||||
import android.app.ActivityManager.StackInfo;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.AlarmManager.AlarmClockInfo;
|
||||
@@ -523,12 +527,18 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
||||
mCurrentNotifs.clear();
|
||||
mUiOffloadThread.submit(() -> {
|
||||
try {
|
||||
int focusedId = ActivityManager.getService().getFocusedStackId();
|
||||
if (focusedId == StackId.FULLSCREEN_WORKSPACE_STACK_ID) {
|
||||
checkStack(StackId.FULLSCREEN_WORKSPACE_STACK_ID, notifs, noMan, pm);
|
||||
final StackInfo focusedStack = ActivityManager.getService().getFocusedStackInfo();
|
||||
if (focusedStack != null) {
|
||||
final int windowingMode =
|
||||
focusedStack.configuration.windowConfiguration.getWindowingMode();
|
||||
if (windowingMode == WINDOWING_MODE_FULLSCREEN
|
||||
|| windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
|
||||
checkStack(focusedStack, notifs, noMan, pm);
|
||||
}
|
||||
}
|
||||
if (mDockedStackExists) {
|
||||
checkStack(StackId.DOCKED_STACK_ID, notifs, noMan, pm);
|
||||
checkStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED,
|
||||
notifs, noMan, pm);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
@@ -539,10 +549,19 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
|
||||
});
|
||||
}
|
||||
|
||||
private void checkStack(int stackId, ArraySet<Pair<String, Integer>> notifs,
|
||||
private void checkStack(int windowingMode, int activityType,
|
||||
ArraySet<Pair<String, Integer>> notifs, NotificationManager noMan, IPackageManager pm) {
|
||||
try {
|
||||
final StackInfo info =
|
||||
ActivityManager.getService().getStackInfo(windowingMode, activityType);
|
||||
checkStack(info, notifs, noMan, pm);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
private void checkStack(StackInfo info, ArraySet<Pair<String, Integer>> notifs,
|
||||
NotificationManager noMan, IPackageManager pm) {
|
||||
try {
|
||||
StackInfo info = ActivityManager.getService().getStackInfo(stackId);
|
||||
if (info == null || info.topActivity == null) return;
|
||||
String pkg = info.topActivity.getPackageName();
|
||||
if (!hasNotif(notifs, pkg, info.userId)) {
|
||||
|
||||
@@ -16,6 +16,19 @@
|
||||
|
||||
package com.android.server.am;
|
||||
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.getStackIdForWindowingMode;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.Display.FLAG_PRIVATE;
|
||||
import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
|
||||
@@ -27,10 +40,12 @@ import static com.android.server.am.proto.ActivityDisplayProto.STACKS;
|
||||
import static com.android.server.am.proto.ActivityDisplayProto.ID;
|
||||
|
||||
import android.app.ActivityManagerInternal;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.util.IntArray;
|
||||
import android.util.Slog;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.Display;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.wm.ConfigurationContainer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -129,6 +144,204 @@ class ActivityDisplay extends ConfigurationContainer {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the topmost stack on the display that is compatible with the input windowing mode and
|
||||
* activity type. {@code null} means no compatible stack on the display.
|
||||
* @see ConfigurationContainer#isCompatible(int, int)
|
||||
*/
|
||||
<T extends ActivityStack> T getStack(int windowingMode, int activityType) {
|
||||
for (int i = mStacks.size() - 1; i >= 0; --i) {
|
||||
final ActivityStack stack = mStacks.get(i);
|
||||
// TODO: Should undefined windowing and activity type be compatible with standard type?
|
||||
if (stack.isCompatible(windowingMode, activityType)) {
|
||||
return (T) stack;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getStack(int, int)
|
||||
* @see #createStack(int, int, boolean)
|
||||
*/
|
||||
<T extends ActivityStack> T getOrCreateStack(int windowingMode, int activityType,
|
||||
boolean onTop) {
|
||||
T stack = getStack(windowingMode, activityType);
|
||||
if (stack != null) {
|
||||
return stack;
|
||||
}
|
||||
return createStack(windowingMode, activityType, onTop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a stack matching the input windowing mode and activity type on this display.
|
||||
* @param windowingMode The windowing mode the stack should be created in. If
|
||||
* {@link WindowConfiguration#WINDOWING_MODE_UNDEFINED} then the stack will
|
||||
* be created in {@link WindowConfiguration#WINDOWING_MODE_FULLSCREEN}.
|
||||
* @param activityType The activityType the stack should be created in. If
|
||||
* {@link WindowConfiguration#ACTIVITY_TYPE_UNDEFINED} then the stack will
|
||||
* be created in {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}.
|
||||
* @param onTop If true the stack will be created at the top of the display, else at the bottom.
|
||||
* @return The newly created stack.
|
||||
*/
|
||||
<T extends ActivityStack> T createStack(int windowingMode, int activityType, boolean onTop) {
|
||||
|
||||
if (activityType == ACTIVITY_TYPE_UNDEFINED) {
|
||||
// Can't have an undefined stack type yet...so re-map to standard. Anyone that wants
|
||||
// anything else should be passing it in anyways...
|
||||
activityType = ACTIVITY_TYPE_STANDARD;
|
||||
}
|
||||
|
||||
if (activityType != ACTIVITY_TYPE_STANDARD) {
|
||||
// For now there can be only one stack of a particular non-standard activity type on a
|
||||
// display. So, get that ignoring whatever windowing mode it is currently in.
|
||||
T stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
|
||||
if (stack != null) {
|
||||
throw new IllegalArgumentException("Stack=" + stack + " of activityType="
|
||||
+ activityType + " already on display=" + this + ". Can't have multiple.");
|
||||
}
|
||||
}
|
||||
|
||||
final ActivityManagerService service = mSupervisor.mService;
|
||||
if (!mSupervisor.isWindowingModeSupported(windowingMode, service.mSupportsMultiWindow,
|
||||
service.mSupportsSplitScreenMultiWindow, service.mSupportsFreeformWindowManagement,
|
||||
service.mSupportsPictureInPicture, activityType)) {
|
||||
throw new IllegalArgumentException("Can't create stack for unsupported windowingMode="
|
||||
+ windowingMode);
|
||||
}
|
||||
|
||||
if (windowingMode == WINDOWING_MODE_UNDEFINED) {
|
||||
// TODO: Should be okay to have stacks with with undefined windowing mode long term, but
|
||||
// have to set them to something for now due to logic that depending on them.
|
||||
windowingMode = WINDOWING_MODE_FULLSCREEN;
|
||||
}
|
||||
|
||||
final boolean inSplitScreenMode = hasSplitScreenStack();
|
||||
if (!inSplitScreenMode
|
||||
&& windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY) {
|
||||
// Switch to fullscreen windowing mode if we are not in split-screen mode and we are
|
||||
// trying to launch in split-screen secondary.
|
||||
windowingMode = WINDOWING_MODE_FULLSCREEN;
|
||||
} else if (inSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN
|
||||
&& WindowConfiguration.supportSplitScreenWindowingMode(
|
||||
windowingMode, activityType)) {
|
||||
windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
}
|
||||
|
||||
int stackId = INVALID_STACK_ID;
|
||||
if (mDisplayId == DEFAULT_DISPLAY && (activityType == ACTIVITY_TYPE_STANDARD
|
||||
|| activityType == ACTIVITY_TYPE_UNDEFINED)) {
|
||||
// TODO: Will be removed once we are no longer using static stack ids.
|
||||
stackId = getStackIdForWindowingMode(windowingMode);
|
||||
if (stackId == INVALID_STACK_ID) {
|
||||
// Whatever...put in fullscreen stack for now.
|
||||
stackId = FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
}
|
||||
final T stack = getStack(stackId);
|
||||
if (stack != null) {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
if (stackId == INVALID_STACK_ID) {
|
||||
stackId = mSupervisor.getNextStackId();
|
||||
}
|
||||
|
||||
final T stack = createStackUnchecked(windowingMode, activityType, stackId, onTop);
|
||||
|
||||
if (mDisplayId == DEFAULT_DISPLAY && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
|
||||
// Make sure recents stack exist when creating a dock stack as it normally need to be on
|
||||
// the other side of the docked stack and we make visibility decisions based on that.
|
||||
// TODO: Not sure if this is needed after we change to calculate visibility based on
|
||||
// stack z-order vs. id.
|
||||
getOrCreateStack(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_RECENTS, onTop);
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
<T extends ActivityStack> T createStackUnchecked(int windowingMode, int activityType,
|
||||
int stackId, boolean onTop) {
|
||||
switch (windowingMode) {
|
||||
case WINDOWING_MODE_PINNED:
|
||||
return (T) new PinnedActivityStack(this, stackId, mSupervisor, onTop);
|
||||
default:
|
||||
return (T) new ActivityStack(
|
||||
this, stackId, mSupervisor, windowingMode, activityType, onTop);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes stacks in the input windowing modes from the system if they are of activity type
|
||||
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
|
||||
*/
|
||||
void removeStacksInWindowingModes(int... windowingModes) {
|
||||
if (windowingModes == null || windowingModes.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int j = windowingModes.length - 1 ; j >= 0; --j) {
|
||||
final int windowingMode = windowingModes[j];
|
||||
for (int i = mStacks.size() - 1; i >= 0; --i) {
|
||||
final ActivityStack stack = mStacks.get(i);
|
||||
if (!stack.isActivityTypeStandardOrUndefined()) {
|
||||
continue;
|
||||
}
|
||||
if (stack.getWindowingMode() != windowingMode) {
|
||||
continue;
|
||||
}
|
||||
mSupervisor.removeStackLocked(stack.mStackId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeStacksWithActivityTypes(int... activityTypes) {
|
||||
if (activityTypes == null || activityTypes.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int j = activityTypes.length - 1 ; j >= 0; --j) {
|
||||
final int activityType = activityTypes[j];
|
||||
for (int i = mStacks.size() - 1; i >= 0; --i) {
|
||||
final ActivityStack stack = mStacks.get(i);
|
||||
if (stack.getActivityType() == activityType) {
|
||||
mSupervisor.removeStackLocked(stack.mStackId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the top visible stack activity type that isn't in the exclude windowing mode. */
|
||||
int getTopVisibleStackActivityType(int excludeWindowingMode) {
|
||||
for (int i = mStacks.size() - 1; i >= 0; --i) {
|
||||
final ActivityStack stack = mStacks.get(i);
|
||||
if (stack.getWindowingMode() == excludeWindowingMode) {
|
||||
continue;
|
||||
}
|
||||
if (stack.shouldBeVisible(null /* starting */)) {
|
||||
return stack.getActivityType();
|
||||
}
|
||||
}
|
||||
return ACTIVITY_TYPE_UNDEFINED;
|
||||
}
|
||||
|
||||
ActivityStack getSplitScreenStack() {
|
||||
return getStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
|
||||
}
|
||||
|
||||
boolean hasSplitScreenStack() {
|
||||
return getSplitScreenStack() != null;
|
||||
}
|
||||
|
||||
PinnedActivityStack getPinnedStack() {
|
||||
return getStack(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
|
||||
}
|
||||
|
||||
boolean hasPinnedStack() {
|
||||
return getPinnedStack() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
|
||||
|
||||
@@ -33,6 +33,13 @@ import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.getWindowingModeForStackId;
|
||||
import static android.app.ActivityManager.StackId.isStaticStack;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
|
||||
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
|
||||
import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
|
||||
@@ -164,7 +171,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMI
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
||||
import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
|
||||
import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
|
||||
import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
|
||||
import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
|
||||
@@ -177,7 +183,6 @@ import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
|
||||
import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
|
||||
import static com.android.server.am.proto.ActivityManagerServiceProto.ACTIVITIES;
|
||||
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
|
||||
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
|
||||
import static com.android.server.wm.AppTransition.TRANSIT_NONE;
|
||||
import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
|
||||
import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
|
||||
@@ -2372,11 +2377,7 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
if (disableNonVrUi) {
|
||||
// If we are in a VR mode where Picture-in-Picture mode is unsupported,
|
||||
// then remove the pinned stack.
|
||||
final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
|
||||
PINNED_STACK_ID);
|
||||
if (pinnedStack != null) {
|
||||
mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
|
||||
}
|
||||
mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
@@ -8105,7 +8106,7 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
|
||||
mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
|
||||
true /* moveHomeStackToFront */, "enterPictureInPictureMode");
|
||||
final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
|
||||
final PinnedActivityStack stack = r.getStack();
|
||||
stack.setPictureInPictureAspectRatio(aspectRatio);
|
||||
stack.setPictureInPictureActions(actions);
|
||||
|
||||
@@ -8220,11 +8221,6 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
+ ": Current activity does not support picture-in-picture.");
|
||||
}
|
||||
|
||||
if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
|
||||
throw new IllegalStateException(caller
|
||||
+ ": Activities on the home, assistant, or recents stack not supported");
|
||||
}
|
||||
|
||||
if (params.hasSetAspectRatio()
|
||||
&& !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
|
||||
params.getAspectRatio())) {
|
||||
@@ -9862,7 +9858,7 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
if (tr.mBounds != null) {
|
||||
rti.bounds = new Rect(tr.mBounds);
|
||||
}
|
||||
rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
|
||||
rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreenWindowingMode();
|
||||
rti.resizeMode = tr.mResizeMode;
|
||||
|
||||
ActivityRecord base = null;
|
||||
@@ -10181,21 +10177,23 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
// - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
|
||||
// that task to freeform
|
||||
// - otherwise the task is not moved
|
||||
int stackId = task.getStackId();
|
||||
ActivityStack stack = task.getStack();
|
||||
if (!task.getWindowConfiguration().canResizeTask()) {
|
||||
throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
|
||||
}
|
||||
if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
|
||||
stackId = FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
} else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
|
||||
stackId = FREEFORM_WORKSPACE_STACK_ID;
|
||||
if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
|
||||
stack = stack.getDisplay().getOrCreateStack(
|
||||
WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
|
||||
} else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
|
||||
stack = stack.getDisplay().getOrCreateStack(
|
||||
WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
|
||||
}
|
||||
|
||||
// Reparent the task to the right stack if necessary
|
||||
boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
|
||||
if (stackId != task.getStackId()) {
|
||||
if (stack != task.getStack()) {
|
||||
// Defer resume until the task is resized below
|
||||
task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
|
||||
task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
|
||||
DEFER_RESUME, "resizeTask");
|
||||
preserveWindow = false;
|
||||
}
|
||||
@@ -10368,13 +10366,14 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
@Override
|
||||
public void removeStack(int stackId) {
|
||||
enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
|
||||
if (StackId.isHomeOrRecentsStack(stackId)) {
|
||||
throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final ActivityStack stack = mStackSupervisor.getStack(stackId);
|
||||
if (stack != null && !stack.isActivityTypeStandardOrUndefined()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Removing non-standard stack is not allowed.");
|
||||
}
|
||||
mStackSupervisor.removeStackLocked(stackId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
@@ -10382,6 +10381,36 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes stacks in the input windowing modes from the system if they are of activity type
|
||||
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
|
||||
*/
|
||||
@Override
|
||||
public void removeStacksInWindowingModes(int[] windowingModes) {
|
||||
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "removeStacksInWindowingModes()");
|
||||
synchronized (this) {
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mStackSupervisor.removeStacksInWindowingModes(windowingModes);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeStacksWithActivityTypes(int[] activityTypes) {
|
||||
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "removeStacksWithActivityTypes()");
|
||||
synchronized (this) {
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveStackToDisplay(int stackId, int displayId) {
|
||||
enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
|
||||
@@ -10525,13 +10554,15 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
public int createStackOnDisplay(int displayId) throws RemoteException {
|
||||
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
|
||||
synchronized (this) {
|
||||
final int stackId = mStackSupervisor.getNextStackId();
|
||||
final ActivityStack stack =
|
||||
mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
|
||||
if (stack == null) {
|
||||
final ActivityDisplay display =
|
||||
mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
|
||||
if (display == null) {
|
||||
return INVALID_STACK_ID;
|
||||
}
|
||||
return stack.mStackId;
|
||||
// TODO(multi-display): Have the caller pass in the windowing mode and activity type.
|
||||
final ActivityStack stack = display.createStack(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /*onTop*/);
|
||||
return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10563,8 +10594,12 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
"exitFreeformMode: You can only go fullscreen from freeform.");
|
||||
}
|
||||
|
||||
final ActivityStack fullscreenStack = stack.getDisplay().getOrCreateStack(
|
||||
WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
|
||||
|
||||
if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
|
||||
r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
|
||||
// TODO: Should just change windowing mode vs. re-parenting...
|
||||
r.getTask().reparent(fullscreenStack, ON_TOP,
|
||||
REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
@@ -10575,10 +10610,6 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
@Override
|
||||
public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
|
||||
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
|
||||
if (StackId.isHomeOrRecentsStack(stackId)) {
|
||||
throw new IllegalArgumentException(
|
||||
"moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
|
||||
}
|
||||
synchronized (this) {
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -10594,8 +10625,25 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
|
||||
null /* initialBounds */);
|
||||
}
|
||||
task.reparent(stackId, toTop,
|
||||
REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
|
||||
|
||||
ActivityStack stack = mStackSupervisor.getStack(stackId);
|
||||
if (stack == null) {
|
||||
if (!isStaticStack(stackId)) {
|
||||
throw new IllegalStateException(
|
||||
"moveTaskToStack: No stack for stackId=" + stackId);
|
||||
}
|
||||
final ActivityDisplay display = task.getStack().getDisplay();
|
||||
final int windowingMode =
|
||||
getWindowingModeForStackId(stackId, display.hasSplitScreenStack());
|
||||
stack = display.getOrCreateStack(windowingMode,
|
||||
task.getStack().getActivityType(), toTop);
|
||||
}
|
||||
if (!stack.isActivityTypeStandardOrUndefined()) {
|
||||
throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
|
||||
+ taskId + " to stack " + stackId);
|
||||
}
|
||||
task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
|
||||
"moveTaskToStack");
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
@@ -10628,13 +10676,18 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
|
||||
+ " to createMode=" + createMode + " toTop=" + toTop);
|
||||
mWindowManager.setDockedStackCreateState(createMode, initialBounds);
|
||||
|
||||
final ActivityDisplay display = task.getStack().getDisplay();
|
||||
final ActivityStack stack = display.getOrCreateStack(
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, task.getStack().getActivityType(),
|
||||
toTop);
|
||||
|
||||
// Defer resuming until we move the home stack to the front below
|
||||
final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
|
||||
// TODO: Should just change windowing mode vs. re-parenting...
|
||||
final boolean moved = task.reparent(stack, toTop,
|
||||
REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
|
||||
"moveTaskToDockedStack");
|
||||
if (moved) {
|
||||
@@ -10682,17 +10735,16 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
try {
|
||||
synchronized (this) {
|
||||
if (animate) {
|
||||
if (stackId == PINNED_STACK_ID) {
|
||||
final PinnedActivityStack pinnedStack =
|
||||
mStackSupervisor.getStack(PINNED_STACK_ID);
|
||||
if (pinnedStack != null) {
|
||||
pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
|
||||
destBounds, animationDuration, false /* fromFullscreen */);
|
||||
}
|
||||
} else {
|
||||
final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
|
||||
if (stack == null) {
|
||||
return;
|
||||
}
|
||||
if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
|
||||
throw new IllegalArgumentException("Stack: " + stackId
|
||||
+ " doesn't support animated resize.");
|
||||
}
|
||||
stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
|
||||
animationDuration, false /* fromFullscreen */);
|
||||
} else {
|
||||
mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
|
||||
null /* tempTaskInsetBounds */, preserveWindows,
|
||||
@@ -10744,11 +10796,6 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
@Override
|
||||
public void positionTaskInStack(int taskId, int stackId, int position) {
|
||||
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
|
||||
if (StackId.isHomeOrRecentsStack(stackId)) {
|
||||
throw new IllegalArgumentException(
|
||||
"positionTaskInStack: Attempt to change the position of task "
|
||||
+ taskId + " in/to home/recents stack");
|
||||
}
|
||||
synchronized (this) {
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -10760,8 +10807,16 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
+ taskId);
|
||||
}
|
||||
|
||||
final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
|
||||
!ON_TOP);
|
||||
final ActivityStack stack = mStackSupervisor.getStack(stackId);
|
||||
|
||||
if (stack == null) {
|
||||
throw new IllegalArgumentException("positionTaskInStack: no stack for id="
|
||||
+ stackId);
|
||||
}
|
||||
if (!stack.isActivityTypeStandardOrUndefined()) {
|
||||
throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
|
||||
+ " the position of task " + taskId + " in/to non-standard stack");
|
||||
}
|
||||
|
||||
// TODO: Have the callers of this API call a separate reparent method if that is
|
||||
// what they intended to do vs. having this method also do reparenting.
|
||||
@@ -10770,8 +10825,8 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
stack.positionChildAt(task, position);
|
||||
} else {
|
||||
// Reparent to new stack.
|
||||
task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
|
||||
!ANIMATE, !DEFER_RESUME, "positionTaskInStack");
|
||||
task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
|
||||
!DEFER_RESUME, "positionTaskInStack");
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
@@ -10793,12 +10848,12 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackInfo getStackInfo(int stackId) {
|
||||
public StackInfo getStackInfo(int windowingMode, int activityType) {
|
||||
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (this) {
|
||||
return mStackSupervisor.getStackInfoLocked(stackId);
|
||||
return mStackSupervisor.getStackInfo(windowingMode, activityType);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
@@ -10849,11 +10904,7 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
}
|
||||
|
||||
// When a task is locked, dismiss the pinned stack if it exists
|
||||
final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
|
||||
PINNED_STACK_ID);
|
||||
if (pinnedStack != null) {
|
||||
mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
|
||||
}
|
||||
mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
|
||||
|
||||
// isAppPinning is used to distinguish between locked and pinned mode, as pinned mode
|
||||
// is initiated by system after the pinning request was shown and locked mode is initiated
|
||||
@@ -20049,12 +20100,20 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFocusedStackId() throws RemoteException {
|
||||
ActivityStack focusedStack = getFocusedStack();
|
||||
if (focusedStack != null) {
|
||||
return focusedStack.getStackId();
|
||||
public StackInfo getFocusedStackInfo() throws RemoteException {
|
||||
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (this) {
|
||||
ActivityStack focusedStack = getFocusedStack();
|
||||
if (focusedStack != null) {
|
||||
return mStackSupervisor.getStackInfo(focusedStack.mStackId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public Configuration getConfiguration() {
|
||||
@@ -20080,16 +20139,18 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
* activity and clearing the task at the same time.
|
||||
*/
|
||||
@Override
|
||||
// TODO: API should just be about changing windowing modes...
|
||||
public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
|
||||
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
|
||||
if (StackId.isHomeOrRecentsStack(fromStackId)) {
|
||||
throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
|
||||
}
|
||||
synchronized (this) {
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
|
||||
if (stack != null){
|
||||
if (!stack.isActivityTypeStandardOrUndefined()) {
|
||||
throw new IllegalArgumentException(
|
||||
"You can't move tasks from non-standard stacks.");
|
||||
}
|
||||
mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -76,6 +76,7 @@ import static android.app.ActivityManager.RESIZE_MODE_USER;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
|
||||
@@ -2113,9 +2114,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
}
|
||||
|
||||
int runStackInfo(PrintWriter pw) throws RemoteException {
|
||||
String stackIdStr = getNextArgRequired();
|
||||
int stackId = Integer.parseInt(stackIdStr);
|
||||
ActivityManager.StackInfo info = mInterface.getStackInfo(stackId);
|
||||
int windowingMode = Integer.parseInt(getNextArgRequired());
|
||||
int activityType = Integer.parseInt(getNextArgRequired());
|
||||
ActivityManager.StackInfo info = mInterface.getStackInfo(windowingMode, activityType);
|
||||
pw.println(info);
|
||||
return 0;
|
||||
}
|
||||
@@ -2149,7 +2150,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
final String delayStr = getNextArg();
|
||||
final int delayMs = (delayStr != null) ? Integer.parseInt(delayStr) : 0;
|
||||
|
||||
ActivityManager.StackInfo info = mInterface.getStackInfo(DOCKED_STACK_ID);
|
||||
ActivityManager.StackInfo info = mInterface.getStackInfo(
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
|
||||
if (info == null) {
|
||||
err.println("Docked stack doesn't exist");
|
||||
return -1;
|
||||
@@ -2252,10 +2254,6 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
return runTaskResizeable(pw);
|
||||
} else if (op.equals("resize")) {
|
||||
return runTaskResize(pw);
|
||||
} else if (op.equals("drag-task-test")) {
|
||||
return runTaskDragTaskTest(pw);
|
||||
} else if (op.equals("size-task-test")) {
|
||||
return runTaskSizeTaskTest(pw);
|
||||
} else if (op.equals("focus")) {
|
||||
return runTaskFocus(pw);
|
||||
} else {
|
||||
@@ -2308,58 +2306,6 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
}
|
||||
}
|
||||
|
||||
int runTaskDragTaskTest(PrintWriter pw) throws RemoteException {
|
||||
final int taskId = Integer.parseInt(getNextArgRequired());
|
||||
final int stepSize = Integer.parseInt(getNextArgRequired());
|
||||
final String delayStr = getNextArg();
|
||||
final int delay_ms = (delayStr != null) ? Integer.parseInt(delayStr) : 0;
|
||||
final ActivityManager.StackInfo stackInfo;
|
||||
Rect taskBounds;
|
||||
stackInfo = mInterface.getStackInfo(mInterface.getFocusedStackId());
|
||||
taskBounds = mInterface.getTaskBounds(taskId);
|
||||
final Rect stackBounds = stackInfo.bounds;
|
||||
int travelRight = stackBounds.width() - taskBounds.width();
|
||||
int travelLeft = -travelRight;
|
||||
int travelDown = stackBounds.height() - taskBounds.height();
|
||||
int travelUp = -travelDown;
|
||||
int passes = 0;
|
||||
|
||||
// We do 2 passes to get back to the original location of the task.
|
||||
while (passes < 2) {
|
||||
// Move right
|
||||
pw.println("Moving right...");
|
||||
pw.flush();
|
||||
travelRight = moveTask(taskId, taskBounds, stackBounds, stepSize,
|
||||
travelRight, MOVING_FORWARD, MOVING_HORIZONTALLY, delay_ms);
|
||||
pw.println("Still need to travel right by " + travelRight);
|
||||
|
||||
// Move down
|
||||
pw.println("Moving down...");
|
||||
pw.flush();
|
||||
travelDown = moveTask(taskId, taskBounds, stackBounds, stepSize,
|
||||
travelDown, MOVING_FORWARD, !MOVING_HORIZONTALLY, delay_ms);
|
||||
pw.println("Still need to travel down by " + travelDown);
|
||||
|
||||
// Move left
|
||||
pw.println("Moving left...");
|
||||
pw.flush();
|
||||
travelLeft = moveTask(taskId, taskBounds, stackBounds, stepSize,
|
||||
travelLeft, !MOVING_FORWARD, MOVING_HORIZONTALLY, delay_ms);
|
||||
pw.println("Still need to travel left by " + travelLeft);
|
||||
|
||||
// Move up
|
||||
pw.println("Moving up...");
|
||||
pw.flush();
|
||||
travelUp = moveTask(taskId, taskBounds, stackBounds, stepSize,
|
||||
travelUp, !MOVING_FORWARD, !MOVING_HORIZONTALLY, delay_ms);
|
||||
pw.println("Still need to travel up by " + travelUp);
|
||||
|
||||
taskBounds = mInterface.getTaskBounds(taskId);
|
||||
passes++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize,
|
||||
int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms)
|
||||
throws RemoteException {
|
||||
@@ -2422,133 +2368,6 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
return stepSize;
|
||||
}
|
||||
|
||||
int runTaskSizeTaskTest(PrintWriter pw) throws RemoteException {
|
||||
final int taskId = Integer.parseInt(getNextArgRequired());
|
||||
final int stepSize = Integer.parseInt(getNextArgRequired());
|
||||
final String delayStr = getNextArg();
|
||||
final int delay_ms = (delayStr != null) ? Integer.parseInt(delayStr) : 0;
|
||||
final ActivityManager.StackInfo stackInfo;
|
||||
final Rect initialTaskBounds;
|
||||
stackInfo = mInterface.getStackInfo(mInterface.getFocusedStackId());
|
||||
initialTaskBounds = mInterface.getTaskBounds(taskId);
|
||||
final Rect stackBounds = stackInfo.bounds;
|
||||
stackBounds.inset(STACK_BOUNDS_INSET, STACK_BOUNDS_INSET);
|
||||
final Rect currentTaskBounds = new Rect(initialTaskBounds);
|
||||
|
||||
// Size by top-left
|
||||
pw.println("Growing top-left");
|
||||
pw.flush();
|
||||
do {
|
||||
currentTaskBounds.top -= getStepSize(
|
||||
currentTaskBounds.top, stackBounds.top, stepSize, GREATER_THAN_TARGET);
|
||||
|
||||
currentTaskBounds.left -= getStepSize(
|
||||
currentTaskBounds.left, stackBounds.left, stepSize, GREATER_THAN_TARGET);
|
||||
|
||||
taskResize(taskId, currentTaskBounds, delay_ms, true);
|
||||
} while (stackBounds.top < currentTaskBounds.top
|
||||
|| stackBounds.left < currentTaskBounds.left);
|
||||
|
||||
// Back to original size
|
||||
pw.println("Shrinking top-left");
|
||||
pw.flush();
|
||||
do {
|
||||
currentTaskBounds.top += getStepSize(
|
||||
currentTaskBounds.top, initialTaskBounds.top, stepSize, !GREATER_THAN_TARGET);
|
||||
|
||||
currentTaskBounds.left += getStepSize(
|
||||
currentTaskBounds.left, initialTaskBounds.left, stepSize, !GREATER_THAN_TARGET);
|
||||
|
||||
taskResize(taskId, currentTaskBounds, delay_ms, true);
|
||||
} while (initialTaskBounds.top > currentTaskBounds.top
|
||||
|| initialTaskBounds.left > currentTaskBounds.left);
|
||||
|
||||
// Size by top-right
|
||||
pw.println("Growing top-right");
|
||||
pw.flush();
|
||||
do {
|
||||
currentTaskBounds.top -= getStepSize(
|
||||
currentTaskBounds.top, stackBounds.top, stepSize, GREATER_THAN_TARGET);
|
||||
|
||||
currentTaskBounds.right += getStepSize(
|
||||
currentTaskBounds.right, stackBounds.right, stepSize, !GREATER_THAN_TARGET);
|
||||
|
||||
taskResize(taskId, currentTaskBounds, delay_ms, true);
|
||||
} while (stackBounds.top < currentTaskBounds.top
|
||||
|| stackBounds.right > currentTaskBounds.right);
|
||||
|
||||
// Back to original size
|
||||
pw.println("Shrinking top-right");
|
||||
pw.flush();
|
||||
do {
|
||||
currentTaskBounds.top += getStepSize(
|
||||
currentTaskBounds.top, initialTaskBounds.top, stepSize, !GREATER_THAN_TARGET);
|
||||
|
||||
currentTaskBounds.right -= getStepSize(currentTaskBounds.right, initialTaskBounds.right,
|
||||
stepSize, GREATER_THAN_TARGET);
|
||||
|
||||
taskResize(taskId, currentTaskBounds, delay_ms, true);
|
||||
} while (initialTaskBounds.top > currentTaskBounds.top
|
||||
|| initialTaskBounds.right < currentTaskBounds.right);
|
||||
|
||||
// Size by bottom-left
|
||||
pw.println("Growing bottom-left");
|
||||
pw.flush();
|
||||
do {
|
||||
currentTaskBounds.bottom += getStepSize(
|
||||
currentTaskBounds.bottom, stackBounds.bottom, stepSize, !GREATER_THAN_TARGET);
|
||||
|
||||
currentTaskBounds.left -= getStepSize(
|
||||
currentTaskBounds.left, stackBounds.left, stepSize, GREATER_THAN_TARGET);
|
||||
|
||||
taskResize(taskId, currentTaskBounds, delay_ms, true);
|
||||
} while (stackBounds.bottom > currentTaskBounds.bottom
|
||||
|| stackBounds.left < currentTaskBounds.left);
|
||||
|
||||
// Back to original size
|
||||
pw.println("Shrinking bottom-left");
|
||||
pw.flush();
|
||||
do {
|
||||
currentTaskBounds.bottom -= getStepSize(currentTaskBounds.bottom,
|
||||
initialTaskBounds.bottom, stepSize, GREATER_THAN_TARGET);
|
||||
|
||||
currentTaskBounds.left += getStepSize(
|
||||
currentTaskBounds.left, initialTaskBounds.left, stepSize, !GREATER_THAN_TARGET);
|
||||
|
||||
taskResize(taskId, currentTaskBounds, delay_ms, true);
|
||||
} while (initialTaskBounds.bottom < currentTaskBounds.bottom
|
||||
|| initialTaskBounds.left > currentTaskBounds.left);
|
||||
|
||||
// Size by bottom-right
|
||||
pw.println("Growing bottom-right");
|
||||
pw.flush();
|
||||
do {
|
||||
currentTaskBounds.bottom += getStepSize(
|
||||
currentTaskBounds.bottom, stackBounds.bottom, stepSize, !GREATER_THAN_TARGET);
|
||||
|
||||
currentTaskBounds.right += getStepSize(
|
||||
currentTaskBounds.right, stackBounds.right, stepSize, !GREATER_THAN_TARGET);
|
||||
|
||||
taskResize(taskId, currentTaskBounds, delay_ms, true);
|
||||
} while (stackBounds.bottom > currentTaskBounds.bottom
|
||||
|| stackBounds.right > currentTaskBounds.right);
|
||||
|
||||
// Back to original size
|
||||
pw.println("Shrinking bottom-right");
|
||||
pw.flush();
|
||||
do {
|
||||
currentTaskBounds.bottom -= getStepSize(currentTaskBounds.bottom,
|
||||
initialTaskBounds.bottom, stepSize, GREATER_THAN_TARGET);
|
||||
|
||||
currentTaskBounds.right -= getStepSize(currentTaskBounds.right, initialTaskBounds.right,
|
||||
stepSize, GREATER_THAN_TARGET);
|
||||
|
||||
taskResize(taskId, currentTaskBounds, delay_ms, true);
|
||||
} while (initialTaskBounds.bottom < currentTaskBounds.bottom
|
||||
|| initialTaskBounds.right < currentTaskBounds.right);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int runTaskFocus(PrintWriter pw) throws RemoteException {
|
||||
final int taskId = Integer.parseInt(getNextArgRequired());
|
||||
pw.println("Setting focus to task " + taskId);
|
||||
@@ -2880,8 +2699,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
pw.println(" Place <TASK_ID> in <STACK_ID> at <POSITION>");
|
||||
pw.println(" list");
|
||||
pw.println(" List all of the activity stacks and their sizes.");
|
||||
pw.println(" info <STACK_ID>");
|
||||
pw.println(" Display the information about activity stack <STACK_ID>.");
|
||||
pw.println(" info <WINDOWING_MODE> <ACTIVITY_TYPE>");
|
||||
pw.println(" Display the information about activity stack in <WINDOWING_MODE> and <ACTIVITY_TYPE>.");
|
||||
pw.println(" remove <STACK_ID>");
|
||||
pw.println(" Remove stack <STACK_ID>.");
|
||||
pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks.");
|
||||
@@ -2899,14 +2718,6 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
pw.println(" Makes sure <TASK_ID> is in a stack with the specified bounds.");
|
||||
pw.println(" Forces the task to be resizeable and creates a stack if no existing stack");
|
||||
pw.println(" has the specified bounds.");
|
||||
pw.println(" drag-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS]");
|
||||
pw.println(" Test command for dragging/moving <TASK_ID> by");
|
||||
pw.println(" <STEP_SIZE> increments around the screen applying the optional [DELAY_MS]");
|
||||
pw.println(" between each step.");
|
||||
pw.println(" size-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS]");
|
||||
pw.println(" Test command for sizing <TASK_ID> by <STEP_SIZE>");
|
||||
pw.println(" increments within the screen applying the optional [DELAY_MS] between");
|
||||
pw.println(" each step.");
|
||||
pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]");
|
||||
pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>");
|
||||
pw.println(" without restarting any processes.");
|
||||
|
||||
@@ -2,12 +2,9 @@ package com.android.server.am;
|
||||
|
||||
import static android.app.ActivityManager.START_SUCCESS;
|
||||
import static android.app.ActivityManager.START_TASK_TO_FRONT;
|
||||
import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
@@ -32,13 +29,10 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_T
|
||||
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_WARM_LAUNCH;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
||||
import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
|
||||
|
||||
import android.app.ActivityManager.StackId;
|
||||
import android.content.Context;
|
||||
import android.metrics.LogMaker;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.server.am;
|
||||
|
||||
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
@@ -103,7 +102,6 @@ import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
|
||||
import static com.android.server.am.ActivityStack.LAUNCH_TICK;
|
||||
import static com.android.server.am.ActivityStack.LAUNCH_TICK_MSG;
|
||||
import static com.android.server.am.ActivityStack.PAUSE_TIMEOUT_MSG;
|
||||
import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
|
||||
import static com.android.server.am.ActivityStack.STOP_TIMEOUT_MSG;
|
||||
import static com.android.server.am.EventLogTags.AM_ACTIVITY_FULLY_DRAWN_TIME;
|
||||
import static com.android.server.am.EventLogTags.AM_ACTIVITY_LAUNCH_TIME;
|
||||
@@ -1069,6 +1067,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
|
||||
return getStack() != null ? getStack().mStackId : INVALID_STACK_ID;
|
||||
}
|
||||
|
||||
ActivityDisplay getDisplay() {
|
||||
final ActivityStack stack = getStack();
|
||||
return stack != null ? stack.getDisplay() : null;
|
||||
}
|
||||
|
||||
boolean changeWindowTranslucency(boolean toOpaque) {
|
||||
if (fullscreen == toOpaque) {
|
||||
return false;
|
||||
@@ -1134,10 +1137,12 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
|
||||
* @return whether this activity supports split-screen multi-window and can be put in the docked
|
||||
* stack.
|
||||
*/
|
||||
boolean supportsSplitScreen() {
|
||||
@Override
|
||||
public boolean supportsSplitScreenWindowingMode() {
|
||||
// An activity can not be docked even if it is considered resizeable because it only
|
||||
// supports picture-in-picture mode but has a non-resizeable resizeMode
|
||||
return service.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow();
|
||||
return super.supportsSplitScreenWindowingMode()
|
||||
&& service.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1198,7 +1203,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
|
||||
|
||||
boolean isKeyguardLocked = service.isKeyguardLocked();
|
||||
boolean isCurrentAppLocked = service.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
|
||||
boolean hasPinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID) != null;
|
||||
final ActivityDisplay display = getDisplay();
|
||||
boolean hasPinnedStack = display != null && display.hasPinnedStack();
|
||||
// Don't return early if !isNotLocked, since we want to throw an exception if the activity
|
||||
// is in an incorrect state
|
||||
boolean isNotLockedOrOnKeyguard = !isKeyguardLocked && !isCurrentAppLocked;
|
||||
@@ -1544,8 +1550,9 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
|
||||
if (service.mSupportsLeanbackOnly && isVisible && isActivityTypeRecents()) {
|
||||
// On devices that support leanback only (Android TV), Recents activity can only be
|
||||
// visible if the home stack is the focused stack or we are in split-screen mode.
|
||||
isVisible = mStackSupervisor.getStack(DOCKED_STACK_ID) != null
|
||||
|| mStackSupervisor.isFocusedStack(getStack());
|
||||
final ActivityDisplay display = getDisplay();
|
||||
boolean hasSplitScreenStack = display != null && display.hasSplitScreenStack();
|
||||
isVisible = hasSplitScreenStack || mStackSupervisor.isFocusedStack(getStack());
|
||||
}
|
||||
|
||||
return isVisible;
|
||||
|
||||
@@ -16,20 +16,19 @@
|
||||
|
||||
package com.android.server.am;
|
||||
|
||||
import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.getActivityTypeForStackId;
|
||||
import static android.app.ActivityManager.StackId.getWindowingModeForStackId;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
|
||||
import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
|
||||
@@ -77,7 +76,6 @@ import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
|
||||
import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
|
||||
import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
|
||||
import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
|
||||
import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
|
||||
import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
|
||||
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
|
||||
import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
|
||||
@@ -112,7 +110,6 @@ import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
@@ -243,11 +240,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
DESTROYED
|
||||
}
|
||||
|
||||
// Stack is not considered visible.
|
||||
static final int STACK_INVISIBLE = 0;
|
||||
// Stack is considered visible
|
||||
static final int STACK_VISIBLE = 1;
|
||||
|
||||
@VisibleForTesting
|
||||
/* The various modes for the method {@link #removeTask}. */
|
||||
// Task is being completely removed from all stacks in the system.
|
||||
@@ -461,7 +453,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
}
|
||||
|
||||
ActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
|
||||
boolean onTop) {
|
||||
int windowingMode, int activityType, boolean onTop) {
|
||||
mStackSupervisor = supervisor;
|
||||
mService = supervisor.mService;
|
||||
mHandler = new ActivityStackHandler(mService.mHandler.getLooper());
|
||||
@@ -471,7 +463,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
mTaskPositioner = mStackId == FREEFORM_WORKSPACE_STACK_ID
|
||||
? new LaunchingTaskPositioner() : null;
|
||||
mTmpRect2.setEmpty();
|
||||
updateOverrideConfiguration();
|
||||
setWindowingMode(windowingMode);
|
||||
setActivityType(activityType);
|
||||
mWindowContainerController = createStackWindowController(display.mDisplayId, onTop,
|
||||
mTmpRect2);
|
||||
postAddToDisplay(display, mTmpRect2.isEmpty() ? null : mTmpRect2, onTop);
|
||||
@@ -485,20 +478,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
return mWindowContainerController;
|
||||
}
|
||||
|
||||
// TODO: Not needed once we are no longer using stack ids as the override config. can be passed
|
||||
// in.
|
||||
private void updateOverrideConfiguration() {
|
||||
final int windowingMode = getWindowingModeForStackId(
|
||||
mStackId, mStackSupervisor.getStack(DOCKED_STACK_ID) != null);
|
||||
if (windowingMode != WINDOWING_MODE_UNDEFINED) {
|
||||
setWindowingMode(windowingMode);
|
||||
}
|
||||
final int activityType = getActivityTypeForStackId(mStackId);
|
||||
if (activityType != ACTIVITY_TYPE_UNDEFINED) {
|
||||
setActivityType(activityType);
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds the stack to specified display and calls WindowManager to do the same. */
|
||||
void reparent(ActivityDisplay activityDisplay, boolean onTop) {
|
||||
removeFromDisplay();
|
||||
@@ -518,8 +497,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
* @param activityDisplay New display to which this stack was attached.
|
||||
* @param bounds Updated bounds.
|
||||
*/
|
||||
private void postAddToDisplay(ActivityDisplay activityDisplay,
|
||||
Rect bounds, boolean onTop) {
|
||||
private void postAddToDisplay(ActivityDisplay activityDisplay, Rect bounds, boolean onTop) {
|
||||
mDisplayId = activityDisplay.mDisplayId;
|
||||
mBounds = bounds != null ? new Rect(bounds) : null;
|
||||
mFullscreen = mBounds == null;
|
||||
@@ -571,12 +549,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
return mStackSupervisor.getActivityDisplay(mDisplayId);
|
||||
}
|
||||
|
||||
void getDisplaySize(Point out) {
|
||||
getDisplay().mDisplay.getSize(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ActivityStack.getStackDockedModeBounds(Rect, Rect, Rect, boolean)
|
||||
* @see #getStackDockedModeBounds(Rect, Rect, Rect, boolean)
|
||||
*/
|
||||
void getStackDockedModeBounds(Rect currentTempTaskBounds, Rect outStackBounds,
|
||||
Rect outTempTaskBounds, boolean ignoreVisibility) {
|
||||
@@ -840,7 +814,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
}
|
||||
|
||||
final boolean isHomeOrRecentsStack() {
|
||||
return StackId.isHomeOrRecentsStack(mStackId);
|
||||
return isActivityTypeHome() || isActivityTypeRecents();
|
||||
}
|
||||
|
||||
final boolean isDockedStack() {
|
||||
@@ -1068,7 +1042,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
"Launch completed; removing icicle of " + r.icicle);
|
||||
}
|
||||
|
||||
|
||||
private void startLaunchTraces(String packageName) {
|
||||
if (mFullyDrawnStartTime != 0) {
|
||||
Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
|
||||
@@ -1483,7 +1456,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
// focus). Also if there is an active pinned stack - we always want to notify it about
|
||||
// task stack changes, because its positioning may depend on it.
|
||||
if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
|
||||
|| mService.mStackSupervisor.getStack(PINNED_STACK_ID) != null) {
|
||||
|| getDisplay().hasPinnedStack()) {
|
||||
mService.mTaskChangeNotificationController.notifyTaskStackChanged();
|
||||
mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
|
||||
}
|
||||
@@ -1558,9 +1531,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
return false;
|
||||
}
|
||||
|
||||
final ActivityStack stackBehind = mStackSupervisor.getStack(stackBehindId);
|
||||
final boolean stackBehindHomeOrRecent = stackBehind != null
|
||||
&& stackBehind.isHomeOrRecentsStack();
|
||||
if (!isHomeOrRecentsStack() && r.frontOfTask && task.isOverHomeStack()
|
||||
&& !StackId.isHomeOrRecentsStack(stackBehindId)
|
||||
&& !isActivityTypeAssistant()) {
|
||||
&& !stackBehindHomeOrRecent && !isActivityTypeAssistant()) {
|
||||
// Stack isn't translucent if it's top activity should have the home stack
|
||||
// behind it and the stack currently behind it isn't the home or recents stack
|
||||
// or the assistant stack.
|
||||
@@ -1591,7 +1566,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
return true;
|
||||
}
|
||||
|
||||
final ArrayList<ActivityStack> displayStacks = getDisplay().mStacks;
|
||||
final ActivityDisplay display = getDisplay();
|
||||
final ArrayList<ActivityStack> displayStacks = display.mStacks;
|
||||
final int stackIndex = displayStacks.indexOf(this);
|
||||
|
||||
if (stackIndex == displayStacks.size() - 1) {
|
||||
@@ -1603,8 +1579,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
// Check position and visibility of this stack relative to the front stack on its display.
|
||||
final ActivityStack topStack = getTopStackOnDisplay();
|
||||
final int topStackId = topStack.mStackId;
|
||||
final int windowingMode = getWindowingMode();
|
||||
final int activityType = getActivityType();
|
||||
|
||||
if (mStackId == DOCKED_STACK_ID) {
|
||||
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
|
||||
// If the assistant stack is focused and translucent, then the docked stack is always
|
||||
// visible
|
||||
if (topStack.isActivityTypeAssistant()) {
|
||||
@@ -1616,9 +1594,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
// Set home stack to invisible when it is below but not immediately below the docked stack
|
||||
// A case would be if recents stack exists but has no tasks and is below the docked stack
|
||||
// and home stack is below recents
|
||||
if (mStackId == HOME_STACK_ID) {
|
||||
int dockedStackIndex = displayStacks.indexOf
|
||||
(mStackSupervisor.getStack(DOCKED_STACK_ID));
|
||||
if (activityType == ACTIVITY_TYPE_HOME) {
|
||||
final ActivityStack splitScreenStack = display.getStack(
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
|
||||
int dockedStackIndex = displayStacks.indexOf(splitScreenStack);
|
||||
if (dockedStackIndex > stackIndex && stackIndex != dockedStackIndex - 1) {
|
||||
return false;
|
||||
}
|
||||
@@ -1630,26 +1609,35 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
displayStacks.get(stackBehindTopIndex).topRunningActivityLocked() == null) {
|
||||
stackBehindTopIndex--;
|
||||
}
|
||||
final int stackBehindTopId = (stackBehindTopIndex >= 0)
|
||||
? displayStacks.get(stackBehindTopIndex).mStackId : INVALID_STACK_ID;
|
||||
final ActivityStack stackBehindTop = (stackBehindTopIndex >= 0)
|
||||
? displayStacks.get(stackBehindTopIndex) : null;
|
||||
int stackBehindTopId = INVALID_STACK_ID;
|
||||
int stackBehindTopWindowingMode = WINDOWING_MODE_UNDEFINED;
|
||||
int stackBehindTopActivityType = ACTIVITY_TYPE_UNDEFINED;
|
||||
if (stackBehindTop != null) {
|
||||
stackBehindTopId = stackBehindTop.mStackId;
|
||||
stackBehindTopWindowingMode = stackBehindTop.getWindowingMode();
|
||||
stackBehindTopActivityType = stackBehindTop.getActivityType();
|
||||
}
|
||||
|
||||
final boolean alwaysOnTop = topStack.getWindowConfiguration().isAlwaysOnTop();
|
||||
if (topStackId == DOCKED_STACK_ID || alwaysOnTop) {
|
||||
if (topStack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY || alwaysOnTop) {
|
||||
if (stackIndex == stackBehindTopIndex) {
|
||||
// Stacks directly behind the docked or pinned stack are always visible.
|
||||
return true;
|
||||
} else if (alwaysOnTop && stackIndex == stackBehindTopIndex - 1) {
|
||||
// Otherwise, this stack can also be visible if it is directly behind a docked stack
|
||||
// or translucent assistant stack behind an always-on-top top-most stack
|
||||
if (stackBehindTopId == DOCKED_STACK_ID) {
|
||||
if (stackBehindTopWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
|
||||
return true;
|
||||
} else if (stackBehindTopId == ASSISTANT_STACK_ID) {
|
||||
} else if (stackBehindTopActivityType == ACTIVITY_TYPE_ASSISTANT) {
|
||||
return displayStacks.get(stackBehindTopIndex).isStackTranslucent(
|
||||
starting, mStackId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (StackId.isBackdropToTranslucentActivity(topStackId)
|
||||
if (topStack.isBackdropToTranslucentActivity()
|
||||
&& topStack.isStackTranslucent(starting, stackBehindTopId)) {
|
||||
// Stacks behind the fullscreen or assistant stack with a translucent activity are
|
||||
// always visible so they can act as a backdrop to the translucent activity.
|
||||
@@ -1658,8 +1646,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
return true;
|
||||
}
|
||||
if (stackBehindTopIndex >= 0) {
|
||||
if ((stackBehindTopId == DOCKED_STACK_ID
|
||||
|| stackBehindTopId == PINNED_STACK_ID)
|
||||
if ((stackBehindTopWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
|
||||
|| stackBehindTopWindowingMode == WINDOWING_MODE_PINNED)
|
||||
&& stackIndex == (stackBehindTopIndex - 1)) {
|
||||
// The stack behind the docked or pinned stack is also visible so we can have a
|
||||
// complete backdrop to the translucent activity when the docked stack is up.
|
||||
@@ -1668,7 +1656,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
}
|
||||
}
|
||||
|
||||
if (StackId.isStaticStack(mStackId)) {
|
||||
if (StackId.isStaticStack(mStackId)
|
||||
|| isHomeOrRecentsStack() || isActivityTypeAssistant()) {
|
||||
// Visibility of any static stack should have been determined by the conditions above.
|
||||
return false;
|
||||
}
|
||||
@@ -1680,7 +1669,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!StackId.isDynamicStacksVisibleBehindAllowed(stack.mStackId)) {
|
||||
if (!stack.isDynamicStacksVisibleBehindAllowed()) {
|
||||
// These stacks can't have any dynamic stacks visible behind them.
|
||||
return false;
|
||||
}
|
||||
@@ -1693,6 +1682,19 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isBackdropToTranslucentActivity() {
|
||||
if (isActivityTypeAssistant()) {
|
||||
return true;
|
||||
}
|
||||
final int windowingMode = getWindowingMode();
|
||||
return windowingMode == WINDOWING_MODE_FULLSCREEN
|
||||
|| windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
}
|
||||
|
||||
private boolean isDynamicStacksVisibleBehindAllowed() {
|
||||
return isActivityTypeAssistant() || getWindowingMode() == WINDOWING_MODE_PINNED;
|
||||
}
|
||||
|
||||
final int rankTaskLayers(int baseLayer) {
|
||||
int layer = 0;
|
||||
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
|
||||
@@ -1727,8 +1729,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
// If the top activity is not fullscreen, then we need to
|
||||
// make sure any activities under it are now visible.
|
||||
boolean aboveTop = top != null;
|
||||
final boolean stackVisible = shouldBeVisible(starting);
|
||||
boolean behindFullscreenActivity = !stackVisible;
|
||||
final boolean stackShouldBeVisible = shouldBeVisible(starting);
|
||||
boolean behindFullscreenActivity = !stackShouldBeVisible;
|
||||
boolean resumeNextActivity = mStackSupervisor.isFocusedStack(this)
|
||||
&& (isInStackLocked(starting) == null);
|
||||
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
|
||||
@@ -1754,7 +1756,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
final boolean reallyVisible = checkKeyguardVisibility(r,
|
||||
visibleIgnoringKeyguard, isTop);
|
||||
if (visibleIgnoringKeyguard) {
|
||||
behindFullscreenActivity = updateBehindFullscreen(!stackVisible,
|
||||
behindFullscreenActivity = updateBehindFullscreen(!stackShouldBeVisible,
|
||||
behindFullscreenActivity, task, r);
|
||||
}
|
||||
if (reallyVisible) {
|
||||
@@ -1792,7 +1794,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
} else {
|
||||
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
|
||||
+ " finishing=" + r.finishing + " state=" + r.state
|
||||
+ " stackVisible=" + stackVisible
|
||||
+ " stackShouldBeVisible=" + stackShouldBeVisible
|
||||
+ " behindFullscreenActivity=" + behindFullscreenActivity
|
||||
+ " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
|
||||
makeInvisible(r);
|
||||
@@ -1802,10 +1804,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
// The visibility of tasks and the activities they contain in freeform stack are
|
||||
// determined individually unlike other stacks where the visibility or fullscreen
|
||||
// status of an activity in a previous task affects other.
|
||||
behindFullscreenActivity = !stackVisible;
|
||||
} else if (mStackId == HOME_STACK_ID) {
|
||||
behindFullscreenActivity = !stackShouldBeVisible;
|
||||
} else if (isActivityTypeHome()) {
|
||||
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
|
||||
+ " stackVisible=" + stackVisible
|
||||
+ " stackShouldBeVisible=" + stackShouldBeVisible
|
||||
+ " behindFullscreenActivity=" + behindFullscreenActivity);
|
||||
// No other task in the home stack should be visible behind the home activity.
|
||||
// Home activities is usually a translucent activity with the wallpaper behind
|
||||
@@ -2898,9 +2900,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
// Ensure that we do not trigger entering PiP an activity on the pinned stack
|
||||
return false;
|
||||
}
|
||||
final int targetStackId = toFrontTask != null ? toFrontTask.getStackId()
|
||||
: toFrontActivity.getStackId();
|
||||
if (targetStackId == ASSISTANT_STACK_ID) {
|
||||
final ActivityStack targetStack = toFrontTask != null
|
||||
? toFrontTask.getStack() : toFrontActivity.getStack();
|
||||
if (targetStack != null && targetStack.isActivityTypeAssistant()) {
|
||||
// Ensure the task/activity being brought forward is not the assistant
|
||||
return false;
|
||||
}
|
||||
@@ -4891,8 +4893,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
}
|
||||
ci.numActivities = numActivities;
|
||||
ci.numRunning = numRunning;
|
||||
ci.supportsSplitScreenMultiWindow = task.supportsSplitScreen();
|
||||
ci.supportsSplitScreenMultiWindow = task.supportsSplitScreenWindowingMode();
|
||||
ci.resizeMode = task.mResizeMode;
|
||||
ci.configuration = task.getConfiguration();
|
||||
list.add(ci);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,18 +27,18 @@ import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
|
||||
import static android.app.ActivityManager.START_SUCCESS;
|
||||
import static android.app.ActivityManager.START_TASK_TO_FRONT;
|
||||
import static android.app.ActivityManager.StackId;
|
||||
import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.isDynamicStack;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
|
||||
@@ -77,7 +77,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
||||
import static com.android.server.am.ActivityManagerService.ANIMATE;
|
||||
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
|
||||
import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
|
||||
import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
|
||||
import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
|
||||
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
|
||||
@@ -590,9 +589,7 @@ class ActivityStarter {
|
||||
auxiliaryResponse.token, auxiliaryResponse.needsPhaseTwo);
|
||||
}
|
||||
|
||||
void postStartActivityProcessing(
|
||||
ActivityRecord r, int result, int prevFocusedStackId, ActivityRecord sourceRecord,
|
||||
ActivityStack targetStack) {
|
||||
void postStartActivityProcessing(ActivityRecord r, int result, ActivityStack targetStack) {
|
||||
|
||||
if (ActivityManager.isStartResultFatalError(result)) {
|
||||
return;
|
||||
@@ -614,7 +611,8 @@ class ActivityStarter {
|
||||
}
|
||||
|
||||
if (startedActivityStackId == DOCKED_STACK_ID) {
|
||||
final ActivityStack homeStack = mSupervisor.getStack(HOME_STACK_ID);
|
||||
final ActivityStack homeStack = mSupervisor.getDefaultDisplay().getStack(
|
||||
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME);
|
||||
final boolean homeStackVisible = homeStack != null && homeStack.isVisible();
|
||||
if (homeStackVisible) {
|
||||
// We launch an activity while being in home stack, which means either launcher or
|
||||
@@ -1002,8 +1000,7 @@ class ActivityStarter {
|
||||
mService.mWindowManager.continueSurfaceLayout();
|
||||
}
|
||||
|
||||
postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId, mSourceRecord,
|
||||
mTargetStack);
|
||||
postStartActivityProcessing(r, result, mTargetStack);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1612,12 +1609,11 @@ class ActivityStarter {
|
||||
mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
|
||||
mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
|
||||
mMovedToFront = true;
|
||||
} else if (launchStack.mStackId == DOCKED_STACK_ID
|
||||
|| launchStack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
|
||||
} else if (launchStack.inSplitScreenWindowingMode()) {
|
||||
if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
|
||||
// If we want to launch adjacent and mTargetStack is not the computed
|
||||
// launch stack - move task to top of computed stack.
|
||||
intentTask.reparent(launchStack.mStackId, ON_TOP,
|
||||
intentTask.reparent(launchStack, ON_TOP,
|
||||
REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
|
||||
"launchToSide");
|
||||
} else {
|
||||
@@ -1634,17 +1630,17 @@ class ActivityStarter {
|
||||
// Target and computed stacks are on different displays and we've
|
||||
// found a matching task - move the existing instance to that display and
|
||||
// move it to front.
|
||||
intentActivity.getTask().reparent(launchStack.mStackId, ON_TOP,
|
||||
intentActivity.getTask().reparent(launchStack, ON_TOP,
|
||||
REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
|
||||
"reparentToDisplay");
|
||||
mMovedToFront = true;
|
||||
} else if (launchStack.getStackId() == StackId.HOME_STACK_ID
|
||||
&& mTargetStack.getStackId() != StackId.HOME_STACK_ID) {
|
||||
} else if (launchStack.isActivityTypeHome()
|
||||
&& !mTargetStack.isActivityTypeHome()) {
|
||||
// It is possible for the home activity to be in another stack initially.
|
||||
// For example, the activity may have been initially started with an intent
|
||||
// which placed it in the fullscreen stack. To ensure the proper handling of
|
||||
// the activity based on home stack assumptions, we must move it over.
|
||||
intentActivity.getTask().reparent(launchStack.mStackId, ON_TOP,
|
||||
intentActivity.getTask().reparent(launchStack, ON_TOP,
|
||||
REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
|
||||
"reparentingHome");
|
||||
mMovedToFront = true;
|
||||
@@ -1879,8 +1875,8 @@ class ActivityStarter {
|
||||
if (mTargetStack == null) {
|
||||
mTargetStack = sourceStack;
|
||||
} else if (mTargetStack != sourceStack) {
|
||||
sourceTask.reparent(mTargetStack.mStackId, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT,
|
||||
!ANIMATE, DEFER_RESUME, "launchToSide");
|
||||
sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
|
||||
DEFER_RESUME, "launchToSide");
|
||||
}
|
||||
|
||||
final TaskRecord topTask = mTargetStack.topTask();
|
||||
@@ -1977,15 +1973,16 @@ class ActivityStarter {
|
||||
if (mLaunchBounds != null) {
|
||||
mInTask.updateOverrideConfiguration(mLaunchBounds);
|
||||
// TODO: Shouldn't we already know what stack to use by the time we get here?
|
||||
int stackId = mSupervisor.getLaunchStackId(null, null, mInTask);
|
||||
if (stackId != mInTask.getStackId()) {
|
||||
mInTask.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
|
||||
ActivityStack stack = mSupervisor.getLaunchStack(null, null, mInTask, ON_TOP);
|
||||
if (stack != mInTask.getStack()) {
|
||||
mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
|
||||
DEFER_RESUME, "inTaskToFront");
|
||||
stackId = mInTask.getStackId();
|
||||
stack = mInTask.getStack();
|
||||
mTargetStack = mInTask.getStack();
|
||||
}
|
||||
if (StackId.resizeStackWithLaunchBounds(stackId)) {
|
||||
mService.resizeStack(stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
|
||||
if (StackId.resizeStackWithLaunchBounds(stack.mStackId)) {
|
||||
mService.resizeStack(
|
||||
stack.mStackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2116,11 +2113,7 @@ class ActivityStarter {
|
||||
}
|
||||
}
|
||||
// If there is no suitable dynamic stack then we figure out which static stack to use.
|
||||
final int stackId = task != null ? mSupervisor.getLaunchStackId(r, aOptions, task)
|
||||
// TODO: This should go in mSupervisor.getLaunchStackId method...
|
||||
: bounds != null && mService.mSupportsFreeformWindowManagement
|
||||
? FREEFORM_WORKSPACE_STACK_ID : FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
stack = mSupervisor.getStack(stackId, CREATE_IF_NEEDED, ON_TOP);
|
||||
stack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
|
||||
}
|
||||
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
|
||||
+ r + " stackId=" + stack.mStackId);
|
||||
@@ -2128,36 +2121,39 @@ class ActivityStarter {
|
||||
}
|
||||
|
||||
/** Check if provided activity record can launch in currently focused stack. */
|
||||
// TODO: This method can probably be consolidated into getLaunchStack() below.
|
||||
private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
|
||||
final ActivityStack focusedStack = mSupervisor.mFocusedStack;
|
||||
final int focusedStackId = mSupervisor.mFocusedStack.mStackId;
|
||||
final boolean canUseFocusedStack;
|
||||
switch (focusedStackId) {
|
||||
case FULLSCREEN_WORKSPACE_STACK_ID:
|
||||
// The fullscreen stack can contain any task regardless of if the task is resizeable
|
||||
// or not. So, we let the task go in the fullscreen task if it is the focus stack.
|
||||
canUseFocusedStack = true;
|
||||
break;
|
||||
case ASSISTANT_STACK_ID:
|
||||
canUseFocusedStack = r.isActivityTypeAssistant();
|
||||
break;
|
||||
case DOCKED_STACK_ID:
|
||||
// Any activity which supports split screen can go in the docked stack.
|
||||
canUseFocusedStack = r.supportsSplitScreen();
|
||||
break;
|
||||
case FREEFORM_WORKSPACE_STACK_ID:
|
||||
// Any activity which supports freeform can go in the freeform stack.
|
||||
canUseFocusedStack = r.supportsFreeform();
|
||||
break;
|
||||
default:
|
||||
// Dynamic stacks behave similarly to the fullscreen stack and can contain any
|
||||
// resizeable task.
|
||||
canUseFocusedStack = isDynamicStack(focusedStackId)
|
||||
&& r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
|
||||
final int focusedStackId = mSupervisor.mFocusedStack.mStackId;
|
||||
if (focusedStack.isActivityTypeAssistant()) {
|
||||
canUseFocusedStack = r.isActivityTypeAssistant();
|
||||
} else {
|
||||
switch (focusedStack.getWindowingMode()) {
|
||||
case WINDOWING_MODE_FULLSCREEN:
|
||||
// The fullscreen stack can contain any task regardless of if the task is
|
||||
// resizeable or not. So, we let the task go in the fullscreen task if it is the
|
||||
// focus stack.
|
||||
canUseFocusedStack = true;
|
||||
break;
|
||||
case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
|
||||
case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
|
||||
// Any activity which supports split screen can go in the docked stack.
|
||||
canUseFocusedStack = r.supportsSplitScreenWindowingMode();
|
||||
break;
|
||||
case WINDOWING_MODE_FREEFORM:
|
||||
// Any activity which supports freeform can go in the freeform stack.
|
||||
canUseFocusedStack = r.supportsFreeform();
|
||||
break;
|
||||
default:
|
||||
// Dynamic stacks behave similarly to the fullscreen stack and can contain any
|
||||
// resizeable task.
|
||||
canUseFocusedStack = isDynamicStack(focusedStackId)
|
||||
&& r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
|
||||
}
|
||||
}
|
||||
|
||||
return canUseFocusedStack && !newTask
|
||||
// Using the focus stack isn't important enough to override the prefered display.
|
||||
// Using the focus stack isn't important enough to override the preferred display.
|
||||
&& (mPreferredDisplayId == focusedStack.mDisplayId);
|
||||
}
|
||||
|
||||
@@ -2168,50 +2164,12 @@ class ActivityStarter {
|
||||
return mReuseTask.getStack();
|
||||
}
|
||||
|
||||
// If the activity is of a specific type, return the associated stack, creating it if
|
||||
// necessary
|
||||
if (r.isActivityTypeHome()) {
|
||||
return mSupervisor.mHomeStack;
|
||||
}
|
||||
if (r.isActivityTypeRecents()) {
|
||||
return mSupervisor.getStack(RECENTS_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
|
||||
}
|
||||
if (r.isActivityTypeAssistant()) {
|
||||
return mSupervisor.getStack(ASSISTANT_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
|
||||
}
|
||||
final int vrDisplayId = mUsingVr2dDisplay ? mPreferredDisplayId : INVALID_DISPLAY;
|
||||
final ActivityStack launchStack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP,
|
||||
vrDisplayId);
|
||||
|
||||
int launchDisplayId = INVALID_DISPLAY;
|
||||
int launchStackId = INVALID_STACK_ID;
|
||||
if (aOptions != null) {
|
||||
launchDisplayId = aOptions.getLaunchDisplayId();
|
||||
final int vrDisplayId = mUsingVr2dDisplay ? mPreferredDisplayId : INVALID_DISPLAY;
|
||||
launchStackId = mSupervisor.getLaunchStackId(r, aOptions, task, vrDisplayId);
|
||||
}
|
||||
|
||||
// TODO: Will no longer be needed once we are on longer using static stack ids.
|
||||
if (mSupervisor.isValidLaunchStackId(launchStackId, launchDisplayId, r)) {
|
||||
return mSupervisor.getStack(launchStackId, CREATE_IF_NEEDED, ON_TOP);
|
||||
}
|
||||
if (launchStackId == DOCKED_STACK_ID) {
|
||||
// The preferred launch stack is the docked stack, but it isn't a valid launch stack
|
||||
// for this activity, so we put the activity in the fullscreen stack.
|
||||
return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
|
||||
}
|
||||
// TODO: Can probably be removed since ASS.getLaunchStackId() does display resolution.
|
||||
if (launchDisplayId != INVALID_DISPLAY) {
|
||||
// Stack id has higher priority than display id.
|
||||
return mSupervisor.getValidLaunchStackOnDisplay(launchDisplayId, r);
|
||||
}
|
||||
|
||||
// If we are using Vr2d display, find the virtual display stack.
|
||||
// TODO: Can be removed.
|
||||
if (mUsingVr2dDisplay) {
|
||||
ActivityStack as = mSupervisor.getValidLaunchStackOnDisplay(mPreferredDisplayId, r);
|
||||
if (DEBUG_STACK) {
|
||||
Slog.v(TAG, "Launch stack for app: " + r.toString() +
|
||||
", on virtual display stack:" + as.toString());
|
||||
}
|
||||
return as;
|
||||
if (launchStack != null) {
|
||||
return launchStack;
|
||||
}
|
||||
|
||||
if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
|
||||
@@ -2237,13 +2195,15 @@ class ActivityStarter {
|
||||
if (parentStack != null && parentStack.isDockedStack()) {
|
||||
// If parent was in docked stack, the natural place to launch another activity
|
||||
// will be fullscreen, so it can appear alongside the docked window.
|
||||
return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED,
|
||||
ON_TOP);
|
||||
final int activityType = mSupervisor.resolveActivityType(r, mOptions, task);
|
||||
return parentStack.getDisplay().getOrCreateStack(
|
||||
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
|
||||
} else {
|
||||
// If the parent is not in the docked stack, we check if there is docked window
|
||||
// and if yes, we will launch into that stack. If not, we just put the new
|
||||
// activity into parent's stack, because we can't find a better place.
|
||||
final ActivityStack dockedStack = mSupervisor.getStack(DOCKED_STACK_ID);
|
||||
final ActivityStack dockedStack = mSupervisor.getDefaultDisplay().getStack(
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
|
||||
if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
|
||||
// There is a docked stack, but it isn't visible, so we can't launch into that.
|
||||
return null;
|
||||
@@ -2267,15 +2227,6 @@ class ActivityStarter {
|
||||
mWindowManager = wm;
|
||||
}
|
||||
|
||||
void removePendingActivityLaunchesLocked(ActivityStack stack) {
|
||||
for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
|
||||
PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
|
||||
if (pal.stack == stack) {
|
||||
mPendingActivityLaunches.remove(palNdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isDocumentLaunchesIntoExisting(int flags) {
|
||||
return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
|
||||
(flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
|
||||
|
||||
@@ -342,7 +342,7 @@ class KeyguardController {
|
||||
// show on top of the lock screen. In this can we want to dismiss the docked
|
||||
// stack since it will be complicated/risky to try to put the activity on top
|
||||
// of the lock screen in the right fullscreen configuration.
|
||||
final ActivityStack stack = mStackSupervisor.getStack(DOCKED_STACK_ID);
|
||||
final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getSplitScreenStack();
|
||||
if (stack == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.server.am;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
|
||||
import android.app.RemoteAction;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
@@ -34,7 +37,7 @@ class PinnedActivityStack extends ActivityStack<PinnedStackWindowController>
|
||||
|
||||
PinnedActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
|
||||
boolean onTop) {
|
||||
super(display, stackId, supervisor, onTop);
|
||||
super(display, stackId, supervisor, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, onTop);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -54,9 +54,6 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
|
||||
import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
|
||||
|
||||
public class TaskPersister {
|
||||
|
||||
@@ -18,20 +18,19 @@ package com.android.server.am;
|
||||
|
||||
import static android.app.ActivityManager.RESIZE_MODE_FORCED;
|
||||
import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
|
||||
import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.getWindowingModeForStackId;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
|
||||
import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
|
||||
@@ -573,36 +572,36 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
/**
|
||||
* Convenience method to reparent a task to the top or bottom position of the stack.
|
||||
*/
|
||||
boolean reparent(int preferredStackId, boolean toTop, @ReparentMoveStackMode int moveStackMode,
|
||||
boolean animate, boolean deferResume, String reason) {
|
||||
return reparent(preferredStackId, toTop ? MAX_VALUE : 0, moveStackMode, animate,
|
||||
deferResume, true /* schedulePictureInPictureModeChange */, reason);
|
||||
boolean reparent(ActivityStack preferredStack, boolean toTop,
|
||||
@ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
|
||||
String reason) {
|
||||
return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume,
|
||||
true /* schedulePictureInPictureModeChange */, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to reparent a task to the top or bottom position of the stack, with
|
||||
* an option to skip scheduling the picture-in-picture mode change.
|
||||
*/
|
||||
boolean reparent(int preferredStackId, boolean toTop, @ReparentMoveStackMode int moveStackMode,
|
||||
boolean animate, boolean deferResume, boolean schedulePictureInPictureModeChange,
|
||||
String reason) {
|
||||
return reparent(preferredStackId, toTop ? MAX_VALUE : 0, moveStackMode, animate,
|
||||
boolean reparent(ActivityStack preferredStack, boolean toTop,
|
||||
@ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
|
||||
boolean schedulePictureInPictureModeChange, String reason) {
|
||||
return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate,
|
||||
deferResume, schedulePictureInPictureModeChange, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to reparent a task to a specific position of the stack.
|
||||
*/
|
||||
boolean reparent(int preferredStackId, int position, @ReparentMoveStackMode int moveStackMode,
|
||||
boolean animate, boolean deferResume, String reason) {
|
||||
return reparent(preferredStackId, position, moveStackMode, animate, deferResume,
|
||||
/** Convenience method to reparent a task to a specific position of the stack. */
|
||||
boolean reparent(ActivityStack preferredStack, int position,
|
||||
@ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
|
||||
String reason) {
|
||||
return reparent(preferredStack, position, moveStackMode, animate, deferResume,
|
||||
true /* schedulePictureInPictureModeChange */, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reparents the task into a preferred stack, creating it if necessary.
|
||||
*
|
||||
* @param preferredStackId the stack id of the target stack to move this task
|
||||
* @param preferredStack the target stack to move this task
|
||||
* @param position the position to place this task in the new stack
|
||||
* @param animate whether or not we should wait for the new window created as a part of the
|
||||
* reparenting to be drawn and animated in
|
||||
@@ -616,13 +615,16 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
* @param reason the caller of this reparenting
|
||||
* @return whether the task was reparented
|
||||
*/
|
||||
boolean reparent(int preferredStackId, int position, @ReparentMoveStackMode int moveStackMode,
|
||||
boolean animate, boolean deferResume, boolean schedulePictureInPictureModeChange,
|
||||
String reason) {
|
||||
// TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
|
||||
// re-parenting the task. Can only be done when we are no longer using static stack Ids like
|
||||
/** {@link ActivityManager.StackId#FULLSCREEN_WORKSPACE_STACK_ID} */
|
||||
boolean reparent(ActivityStack preferredStack, int position,
|
||||
@ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
|
||||
boolean schedulePictureInPictureModeChange, String reason) {
|
||||
final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
|
||||
final WindowManagerService windowManager = mService.mWindowManager;
|
||||
final ActivityStack sourceStack = getStack();
|
||||
final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStackId,
|
||||
final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
|
||||
position == MAX_VALUE);
|
||||
if (toStack == sourceStack) {
|
||||
return false;
|
||||
@@ -705,19 +707,22 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
toStack.prepareFreezingTaskBounds();
|
||||
|
||||
// Make sure the task has the appropriate bounds/size for the stack it is in.
|
||||
final int toStackWindowingMode = toStack.getWindowingMode();
|
||||
final boolean toStackSplitScreenPrimary =
|
||||
toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
if (stackId == FULLSCREEN_WORKSPACE_STACK_ID
|
||||
&& !Objects.equals(mBounds, toStack.mBounds)) {
|
||||
kept = resize(toStack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow,
|
||||
deferResume);
|
||||
} else if (stackId == FREEFORM_WORKSPACE_STACK_ID) {
|
||||
} else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
|
||||
Rect bounds = getLaunchBounds();
|
||||
if (bounds == null) {
|
||||
toStack.layoutTaskInStack(this, null);
|
||||
bounds = mBounds;
|
||||
}
|
||||
kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
|
||||
} else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) {
|
||||
if (stackId == DOCKED_STACK_ID && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
|
||||
} else if (toStackSplitScreenPrimary || toStackWindowingMode == WINDOWING_MODE_PINNED) {
|
||||
if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
|
||||
// Move recents to front so it is not behind home stack when going into docked
|
||||
// mode
|
||||
mService.mStackSupervisor.moveRecentsStackToFront(reason);
|
||||
@@ -744,11 +749,12 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
}
|
||||
|
||||
// TODO: Handle incorrect request to move before the actual move, not after.
|
||||
supervisor.handleNonResizableTaskIfNeeded(this, getWindowingModeForStackId(preferredStackId,
|
||||
supervisor.getStack(DOCKED_STACK_ID) != null), DEFAULT_DISPLAY, stackId);
|
||||
final boolean inSplitScreenMode = supervisor.getDefaultDisplay().hasSplitScreenStack();
|
||||
supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(),
|
||||
DEFAULT_DISPLAY, stackId);
|
||||
|
||||
boolean successful = (preferredStackId == stackId);
|
||||
if (successful && stackId == DOCKED_STACK_ID) {
|
||||
boolean successful = (preferredStack == toStack);
|
||||
if (successful && toStack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
|
||||
// If task moved to docked stack - show recents if needed.
|
||||
mService.mWindowManager.showRecentApps(false /* fromHome */);
|
||||
}
|
||||
@@ -941,8 +947,8 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
|
||||
}
|
||||
|
||||
ActivityStack getStack() {
|
||||
return mStack;
|
||||
<T extends ActivityStack> T getStack() {
|
||||
return (T) mStack;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1457,10 +1463,12 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
return isResizeable(true /* checkSupportsPip */);
|
||||
}
|
||||
|
||||
boolean supportsSplitScreen() {
|
||||
@Override
|
||||
public boolean supportsSplitScreenWindowingMode() {
|
||||
// A task can not be docked even if it is considered resizeable because it only supports
|
||||
// picture-in-picture mode but has a non-resizeable resizeMode
|
||||
return mService.mSupportsSplitScreenMultiWindow
|
||||
return super.supportsSplitScreenWindowingMode()
|
||||
&& mService.mSupportsSplitScreenMultiWindow
|
||||
&& (mService.mForceResizableActivities
|
||||
|| (isResizeable(false /* checkSupportsPip */)
|
||||
&& !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
|
||||
@@ -2101,12 +2109,10 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
return null;
|
||||
}
|
||||
|
||||
final int stackId = mStack.mStackId;
|
||||
if (stackId == HOME_STACK_ID
|
||||
|| stackId == RECENTS_STACK_ID
|
||||
|| stackId == ASSISTANT_STACK_ID
|
||||
|| stackId == FULLSCREEN_WORKSPACE_STACK_ID
|
||||
|| (stackId == DOCKED_STACK_ID && !isResizeable())) {
|
||||
final int windowingMode = getWindowingMode();
|
||||
if (!isActivityTypeStandardOrUndefined()
|
||||
|| windowingMode == WINDOWING_MODE_FULLSCREEN
|
||||
|| (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && !isResizeable())) {
|
||||
return isResizeable() ? mStack.mBounds : null;
|
||||
} else if (!getWindowConfiguration().persistTaskBounds()) {
|
||||
return mStack.mBounds;
|
||||
|
||||
@@ -20,9 +20,12 @@ import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
|
||||
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
|
||||
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
|
||||
import static android.app.AppOpsManager.OP_TOAST_WINDOW;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.Context.CONTEXT_RESTRICTED;
|
||||
import static android.content.Context.DISPLAY_SERVICE;
|
||||
import static android.content.Context.WINDOW_SERVICE;
|
||||
@@ -7917,8 +7920,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState);
|
||||
final int dockedVisibility = updateLightStatusBarLw(0 /* vis */,
|
||||
mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState);
|
||||
mWindowManagerFuncs.getStackBounds(HOME_STACK_ID, mNonDockedStackBounds);
|
||||
mWindowManagerFuncs.getStackBounds(DOCKED_STACK_ID, mDockedStackBounds);
|
||||
mWindowManagerFuncs.getStackBounds(
|
||||
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, mNonDockedStackBounds);
|
||||
mWindowManagerFuncs.getStackBounds(
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, mDockedStackBounds);
|
||||
final int visibility = updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility);
|
||||
final int diff = visibility ^ mLastSystemUiFlags;
|
||||
final int fullscreenDiff = fullscreenVisibility ^ mLastFullscreenStackSysUiFlags;
|
||||
|
||||
@@ -21,8 +21,10 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.activityTypeToString;
|
||||
import static com.android.server.wm.proto.ConfigurationContainerProto.FULL_CONFIGURATION;
|
||||
import static com.android.server.wm.proto.ConfigurationContainerProto.MERGED_OVERRIDE_CONFIGURATION;
|
||||
@@ -152,6 +154,17 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
|
||||
onOverrideConfigurationChanged(mTmpConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this container is currently in multi-window mode. I.e. sharing the screen
|
||||
* with another activity.
|
||||
*/
|
||||
public boolean inMultiWindowMode() {
|
||||
/*@WindowConfiguration.WindowingMode*/ int windowingMode =
|
||||
mFullConfiguration.windowConfiguration.getWindowingMode();
|
||||
return windowingMode != WINDOWING_MODE_FULLSCREEN
|
||||
&& windowingMode != WINDOWING_MODE_UNDEFINED;
|
||||
}
|
||||
|
||||
/** Returns true if this container is currently in split-screen windowing mode. */
|
||||
public boolean inSplitScreenWindowingMode() {
|
||||
/*@WindowConfiguration.WindowingMode*/ int windowingMode =
|
||||
@@ -175,7 +188,7 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
|
||||
* {@link WindowConfiguration##WINDOWING_MODE_SPLIT_SCREEN_SECONDARY} windowing modes based on
|
||||
* its current state.
|
||||
*/
|
||||
public boolean supportSplitScreenWindowingMode() {
|
||||
public boolean supportsSplitScreenWindowingMode() {
|
||||
return mFullConfiguration.windowConfiguration.supportSplitScreenWindowingMode();
|
||||
}
|
||||
|
||||
@@ -238,6 +251,16 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
|
||||
|
||||
/**
|
||||
* Returns true if this container is compatible with the input windowing mode and activity type.
|
||||
* The container is compatible:
|
||||
* - If {@param activityType} and {@param windowingMode} match this container activity type and
|
||||
* windowing mode.
|
||||
* - If {@param activityType} is {@link WindowConfiguration#ACTIVITY_TYPE_UNDEFINED} or
|
||||
* {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD} and this containers activity type is also
|
||||
* standard or undefined and its windowing mode matches {@param windowingMode}.
|
||||
* - If {@param activityType} isn't {@link WindowConfiguration#ACTIVITY_TYPE_UNDEFINED} or
|
||||
* {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD} or this containers activity type isn't
|
||||
* also standard or undefined and its activity type matches {@param activityType} regardless of
|
||||
* if {@param windowingMode} matches the containers windowing mode.
|
||||
*/
|
||||
public boolean isCompatible(int windowingMode, int activityType) {
|
||||
final int thisActivityType = getActivityType();
|
||||
@@ -249,7 +272,8 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (activityType != ACTIVITY_TYPE_UNDEFINED && activityType != ACTIVITY_TYPE_STANDARD) {
|
||||
if ((activityType != ACTIVITY_TYPE_UNDEFINED && activityType != ACTIVITY_TYPE_STANDARD)
|
||||
|| !isActivityTypeStandardOrUndefined()) {
|
||||
// Only activity type need to match for non-standard activity types that are defined.
|
||||
return sameActivityType;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
@@ -1470,7 +1469,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
* Returns the topmost stack on the display that is compatible with the input windowing mode and
|
||||
* activity type. Null is no compatible stack on the display.
|
||||
*/
|
||||
private TaskStack getStack(int windowingMode, int activityType) {
|
||||
TaskStack getStack(int windowingMode, int activityType) {
|
||||
for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
|
||||
final TaskStack stack = mTaskStackContainers.get(i);
|
||||
if (stack.isCompatible(windowingMode, activityType)) {
|
||||
@@ -1486,10 +1485,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
int getStackPosById(int stackId) {
|
||||
int getStackPosition(int windowingMode, int activityType) {
|
||||
for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
|
||||
final TaskStack stack = mTaskStackContainers.get(i);
|
||||
if (stack.mStackId == stackId) {
|
||||
if (stack.isCompatible(windowingMode, activityType)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -2049,8 +2048,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
|
||||
final TaskStack stack = mTaskStackContainers.get(i);
|
||||
final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
|
||||
if (stack.isVisible() && (imeOnBottom || isDockedOnBottom) &&
|
||||
StackId.isStackAffectedByDragResizing(stack.mStackId)) {
|
||||
if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)
|
||||
&& stack.inSplitScreenWindowingMode()) {
|
||||
stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
|
||||
} else {
|
||||
stack.resetAdjustedForIme(false);
|
||||
@@ -3379,7 +3378,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
* @see WindowManagerService#addStackToDisplay(int, int, boolean)
|
||||
*/
|
||||
void addStackToDisplay(TaskStack stack, boolean onTop) {
|
||||
if (stack.mStackId == HOME_STACK_ID) {
|
||||
if (stack.isActivityTypeHome()) {
|
||||
if (mHomeStack != null) {
|
||||
throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first.");
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||
import static android.view.Surface.ROTATION_270;
|
||||
@@ -331,7 +332,7 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
mLastVisibility = visible;
|
||||
notifyDockedDividerVisibilityChanged(visible);
|
||||
if (!visible) {
|
||||
setResizeDimLayer(false, INVALID_STACK_ID, 0f);
|
||||
setResizeDimLayer(false, WINDOWING_MODE_UNDEFINED, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,9 +520,18 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
|
||||
}
|
||||
|
||||
void setResizeDimLayer(boolean visible, int targetStackId, float alpha) {
|
||||
/**
|
||||
* Shows a dim layer with {@param alpha} if {@param visible} is true and
|
||||
* {@param targetWindowingMode} isn't
|
||||
* {@link android.app.WindowConfiguration#WINDOWING_MODE_UNDEFINED} and there is a stack on the
|
||||
* display in that windowing mode.
|
||||
*/
|
||||
void setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha) {
|
||||
mService.openSurfaceTransaction();
|
||||
final TaskStack stack = mDisplayContent.getStackById(targetStackId);
|
||||
// TODO: Maybe only allow split-screen windowing modes?
|
||||
final TaskStack stack = targetWindowingMode != WINDOWING_MODE_UNDEFINED
|
||||
? mDisplayContent.getStack(targetWindowingMode)
|
||||
: null;
|
||||
final TaskStack dockedStack = mDisplayContent.getDockedStackLocked();
|
||||
boolean visibleAndValid = visible && stack != null && dockedStack != null;
|
||||
if (visibleAndValid) {
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
|
||||
/**
|
||||
* Describes the mode in which a window is drag resizing.
|
||||
@@ -39,15 +35,12 @@ class DragResizeMode {
|
||||
*/
|
||||
static final int DRAG_RESIZE_MODE_DOCKED_DIVIDER = 1;
|
||||
|
||||
static boolean isModeAllowedForStack(int stackId, int mode) {
|
||||
static boolean isModeAllowedForStack(TaskStack stack, int mode) {
|
||||
switch (mode) {
|
||||
case DRAG_RESIZE_MODE_FREEFORM:
|
||||
return stackId == FREEFORM_WORKSPACE_STACK_ID;
|
||||
return stack.getWindowingMode() == WINDOWING_MODE_FREEFORM;
|
||||
case DRAG_RESIZE_MODE_DOCKED_DIVIDER:
|
||||
return stackId == DOCKED_STACK_ID
|
||||
|| stackId == FULLSCREEN_WORKSPACE_STACK_ID
|
||||
|| stackId == HOME_STACK_ID
|
||||
|| stackId == RECENTS_STACK_ID;
|
||||
return stack.inSplitScreenWindowingMode();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
|
||||
|
||||
@@ -494,7 +494,7 @@ class PinnedStackController {
|
||||
pw.println(prefix + "PinnedStackController");
|
||||
pw.print(prefix + " defaultBounds="); getDefaultBounds().printShortString(pw);
|
||||
pw.println();
|
||||
mService.getStackBounds(PINNED_STACK_ID, mTmpRect);
|
||||
mService.getStackBounds(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mTmpRect);
|
||||
pw.print(prefix + " movementBounds="); getMovementBounds(mTmpRect).printShortString(pw);
|
||||
pw.println();
|
||||
pw.println(prefix + " mIsImeShowing=" + mIsImeShowing);
|
||||
@@ -515,7 +515,7 @@ class PinnedStackController {
|
||||
void writeToProto(ProtoOutputStream proto, long fieldId) {
|
||||
final long token = proto.start(fieldId);
|
||||
getDefaultBounds().writeToProto(proto, DEFAULT_BOUNDS);
|
||||
mService.getStackBounds(PINNED_STACK_ID, mTmpRect);
|
||||
mService.getStackBounds(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mTmpRect);
|
||||
getMovementBounds(mTmpRect).writeToProto(proto, MOVEMENT_BOUNDS);
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
@@ -16,19 +16,16 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
|
||||
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
|
||||
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
|
||||
import static com.android.server.wm.BoundsAnimationController.SchedulePipModeChangedState;
|
||||
|
||||
import android.app.RemoteAction;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
|
||||
import com.android.server.UiThread;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -101,7 +98,8 @@ public class PinnedStackWindowController extends StackWindowController {
|
||||
}
|
||||
schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_START;
|
||||
|
||||
mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpToBounds);
|
||||
mService.getStackBounds(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mTmpToBounds);
|
||||
if (!mTmpToBounds.isEmpty()) {
|
||||
// If there is a fullscreen bounds, use that
|
||||
toBounds = new Rect(mTmpToBounds);
|
||||
|
||||
@@ -422,6 +422,17 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
|
||||
return null;
|
||||
}
|
||||
|
||||
TaskStack getStack(int windowingMode, int activityType) {
|
||||
for (int i = mChildren.size() - 1; i >= 0; i--) {
|
||||
final DisplayContent dc = mChildren.get(i);
|
||||
final TaskStack stack = dc.getStack(windowingMode, activityType);
|
||||
if (stack != null) {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void setSecureSurfaceState(int userId, boolean disabled) {
|
||||
forAllWindows((w) -> {
|
||||
if (w.mHasSurface && userId == UserHandle.getUserId(w.mOwnerUid)) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSC
|
||||
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
|
||||
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
|
||||
import static android.content.res.Configuration.EMPTY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
|
||||
|
||||
import static com.android.server.EventLogTags.WM_TASK_REMOVED;
|
||||
@@ -37,7 +38,6 @@ import static com.android.server.wm.proto.TaskProto.TEMP_INSET_BOUNDS;
|
||||
import static com.android.server.wm.proto.TaskProto.WINDOW_CONTAINER;
|
||||
|
||||
import android.annotation.CallSuper;
|
||||
import android.app.ActivityManager.StackId;
|
||||
import android.app.ActivityManager.TaskDescription;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
@@ -280,15 +280,9 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
|
||||
// WindowConfiguration long term.
|
||||
private int setBounds(Rect bounds, Configuration overrideConfig) {
|
||||
if (overrideConfig == null) {
|
||||
overrideConfig = Configuration.EMPTY;
|
||||
}
|
||||
if (bounds == null && !Configuration.EMPTY.equals(overrideConfig)) {
|
||||
throw new IllegalArgumentException("null bounds but non empty configuration: "
|
||||
+ overrideConfig);
|
||||
}
|
||||
if (bounds != null && Configuration.EMPTY.equals(overrideConfig)) {
|
||||
throw new IllegalArgumentException("non null bounds, but empty configuration");
|
||||
overrideConfig = EMPTY;
|
||||
}
|
||||
|
||||
boolean oldFullscreen = mFillsParent;
|
||||
int rotation = Surface.ROTATION_0;
|
||||
final DisplayContent displayContent = mStack.getDisplayContent();
|
||||
@@ -323,7 +317,7 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
|
||||
if (displayContent != null) {
|
||||
displayContent.mDimLayerController.updateDimLayer(this);
|
||||
}
|
||||
onOverrideConfigurationChanged(mFillsParent ? Configuration.EMPTY : overrideConfig);
|
||||
onOverrideConfigurationChanged(overrideConfig);
|
||||
return boundsChange;
|
||||
}
|
||||
|
||||
@@ -406,7 +400,7 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
|
||||
* the adjusted bounds's top.
|
||||
*/
|
||||
void alignToAdjustedBounds(Rect adjustedBounds, Rect tempInsetBounds, boolean alignBottom) {
|
||||
if (!isResizeable() || Configuration.EMPTY.equals(getOverrideConfiguration())) {
|
||||
if (!isResizeable() || EMPTY.equals(getOverrideConfiguration())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -531,7 +525,7 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
|
||||
|
||||
void setDragResizing(boolean dragResizing, int dragResizeMode) {
|
||||
if (mDragResizing != dragResizing) {
|
||||
if (!DragResizeMode.isModeAllowedForStack(mStack.mStackId, dragResizeMode)) {
|
||||
if (!DragResizeMode.isModeAllowedForStack(mStack, dragResizeMode)) {
|
||||
throw new IllegalArgumentException("Drag resize mode not allow for stack stackId="
|
||||
+ mStack.mStackId + " dragResizeMode=" + dragResizeMode);
|
||||
}
|
||||
@@ -554,7 +548,9 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
|
||||
return;
|
||||
}
|
||||
if (mFillsParent) {
|
||||
setBounds(null, Configuration.EMPTY);
|
||||
// TODO: Yeah...not sure if this works with WindowConfiguration, but shouldn't be a
|
||||
// problem once we move mBounds into WindowConfiguration.
|
||||
setBounds(null, getOverrideConfiguration());
|
||||
return;
|
||||
}
|
||||
final int newRotation = displayContent.getDisplayInfo().rotation;
|
||||
|
||||
@@ -254,7 +254,7 @@ class TaskSnapshotController {
|
||||
@VisibleForTesting
|
||||
int getSnapshotMode(Task task) {
|
||||
final AppWindowToken topChild = task.getTopChild();
|
||||
if (StackId.isHomeOrRecentsStack(task.mStack.mStackId)) {
|
||||
if (!task.isActivityTypeStandardOrUndefined()) {
|
||||
return SNAPSHOT_MODE_NONE;
|
||||
} else if (topChild != null && topChild.shouldUseAppThemeSnapshot()) {
|
||||
return SNAPSHOT_MODE_APP_THEME;
|
||||
|
||||
@@ -19,8 +19,11 @@ package com.android.server.wm;
|
||||
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
|
||||
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
|
||||
import static android.content.res.Configuration.DENSITY_DPI_UNDEFINED;
|
||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||
@@ -44,7 +47,6 @@ import static com.android.server.wm.proto.StackProto.TASKS;
|
||||
import static com.android.server.wm.proto.StackProto.WINDOW_CONTAINER;
|
||||
|
||||
import android.annotation.CallSuper;
|
||||
import android.app.ActivityManager.StackId;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
@@ -736,7 +738,7 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
outTempTaskBounds.setEmpty();
|
||||
|
||||
// When the home stack is resizable, should always have the same stack and task bounds
|
||||
if (mStackId == HOME_STACK_ID) {
|
||||
if (isActivityTypeHome()) {
|
||||
final Task homeTask = findHomeTask();
|
||||
if (homeTask != null && homeTask.isResizeable()) {
|
||||
// Calculate the home stack bounds when in docked mode and the home stack is
|
||||
@@ -1008,7 +1010,7 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
mAdjustImeAmount = 0f;
|
||||
mAdjustDividerAmount = 0f;
|
||||
updateAdjustedBounds();
|
||||
mService.setResizeDimLayer(false, mStackId, 1.0f);
|
||||
mService.setResizeDimLayer(false, getWindowingMode(), 1.0f);
|
||||
} else {
|
||||
mImeGoingAway |= mAdjustedForIme;
|
||||
}
|
||||
@@ -1204,7 +1206,7 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
if (mAdjustedForIme && adjust && !isImeTarget) {
|
||||
final float alpha = Math.max(mAdjustImeAmount, mAdjustDividerAmount)
|
||||
* IME_ADJUST_DIM_AMOUNT;
|
||||
mService.setResizeDimLayer(true, mStackId, alpha);
|
||||
mService.setResizeDimLayer(true, getWindowingMode(), alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1283,7 +1285,7 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
|
||||
@Override
|
||||
public boolean dimFullscreen() {
|
||||
return StackId.isHomeOrRecentsStack(mStackId) || fillsParent();
|
||||
return !isActivityTypeStandard() || fillsParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1663,7 +1665,15 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
|
||||
|
||||
@Override
|
||||
int getOrientation() {
|
||||
return (StackId.canSpecifyOrientation(mStackId))
|
||||
? super.getOrientation() : SCREEN_ORIENTATION_UNSET;
|
||||
return (canSpecifyOrientation()) ? super.getOrientation() : SCREEN_ORIENTATION_UNSET;
|
||||
}
|
||||
|
||||
private boolean canSpecifyOrientation() {
|
||||
final int windowingMode = getWindowingMode();
|
||||
final int activityType = getActivityType();
|
||||
return windowingMode == WINDOWING_MODE_FULLSCREEN
|
||||
|| activityType == ACTIVITY_TYPE_HOME
|
||||
|| activityType == ACTIVITY_TYPE_RECENTS
|
||||
|| activityType == ACTIVITY_TYPE_ASSISTANT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,8 @@ import android.util.Slog;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static android.app.ActivityManager.StackId;
|
||||
import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
|
||||
@@ -187,12 +184,13 @@ class WindowLayersController {
|
||||
}
|
||||
}
|
||||
|
||||
final int stackId = w.getAppToken() != null ? w.getStackId() : INVALID_STACK_ID;
|
||||
if (stackId == PINNED_STACK_ID) {
|
||||
final int windowingMode = w.getWindowingMode();
|
||||
if (windowingMode == WINDOWING_MODE_PINNED) {
|
||||
mPinnedWindows.add(w);
|
||||
} else if (stackId == DOCKED_STACK_ID) {
|
||||
} else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
|
||||
mDockedWindows.add(w);
|
||||
} else if (stackId == ASSISTANT_STACK_ID) {
|
||||
}
|
||||
if (w.isActivityTypeAssistant()) {
|
||||
mAssistantWindows.add(w);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2905,9 +2905,9 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getStackBounds(int stackId, Rect bounds) {
|
||||
public void getStackBounds(int windowingMode, int activityType, Rect bounds) {
|
||||
synchronized (mWindowMap) {
|
||||
final TaskStack stack = mRoot.getStackById(stackId);
|
||||
final TaskStack stack = mRoot.getStack(windowingMode, activityType);
|
||||
if (stack != null) {
|
||||
stack.getBounds(bounds);
|
||||
return;
|
||||
@@ -7151,10 +7151,10 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResizeDimLayer(boolean visible, int targetStackId, float alpha) {
|
||||
public void setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha) {
|
||||
synchronized (mWindowMap) {
|
||||
getDefaultDisplayContentLocked().getDockedDividerController().setResizeDimLayer(
|
||||
visible, targetStackId, alpha);
|
||||
visible, targetWindowingMode, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3088,7 +3088,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
if (task == null) {
|
||||
return false;
|
||||
}
|
||||
if (!StackId.isStackAffectedByDragResizing(getStackId())) {
|
||||
if (!inSplitScreenWindowingMode()) {
|
||||
return false;
|
||||
}
|
||||
if (mAttrs.width != MATCH_PARENT || mAttrs.height != MATCH_PARENT) {
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
|
||||
package com.android.server.am;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
|
||||
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM;
|
||||
import static android.view.WindowManagerPolicy.NAV_BAR_LEFT;
|
||||
import static android.view.WindowManagerPolicy.NAV_BAR_RIGHT;
|
||||
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
@@ -26,14 +32,13 @@ import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.graphics.Rect;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.support.test.filters.MediumTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import android.view.Display;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
@@ -46,64 +51,53 @@ import org.junit.Test;
|
||||
@Presubmit
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ActivityRecordTests extends ActivityTestsBase {
|
||||
private static final int TEST_STACK_ID = 100;
|
||||
|
||||
private final ComponentName testActivityComponent =
|
||||
ComponentName.unflattenFromString("com.foo/.BarActivity");
|
||||
private final ComponentName secondaryActivityComponent =
|
||||
ComponentName.unflattenFromString("com.foo/.BarActivity2");
|
||||
|
||||
private ActivityManagerService mService;
|
||||
private ActivityStack mStack;
|
||||
private TaskRecord mTask;
|
||||
private ActivityRecord mActivity;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
mService = createActivityManagerService();
|
||||
mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
mTask = createTask(mService.mStackSupervisor, testActivityComponent, mStack);
|
||||
mActivity = createActivity(mService, testActivityComponent, mTask);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStackCleanupOnClearingTask() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
|
||||
final ActivityRecord record = createActivity(service, testActivityComponent, task);
|
||||
|
||||
record.setTask(null);
|
||||
assertEquals(getActivityRemovedFromStackCount(service, TEST_STACK_ID), 1);
|
||||
mActivity.setTask(null);
|
||||
assertEquals(getActivityRemovedFromStackCount(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStackCleanupOnActivityRemoval() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
|
||||
final ActivityRecord record = createActivity(service, testActivityComponent, task);
|
||||
|
||||
task.removeActivity(record);
|
||||
assertEquals(getActivityRemovedFromStackCount(service, TEST_STACK_ID), 1);
|
||||
mTask.removeActivity(mActivity);
|
||||
assertEquals(getActivityRemovedFromStackCount(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStackCleanupOnTaskRemoval() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
|
||||
final ActivityRecord record = createActivity(service, testActivityComponent, task);
|
||||
|
||||
service.mStackSupervisor.getStack(TEST_STACK_ID)
|
||||
.removeTask(task, null /*reason*/, ActivityStack.REMOVE_TASK_MODE_MOVING);
|
||||
|
||||
mStack.removeTask(mTask, null /*reason*/, REMOVE_TASK_MODE_MOVING);
|
||||
// Stack should be gone on task removal.
|
||||
assertNull(service.mStackSupervisor.getStack(TEST_STACK_ID));
|
||||
assertNull(mService.mStackSupervisor.getStack(mStack.mStackId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoCleanupMovingActivityInSameStack() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord oldTask = createTask(service, testActivityComponent, TEST_STACK_ID);
|
||||
final ActivityRecord record = createActivity(service, testActivityComponent, oldTask);
|
||||
final TaskRecord newTask = createTask(service, testActivityComponent, TEST_STACK_ID);
|
||||
|
||||
record.reparent(newTask, 0, null /*reason*/);
|
||||
assertEquals(getActivityRemovedFromStackCount(service, TEST_STACK_ID), 0);
|
||||
}
|
||||
|
||||
private static int getActivityRemovedFromStackCount(ActivityManagerService service,
|
||||
int stackId) {
|
||||
final ActivityStack stack = service.mStackSupervisor.getStack(stackId);
|
||||
if (stack instanceof ActivityStackReporter) {
|
||||
return ((ActivityStackReporter) stack).onActivityRemovedFromStackInvocationCount();
|
||||
}
|
||||
|
||||
return -1;
|
||||
final TaskRecord newTask =
|
||||
createTask(mService.mStackSupervisor, testActivityComponent, mStack);
|
||||
mActivity.reparent(newTask, 0, null /*reason*/);
|
||||
assertEquals(getActivityRemovedFromStackCount(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,16 +120,21 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
||||
|
||||
private void verifyPositionWithLimitedAspectRatio(int navBarPosition, Rect taskBounds,
|
||||
float aspectRatio, Rect expectedActivityBounds) {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
|
||||
final ActivityRecord record = createActivity(service, testActivityComponent, task);
|
||||
|
||||
// Verify with nav bar on the right.
|
||||
when(service.mWindowManager.getNavBarPosition()).thenReturn(navBarPosition);
|
||||
task.getConfiguration().windowConfiguration.setAppBounds(taskBounds);
|
||||
record.info.maxAspectRatio = aspectRatio;
|
||||
record.ensureActivityConfigurationLocked(0 /* globalChanges */, false /* preserveWindow */);
|
||||
assertEquals(expectedActivityBounds, record.getBounds());
|
||||
when(mService.mWindowManager.getNavBarPosition()).thenReturn(navBarPosition);
|
||||
mTask.getConfiguration().windowConfiguration.setAppBounds(taskBounds);
|
||||
mActivity.info.maxAspectRatio = aspectRatio;
|
||||
mActivity.ensureActivityConfigurationLocked(
|
||||
0 /* globalChanges */, false /* preserveWindow */);
|
||||
assertEquals(expectedActivityBounds, mActivity.getBounds());
|
||||
}
|
||||
|
||||
private int getActivityRemovedFromStackCount() {
|
||||
if (mStack instanceof ActivityStackReporter) {
|
||||
return ((ActivityStackReporter) mStack).onActivityRemovedFromStackInvocationCount();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -156,26 +155,22 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
||||
|
||||
private void testSupportsLaunchingResizeable(boolean taskPresent, boolean taskResizeable,
|
||||
boolean activityResizeable, boolean expected) {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
service.mSupportsMultiWindow = true;
|
||||
|
||||
mService.mSupportsMultiWindow = true;
|
||||
|
||||
final TaskRecord task = taskPresent
|
||||
? createTask(service, testActivityComponent, TEST_STACK_ID) : null;
|
||||
? createTask(mService.mStackSupervisor, testActivityComponent, mStack) : null;
|
||||
|
||||
if (task != null) {
|
||||
task.setResizeMode(taskResizeable ? ActivityInfo.RESIZE_MODE_RESIZEABLE
|
||||
: ActivityInfo.RESIZE_MODE_UNRESIZEABLE);
|
||||
task.setResizeMode(taskResizeable ? RESIZE_MODE_RESIZEABLE : RESIZE_MODE_UNRESIZEABLE);
|
||||
}
|
||||
|
||||
final ActivityRecord record = createActivity(service, secondaryActivityComponent,
|
||||
task);
|
||||
record.info.resizeMode = activityResizeable ? ActivityInfo.RESIZE_MODE_RESIZEABLE
|
||||
: ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
|
||||
final ActivityRecord record = createActivity(mService, secondaryActivityComponent, task);
|
||||
record.info.resizeMode = activityResizeable
|
||||
? RESIZE_MODE_RESIZEABLE : RESIZE_MODE_UNRESIZEABLE;
|
||||
|
||||
record.canBeLaunchedOnDisplay(Display.DEFAULT_DISPLAY);
|
||||
record.canBeLaunchedOnDisplay(DEFAULT_DISPLAY);
|
||||
|
||||
assertEquals(((TestActivityStackSupervisor) service.mStackSupervisor)
|
||||
assertEquals(((TestActivityStackSupervisor) mService.mStackSupervisor)
|
||||
.getLastResizeableFromCanPlaceEntityOnDisplay(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
package com.android.server.am;
|
||||
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@@ -33,6 +32,7 @@ import android.support.test.filters.MediumTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -54,6 +54,21 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
|
||||
private final ComponentName testActivityComponent =
|
||||
ComponentName.unflattenFromString("com.foo/.BarActivity");
|
||||
|
||||
private ActivityManagerService mService;
|
||||
private ActivityStackSupervisor mSupervisor;
|
||||
private ActivityStack mFullscreenStack;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
mService = createActivityManagerService();
|
||||
mSupervisor = mService.mStackSupervisor;
|
||||
mFullscreenStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
}
|
||||
|
||||
/**
|
||||
* This test ensures that we do not try to restore a task based off an invalid task id. The
|
||||
* stack supervisor is a test version so there will be no tasks present. We should expect
|
||||
@@ -61,8 +76,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
|
||||
*/
|
||||
@Test
|
||||
public void testRestoringInvalidTask() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
TaskRecord task = service.mStackSupervisor.anyTaskForIdLocked(0 /*taskId*/,
|
||||
TaskRecord task = mSupervisor.anyTaskForIdLocked(0 /*taskId*/,
|
||||
MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, null);
|
||||
assertNull(task);
|
||||
}
|
||||
@@ -73,43 +87,44 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
|
||||
*/
|
||||
@Test
|
||||
public void testReplacingTaskInPinnedStack() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord firstTask = createTask(service, testActivityComponent,
|
||||
FULLSCREEN_WORKSPACE_STACK_ID);
|
||||
final ActivityRecord firstActivity = createActivity(service, testActivityComponent,
|
||||
final TaskRecord firstTask = createTask(
|
||||
mSupervisor, testActivityComponent, mFullscreenStack);
|
||||
final ActivityRecord firstActivity = createActivity(mService, testActivityComponent,
|
||||
firstTask);
|
||||
// Create a new task on the full screen stack
|
||||
final TaskRecord secondTask = createTask(service, testActivityComponent,
|
||||
FULLSCREEN_WORKSPACE_STACK_ID);
|
||||
final ActivityRecord secondActivity = createActivity(service, testActivityComponent,
|
||||
final TaskRecord secondTask = createTask(
|
||||
mSupervisor, testActivityComponent, mFullscreenStack);
|
||||
final ActivityRecord secondActivity = createActivity(mService, testActivityComponent,
|
||||
secondTask);
|
||||
service.mStackSupervisor.setFocusStackUnchecked("testReplacingTaskInPinnedStack",
|
||||
service.mStackSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID));
|
||||
mSupervisor.setFocusStackUnchecked("testReplacingTaskInPinnedStack", mFullscreenStack);
|
||||
|
||||
// Ensure full screen stack has both tasks.
|
||||
ensureStackPlacement(service.mStackSupervisor, FULLSCREEN_WORKSPACE_STACK_ID, firstTask,
|
||||
secondTask);
|
||||
ensureStackPlacement(mFullscreenStack, firstTask, secondTask);
|
||||
|
||||
// Move first activity to pinned stack.
|
||||
service.mStackSupervisor.moveActivityToPinnedStackLocked(firstActivity,
|
||||
new Rect() /*sourceBounds*/, 0f /*aspectRatio*/, false, "initialMove");
|
||||
final Rect sourceBounds = new Rect();
|
||||
mSupervisor.moveActivityToPinnedStackLocked(firstActivity, sourceBounds,
|
||||
0f /*aspectRatio*/, false, "initialMove");
|
||||
|
||||
final ActivityDisplay display = mFullscreenStack.getDisplay();
|
||||
ActivityStack pinnedStack = display.getPinnedStack();
|
||||
// Ensure a task has moved over.
|
||||
ensureStackPlacement(service.mStackSupervisor, PINNED_STACK_ID, firstTask);
|
||||
ensureStackPlacement(service.mStackSupervisor, FULLSCREEN_WORKSPACE_STACK_ID, secondTask);
|
||||
ensureStackPlacement(pinnedStack, firstTask);
|
||||
ensureStackPlacement(mFullscreenStack, secondTask);
|
||||
|
||||
// Move second activity to pinned stack.
|
||||
service.mStackSupervisor.moveActivityToPinnedStackLocked(secondActivity,
|
||||
new Rect() /*sourceBounds*/, 0f /*aspectRatio*/ /*destBounds*/, false, "secondMove");
|
||||
mSupervisor.moveActivityToPinnedStackLocked(secondActivity, sourceBounds,
|
||||
0f /*aspectRatio*/, false, "secondMove");
|
||||
|
||||
// Need to get pinned stack again as a new instance might have been created.
|
||||
pinnedStack = display.getPinnedStack();
|
||||
|
||||
// Ensure stacks have swapped tasks.
|
||||
ensureStackPlacement(service.mStackSupervisor, PINNED_STACK_ID, secondTask);
|
||||
ensureStackPlacement(service.mStackSupervisor, FULLSCREEN_WORKSPACE_STACK_ID, firstTask);
|
||||
ensureStackPlacement(pinnedStack, secondTask);
|
||||
ensureStackPlacement(mFullscreenStack, firstTask);
|
||||
}
|
||||
|
||||
private static void ensureStackPlacement(ActivityStackSupervisor supervisor, int stackId,
|
||||
TaskRecord... tasks) {
|
||||
final ActivityStack stack = supervisor.getStack(stackId);
|
||||
private static void ensureStackPlacement(ActivityStack stack, TaskRecord... tasks) {
|
||||
final ArrayList<TaskRecord> stackTasks = stack.getAllTasks();
|
||||
assertEquals(stackTasks.size(), tasks != null ? tasks.length : 0);
|
||||
|
||||
@@ -127,15 +142,14 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
|
||||
*/
|
||||
@Test
|
||||
public void testStoppingActivityRemovedWhenResumed() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord firstTask = createTask(service, testActivityComponent,
|
||||
FULLSCREEN_WORKSPACE_STACK_ID);
|
||||
final ActivityRecord firstActivity = createActivity(service, testActivityComponent,
|
||||
final TaskRecord firstTask = createTask(
|
||||
mSupervisor, testActivityComponent, mFullscreenStack);
|
||||
final ActivityRecord firstActivity = createActivity(mService, testActivityComponent,
|
||||
firstTask);
|
||||
service.mStackSupervisor.mStoppingActivities.add(firstActivity);
|
||||
mSupervisor.mStoppingActivities.add(firstActivity);
|
||||
|
||||
firstActivity.completeResumeLocked();
|
||||
|
||||
assertFalse(service.mStackSupervisor.mStoppingActivities.contains(firstActivity));
|
||||
assertFalse(mSupervisor.mStoppingActivities.contains(firstActivity));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
|
||||
package com.android.server.am;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.os.UserHandle;
|
||||
@@ -30,6 +32,7 @@ import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
@@ -48,78 +51,80 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
private static final ComponentName testOverlayComponent =
|
||||
ComponentName.unflattenFromString("com.foo/.OverlayActivity");
|
||||
|
||||
private ActivityManagerService mService;
|
||||
private ActivityStackSupervisor mSupervisor;
|
||||
private ActivityStack mStack;
|
||||
private TaskRecord mTask;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
mService = createActivityManagerService();
|
||||
mSupervisor = mService.mStackSupervisor;
|
||||
mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
||||
mTask = createTask(mSupervisor, testActivityComponent, mStack);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyTaskCleanupOnRemove() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
|
||||
assertNotNull(task.getWindowContainerController());
|
||||
service.mStackSupervisor.getStack(TEST_STACK_ID).removeTask(task,
|
||||
"testEmptyTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING);
|
||||
assertNull(task.getWindowContainerController());
|
||||
assertNotNull(mTask.getWindowContainerController());
|
||||
mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
|
||||
assertNull(mTask.getWindowContainerController());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOccupiedTaskCleanupOnRemove() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
|
||||
final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task);
|
||||
assertNotNull(task.getWindowContainerController());
|
||||
service.mStackSupervisor.getStack(TEST_STACK_ID).removeTask(task,
|
||||
"testOccupiedTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING);
|
||||
assertNotNull(task.getWindowContainerController());
|
||||
final ActivityRecord r = createActivity(mService, testActivityComponent, mTask);
|
||||
assertNotNull(mTask.getWindowContainerController());
|
||||
mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
|
||||
assertNotNull(mTask.getWindowContainerController());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoPauseDuringResumeTopActivity() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
|
||||
final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task);
|
||||
final ActivityStack testStack = service.mStackSupervisor.getStack(TEST_STACK_ID);
|
||||
final ActivityRecord r = createActivity(mService, testActivityComponent, mTask);
|
||||
|
||||
// Simulate the a resumed activity set during
|
||||
// {@link ActivityStack#resumeTopActivityUncheckedLocked}.
|
||||
service.mStackSupervisor.inResumeTopActivity = true;
|
||||
testStack.mResumedActivity = activityRecord;
|
||||
mSupervisor.inResumeTopActivity = true;
|
||||
mStack.mResumedActivity = r;
|
||||
|
||||
final boolean waiting = testStack.goToSleepIfPossible(false);
|
||||
final boolean waiting = mStack.goToSleepIfPossible(false);
|
||||
|
||||
// Ensure we report not being ready for sleep.
|
||||
assertFalse(waiting);
|
||||
|
||||
// Make sure the resumed activity is untouched.
|
||||
assertEquals(testStack.mResumedActivity, activityRecord);
|
||||
assertEquals(mStack.mResumedActivity, r);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopActivityWhenActivityDestroyed() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
|
||||
final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task);
|
||||
activityRecord.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
|
||||
final ActivityStack testStack = service.mStackSupervisor.getStack(TEST_STACK_ID);
|
||||
service.mStackSupervisor.setFocusStackUnchecked("testStopActivityWithDestroy", testStack);
|
||||
|
||||
testStack.stopActivityLocked(activityRecord);
|
||||
final ActivityRecord r = createActivity(mService, testActivityComponent, mTask);
|
||||
r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
|
||||
mSupervisor.setFocusStackUnchecked("testStopActivityWithDestroy", mStack);
|
||||
mStack.stopActivityLocked(r);
|
||||
// Mostly testing to make sure there is a crash in the call part, so if we get here we are
|
||||
// good-to-go!
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindTaskWithOverlay() throws Exception {
|
||||
final ActivityManagerService service = createActivityManagerService();
|
||||
final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
|
||||
final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task,
|
||||
0);
|
||||
final ActivityRecord r = createActivity(mService, testActivityComponent, mTask, 0);
|
||||
// Overlay must be for a different user to prevent recognizing a matching top activity
|
||||
final ActivityRecord taskOverlay = createActivity(service, testOverlayComponent, task,
|
||||
final ActivityRecord taskOverlay = createActivity(mService, testOverlayComponent, mTask,
|
||||
UserHandle.PER_USER_RANGE * 2);
|
||||
taskOverlay.mTaskOverlay = true;
|
||||
|
||||
final ActivityStack testStack = service.mStackSupervisor.getStack(TEST_STACK_ID);
|
||||
final ActivityStackSupervisor.FindTaskResult result =
|
||||
new ActivityStackSupervisor.FindTaskResult();
|
||||
testStack.findTaskLocked(activityRecord, result);
|
||||
mStack.findTaskLocked(r, result);
|
||||
|
||||
assertEquals(task.getTopActivity(false /* includeOverlays */), activityRecord);
|
||||
assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay);
|
||||
assertEquals(mTask.getTopActivity(false /* includeOverlays */), r);
|
||||
assertEquals(mTask.getTopActivity(true /* includeOverlays */), taskOverlay);
|
||||
assertNotNull(result.r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.server.am;
|
||||
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
@@ -76,16 +76,6 @@ public class ActivityTestsBase {
|
||||
return service;
|
||||
}
|
||||
|
||||
protected static ActivityStack createActivityStack(ActivityManagerService service,
|
||||
int stackId, int displayId, boolean onTop) {
|
||||
if (service.mStackSupervisor instanceof TestActivityStackSupervisor) {
|
||||
return ((TestActivityStackSupervisor) service.mStackSupervisor)
|
||||
.createTestStack(stackId, onTop);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static ActivityRecord createActivity(ActivityManagerService service,
|
||||
ComponentName component, TaskRecord task) {
|
||||
return createActivity(service, component, task, 0 /* userId */);
|
||||
@@ -114,8 +104,8 @@ public class ActivityTestsBase {
|
||||
return activity;
|
||||
}
|
||||
|
||||
protected static TaskRecord createTask(ActivityManagerService service,
|
||||
ComponentName component, int stackId) {
|
||||
protected static TaskRecord createTask(ActivityStackSupervisor supervisor,
|
||||
ComponentName component, ActivityStack stack) {
|
||||
final ActivityInfo aInfo = new ActivityInfo();
|
||||
aInfo.applicationInfo = new ApplicationInfo();
|
||||
aInfo.applicationInfo.packageName = component.getPackageName();
|
||||
@@ -123,11 +113,9 @@ public class ActivityTestsBase {
|
||||
Intent intent = new Intent();
|
||||
intent.setComponent(component);
|
||||
|
||||
final TaskRecord task = new TaskRecord(service, 0, aInfo, intent /*intent*/,
|
||||
final TaskRecord task = new TaskRecord(supervisor.mService, 0, aInfo, intent /*intent*/,
|
||||
null /*_taskDescription*/);
|
||||
final ActivityStack stack = service.mStackSupervisor.getStack(stackId,
|
||||
true /*createStaticStackIfNeeded*/, true /*onTop*/);
|
||||
service.mStackSupervisor.setFocusStackUnchecked("test", stack);
|
||||
supervisor.setFocusStackUnchecked("test", stack);
|
||||
stack.addTask(task, true, "creating test task");
|
||||
task.setStack(stack);
|
||||
task.setWindowContainerController(mock(TaskWindowContainerController.class));
|
||||
@@ -135,16 +123,18 @@ public class ActivityTestsBase {
|
||||
return task;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An {@link ActivityManagerService} subclass which provides a test
|
||||
* {@link ActivityStackSupervisor}.
|
||||
*/
|
||||
protected static class TestActivityManagerService extends ActivityManagerService {
|
||||
public TestActivityManagerService(Context context) {
|
||||
TestActivityManagerService(Context context) {
|
||||
super(context);
|
||||
mSupportsMultiWindow = true;
|
||||
mSupportsMultiDisplay = true;
|
||||
mSupportsSplitScreenMultiWindow = true;
|
||||
mSupportsFreeformWindowManagement = true;
|
||||
mSupportsPictureInPicture = true;
|
||||
mWindowManager = WindowTestUtils.getWindowManagerService(context);
|
||||
}
|
||||
|
||||
@@ -171,10 +161,15 @@ public class ActivityTestsBase {
|
||||
mDisplayManager =
|
||||
(DisplayManager) mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
|
||||
mWindowManager = prepareMockWindowManager();
|
||||
mDisplay = new ActivityDisplay(this, DEFAULT_DISPLAY);
|
||||
mDisplay = new TestActivityDisplay(this, DEFAULT_DISPLAY);
|
||||
attachDisplay(mDisplay);
|
||||
}
|
||||
|
||||
@Override
|
||||
ActivityDisplay getDefaultDisplay() {
|
||||
return mDisplay;
|
||||
}
|
||||
|
||||
// TODO: Use Mockito spy instead. Currently not possible due to TestActivityStackSupervisor
|
||||
// access to ActivityDisplay
|
||||
@Override
|
||||
@@ -218,41 +213,36 @@ public class ActivityTestsBase {
|
||||
boolean preserveWindows) {
|
||||
}
|
||||
|
||||
<T extends ActivityStack> T createTestStack(int stackId, boolean onTop) {
|
||||
return (T) createStack(stackId, mDisplay, onTop);
|
||||
// Always keep things awake
|
||||
@Override
|
||||
boolean hasAwakeDisplay() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestActivityDisplay extends ActivityDisplay {
|
||||
|
||||
private final ActivityStackSupervisor mSupervisor;
|
||||
TestActivityDisplay(ActivityStackSupervisor supervisor, int displayId) {
|
||||
super(supervisor, displayId);
|
||||
mSupervisor = supervisor;
|
||||
}
|
||||
|
||||
@Override
|
||||
ActivityStack createStack(int stackId, ActivityDisplay display, boolean onTop) {
|
||||
if (stackId == PINNED_STACK_ID) {
|
||||
return new PinnedActivityStack(display, stackId, this, onTop) {
|
||||
<T extends ActivityStack> T createStackUnchecked(int windowingMode, int activityType,
|
||||
int stackId, boolean onTop) {
|
||||
if (windowingMode == WINDOWING_MODE_PINNED) {
|
||||
return (T) new PinnedActivityStack(this, stackId, mSupervisor, onTop) {
|
||||
@Override
|
||||
Rect getDefaultPictureInPictureBounds(float aspectRatio) {
|
||||
return new Rect(50, 50, 100, 100);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return new TestActivityStack(display, stackId, this, onTop);
|
||||
return (T) new TestActivityStack(
|
||||
this, stackId, mSupervisor, windowingMode, activityType, onTop);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T extends ActivityStack> T getStack(int stackId,
|
||||
boolean createStaticStackIfNeeded, boolean createOnTop) {
|
||||
final T stack = super.getStack(stackId, createStaticStackIfNeeded, createOnTop);
|
||||
|
||||
if (stack != null || !createStaticStackIfNeeded) {
|
||||
return stack;
|
||||
}
|
||||
|
||||
return createTestStack(stackId, createOnTop);
|
||||
}
|
||||
|
||||
// Always keep things awake
|
||||
@Override
|
||||
boolean hasAwakeDisplay() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static WindowManagerService prepareMockWindowManager() {
|
||||
@@ -282,9 +272,10 @@ public class ActivityTestsBase {
|
||||
extends ActivityStack<T> implements ActivityStackReporter {
|
||||
private int mOnActivityRemovedFromStackCount = 0;
|
||||
private T mContainerController;
|
||||
|
||||
TestActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
|
||||
boolean onTop) {
|
||||
super(display, stackId, supervisor, onTop);
|
||||
int windowingMode, int activityType, boolean onTop) {
|
||||
super(display, stackId, supervisor, windowingMode, activityType, onTop);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -310,36 +301,4 @@ public class ActivityTestsBase {
|
||||
return mContainerController;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static class ActivityStackBuilder {
|
||||
private boolean mOnTop = true;
|
||||
private int mStackId = 0;
|
||||
private int mDisplayId = 1;
|
||||
|
||||
private final ActivityManagerService mService;
|
||||
|
||||
public ActivityStackBuilder(ActivityManagerService ams) {
|
||||
mService = ams;
|
||||
}
|
||||
|
||||
public ActivityStackBuilder setOnTop(boolean onTop) {
|
||||
mOnTop = onTop;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ActivityStackBuilder setStackId(int id) {
|
||||
mStackId = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ActivityStackBuilder setDisplayId(int id) {
|
||||
mDisplayId = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ActivityStack build() {
|
||||
return createActivityStack(mService, mStackId, mDisplayId, mOnTop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
|
||||
@@ -347,17 +348,20 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
*/
|
||||
@Test
|
||||
public void testPinnedStackLocation() {
|
||||
createStackControllerOnStackOnDisplay(PINNED_STACK_ID, mDisplayContent);
|
||||
createStackControllerOnStackOnDisplay(
|
||||
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
|
||||
final int initialStackCount = mDisplayContent.getStackCount();
|
||||
// Ensure that the pinned stack was placed at the end
|
||||
assertEquals(initialStackCount - 1, mDisplayContent.getStackPosById(PINNED_STACK_ID));
|
||||
assertEquals(initialStackCount - 1,
|
||||
mDisplayContent.getStackPosition(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD));
|
||||
// By default, this should try to create a new stack on top
|
||||
createTaskStackOnDisplay(mDisplayContent);
|
||||
final int afterStackCount = mDisplayContent.getStackCount();
|
||||
// Make sure the stack count has increased
|
||||
assertEquals(initialStackCount + 1, afterStackCount);
|
||||
// Ensure that the pinned stack is still on top
|
||||
assertEquals(afterStackCount - 1, mDisplayContent.getStackPosById(PINNED_STACK_ID));
|
||||
assertEquals(afterStackCount - 1,
|
||||
mDisplayContent.getStackPosition(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,7 +29,7 @@ import android.platform.test.annotations.Presubmit;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import static android.app.ActivityManager.StackId.getWindowingModeForStackId;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -53,8 +53,7 @@ public class TaskStackContainersTests extends WindowTestsBase {
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final Configuration overrideConfig = new Configuration();
|
||||
overrideConfig.windowConfiguration.setWindowingMode(
|
||||
getWindowingModeForStackId(PINNED_STACK_ID, false /* inSplitScreenMode */));
|
||||
overrideConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_PINNED);
|
||||
mPinnedStack = new StackWindowController(PINNED_STACK_ID, null,
|
||||
mDisplayContent.getDisplayId(), true /* onTop */, new Rect(), sWm).mContainer;
|
||||
mPinnedStack.onOverrideConfigurationChanged(overrideConfig);
|
||||
|
||||
@@ -26,10 +26,10 @@ import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.view.DisplayInfo;
|
||||
|
||||
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS;
|
||||
import static android.app.WindowConfiguration.WINDOW_CONFIG_WINDOWING_MODE;
|
||||
import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
|
||||
@@ -155,7 +155,7 @@ public class WindowConfigurationTests extends WindowTestsBase {
|
||||
shiftedBounds.offset(10, 10);
|
||||
final Rect expectedBounds = new Rect(mParentBounds);
|
||||
expectedBounds.intersect(shiftedBounds);
|
||||
testStackBoundsConfiguration(null /*stackId*/, mParentBounds, shiftedBounds,
|
||||
testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, shiftedBounds,
|
||||
expectedBounds);
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ public class WindowConfigurationTests extends WindowTestsBase {
|
||||
@Test
|
||||
public void testAppBounds_EmptyBounds() throws Exception {
|
||||
final Rect emptyBounds = new Rect();
|
||||
testStackBoundsConfiguration(null /*stackId*/, mParentBounds, emptyBounds,
|
||||
testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, emptyBounds,
|
||||
null /*ExpectedBounds*/);
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ public class WindowConfigurationTests extends WindowTestsBase {
|
||||
public void testAppBounds_FreeFormBounds() throws Exception {
|
||||
final Rect freeFormBounds = new Rect(mParentBounds);
|
||||
freeFormBounds.offset(10, 10);
|
||||
testStackBoundsConfiguration(FREEFORM_WORKSPACE_STACK_ID, mParentBounds, freeFormBounds,
|
||||
testStackBoundsConfiguration(WINDOWING_MODE_FREEFORM, mParentBounds, freeFormBounds,
|
||||
freeFormBounds);
|
||||
}
|
||||
|
||||
@@ -181,7 +181,8 @@ public class WindowConfigurationTests extends WindowTestsBase {
|
||||
public void testAppBounds_ContainedBounds() throws Exception {
|
||||
final Rect insetBounds = new Rect(mParentBounds);
|
||||
insetBounds.inset(5, 5, 5, 5);
|
||||
testStackBoundsConfiguration(null /*stackId*/, mParentBounds, insetBounds, insetBounds);
|
||||
testStackBoundsConfiguration(
|
||||
WINDOWING_MODE_FULLSCREEN, mParentBounds, insetBounds, insetBounds);
|
||||
}
|
||||
|
||||
/** Ensures that full screen free form bounds are clipped */
|
||||
@@ -189,15 +190,14 @@ public class WindowConfigurationTests extends WindowTestsBase {
|
||||
public void testAppBounds_FullScreenFreeFormBounds() throws Exception {
|
||||
final Rect fullScreenBounds = new Rect(0, 0, mDisplayInfo.logicalWidth,
|
||||
mDisplayInfo.logicalHeight);
|
||||
testStackBoundsConfiguration(null /*stackId*/, mParentBounds, fullScreenBounds,
|
||||
testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, fullScreenBounds,
|
||||
mParentBounds);
|
||||
}
|
||||
|
||||
private void testStackBoundsConfiguration(Integer stackId, Rect parentBounds, Rect bounds,
|
||||
private void testStackBoundsConfiguration(int windowingMode, Rect parentBounds, Rect bounds,
|
||||
Rect expectedConfigBounds) {
|
||||
final StackWindowController stackController = stackId != null ?
|
||||
createStackControllerOnStackOnDisplay(stackId, mDisplayContent)
|
||||
: createStackControllerOnDisplay(mDisplayContent);
|
||||
final StackWindowController stackController = createStackControllerOnStackOnDisplay(
|
||||
windowingMode, ACTIVITY_TYPE_STANDARD, mDisplayContent);
|
||||
|
||||
final Configuration parentConfig = mDisplayContent.getConfiguration();
|
||||
parentConfig.windowConfiguration.setAppBounds(parentBounds);
|
||||
|
||||
@@ -23,9 +23,11 @@ import android.platform.test.annotations.Presubmit;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
||||
@@ -160,12 +162,14 @@ public class WindowLayersControllerTests extends WindowTestsBase {
|
||||
|
||||
@Test
|
||||
public void testStackLayers() throws Exception {
|
||||
WindowState pinnedStackWindow = createWindowOnStack(null, PINNED_STACK_ID,
|
||||
TYPE_BASE_APPLICATION, mDisplayContent, "pinnedStackWindow");
|
||||
WindowState dockedStackWindow = createWindowOnStack(null, DOCKED_STACK_ID,
|
||||
TYPE_BASE_APPLICATION, mDisplayContent, "dockedStackWindow");
|
||||
WindowState assistantStackWindow = createWindowOnStack(null, ASSISTANT_STACK_ID,
|
||||
TYPE_BASE_APPLICATION, mDisplayContent, "assistantStackWindow");
|
||||
WindowState pinnedStackWindow = createWindowOnStack(null, WINDOWING_MODE_PINNED,
|
||||
ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION, mDisplayContent, "pinnedStackWindow");
|
||||
WindowState dockedStackWindow = createWindowOnStack(null,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION,
|
||||
mDisplayContent, "dockedStackWindow");
|
||||
WindowState assistantStackWindow = createWindowOnStack(null, WINDOWING_MODE_FULLSCREEN,
|
||||
ACTIVITY_TYPE_ASSISTANT, TYPE_BASE_APPLICATION,
|
||||
mDisplayContent, "assistantStackWindow");
|
||||
|
||||
mLayersController.assignWindowLayers(mDisplayContent);
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityManager.StackId.getWindowingModeForStackId;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
||||
@@ -167,14 +168,14 @@ class WindowTestsBase {
|
||||
sWm.mAnimationHandler.runWithScissors(() -> { }, 0);
|
||||
}
|
||||
|
||||
private WindowToken createWindowToken(DisplayContent dc, int stackId, int type) {
|
||||
private WindowToken createWindowToken(
|
||||
DisplayContent dc, int windowingMode, int activityType, int type) {
|
||||
if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
|
||||
return new WindowTestUtils.TestWindowToken(type, dc);
|
||||
}
|
||||
|
||||
final TaskStack stack = stackId == INVALID_STACK_ID
|
||||
? createTaskStackOnDisplay(dc)
|
||||
: createStackControllerOnStackOnDisplay(stackId, dc).mContainer;
|
||||
final TaskStack stack =
|
||||
createStackControllerOnStackOnDisplay(windowingMode, activityType, dc).mContainer;
|
||||
final Task task = createTaskInStack(stack, 0 /* userId */);
|
||||
final WindowTestUtils.TestAppWindowToken token = new WindowTestUtils.TestAppWindowToken(dc);
|
||||
task.addChild(token, 0);
|
||||
@@ -187,9 +188,9 @@ class WindowTestsBase {
|
||||
: createWindow(parent, type, parent.mToken, name);
|
||||
}
|
||||
|
||||
WindowState createWindowOnStack(WindowState parent, int stackId, int type,
|
||||
DisplayContent dc, String name) {
|
||||
final WindowToken token = createWindowToken(dc, stackId, type);
|
||||
WindowState createWindowOnStack(WindowState parent, int windowingMode, int activityType,
|
||||
int type, DisplayContent dc, String name) {
|
||||
final WindowToken token = createWindowToken(dc, windowingMode, activityType, type);
|
||||
return createWindow(parent, type, token, name);
|
||||
}
|
||||
|
||||
@@ -200,13 +201,15 @@ class WindowTestsBase {
|
||||
}
|
||||
|
||||
WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
|
||||
final WindowToken token = createWindowToken(dc, INVALID_STACK_ID, type);
|
||||
final WindowToken token = createWindowToken(
|
||||
dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
|
||||
return createWindow(parent, type, token, name);
|
||||
}
|
||||
|
||||
WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
|
||||
boolean ownerCanAddInternalSystemWindow) {
|
||||
final WindowToken token = createWindowToken(dc, INVALID_STACK_ID, type);
|
||||
final WindowToken token = createWindowToken(
|
||||
dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
|
||||
return createWindow(parent, type, token, name, ownerCanAddInternalSystemWindow);
|
||||
}
|
||||
|
||||
@@ -233,14 +236,16 @@ class WindowTestsBase {
|
||||
}
|
||||
|
||||
StackWindowController createStackControllerOnDisplay(DisplayContent dc) {
|
||||
final int stackId = ++sNextStackId;
|
||||
return createStackControllerOnStackOnDisplay(stackId, dc);
|
||||
return createStackControllerOnStackOnDisplay(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, dc);
|
||||
}
|
||||
|
||||
StackWindowController createStackControllerOnStackOnDisplay(int stackId, DisplayContent dc) {
|
||||
StackWindowController createStackControllerOnStackOnDisplay(
|
||||
int windowingMode, int activityType, DisplayContent dc) {
|
||||
final Configuration overrideConfig = new Configuration();
|
||||
overrideConfig.windowConfiguration.setWindowingMode(
|
||||
getWindowingModeForStackId(stackId, false /* inSplitScreenMode */));
|
||||
overrideConfig.windowConfiguration.setWindowingMode(windowingMode);
|
||||
overrideConfig.windowConfiguration.setActivityType(activityType);
|
||||
final int stackId = ++sNextStackId;
|
||||
final StackWindowController controller = new StackWindowController(stackId, null,
|
||||
dc.getDisplayId(), true /* onTop */, new Rect(), sWm);
|
||||
controller.onOverrideConfigurationChanged(overrideConfig);
|
||||
|
||||
Reference in New Issue
Block a user