/**
- * Moves the activity from
- * {@link android.app.ActivityManager.StackId#FREEFORM_WORKSPACE_STACK_ID} to
- * {@link android.app.ActivityManager.StackId#FULLSCREEN_WORKSPACE_STACK_ID} stack.
+ * Moves the activity from {@link WindowConfiguration#WINDOWING_MODE_FREEFORM} windowing mode to
+ * {@link WindowConfiguration#WINDOWING_MODE_FULLSCREEN}.
*
* @hide
*/
ActivityManager.getService().exitFreeformMode(mToken);
}
- /** Returns the current stack Id for the window.
- * @hide
- */
- @Override
- public int getWindowStackId() throws RemoteException {
- return ActivityManager.getService().getActivityStackId(mToken);
- }
-
/**
* Puts the activity in picture-in-picture mode if the activity supports.
* @see android.R.attr#supportsPictureInPicture
/** Start of ID range used by stacks that are created dynamically. */
public static final int FIRST_DYNAMIC_STACK_ID = LAST_STATIC_STACK_ID + 1;
+ // TODO: Figure-out a way to remove this.
public static boolean isStaticStack(int stackId) {
return stackId >= FIRST_STATIC_STACK_ID && stackId <= LAST_STATIC_STACK_ID;
}
+ // TODO: It seems this mostly means a stack on a secondary display now. Need to see if
+ // there are other meanings. If not why not just use information from the display?
public static boolean isDynamicStack(int stackId) {
return stackId >= FIRST_DYNAMIC_STACK_ID;
}
/**
- * Returns true if the activities contained in the input stack display a shadow around
- * their border.
- */
- public static boolean hasWindowShadow(int stackId) {
- return stackId == FREEFORM_WORKSPACE_STACK_ID || stackId == PINNED_STACK_ID;
- }
-
- /**
- * Returns true if the activities contained in the input stack display a decor view.
- */
- public static boolean hasWindowDecor(int stackId) {
- return stackId == FREEFORM_WORKSPACE_STACK_ID;
- }
-
- /**
- * Returns true if the tasks contained in the stack can be resized independently of the
- * stack.
- */
- public static boolean isTaskResizeAllowed(int stackId) {
- return stackId == FREEFORM_WORKSPACE_STACK_ID;
- }
-
- /** Returns true if the task bounds should persist across power cycles. */
- public static boolean persistTaskBounds(int stackId) {
- return stackId == FREEFORM_WORKSPACE_STACK_ID;
- }
-
- /**
* Returns true if dynamic stacks are allowed to be visible behind the input stack.
*/
+ // 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.
*/
+ // TODO: Figure-out a way to remove. Probably isn't needed in the new world...
public static boolean keepFocusInStackIfPossible(int stackId) {
return stackId == FREEFORM_WORKSPACE_STACK_ID
|| stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID;
/**
* Returns true if Stack size is affected by the docked stack changing size.
*/
+ // TODO: Figure-out a way to remove.
public static boolean isResizeableByDockedStack(int stackId) {
return isStaticStack(stackId) && stackId != DOCKED_STACK_ID
&& stackId != PINNED_STACK_ID && stackId != ASSISTANT_STACK_ID;
* Returns true if the size of tasks in the input stack are affected by the docked stack
* changing size.
*/
+ // TODO: What is the difference between this method and the one above??
public static boolean isTaskResizeableByDockedStack(int stackId) {
return isStaticStack(stackId) && stackId != FREEFORM_WORKSPACE_STACK_ID
&& stackId != DOCKED_STACK_ID && stackId != PINNED_STACK_ID
}
/**
- * Return whether a stackId is a stack containing floating windows. Floating windows
- * are laid out differently as they are allowed to extend past the display bounds
- * without overscan insets.
- */
- public static boolean tasksAreFloating(int stackId) {
- return stackId == FREEFORM_WORKSPACE_STACK_ID
- || stackId == PINNED_STACK_ID;
- }
-
- /**
* Return whether a stackId is a stack that be a backdrop to a translucent activity. These
* are generally fullscreen stacks.
*/
}
/**
- * Returns true if the windows in the stack can receive input keys.
- */
- public static boolean canReceiveKeys(int stackId) {
- return stackId != PINNED_STACK_ID;
- }
-
- /**
- * Returns true if the stack can be visible above lockscreen.
- */
- public static boolean isAllowedOverLockscreen(int stackId) {
- return stackId == HOME_STACK_ID || 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.
*/
stackId != RECENTS_STACK_ID;
}
- public static boolean isAlwaysOnTop(int stackId) {
- return stackId == PINNED_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.
}
/**
- * Returns true if any visible windows belonging to apps in this stack should be kept on
- * screen when the app is killed due to something like the low memory killer.
- */
- public static boolean keepVisibleDeadAppWindowOnScreen(int stackId) {
- return stackId != PINNED_STACK_ID;
- }
-
- /**
- * Returns true if the backdrop on the client side should match the frame of the window.
- * Returns false, if the backdrop should be fullscreen.
- */
- public static boolean useWindowFrameForBackdrop(int stackId) {
- return stackId == FREEFORM_WORKSPACE_STACK_ID || stackId == PINNED_STACK_ID;
- }
-
- /**
* Returns true if a window from the specified stack with {@param stackId} are normally
* fullscreen, i. e. they can become the top opaque fullscreen window, meaning that it
* controls system bars, lockscreen occluded/dismissing state, screen rotation animation,
* etc.
*/
+ // TODO: What about the other side of docked stack if we move this to WindowConfiguration?
public static boolean normallyFullscreenWindows(int stackId) {
return stackId != PINNED_STACK_ID && stackId != FREEFORM_WORKSPACE_STACK_ID
&& stackId != DOCKED_STACK_ID;
* multi-window mode.
* @see android.app.ActivityManager#supportsMultiWindow
*/
+ // 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;
return stackId == HOME_STACK_ID || stackId == RECENTS_STACK_ID;
}
- /**
- * Returns true if this stack may be scaled without resizing, and windows within may need
- * to be configured as such.
- */
- public static boolean windowsAreScaleable(int stackId) {
- return stackId == PINNED_STACK_ID;
- }
-
- /**
- * Returns true if windows in this stack should be given move animations by default.
- */
- public static boolean hasMovementAnimations(int stackId) {
- return stackId != PINNED_STACK_ID;
- }
-
/** Returns true if the input stack and its content can affect the device orientation. */
public static boolean canSpecifyOrientation(int stackId) {
return stackId == HOME_STACK_ID
* different stack.
*/
void positionTaskInStack(int taskId, int stackId, int position);
- int getActivityStackId(in IBinder token);
void exitFreeformMode(in IBinder token);
void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration,
in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations);
+ " mWindowingMode=" + windowingModeToString(mWindowingMode) + "}";
}
+ /**
+ * Returns true if the activities associated with this window configuration display a shadow
+ * around their border.
+ */
+ public boolean hasWindowShadow() {
+ return tasksAreFloating();
+ }
+
+ /**
+ * Returns true if the activities associated with this window configuration display a decor
+ * view.
+ */
+ public boolean hasWindowDecorCaption() {
+ return mWindowingMode == WINDOWING_MODE_FREEFORM;
+ }
+
+ /**
+ * Returns true if the tasks associated with this window configuration can be resized
+ * independently of their parent container.
+ */
+ public boolean canResizeTask() {
+ return mWindowingMode == WINDOWING_MODE_FREEFORM;
+ }
+
+ /** Returns true if the task bounds should persist across power cycles. */
+ public boolean persistTaskBounds() {
+ return mWindowingMode == WINDOWING_MODE_FREEFORM;
+ }
+
+ /**
+ * Returns true if the tasks associated with this window configuration are floating.
+ * Floating tasks are laid out differently as they are allowed to extend past the display bounds
+ * without overscan insets.
+ */
+ public boolean tasksAreFloating() {
+ return mWindowingMode == WINDOWING_MODE_FREEFORM || mWindowingMode == WINDOWING_MODE_PINNED;
+ }
+
+ /**
+ * Returns true if the windows associated with this window configuration can receive input keys.
+ */
+ public boolean canReceiveKeys() {
+ return mWindowingMode != WINDOWING_MODE_PINNED;
+ }
+
+ /**
+ * Returns true if the container associated with this window configuration is always-on-top of
+ * its siblings.
+ */
+ public boolean isAlwaysOnTop() {
+ return mWindowingMode == WINDOWING_MODE_PINNED;
+ }
+
+ /**
+ * Returns true if any visible windows belonging to apps with this window configuration should
+ * be kept on screen when the app is killed due to something like the low memory killer.
+ */
+ public boolean keepVisibleDeadAppWindowOnScreen() {
+ return mWindowingMode != WINDOWING_MODE_PINNED;
+ }
+
+ /**
+ * Returns true if the backdrop on the client side should match the frame of the window.
+ * Returns false, if the backdrop should be fullscreen.
+ */
+ public boolean useWindowFrameForBackdrop() {
+ return mWindowingMode == WINDOWING_MODE_FREEFORM || mWindowingMode == WINDOWING_MODE_PINNED;
+ }
+
+ /**
+ * Returns true if this container may be scaled without resizing, and windows within may need
+ * to be configured as such.
+ */
+ public boolean windowsAreScaleable() {
+ return mWindowingMode == WINDOWING_MODE_PINNED;
+ }
+
+ /**
+ * Returns true if windows in this container should be given move animations by default.
+ */
+ public boolean hasMovementAnimations() {
+ return mWindowingMode == WINDOWING_MODE_PINNED;
+ }
+
private static String windowingModeToString(@WindowingMode int windowingMode) {
switch (windowingMode) {
case WINDOWING_MODE_UNDEFINED: return "undefined";
import android.annotation.Nullable;
import android.annotation.StyleRes;
import android.annotation.SystemApi;
+import android.app.WindowConfiguration;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
public interface WindowControllerCallback {
/**
* Moves the activity from
- * {@link android.app.ActivityManager.StackId#FREEFORM_WORKSPACE_STACK_ID} to
- * {@link android.app.ActivityManager.StackId#FULLSCREEN_WORKSPACE_STACK_ID} stack.
+ * Moves the activity from {@link WindowConfiguration#WINDOWING_MODE_FREEFORM} windowing
+ * mode to {@link WindowConfiguration#WINDOWING_MODE_FULLSCREEN}.
*/
void exitFreeformMode() throws RemoteException;
*/
void enterPictureInPictureModeIfPossible();
- /** Returns the current stack Id for the window. */
- int getWindowStackId() throws RemoteException;
-
/** Returns whether the window belongs to the task root. */
boolean isTaskRoot();
}
package com.android.internal.policy;
+import android.app.WindowConfiguration;
import android.graphics.Outline;
import android.view.ViewOutlineProvider;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.PopupWindow;
-import static android.app.ActivityManager.StackId;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.N;
// If the window type does not require such a view, this member might be null.
DecorCaptionView mDecorCaptionView;
- // Stack window is currently in. Since querying and changing the stack is expensive,
- // this is the stack value the window is currently set up for.
- int mStackId;
-
private boolean mWindowResizeCallbacksAdded = false;
private Drawable.Callback mLastBackgroundDrawableCb = null;
private BackdropFrameRenderer mBackdropFrameRenderer = null;
invalidate();
int opacity = PixelFormat.OPAQUE;
- if (StackId.hasWindowShadow(mStackId)) {
+ final WindowConfiguration winConfig = getResources().getConfiguration().windowConfiguration;
+ if (winConfig.hasWindowShadow()) {
// If the window has a shadow, it must be translucent.
opacity = PixelFormat.TRANSLUCENT;
} else{
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- int workspaceId = getStackId();
- if (mStackId != workspaceId) {
- mStackId = workspaceId;
- if (mDecorCaptionView == null && StackId.hasWindowDecor(mStackId)) {
- // Configuration now requires a caption.
- final LayoutInflater inflater = mWindow.getLayoutInflater();
- mDecorCaptionView = createDecorCaptionView(inflater);
- if (mDecorCaptionView != null) {
- if (mDecorCaptionView.getParent() == null) {
- addView(mDecorCaptionView, 0,
- new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
- }
- removeView(mContentRoot);
- mDecorCaptionView.addView(mContentRoot,
- new ViewGroup.MarginLayoutParams(MATCH_PARENT, MATCH_PARENT));
+
+ final boolean displayWindowDecor =
+ newConfig.windowConfiguration.hasWindowDecorCaption();
+ if (mDecorCaptionView == null && displayWindowDecor) {
+ // Configuration now requires a caption.
+ final LayoutInflater inflater = mWindow.getLayoutInflater();
+ mDecorCaptionView = createDecorCaptionView(inflater);
+ if (mDecorCaptionView != null) {
+ if (mDecorCaptionView.getParent() == null) {
+ addView(mDecorCaptionView, 0,
+ new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
- } else if (mDecorCaptionView != null) {
- // We might have to change the kind of surface before we do anything else.
- mDecorCaptionView.onConfigurationChanged(StackId.hasWindowDecor(mStackId));
- enableCaption(StackId.hasWindowDecor(workspaceId));
+ removeView(mContentRoot);
+ mDecorCaptionView.addView(mContentRoot,
+ new ViewGroup.MarginLayoutParams(MATCH_PARENT, MATCH_PARENT));
}
+ } else if (mDecorCaptionView != null) {
+ // We might have to change the kind of surface before we do anything else.
+ mDecorCaptionView.onConfigurationChanged(displayWindowDecor);
+ enableCaption(displayWindowDecor);
}
+
updateAvailableWidth();
initializeElevation();
}
void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
- mStackId = getStackId();
-
if (mBackdropFrameRenderer != null) {
loadBackgroundDrawablesIfNeeded();
mBackdropFrameRenderer.onResourcesLoaded(
final WindowManager.LayoutParams attrs = mWindow.getAttributes();
final boolean isApplication = attrs.type == TYPE_BASE_APPLICATION ||
attrs.type == TYPE_APPLICATION || attrs.type == TYPE_DRAWN_APPLICATION;
+ final WindowConfiguration winConfig = getResources().getConfiguration().windowConfiguration;
// Only a non floating application window on one of the allowed workspaces can get a caption
- if (!mWindow.isFloating() && isApplication && StackId.hasWindowDecor(mStackId)) {
+ if (!mWindow.isFloating() && isApplication && winConfig.hasWindowDecorCaption()) {
// Dependent on the brightness of the used title we either use the
// dark or the light button frame.
if (decorCaptionView == null) {
return drawable;
}
- /**
- * Returns the Id of the stack which contains this window.
- * Note that if no stack can be determined - which usually means that it was not
- * created for an activity - the fullscreen stack ID will be returned.
- * @return Returns the stack id which contains this window.
- **/
- private int getStackId() {
- int workspaceId = INVALID_STACK_ID;
- final Window.WindowControllerCallback callback = mWindow.getWindowControllerCallback();
- if (callback != null) {
- try {
- workspaceId = callback.getWindowStackId();
- } catch (RemoteException ex) {
- Log.e(mLogTag, "Failed to get the workspace ID of a PhoneWindow.");
- }
- }
- if (workspaceId == INVALID_STACK_ID) {
- return FULLSCREEN_WORKSPACE_STACK_ID;
- }
- return workspaceId;
- }
-
void clearContentView() {
if (mDecorCaptionView != null) {
mDecorCaptionView.removeContentView();
final boolean wasAdjustedForStack = mElevationAdjustedForStack;
// Do not use a shadow when we are in resizing mode (mBackdropFrameRenderer not null)
// since the shadow is bound to the content size and not the target size.
- if ((mStackId == FREEFORM_WORKSPACE_STACK_ID) && !isResizing()) {
+ final int windowingMode =
+ getResources().getConfiguration().windowConfiguration.getWindowingMode();
+ if ((windowingMode == WINDOWING_MODE_FREEFORM) && !isResizing()) {
elevation = hasWindowFocus() ?
DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
// Add a maximum shadow height value to the top level view.
// Convert the DP elevation into physical pixels.
elevation = dipToPx(elevation);
mElevationAdjustedForStack = true;
- } else if (mStackId == PINNED_STACK_ID) {
+ } else if (windowingMode == WINDOWING_MODE_PINNED) {
elevation = dipToPx(DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP);
mElevationAdjustedForStack = true;
} else {
// that task to freeform
// - otherwise the task is not moved
int stackId = task.getStackId();
- if (!StackId.isTaskResizeAllowed(stackId)) {
+ if (!task.getWindowConfiguration().canResizeTask()) {
throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
}
if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
}
@Override
- public int getActivityStackId(IBinder token) throws RemoteException {
- synchronized (this) {
- ActivityStack stack = ActivityRecord.getStackLocked(token);
- if (stack == null) {
- return INVALID_STACK_ID;
- }
- return stack.mStackId;
- }
- }
-
- @Override
public void exitFreeformMode(IBinder token) throws RemoteException {
synchronized (this) {
long ident = Binder.clearCallingIdentity();
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.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.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
+import static android.app.WindowConfiguration.WINDOWING_MODE_DOCKED;
+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 com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_BIND_APPLICATION_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CALLING_PACKAGE_NAME;
}
mWindowState = WINDOW_STATE_INVALID;
stack = mSupervisor.getFocusedStack();
- if (stack.mStackId == PINNED_STACK_ID) {
+ int windowingMode = stack.getWindowingMode();
+ if (windowingMode == WINDOWING_MODE_PINNED) {
stack = mSupervisor.findStackBehind(stack);
+ windowingMode = stack.getWindowingMode();
}
if (StackId.isHomeOrRecentsStack(stack.mStackId)
- || stack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
+ || windowingMode == WINDOWING_MODE_FULLSCREEN) {
mWindowState = WINDOW_STATE_STANDARD;
- } else if (stack.mStackId == DOCKED_STACK_ID) {
+ } else if (windowingMode == WINDOWING_MODE_DOCKED) {
Slog.wtf(TAG, "Docked stack shouldn't be the focused stack, because it reported not"
+ " being visible.");
mWindowState = WINDOW_STATE_INVALID;
- } else if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
+ } else if (windowingMode == WINDOWING_MODE_FREEFORM) {
mWindowState = WINDOW_STATE_FREEFORM;
} else if (stack.mStackId == ASSISTANT_STACK_ID) {
mWindowState = WINDOW_STATE_ASSISTANT;
return mActivityType == ASSISTANT_ACTIVITY_TYPE;
}
- boolean isApplicationActivity() {
- return mActivityType == APPLICATION_ACTIVITY_TYPE;
- }
-
boolean isPersistable() {
return (info.persistableMode == PERSIST_ROOT_ONLY ||
info.persistableMode == PERSIST_ACROSS_REBOOTS) &&
- (intent == null ||
- (intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
+ (intent == null || (intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
}
boolean isFocusable() {
- return StackId.canReceiveKeys(task.getStackId()) || isAlwaysFocusable();
+ return getWindowConfiguration().canReceiveKeys() || isAlwaysFocusable();
}
boolean isResizeable() {
// We must base this on the parent configuration, because we set our override
// configuration's appBounds based on the result of this method. If we used our own
// configuration, it would be influenced by past invocations.
- final Rect appBounds = getParent().getConfiguration().windowConfiguration.getAppBounds();
+ final Rect appBounds = getParent().getWindowConfiguration().getAppBounds();
final int containingAppWidth = appBounds.width();
final int containingAppHeight = appBounds.height();
int maxActivityWidth = containingAppWidth;
int addIndex = mStacks.size();
if (addIndex > 0) {
final ActivityStack topStack = mStacks.get(addIndex - 1);
- if (StackId.isAlwaysOnTop(topStack.mStackId) && topStack != this) {
+ if (topStack.getWindowConfiguration().isAlwaysOnTop()
+ && topStack != this) {
// If the top stack is always on top, we move this stack just below it.
addIndex--;
}
}
boolean isFocusable() {
- if (StackId.canReceiveKeys(mStackId)) {
+ if (getWindowConfiguration().canReceiveKeys()) {
return true;
}
// The stack isn't focusable. See if its top activity is focusable to force focus on the
}
final int stackBehindTopId = (stackBehindTopIndex >= 0)
? mStacks.get(stackBehindTopIndex).mStackId : INVALID_STACK_ID;
- if (topStackId == DOCKED_STACK_ID || StackId.isAlwaysOnTop(topStackId)) {
+ final boolean alwaysOnTop = topStack.getWindowConfiguration().isAlwaysOnTop();
+ if (topStackId == DOCKED_STACK_ID || alwaysOnTop) {
if (stackIndex == stackBehindTopIndex) {
// Stacks directly behind the docked or pinned stack are always visible.
return STACK_VISIBLE;
- } else if (StackId.isAlwaysOnTop(topStackId) && stackIndex == stackBehindTopIndex - 1) {
+ } 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) {
return;
}
- if (!allowResizeInDockedMode && !StackId.tasksAreFloating(stackId) &&
- getStack(DOCKED_STACK_ID) != null) {
+ if (!allowResizeInDockedMode
+ && !stack.getWindowConfiguration().tasksAreFloating()
+ && getStack(DOCKED_STACK_ID) != null) {
// If the docked stack exists, don't resize non-floating stacks independently of the
// size computed from the docked stack size (otherwise they will be out of sync)
return;
void removeWindowContainer() {
mService.mStackSupervisor.removeLockedTaskLocked(this);
mWindowContainerController.removeContainer();
- if (!StackId.persistTaskBounds(getStackId())) {
+ if (!getWindowConfiguration().persistTaskBounds()) {
// Reset current bounds for task whose bounds shouldn't be persisted so it uses
// default configuration the next time it launches.
updateOverrideConfiguration(null);
final Configuration newConfig = getOverrideConfiguration();
mFullscreen = bounds == null;
+ final boolean persistBounds = getWindowConfiguration().persistTaskBounds();
if (mFullscreen) {
- if (mBounds != null && StackId.persistTaskBounds(mStack.mStackId)) {
+ if (mBounds != null && persistBounds) {
mLastNonFullscreenBounds = mBounds;
}
mBounds = null;
} else {
mBounds.set(mTmpRect);
}
- if (mStack == null || StackId.persistTaskBounds(mStack.mStackId)) {
+ if (mStack == null || persistBounds) {
mLastNonFullscreenBounds = mBounds;
}
computeOverrideConfiguration(newConfig, mTmpRect, insetBounds,
}
/** Returns the bounds that should be used to launch this task. */
- Rect getLaunchBounds() {
+ private Rect getLaunchBounds() {
if (mStack == null) {
return null;
}
|| stackId == FULLSCREEN_WORKSPACE_STACK_ID
|| (stackId == DOCKED_STACK_ID && !isResizeable())) {
return isResizeable() ? mStack.mBounds : null;
- } else if (!StackId.persistTaskBounds(stackId)) {
+ } else if (!getWindowConfiguration().persistTaskBounds()) {
return mStack.mBounds;
}
return mLastNonFullscreenBounds;
}
boolean windowsAreFocusable() {
- return StackId.canReceiveKeys(getTask().mStack.mStackId) || mAlwaysFocusable;
+ return getWindowConfiguration().canReceiveKeys() || mAlwaysFocusable;
}
AppWindowContainerController getController() {
}
}
+ public WindowConfiguration getWindowConfiguration() {
+ return mFullConfiguration.windowConfiguration;
+ }
+
+ /** Returns the windowing mode the configuration container is currently in. */
+ public int getWindowingMode() {
+ return mFullConfiguration.windowConfiguration.getWindowingMode();
+ }
+
/** Sets the windowing mode for the configuration container. */
void setWindowingMode(/*@WindowConfiguration.WindowingMode TODO: causes build error...why?*/
int windowingMode) {
mTmpTaskForResizePointSearchResult.reset();
for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
final TaskStack stack = mTaskStackContainers.get(stackNdx);
- if (!StackId.isTaskResizeAllowed(stack.mStackId)) {
+ if (!stack.getWindowConfiguration().canResizeTask()) {
return null;
}
@Override
void positionChildAt(int position, TaskStack child, boolean includingParents) {
- if (StackId.isAlwaysOnTop(child.mStackId) && position != POSITION_TOP) {
+ if (child.getWindowConfiguration().isAlwaysOnTop()
+ && position != POSITION_TOP) {
// This stack is always-on-top, override the default behavior.
Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + this + " to bottom");
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import android.app.ActivityManager.StackId;
+import android.app.WindowConfiguration;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Handler;
config.windowConfiguration.setAppBounds(!bounds.isEmpty() ? bounds : null);
boolean intersectParentBounds = false;
- if (StackId.tasksAreFloating(mStackId)) {
+ if (stack.getWindowConfiguration().tasksAreFloating()) {
// Floating tasks should not be resized to the screen's bounds.
if (mStackId == PINNED_STACK_ID && bounds.width() == mTmpDisplayBounds.width() &&
bounds.height() == displayInfo.logicalHeight)) {
// If the bounds are fullscreen, return the value of the fullscreen configuration
return displayContent.getConfiguration().smallestScreenWidthDp;
- } else if (StackId.tasksAreFloating(mStackId)) {
+ } else if (mContainer.getWindowConfiguration().tasksAreFloating()) {
// For floating tasks, calculate the smallest width from the bounds of the task
return (int) (Math.min(bounds.width(), bounds.height()) / density);
} else {
// Update task bounds if needed.
updateDisplayInfo(getDisplayContent());
- if (StackId.windowsAreScaleable(mStack.mStackId)) {
+ if (getWindowConfiguration().windowsAreScaleable()) {
// We force windows out of SCALING_MODE_FREEZE so that we can continue to animate them
// while a resize is pending.
forceWindowsScaleable(true /* force */);
// from its stack. The stack will take care of task rotation for the other case.
mTmpRect2.set(mBounds);
- if (!StackId.isTaskResizeAllowed(mStack.mStackId)) {
+ if (!getWindowConfiguration().canResizeTask()) {
setBounds(mTmpRect2, getOverrideConfiguration());
return;
}
* we will have a jump at the end.
*/
boolean isFloating() {
- return StackId.tasksAreFloating(mStack.mStackId)
+ return getWindowConfiguration().tasksAreFloating()
&& !mStack.isAnimatingBoundsToFullscreen() && !mPreserveNonFloatingState;
}
@Override
boolean fillsParent() {
- return mFillsParent || !StackId.isTaskResizeAllowed(mStack.mStackId);
+ return mFillsParent || !getWindowConfiguration().canResizeTask();
}
@Override
void findTaskForResizePoint(int x, int y, int delta,
DisplayContent.TaskForResizePointSearchResult results) {
- if (!StackId.isTaskResizeAllowed(mStackId)) {
+ if (!getWindowConfiguration().canResizeTask()) {
results.searchDone = true;
return;
}
return false;
}
- public boolean hasMovementAnimations() {
- return StackId.hasMovementAnimations(mStackId);
- }
-
public boolean isForceScaled() {
return mBoundsAnimating;
}
if (mToken.okToAnimate()
&& (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
&& !isDragResizing() && !adjustedForMinimizedDockOrIme
- && (task == null || getTask().mStack.hasMovementAnimations())
+ && getWindowConfiguration().hasMovementAnimations()
&& !mWinAnimator.mLastHidden) {
mWinAnimator.setMoveAnimation(left, top);
}
* because we want to preserve its location on screen to be re-activated later when the user
* interacts with it.
*/
- boolean shouldKeepVisibleDeadAppWindow() {
+ private boolean shouldKeepVisibleDeadAppWindow() {
if (!isWinVisibleLw() || mAppToken == null || mAppToken.isClientHidden()) {
// Not a visible app window or the app isn't dead.
return false;
return false;
}
- final TaskStack stack = getStack();
- return stack != null && StackId.keepVisibleDeadAppWindowOnScreen(stack.mStackId);
+ return getWindowConfiguration().keepVisibleDeadAppWindowOnScreen();
}
/** @return true if this window desires key events. */
// one or more frame to wrong offset. So here we send fullscreen backdrop if either
// isDragResizing() or isDragResizeChanged() is true.
boolean resizing = isDragResizing() || isDragResizeChanged();
- if (StackId.useWindowFrameForBackdrop(getStackId()) || !resizing) {
+ if (getWindowConfiguration().useWindowFrameForBackdrop() || !resizing) {
return frame;
}
final DisplayInfo displayInfo = getDisplayInfo();
import static com.android.server.wm.proto.WindowStateAnimatorProto.LAST_CLIP_RECT;
import static com.android.server.wm.proto.WindowStateAnimatorProto.SURFACE;
+import android.app.WindowConfiguration;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
final TaskStack stack = w.getTask().mStack;
stack.getDimBounds(finalClipRect);
- if (StackId.tasksAreFloating(stack.mStackId)) {
+ if (stack.getWindowConfiguration().tasksAreFloating()) {
w.expandForSurfaceInsets(finalClipRect);
}
transform.mapRect(finalCrop);
finalClipRect.top = (int)finalCrop.top;
finalClipRect.left = (int)finalCrop.left;
+ // TODO: Are the assignments below a mistake?
finalClipRect.right = (int)finalClipRect.right;
finalClipRect.bottom = (int)finalClipRect.bottom;
}
// We need to do some acrobatics with surface position, because their clip region is
// relative to the inside of the surface, but the stack bounds aren't.
- if (StackId.hasWindowShadow(stack.mStackId)
- && !StackId.isTaskResizeAllowed(stack.mStackId)) {
+ final WindowConfiguration winConfig = w.getWindowConfiguration();
+ if (winConfig.hasWindowShadow() && !winConfig.canResizeTask()) {
// The windows in this stack display drop shadows and the fill the entire stack
// area. Adjust the stack bounds we will use to cropping take into account the
// offsets we use to display the drop shadow so it doesn't get cropped.
* @return Returns true if the surface was successfully shown.
*/
private boolean showSurfaceRobustlyLocked() {
- final Task task = mWin.getTask();
- if (task != null && StackId.windowsAreScaleable(task.mStack.mStackId)) {
+ if (mWin.getWindowConfiguration().windowsAreScaleable()) {
mSurfaceController.forceScaleableInTransaction(true);
}