Merge "Allow stacks to hold tasks on various sizes."
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b2f068b..5974fcf 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1789,6 +1789,7 @@
public Rect bounds = new Rect();
public int[] taskIds;
public String[] taskNames;
+ public Rect[] taskBounds;
public int displayId;
@Override
@@ -1805,6 +1806,14 @@
dest.writeInt(bounds.bottom);
dest.writeIntArray(taskIds);
dest.writeStringArray(taskNames);
+ final int boundsCount = taskBounds == null ? 0 : taskBounds.length;
+ dest.writeInt(boundsCount);
+ for (int i = 0; i < boundsCount; i++) {
+ dest.writeInt(taskBounds[i].left);
+ dest.writeInt(taskBounds[i].top);
+ dest.writeInt(taskBounds[i].right);
+ dest.writeInt(taskBounds[i].bottom);
+ }
dest.writeInt(displayId);
}
@@ -1814,6 +1823,17 @@
source.readInt(), source.readInt(), source.readInt(), source.readInt());
taskIds = source.createIntArray();
taskNames = source.createStringArray();
+ final int boundsCount = source.readInt();
+ if (boundsCount > 0) {
+ taskBounds = new Rect[boundsCount];
+ for (int i = 0; i < boundsCount; i++) {
+ taskBounds[i] = new Rect();
+ taskBounds[i].set(
+ source.readInt(), source.readInt(), source.readInt(), source.readInt());
+ }
+ } else {
+ taskBounds = null;
+ }
displayId = source.readInt();
}
@@ -1844,7 +1864,11 @@
prefix = prefix + " ";
for (int i = 0; i < taskIds.length; ++i) {
sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]);
- sb.append(": "); sb.append(taskNames[i]); sb.append("\n");
+ sb.append(": "); sb.append(taskNames[i]);
+ if (taskBounds != null) {
+ sb.append(" bounds="); sb.append(taskBounds[i].toShortString());
+ }
+ sb.append("\n");
}
return sb.toString();
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index e83d635..facaee4 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -799,6 +799,14 @@
return true;
}
+ case SET_FOCUSED_TASK_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int taskId = data.readInt();
+ setFocusedStack(taskId);
+ reply.writeNoException();
+ return true;
+ }
+
case REGISTER_TASK_STACK_LISTENER_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -2429,6 +2437,15 @@
return true;
}
+ case GET_TASK_BOUNDS_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int taskId = data.readInt();
+ Rect r = getTaskBounds(taskId);
+ reply.writeNoException();
+ r.writeToParcel(reply, 0);
+ return true;
+ }
+
case GET_TASK_DESCRIPTION_ICON_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
String filename = data.readString();
@@ -3520,6 +3537,18 @@
return focusedStackId;
}
@Override
+ public void setFocusedTask(int taskId) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(taskId);
+ mRemote.transact(SET_FOCUSED_TASK_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+ @Override
public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException
{
Parcel data = Parcel.obtain();
@@ -5790,6 +5819,21 @@
}
@Override
+ public Rect getTaskBounds(int taskId) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(taskId);
+ mRemote.transact(GET_TASK_BOUNDS_TRANSACTION, data, reply, 0);
+ reply.readException();
+ Rect rect = Rect.CREATOR.createFromParcel(reply);
+ data.recycle();
+ reply.recycle();
+ return rect;
+ }
+
+ @Override
public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 55cf3462..c3e55f1 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -144,6 +144,7 @@
public boolean isInHomeStack(int taskId) throws RemoteException;
public void setFocusedStack(int stackId) throws RemoteException;
public int getFocusedStackId() throws RemoteException;
+ public void setFocusedTask(int taskId) throws RemoteException;
public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException;
public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
public ContentProviderHolder getContentProvider(IApplicationThread caller,
@@ -486,6 +487,7 @@
throws RemoteException;
public void setTaskResizeable(int taskId, boolean resizeable) throws RemoteException;
public void resizeTask(int taskId, Rect bounds) throws RemoteException;
+ public Rect getTaskBounds(int taskId) throws RemoteException;
public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException;
public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
@@ -752,7 +754,7 @@
int GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+127;
int SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+128;
int SWITCH_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+129;
- int ___AVAILABLE_1___ = IBinder.FIRST_CALL_TRANSACTION+130;
+ int SET_FOCUSED_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+130;
int REMOVE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+131;
int REGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+132;
int UNREGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+133;
@@ -804,7 +806,7 @@
int RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+180;
int GET_PERSISTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+181;
int APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+182;
- // Available
+ int GET_TASK_BOUNDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183;
int GET_ACTIVITY_DISPLAY_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184;
int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
int SET_PROCESS_MEMORY_TRIM_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+186;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 17db471..6e3a29d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -70,6 +70,7 @@
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsAppWidgetHost;
+import com.android.systemui.recents.RecentsConfiguration;
import java.io.IOException;
import java.util.ArrayList;
@@ -255,12 +256,16 @@
return false;
}
- /** Get the bounds of a stack / task. */
- public Rect getTaskBounds(int stackId) {
- ActivityManager.StackInfo info = getAllStackInfos().get(stackId);
- if (info != null)
- return info.bounds;
- return new Rect();
+ /** Get the bounds of a task. */
+ public Rect getTaskBounds(int taskId) {
+ if (mIam == null) return null;
+
+ try {
+ return mIam.getTaskBounds(taskId);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ return null;
}
/** Resize a given task. */
@@ -268,32 +273,17 @@
if (mIam == null) return;
try {
+ if (RecentsConfiguration.getInstance().multiStackEnabled) {
+ // In debug mode, we force all task to be resizeable regardless of the
+ // current app configuration.
+ mIam.setTaskResizeable(taskId, true);
+ }
mIam.resizeTask(taskId, bounds);
} catch (RemoteException e) {
e.printStackTrace();
}
}
- /** Returns the stack info for all stacks. */
- public SparseArray<ActivityManager.StackInfo> getAllStackInfos() {
- if (mIam == null) return new SparseArray<ActivityManager.StackInfo>();
-
- try {
- SparseArray<ActivityManager.StackInfo> stacks =
- new SparseArray<ActivityManager.StackInfo>();
- List<ActivityManager.StackInfo> infos = mIam.getAllStackInfos();
- int stackCount = infos.size();
- for (int i = 0; i < stackCount; i++) {
- ActivityManager.StackInfo info = infos.get(i);
- stacks.put(info.stackId, info);
- }
- return stacks;
- } catch (RemoteException e) {
- e.printStackTrace();
- return new SparseArray<ActivityManager.StackInfo>();
- }
- }
-
/** Returns the focused stack id. */
public int getFocusedStack() {
if (mIam == null) return -1;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index f40c58d..b8015c0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -172,19 +172,13 @@
}
// Initialize the stacks
- SparseArray<ActivityManager.StackInfo> stackInfos = mSystemServicesProxy.getAllStackInfos();
mStacks.clear();
int stackCount = stacksTasks.size();
for (int i = 0; i < stackCount; i++) {
int stackId = stacksTasks.keyAt(i);
- ActivityManager.StackInfo info = stackInfos.get(stackId);
ArrayList<Task> stackTasks = stacksTasks.valueAt(i);
TaskStack stack = new TaskStack(stackId);
- if (Constants.DebugFlags.App.EnableMultiStackToSingleStack) {
- stack.setBounds(displayBounds, displayBounds);
- } else {
- stack.setBounds(info.bounds, displayBounds);
- }
+ stack.setBounds(displayBounds, displayBounds);
stack.setTasks(stackTasks);
stack.createAffiliatedGroupings(mConfig);
mStacks.put(stackId, stack);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 6db4020..353bcbe 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -224,7 +224,7 @@
/** Updates the resize task bar button. */
void updateResizeTaskBarIcon(Task t) {
Rect display = mSsp.getWindowRect();
- Rect taskRect = mSsp.getTaskBounds(t.key.stackId);
+ Rect taskRect = mSsp.getTaskBounds(t.key.id);
int resId = R.drawable.star;
if (display.equals(taskRect) || taskRect.isEmpty()) {
resId = R.drawable.vector_drawable_place_fullscreen;
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index daf1751..13b3f8d 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -158,7 +158,7 @@
# Task removed with source explanation.
31003 wm_task_removed (TaskId|1|5),(Reason|3)
# Stack created.
-31004 wm_stack_created (StackId|1|5),(RelativeBoxId|1|5),(Position|1),(Weight|1|6)
+31004 wm_stack_created (StackId|1|5)
# Home stack moved to top (1) or bottom (0).
31005 wm_home_stack_moved (ToTop|1)
# Stack removed.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 755d7a0..266e3c7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2695,6 +2695,21 @@
}
}
+ @Override
+ public void setFocusedTask(int taskId) {
+ if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
+ synchronized (ActivityManagerService.this) {
+ TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task != null) {
+ ActivityRecord r = task.topRunningActivityLocked(null);
+ if (r != null) {
+ setFocusedActivityLocked(r, "setFocusedTask");
+ mStackSupervisor.resumeTopActivitiesLocked(task.stack, null, null);
+ }
+ }
+ }
+ }
+
/** Sets the task stack listener that gets callbacks when a task stack changes. */
@Override
public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
@@ -8575,6 +8590,27 @@
}
@Override
+ public Rect getTaskBounds(int taskId) {
+ enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+ "getTaskBounds()");
+ long ident = Binder.clearCallingIdentity();
+ Rect rect = new Rect();
+ try {
+ synchronized (this) {
+ TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task == null) {
+ Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
+ return rect;
+ }
+ mWindowManager.getTaskBounds(task.taskId, rect);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ return rect;
+ }
+
+ @Override
public Bitmap getTaskDescriptionIcon(String filename) {
if (!FileUtils.isValidExtFilename(filename)
|| !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 0957eb5..9b1044c 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -130,10 +130,10 @@
long pauseTime; // last time we started pausing the activity
long launchTickTime; // base time for launch tick messages
Configuration configuration; // configuration activity was last running in
- // Overridden configuration by the activity stack
- // WARNING: Reference points to {@link ActivityStack#mOverrideConfig}, so its internal state
+ // Overridden configuration by the activity task
+ // WARNING: Reference points to {@link TaskRecord#mOverrideConfig}, so its internal state
// should never be altered directly.
- Configuration stackConfigOverride;
+ Configuration taskConfigOverride;
CompatibilityInfo compat;// last used compatibility mode
ActivityRecord resultTo; // who started this entry, so will get our reply
final String resultWho; // additional identifier for use by resultTo.
@@ -212,7 +212,7 @@
pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
pw.print(prefix); pw.print("config="); pw.println(configuration);
- pw.print(prefix); pw.print("stackConfigOverride="); pw.println(stackConfigOverride);
+ pw.print(prefix); pw.print("taskConfigOverride="); pw.println(taskConfigOverride);
if (resultTo != null || resultWho != null) {
pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
pw.print(" resultWho="); pw.print(resultWho);
@@ -445,8 +445,7 @@
resolvedType = _resolvedType;
componentSpecified = _componentSpecified;
configuration = _configuration;
- stackConfigOverride = (container != null)
- ? container.mStack.mOverrideConfig : Configuration.EMPTY;
+ taskConfigOverride = Configuration.EMPTY;
resultTo = _resultTo;
resultWho = _resultWho;
requestCode = _reqCode;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 2b763ed..431b433 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -113,11 +113,11 @@
// How long we wait for the activity to tell us it has stopped before
// giving up. This is a good amount of time because we really need this
// from the application in order to get its saved state.
- static final int STOP_TIMEOUT = 10*1000;
+ static final int STOP_TIMEOUT = 10 * 1000;
// How long we wait until giving up on an activity telling us it has
// finished destroying itself.
- static final int DESTROY_TIMEOUT = 10*1000;
+ static final int DESTROY_TIMEOUT = 10 * 1000;
// How long until we reset a task when the user returns to it. Currently
// disabled.
@@ -125,7 +125,7 @@
// How long between activity launches that we consider safe to not warn
// the user about an unexpected activity being launched on top.
- static final long START_WARN_TIME = 5*1000;
+ static final long START_WARN_TIME = 5 * 1000;
// Set to false to disable the preview that is shown while a new activity
// is being started.
@@ -214,8 +214,7 @@
// Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
// background activity being drawn then the same call will be made with a true value.
ActivityRecord mTranslucentActivityWaiting = null;
- private ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent =
- new ArrayList<ActivityRecord>();
+ private ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent = new ArrayList<>();
/**
* Set when we know we are going to be calling updateConfiguration()
@@ -223,7 +222,7 @@
*/
boolean mConfigWillChange;
- // Whether or not this stack covers the entire screen; by default stacks are full screen
+ // Whether or not this stack covers the entire screen; by default stacks are fullscreen
boolean mFullscreen = true;
long mLaunchStartTime = 0;
@@ -241,11 +240,6 @@
/** Run all ActivityStacks through this */
final ActivityStackSupervisor mStackSupervisor;
- Configuration mOverrideConfig;
- /** True if the stack was forced to full screen because {@link TaskRecord#mResizeable} is false
- * and the stack was previously resized. */
- private boolean mForcedFullscreen = false;
-
static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
@@ -361,7 +355,6 @@
mStackId = activityContainer.mStackId;
mCurrentUser = mService.mCurrentUserId;
mRecentTasks = recentTasks;
- mOverrideConfig = Configuration.EMPTY;
}
boolean okToShowLocked(ActivityRecord r) {
@@ -1165,16 +1158,18 @@
final int numStacks = mStacks.size();
while (stackNdx < numStacks) {
- ActivityStack historyStack = mStacks.get(stackNdx);
+ final ActivityStack historyStack = mStacks.get(stackNdx);
tasks = historyStack.mTaskHistory;
final int numTasks = tasks.size();
while (taskNdx < numTasks) {
- activities = tasks.get(taskNdx).mActivities;
+ final TaskRecord currentTask = tasks.get(taskNdx);
+ activities = currentTask.mActivities;
final int numActivities = activities.size();
while (activityNdx < numActivities) {
final ActivityRecord activity = activities.get(activityNdx);
if (!activity.finishing) {
- return historyStack.mFullscreen && activity.fullscreen ? null : activity;
+ return historyStack.mFullscreen
+ && currentTask.mFullscreen && activity.fullscreen ? null : activity;
}
++activityNdx;
}
@@ -1222,16 +1217,18 @@
* wallpaper to be shown behind it.
*/
for (int i = mStacks.indexOf(this) + 1; i < mStacks.size(); i++) {
- ActivityStack stack = mStacks.get(i);
- // stack above isn't full screen, so, we assume we're still visible. at some point
- // we should look at the stack bounds to see if we're occluded even if the stack
- // isn't fullscreen
+ final ActivityStack stack = mStacks.get(i);
+ // stack above isn't fullscreen, so, we assume we're still visible.
if (!stack.mFullscreen) {
continue;
}
final ArrayList<TaskRecord> tasks = stack.getAllTasks();
for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = tasks.get(taskNdx);
+ // task above isn't fullscreen, so, we assume we're still visible.
+ if (!task.mFullscreen) {
+ continue;
+ }
final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
@@ -1285,6 +1282,10 @@
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
final ArrayList<ActivityRecord> activities = task.mActivities;
+ // Set to true if an activity in this task is fullscreen thereby hiding other
+ // activities in the same task. Initialized to the same value as behindFullscreen
+ // which represent if the entire task/stack is behind another fullscreen task/stack.
+ boolean behindFullscreenActivity = behindFullscreen;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
if (r.finishing) {
@@ -1296,7 +1297,7 @@
aboveTop = false;
// mLaunchingBehind: Activities launching behind are at the back of the task stack
// but must be drawn initially for the animation as though they were visible.
- if (!behindFullscreen || r.mLaunchTaskBehind) {
+ if (!behindFullscreenActivity || r.mLaunchTaskBehind) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
"Make visible? " + r + " finishing=" + r.finishing
+ " state=" + r.state);
@@ -1379,17 +1380,22 @@
configChanges |= r.configChangeFlags;
if (r.fullscreen) {
- // At this point, nothing else needs to be shown
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r);
- behindFullscreen = true;
+ // At this point, nothing else needs to be shown in this task.
+ behindFullscreenActivity = true;
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
+ + " behindFullscreen=" + behindFullscreen
+ + " behindFullscreenActivity=" + behindFullscreenActivity);
} else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r);
- behindFullscreen = true;
+ behindFullscreenActivity = true;
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r
+ + " behindFullscreen=" + behindFullscreen
+ + " behindFullscreenActivity=" + behindFullscreenActivity);
}
} else {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
- "Make invisible? " + r + " finishing=" + r.finishing
- + " state=" + r.state + " behindFullscreen=" + behindFullscreen);
+ "Make invisible? " + r + " finishing=" + r.finishing
+ + " state=" + r.state + " behindFullscreen=" + behindFullscreen
+ + " behindFullscreenActivity=" + behindFullscreenActivity);
// Now for any activities that aren't visible to the user, make
// sure they no longer are keeping the screen frozen.
if (r.visible) {
@@ -1436,6 +1442,9 @@
}
}
}
+ // Factoring if the previous task is fullscreen there by affecting the visibility of
+ // task behind it.
+ behindFullscreen |= task.mFullscreen;
}
if (mTranslucentActivityWaiting != null &&
@@ -3818,29 +3827,12 @@
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Ensuring correct configuration: " + r);
- // Make sure the current stack override configuration is supported by the top task
- // before continuing.
- final TaskRecord topTask = topTask();
- if (topTask != null && ((topTask.mResizeable && mForcedFullscreen)
- || (!topTask.mResizeable && !mFullscreen))) {
- final boolean prevFullscreen = mFullscreen;
- final Configuration newOverrideConfig =
- mWindowManager.forceStackToFullscreen(mStackId, !topTask.mResizeable);
- updateOverrideConfiguration(newOverrideConfig);
- mForcedFullscreen = !prevFullscreen && mFullscreen;
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Updated stack config to support task=" + topTask
- + " resizeable=" + topTask.mResizeable
- + " mForcedFullscreen=" + mForcedFullscreen
- + " prevFullscreen=" + prevFullscreen
- + " mFullscreen=" + mFullscreen);
- }
-
// Short circuit: if the two configurations are the exact same
// object (the common case), then there is nothing to do.
- Configuration newConfig = mService.mConfiguration;
+ final Configuration newConfig = mService.mConfiguration;
+ final Configuration taskConfig = r.task.mOverrideConfig;
if (r.configuration == newConfig
- && r.stackConfigOverride == mOverrideConfig
+ && r.taskConfigOverride == taskConfig
&& !r.forceNewConfig) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Configuration unchanged in " + r);
@@ -3858,30 +3850,30 @@
// Okay we now are going to make this activity have the new config.
// But then we need to figure out how it needs to deal with that.
final Configuration oldConfig = r.configuration;
- final Configuration oldStackOverride = r.stackConfigOverride;
+ final Configuration oldTaskOverride = r.taskConfigOverride;
r.configuration = newConfig;
- r.stackConfigOverride = mOverrideConfig;
+ r.taskConfigOverride = taskConfig;
// Determine what has changed. May be nothing, if this is a config
// that has come back from the app after going idle. In that case
// we just want to leave the official config object now in the
// activity and do nothing else.
- int stackChanges = oldStackOverride.diff(mOverrideConfig);
- if (stackChanges == 0) {
+ int taskChanges = oldTaskOverride.diff(taskConfig);
+ if (taskChanges == 0) {
// {@link Configuration#diff} doesn't catch changes from unset values.
// Check for changes we care about.
- if (oldStackOverride.orientation != mOverrideConfig.orientation) {
- stackChanges |= ActivityInfo.CONFIG_ORIENTATION;
+ if (oldTaskOverride.orientation != taskConfig.orientation) {
+ taskChanges |= ActivityInfo.CONFIG_ORIENTATION;
}
- if (oldStackOverride.screenHeightDp != mOverrideConfig.screenHeightDp
- || oldStackOverride.screenWidthDp != mOverrideConfig.screenWidthDp) {
- stackChanges |= ActivityInfo.CONFIG_SCREEN_SIZE;
+ if (oldTaskOverride.screenHeightDp != taskConfig.screenHeightDp
+ || oldTaskOverride.screenWidthDp != taskConfig.screenWidthDp) {
+ taskChanges |= ActivityInfo.CONFIG_SCREEN_SIZE;
}
- if (oldStackOverride.smallestScreenWidthDp != mOverrideConfig.smallestScreenWidthDp) {
- stackChanges |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+ if (oldTaskOverride.smallestScreenWidthDp != taskConfig.smallestScreenWidthDp) {
+ taskChanges |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
}
}
- final int changes = oldConfig.diff(newConfig) | stackChanges;
+ final int changes = oldConfig.diff(newConfig) | taskChanges;
if (changes == 0 && !r.forceNewConfig) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Configuration no differences in " + r);
@@ -3943,14 +3935,14 @@
}
// Default case: the activity can handle this new configuration, so hand it over.
- // NOTE: We only forward the stack override configuration as the system level configuration
+ // NOTE: We only forward the task override configuration as the system level configuration
// changes is always sent to all processes when they happen so it can just use whatever
// system level configuration it last got.
if (r.app != null && r.app.thread != null) {
try {
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending new config to " + r);
r.app.thread.scheduleActivityConfigurationChanged(
- r.appToken, new Configuration(mOverrideConfig));
+ r.appToken, new Configuration(taskConfig));
} catch (RemoteException e) {
// If process died, whatever.
}
@@ -3984,7 +3976,7 @@
r.forceNewConfig = false;
r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes,
!andResume, new Configuration(mService.mConfiguration),
- new Configuration(mOverrideConfig));
+ new Configuration(r.task.mOverrideConfig));
// Note: don't need to call pauseIfSleepingLocked() here, because
// the caller will only pass in 'andResume' if this activity is
// currently resumed, which implies we aren't sleeping.
@@ -4381,16 +4373,6 @@
+ " stackId=" + mStackId + ", " + mTaskHistory.size() + " tasks}";
}
- boolean updateOverrideConfiguration(Configuration newConfig) {
- Configuration oldConfig = mOverrideConfig;
- mOverrideConfig = (newConfig == null) ? Configuration.EMPTY : newConfig;
- // We override the configuration only when the stack's dimensions are different from
- // the display. In this manner, we know that if the override configuration is empty,
- // the stack is necessarily full screen.
- mFullscreen = Configuration.EMPTY.equals(mOverrideConfig);
- return !mOverrideConfig.equals(oldConfig);
- }
-
void onLockTaskPackagesUpdatedLocked() {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
mTaskHistory.get(taskNdx).setLockTaskAuth();
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index b1ac7ee..e7f28c5 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -99,6 +99,7 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
+import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;
@@ -1283,7 +1284,7 @@
app.forceProcessStateUpTo(mService.mTopProcessState);
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
- new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
+ new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
@@ -2871,9 +2872,54 @@
return;
}
- final Configuration overrideConfig = mWindowManager.resizeStack(stackId, bounds);
- if (stack.updateOverrideConfiguration(overrideConfig)) {
+ final IntArray changedTaskIds = new IntArray(stack.numTasks());
+ final List<Configuration> newTaskConfigs = new ArrayList<>(stack.numTasks());
+ stack.mFullscreen =
+ mWindowManager.resizeStack(stackId, bounds, changedTaskIds, newTaskConfigs);
+ for (int i = changedTaskIds.size() - 1; i >= 0; i--) {
+ final TaskRecord task = anyTaskForIdLocked(changedTaskIds.get(i), false);
+ if (task == null) {
+ Slog.wtf(TAG, "Task in WindowManager, but not in ActivityManager???");
+ continue;
+ }
+ task.updateOverrideConfiguration(newTaskConfigs.get(i));
+ }
+
+ if (r != null) {
+ final boolean updated = stack.ensureActivityConfigurationLocked(r, 0);
+ // And we need to make sure at this point that all other activities
+ // are made visible with the correct configuration.
+ ensureActivitiesVisibleLocked(r, 0);
+ if (!updated) {
+ resumeTopActivitiesLocked(stack, null, null);
+ }
+ }
+ }
+
+ void resizeTaskLocked(TaskRecord task, Rect bounds) {
+ if (!task.mResizeable) {
+ Slog.w(TAG, "resizeTask: task " + task + " not resizeable.");
+ return;
+ }
+
+ if (task.mBounds != null && task.mBounds.equals(bounds)) {
+ // Nothing to do here...
+ return;
+ }
+
+ task.mBounds = new Rect(bounds);
+
+ if (!mWindowManager.isValidTaskId(task.taskId)) {
+ // Task doesn't exist in window manager yet (e.g. was restored from recents).
+ // No need to do anything else until we add the task to window manager.
+ return;
+ }
+
+ final Configuration overrideConfig = mWindowManager.resizeTask(task.taskId, bounds);
+ if (task.updateOverrideConfiguration(overrideConfig)) {
+ ActivityRecord r = task.topRunningActivityLocked(null);
if (r != null) {
+ final ActivityStack stack = task.stack;
final boolean updated = stack.ensureActivityConfigurationLocked(r, 0);
// And we need to make sure at this point that all other activities
// are made visible with the correct configuration.
@@ -2885,48 +2931,6 @@
}
}
- /** Makes sure the input task is in a stack with the specified bounds by either resizing the
- * current task stack if it only has one entry, moving the task to a stack that matches the
- * bounds, or creating a new stack with the required bounds. Also, makes the task resizeable.*/
- void resizeTaskLocked(TaskRecord task, Rect bounds) {
- task.mResizeable = true;
- final ActivityStack currentStack = task.stack;
- if (currentStack.isHomeStack()) {
- // Can't move task off the home stack. Sorry!
- return;
- }
-
- final int matchingStackId = mWindowManager.getStackIdWithBounds(bounds);
- if (matchingStackId != -1) {
- // There is already a stack with the right bounds!
- if (currentStack != null && currentStack.mStackId == matchingStackId) {
- // Nothing to do here. Already in the right stack...
- return;
- }
- // Move task to stack with matching bounds.
- moveTaskToStackLocked(task.taskId, matchingStackId, true);
- return;
- }
-
- if (currentStack != null && currentStack.numTasks() == 1) {
- // Just resize the current stack since this is the task in it.
- resizeStackLocked(currentStack.mStackId, bounds);
- return;
- }
-
- // Create new stack and move the task to it.
- final int displayId = (currentStack != null && currentStack.mDisplayId != -1)
- ? currentStack.mDisplayId : Display.DEFAULT_DISPLAY;
- ActivityStack newStack = createStackOnDisplay(getNextStackId(), displayId);
-
- if (newStack == null) {
- Slog.e(TAG, "resizeTaskLocked: Can't create stack for task=" + task);
- return;
- }
- moveTaskToStackLocked(task.taskId, newStack.mStackId, true);
- resizeStackLocked(newStack.mStackId, bounds);
- }
-
ActivityStack createStackOnDisplay(int stackId, int displayId) {
ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
if (activityDisplay == null) {
@@ -2962,7 +2966,7 @@
final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack tmpStack = homeDisplayStacks.get(stackNdx);
- if (!tmpStack.isHomeStack() && tmpStack.mFullscreen) {
+ if (!tmpStack.isHomeStack()) {
stack = tmpStack;
break;
}
@@ -3789,6 +3793,7 @@
final int numTasks = tasks.size();
int[] taskIds = new int[numTasks];
String[] taskNames = new String[numTasks];
+ Rect[] taskBounds = new Rect[numTasks];
for (int i = 0; i < numTasks; ++i) {
final TaskRecord task = tasks.get(i);
taskIds[i] = task.taskId;
@@ -3796,6 +3801,8 @@
: task.realActivity != null ? task.realActivity.flattenToString()
: task.getTopActivity() != null ? task.getTopActivity().packageName
: "unknown";
+ taskBounds[i] = new Rect();
+ mWindowManager.getTaskBounds(task.taskId, taskBounds[i]);
}
info.taskIds = taskIds;
info.taskNames = taskNames;
@@ -3811,7 +3818,7 @@
}
ArrayList<StackInfo> getAllStackInfosLocked() {
- ArrayList<StackInfo> list = new ArrayList<StackInfo>();
+ ArrayList<StackInfo> list = new ArrayList<>();
for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 7e2ad29..a892c7d 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -40,7 +40,9 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.graphics.Rect;
import android.os.Debug;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -92,6 +94,7 @@
private static final String ATTR_CALLING_PACKAGE = "calling_package";
private static final String ATTR_RESIZEABLE = "resizeable";
private static final String ATTR_PRIVILEGED = "privileged";
+ private static final String ATTR_BOUNDS = "bounds";
private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
@@ -199,6 +202,14 @@
final ActivityManagerService mService;
+ // Whether or not this task covers the entire screen; by default tasks are fullscreen.
+ boolean mFullscreen = true;
+
+ // Bounds of the Task. null for fullscreen tasks.
+ Rect mBounds = null;
+
+ Configuration mOverrideConfig = Configuration.EMPTY;
+
TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
mService = service;
@@ -252,7 +263,8 @@
long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
- int callingUid, String callingPackage, boolean resizeable, boolean privileged) {
+ int callingUid, String callingPackage, boolean resizeable, boolean privileged,
+ Rect bounds) {
mService = service;
mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
TaskPersister.IMAGE_EXTENSION;
@@ -289,6 +301,7 @@
mCallingPackage = callingPackage;
mResizeable = resizeable;
mPrivileged = privileged;
+ mBounds = bounds;
}
void touchActiveTime() {
@@ -950,6 +963,9 @@
out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
out.attribute(null, ATTR_RESIZEABLE, String.valueOf(mResizeable));
out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
+ if (mBounds != null) {
+ out.attribute(null, ATTR_BOUNDS, mBounds.flattenToString());
+ }
if (affinityIntent != null) {
out.startTag(null, TAG_AFFINITYINTENT);
@@ -1010,6 +1026,7 @@
String callingPackage = "";
boolean resizeable = false;
boolean privileged = false;
+ Rect bounds = null;
for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
final String attrName = in.getAttributeName(attrNdx);
@@ -1067,6 +1084,8 @@
resizeable = Boolean.valueOf(attrValue);
} else if (ATTR_PRIVILEGED.equals(attrName)) {
privileged = Boolean.valueOf(attrValue);
+ } else if (ATTR_BOUNDS.equals(attrName)) {
+ bounds = Rect.unflattenFromString(attrValue);
} else {
Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
}
@@ -1126,7 +1145,7 @@
autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
- callingUid, callingPackage, resizeable, privileged);
+ callingUid, callingPackage, resizeable, privileged, bounds);
for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
activities.get(activityNdx).task = task;
@@ -1136,6 +1155,16 @@
return task;
}
+ boolean updateOverrideConfiguration(Configuration newConfig) {
+ Configuration oldConfig = mOverrideConfig;
+ mOverrideConfig = (newConfig == null) ? Configuration.EMPTY : newConfig;
+ // We override the configuration only when the task's dimensions are different from the
+ // display. In this manner, we know that if the override configuration is empty, the task
+ // is necessarily fullscreen.
+ mFullscreen = Configuration.EMPTY.equals(mOverrideConfig);
+ return !mOverrideConfig.equals(oldConfig);
+ }
+
void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("userId="); pw.print(userId);
pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index e385be3..538d6b84 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -29,9 +29,6 @@
private static final String TAG = "DimLayer";
private static final boolean DEBUG = false;
- /** Reference to the owner of this object. */
- final DisplayContent mDisplayContent;
-
/** Actual surface that dims */
SurfaceControl mDimSurface;
@@ -62,13 +59,18 @@
/** Time in milliseconds to take to transition from mStartAlpha to mTargetAlpha */
long mDuration;
- /** Owning stack */
- final TaskStack mStack;
+ /** Interface implemented by users of the dim layer */
+ interface DimLayerUser {
+ /** Returns true if the user of the dim layer is fullscreen. */
+ boolean isFullscreen();
+ /** Returns the display info. of the dim layer user. */
+ DisplayInfo getDisplayInfo();
+ }
+ /** The user of this dim layer. */
+ final DimLayerUser mUser;
- DimLayer(WindowManagerService service, TaskStack stack, DisplayContent displayContent) {
- mStack = stack;
- mDisplayContent = displayContent;
- final int displayId = mDisplayContent.getDisplayId();
+ DimLayer(WindowManagerService service, DimLayerUser user, int displayId) {
+ mUser = user;
if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId);
SurfaceControl.openTransaction();
try {
@@ -145,14 +147,14 @@
private void adjustBounds() {
final int dw, dh;
final float xPos, yPos;
- if (!mStack.isFullscreen()) {
+ if (!mUser.isFullscreen()) {
dw = mBounds.width();
dh = mBounds.height();
xPos = mBounds.left;
yPos = mBounds.top;
} else {
// Set surface size to screen size.
- final DisplayInfo info = mDisplayContent.getDisplayInfo();
+ final DisplayInfo info = mUser.getDisplayInfo();
// Multiply by 1.5 so that rotating a frozen surface that includes this does not expose
// a corner.
dw = (int) (info.logicalWidth * 1.5);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 5d6df26..d9786c8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -89,8 +89,8 @@
* (except a future lockscreen TaskStack) moves to the top. */
private TaskStack mHomeStack = null;
- /** Detect user tapping outside of current focused stack bounds .*/
- StackTapPointerEventListener mTapDetector;
+ /** Detect user tapping outside of current focused task bounds .*/
+ TaskTapPointerEventListener mTapDetector;
/** Detect user tapping outside of current focused stack bounds .*/
Region mTouchExcludeRegion = new Region();
@@ -219,24 +219,27 @@
mContentRect.set(contentRect);
}
- int stackIdFromPoint(int x, int y) {
+ int taskIdFromPoint(int x, int y) {
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final TaskStack stack = mStacks.get(stackNdx);
- stack.getBounds(mTmpRect);
- if (mTmpRect.contains(x, y)) {
- return stack.mStackId;
+ final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ final Task task = tasks.get(taskNdx);
+ task.getBounds(mTmpRect);
+ if (mTmpRect.contains(x, y)) {
+ return task.mTaskId;
+ }
}
}
return -1;
}
- void setTouchExcludeRegion(TaskStack focusedStack) {
+ void setTouchExcludeRegion(Task focusedTask) {
mTouchExcludeRegion.set(mBaseDisplayRect);
WindowList windows = getWindowList();
for (int i = windows.size() - 1; i >= 0; --i) {
final WindowState win = windows.get(i);
- final TaskStack stack = win.getStack();
- if (win.isVisibleLw() && stack != null && stack != focusedStack) {
+ final Task task = win.getTask();
+ if (win.isVisibleLw() && task != null && task != focusedTask) {
mTmpRect.set(win.mVisibleFrame);
// If no intersection, we need mTmpRect to be unmodified.
mTmpRect.intersect(win.mVisibleInsets);
@@ -273,21 +276,37 @@
boolean animateDimLayers() {
boolean result = false;
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- result |= mStacks.get(stackNdx).animateDimLayers();
+ final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ final Task task = tasks.get(taskNdx);
+ result |= task.animateDimLayers();
+ if (task.isFullscreen()) {
+ // No point in continuing as this task covers the entire screen.
+ // Also, fullscreen tasks all share the same dim layer, so we don't want
+ // processing of fullscreen task below this one affecting the dim layer state.
+ return result;
+ }
+ }
}
return result;
}
void resetDimming() {
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- mStacks.get(stackNdx).resetDimmingTag();
+ final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ tasks.get(taskNdx).clearContinueDimming();
+ }
}
}
boolean isDimming() {
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- if (mStacks.get(stackNdx).isDimming()) {
- return true;
+ final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ if (tasks.get(taskNdx).isDimming()) {
+ return true;
+ }
}
}
return false;
@@ -295,7 +314,10 @@
void stopDimmingIfNeeded() {
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- mStacks.get(stackNdx).stopDimmingIfNeeded();
+ final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ tasks.get(taskNdx).stopDimmingIfNeeded();
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 1a125d4..222945c 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -413,7 +413,7 @@
continue;
}
- child.getStackBounds(mTmpRect);
+ child.getTaskBounds(mTmpRect);
if (!mTmpRect.contains(x, y)) {
// outside of this window's activity stack == don't tell about drags
continue;
diff --git a/services/core/java/com/android/server/wm/FocusedStackFrame.java b/services/core/java/com/android/server/wm/FocusedTaskFrame.java
similarity index 91%
rename from services/core/java/com/android/server/wm/FocusedStackFrame.java
rename to services/core/java/com/android/server/wm/FocusedTaskFrame.java
index 826fe97..d8e1095 100644
--- a/services/core/java/com/android/server/wm/FocusedStackFrame.java
+++ b/services/core/java/com/android/server/wm/FocusedTaskFrame.java
@@ -33,8 +33,8 @@
import com.android.server.wm.WindowStateAnimator.SurfaceTrace;
-class FocusedStackFrame {
- private static final String TAG = "FocusedStackFrame";
+class FocusedTaskFrame {
+ private static final String TAG = "FocusedTaskFrame";
private static final boolean DEBUG = false;
private static final int THICKNESS = 2;
private static final float ALPHA = 0.3f;
@@ -47,14 +47,14 @@
private final Rect mLastBounds = new Rect();
private int mLayer = -1;
- public FocusedStackFrame(Display display, SurfaceSession session) {
+ public FocusedTaskFrame(Display display, SurfaceSession session) {
SurfaceControl ctrl = null;
try {
if (DEBUG_SURFACE_TRACE) {
- ctrl = new SurfaceTrace(session, "FocusedStackFrame",
+ ctrl = new SurfaceTrace(session, "FocusedTaskFrame",
1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
} else {
- ctrl = new SurfaceControl(session, "FocusedStackFrame",
+ ctrl = new SurfaceControl(session, "FocusedTaskFrame",
1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
}
ctrl.setLayerStack(display.getLayerStack());
@@ -122,11 +122,11 @@
}
}
- void setVisibility(TaskStack stack) {
- if (stack == null || stack.isFullscreen()) {
+ void setVisibility(Task task) {
+ if (task == null || task.isFullscreen()) {
setupSurface(false);
} else {
- stack.getBounds(mBounds);
+ task.getBounds(mBounds);
setupSurface(true);
if (!mBounds.equals(mLastBounds)) {
draw();
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index ae442e5..21e92c9 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -177,7 +177,7 @@
if (modal && child.mAppToken != null) {
// Limit the outer touch to the activity stack region.
flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- child.getStackBounds(mTmpRect);
+ child.getTaskBounds(mTmpRect);
inputWindowHandle.touchableRegion.set(mTmpRect);
} else {
// Not modal or full screen modal
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 0c3cf65..09d70d8 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -17,13 +17,29 @@
package com.android.server.wm;
import static com.android.server.wm.WindowManagerService.TAG;
+import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE;
import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.view.DisplayInfo;
+import android.view.Surface;
+
import com.android.server.EventLogTags;
-class Task {
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+class Task implements DimLayer.DimLayerUser {
+ /** Amount of time in milliseconds to animate the dim surface from one value to another,
+ * when no window animation is driving it. */
+ private static final int DEFAULT_DIM_DURATION = 200;
+
TaskStack mStack;
final AppTokenList mAppTokens = new AppTokenList();
final int mTaskId;
@@ -31,11 +47,41 @@
boolean mDeferRemoval = false;
final WindowManagerService mService;
+ // Content limits relative to the DisplayContent this sits in.
+ private Rect mBounds = new Rect();
+
+ // Device rotation as of the last time {@link #mBounds} was set.
+ int mRotation;
+
+ // Whether mBounds is fullscreen
+ private boolean mFullscreen = true;
+
+ // Contains configurations settings that are different from the global configuration due to
+ // stack specific operations. E.g. {@link #setBounds}.
+ Configuration mOverrideConfig;
+
+ // For comparison with DisplayContent bounds.
+ private Rect mTmpRect = new Rect();
+ // For handling display rotations.
+ private Rect mTmpRect2 = new Rect();
+
+ // The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer.
+ WindowStateAnimator mDimWinAnimator;
+ // Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND}
+ private DimLayer mDimLayer;
+ // Set to false at the start of performLayoutAndPlaceSurfaces. If it is still false by the end
+ // then stop any dimming.
+ private boolean mContinueDimming;
+ // Shared dim layer for fullscreen tasks. {@link #mDimLayer} will point to this instead
+ // of creating a new object per fullscreen task on a display.
+ private static final SparseArray<DimLayer> sSharedFullscreenDimLayers = new SparseArray<>();
+
Task(int taskId, TaskStack stack, int userId, WindowManagerService service) {
mTaskId = taskId;
mStack = stack;
mUserId = userId;
mService = service;
+ mOverrideConfig = Configuration.EMPTY;
}
DisplayContent getDisplayContent() {
@@ -107,13 +153,290 @@
}
}
+ /** Set the task bounds. Passing in null sets the bounds to fullscreen. */
+ boolean setBounds(Rect bounds) {
+ boolean oldFullscreen = mFullscreen;
+ int rotation = Surface.ROTATION_0;
+ final DisplayContent displayContent = mStack.getDisplayContent();
+ if (displayContent != null) {
+ displayContent.getLogicalDisplayRect(mTmpRect);
+ rotation = displayContent.getDisplayInfo().rotation;
+ if (bounds == null) {
+ bounds = mTmpRect;
+ mFullscreen = true;
+ } else {
+ // ensure bounds are entirely within the display rect
+ if (!bounds.intersect(mTmpRect)) {
+ // Can't set bounds outside the containing display...Sorry!
+ return false;
+ }
+ mFullscreen = mTmpRect.equals(bounds);
+ }
+ }
+
+ if (bounds == null) {
+ // Can't set to fullscreen if we don't have a display to get bounds from...
+ return false;
+ }
+ if (mBounds.equals(bounds) && oldFullscreen == mFullscreen && mRotation == rotation) {
+ return false;
+ }
+
+ mBounds.set(bounds);
+ mRotation = rotation;
+ updateDimLayer();
+ updateOverrideConfiguration();
+ return true;
+ }
+
+ void getBounds(Rect out) {
+ out.set(mBounds);
+ }
+
+ private void updateOverrideConfiguration() {
+ final Configuration serviceConfig = mService.mCurConfiguration;
+ if (mFullscreen) {
+ mOverrideConfig = Configuration.EMPTY;
+ return;
+ }
+
+ if (mOverrideConfig == Configuration.EMPTY) {
+ mOverrideConfig = new Configuration();
+ }
+
+ // TODO(multidisplay): Update Dp to that of display stack is on.
+ final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+ mOverrideConfig.screenWidthDp =
+ Math.min((int)(mBounds.width() / density), serviceConfig.screenWidthDp);
+ mOverrideConfig.screenHeightDp =
+ Math.min((int)(mBounds.height() / density), serviceConfig.screenHeightDp);
+ mOverrideConfig.smallestScreenWidthDp =
+ Math.min(mOverrideConfig.screenWidthDp, mOverrideConfig.screenHeightDp);
+ mOverrideConfig.orientation =
+ (mOverrideConfig.screenWidthDp <= mOverrideConfig.screenHeightDp)
+ ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
+ }
+
+ void updateDisplayInfo(final DisplayContent displayContent) {
+ if (displayContent == null) {
+ return;
+ }
+ if (mFullscreen) {
+ setBounds(null);
+ return;
+ }
+ final int newRotation = displayContent.getDisplayInfo().rotation;
+ if (mRotation == newRotation) {
+ return;
+ }
+
+ // Device rotation changed. We don't want the task to move around on the screen when
+ // this happens, so update the task bounds so it stays in the same place.
+ final int rotationDelta = DisplayContent.deltaRotation(mRotation, newRotation);
+ displayContent.getLogicalDisplayRect(mTmpRect);
+ switch (rotationDelta) {
+ case Surface.ROTATION_0:
+ mTmpRect2.set(mBounds);
+ break;
+ case Surface.ROTATION_90:
+ mTmpRect2.top = mTmpRect.bottom - mBounds.right;
+ mTmpRect2.left = mBounds.top;
+ mTmpRect2.right = mTmpRect2.left + mBounds.height();
+ mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
+ break;
+ case Surface.ROTATION_180:
+ mTmpRect2.top = mTmpRect.bottom - mBounds.bottom;
+ mTmpRect2.left = mTmpRect.right - mBounds.right;
+ mTmpRect2.right = mTmpRect2.left + mBounds.width();
+ mTmpRect2.bottom = mTmpRect2.top + mBounds.height();
+ break;
+ case Surface.ROTATION_270:
+ mTmpRect2.top = mBounds.left;
+ mTmpRect2.left = mTmpRect.right - mBounds.bottom;
+ mTmpRect2.right = mTmpRect2.left + mBounds.height();
+ mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
+ break;
+ }
+ setBounds(mTmpRect2);
+ }
+
+ /** Updates the dim layer bounds, recreating it if needed. */
+ private void updateDimLayer() {
+ DimLayer newDimLayer;
+ final boolean previousFullscreen =
+ mDimLayer != null && sSharedFullscreenDimLayers.indexOfValue(mDimLayer) > -1;
+ final int displayId = mStack.getDisplayContent().getDisplayId();
+ if (mFullscreen) {
+ if (previousFullscreen) {
+ // Nothing to do here...
+ return;
+ }
+ // Use shared fullscreen dim layer
+ newDimLayer = sSharedFullscreenDimLayers.get(displayId);
+ if (newDimLayer == null) {
+ if (mDimLayer != null) {
+ // Re-purpose the previous dim layer.
+ newDimLayer = mDimLayer;
+ } else {
+ // Create new full screen dim layer.
+ newDimLayer = new DimLayer(mService, this, displayId);
+ }
+ newDimLayer.setBounds(mBounds);
+ sSharedFullscreenDimLayers.put(displayId, newDimLayer);
+ } else if (mDimLayer != null) {
+ mDimLayer.destroySurface();
+ }
+ } else {
+ newDimLayer = (mDimLayer == null || previousFullscreen)
+ ? new DimLayer(mService, this, displayId) : mDimLayer;
+ newDimLayer.setBounds(mBounds);
+ }
+ mDimLayer = newDimLayer;
+ }
+
+ boolean animateDimLayers() {
+ final int dimLayer;
+ final float dimAmount;
+ if (mDimWinAnimator == null) {
+ dimLayer = mDimLayer.getLayer();
+ dimAmount = 0;
+ } else {
+ dimLayer = mDimWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM;
+ dimAmount = mDimWinAnimator.mWin.mAttrs.dimAmount;
+ }
+ final float targetAlpha = mDimLayer.getTargetAlpha();
+ if (targetAlpha != dimAmount) {
+ if (mDimWinAnimator == null) {
+ mDimLayer.hide(DEFAULT_DIM_DURATION);
+ } else {
+ long duration = (mDimWinAnimator.mAnimating && mDimWinAnimator.mAnimation != null)
+ ? mDimWinAnimator.mAnimation.computeDurationHint()
+ : DEFAULT_DIM_DURATION;
+ if (targetAlpha > dimAmount) {
+ duration = getDimBehindFadeDuration(duration);
+ }
+ mDimLayer.show(dimLayer, dimAmount, duration);
+ }
+ } else if (mDimLayer.getLayer() != dimLayer) {
+ mDimLayer.setLayer(dimLayer);
+ }
+ if (mDimLayer.isAnimating()) {
+ if (!mService.okToDisplay()) {
+ // Jump to the end of the animation.
+ mDimLayer.show();
+ } else {
+ return mDimLayer.stepAnimation();
+ }
+ }
+ return false;
+ }
+
+ private long getDimBehindFadeDuration(long duration) {
+ TypedValue tv = new TypedValue();
+ mService.mContext.getResources().getValue(
+ com.android.internal.R.fraction.config_dimBehindFadeDuration, tv, true);
+ if (tv.type == TypedValue.TYPE_FRACTION) {
+ duration = (long)tv.getFraction(duration, duration);
+ } else if (tv.type >= TypedValue.TYPE_FIRST_INT && tv.type <= TypedValue.TYPE_LAST_INT) {
+ duration = tv.data;
+ }
+ return duration;
+ }
+
+ void clearContinueDimming() {
+ mContinueDimming = false;
+ }
+
+ void setContinueDimming() {
+ mContinueDimming = true;
+ }
+
+ boolean getContinueDimming() {
+ return mContinueDimming;
+ }
+
+ boolean isDimming() {
+ return mDimLayer.isDimming();
+ }
+
+ boolean isDimming(WindowStateAnimator winAnimator) {
+ return mDimWinAnimator == winAnimator && isDimming();
+ }
+
+ void startDimmingIfNeeded(WindowStateAnimator newWinAnimator) {
+ // Only set dim params on the highest dimmed layer.
+ // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
+ if (newWinAnimator.mSurfaceShown && (mDimWinAnimator == null
+ || !mDimWinAnimator.mSurfaceShown
+ || mDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
+ mDimWinAnimator = newWinAnimator;
+ if (mDimWinAnimator.mWin.mAppToken == null
+ && !mFullscreen && mStack.getDisplayContent() != null) {
+ // Dim should cover the entire screen for system windows.
+ mStack.getDisplayContent().getLogicalDisplayRect(mTmpRect);
+ mDimLayer.setBounds(mTmpRect);
+ }
+ }
+ }
+
+ void stopDimmingIfNeeded() {
+ if (!mContinueDimming && isDimming()) {
+ mDimWinAnimator = null;
+ mDimLayer.setBounds(mBounds);
+ }
+ }
+
+ void close() {
+ if (mDimLayer != null) {
+ mDimLayer.destroySurface();
+ mDimLayer = null;
+ }
+ }
+
+ void resizeWindows() {
+ final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
+ for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
+ final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState win = windows.get(winNdx);
+ if (!resizingWindows.contains(win)) {
+ if (DEBUG_RESIZE) Slog.d(TAG, "setBounds: Resizing " + win);
+ resizingWindows.add(win);
+ }
+ }
+ }
+ }
+
boolean showForAllUsers() {
final int tokensCount = mAppTokens.size();
return (tokensCount != 0) && mAppTokens.get(tokensCount - 1).showForAllUsers;
}
@Override
+ public boolean isFullscreen() {
+ return mFullscreen;
+ }
+
+ @Override
+ public DisplayInfo getDisplayInfo() {
+ return mStack.getDisplayContent().getDisplayInfo();
+ }
+
+ @Override
public String toString() {
return "{taskId=" + mTaskId + " appTokens=" + mAppTokens + " mdr=" + mDeferRemoval + "}";
}
+
+ public void printTo(String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.print("taskId="); pw.print(mTaskId);
+ pw.print(prefix); pw.print("appTokens="); pw.print(mAppTokens);
+ pw.print(prefix); pw.print("mdr="); pw.println(mDeferRemoval);
+ if (mDimLayer.isDimming()) {
+ pw.print(prefix); pw.println("mDimLayer:");
+ mDimLayer.printTo(prefix + " ", pw);
+ pw.print(prefix); pw.print("mDimWinAnimator="); pw.println(mDimWinAnimator);
+ } else {
+ pw.println();
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 4545032..90a173a 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -22,22 +22,18 @@
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Debug;
-import android.util.DisplayMetrics;
import android.util.EventLog;
+import android.util.IntArray;
import android.util.Slog;
-import android.util.TypedValue;
-import android.view.Surface;
+import android.view.DisplayInfo;
import com.android.server.EventLogTags;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
-public class TaskStack {
- /** Amount of time in milliseconds to animate the dim surface from one value to another,
- * when no window animation is driving it. */
- private static final int DEFAULT_DIM_DURATION = 200;
-
+public class TaskStack implements DimLayer.DimLayerUser {
/** Unique identifier */
final int mStackId;
@@ -49,12 +45,10 @@
/** The Tasks that define this stack. Oldest Tasks are at the bottom. The ordering must match
* mTaskHistory in the ActivityStack with the same mStackId */
- private final ArrayList<Task> mTasks = new ArrayList<Task>();
+ private final ArrayList<Task> mTasks = new ArrayList<>();
/** For comparison with DisplayContent bounds. */
private Rect mTmpRect = new Rect();
- /** For handling display rotations. */
- private Rect mTmpRect2 = new Rect();
/** Content limits relative to the DisplayContent this sits in. */
private Rect mBounds = new Rect();
@@ -62,49 +56,22 @@
/** Whether mBounds is fullscreen */
private boolean mFullscreen = true;
- /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */
- private DimLayer mDimLayer;
-
- /** The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer. */
- WindowStateAnimator mDimWinAnimator;
-
/** Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()} */
DimLayer mAnimationBackgroundSurface;
/** The particular window with an Animation with non-zero background color. */
WindowStateAnimator mAnimationBackgroundAnimator;
- /** Set to false at the start of performLayoutAndPlaceSurfaces. If it is still false by the end
- * then stop any dimming. */
- boolean mDimmingTag;
-
/** Application tokens that are exiting, but still on screen for animations. */
final AppTokenList mExitingAppTokens = new AppTokenList();
/** Detach this stack from its display when animation completes. */
boolean mDeferDetach;
- // Contains configurations settings that are different from the global configuration due to
- // stack specific operations. E.g. {@link #setBounds}.
- Configuration mOverrideConfig;
- // True if the stack was forced to fullscreen disregarding the override configuration.
- private boolean mForceFullscreen;
- // The {@link #mBounds} before the stack was forced to fullscreen. Will be restored as the
- // stack bounds once the stack is no longer forced to fullscreen.
- final private Rect mPreForceFullscreenBounds;
-
- // Device rotation as of the last time {@link #mBounds} was set.
- int mRotation;
-
TaskStack(WindowManagerService service, int stackId) {
mService = service;
mStackId = stackId;
- mOverrideConfig = Configuration.EMPTY;
- mForceFullscreen = false;
- mPreForceFullscreenBounds = new Rect();
- // TODO: remove bounds from log, they are always 0.
- EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, mBounds.left, mBounds.top,
- mBounds.right, mBounds.bottom);
+ EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId);
}
DisplayContent getDisplayContent() {
@@ -116,30 +83,39 @@
}
void resizeWindows() {
- final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
- final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
- for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
- final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
- for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState win = windows.get(winNdx);
- if (!resizingWindows.contains(win)) {
- if (WindowManagerService.DEBUG_RESIZE) Slog.d(TAG,
- "setBounds: Resizing " + win);
- resizingWindows.add(win);
- }
- }
- }
+ mTasks.get(taskNdx).resizeWindows();
}
}
- /** Set the stack bounds. Passing in null sets the bounds to fullscreen. */
- boolean setBounds(Rect bounds) {
+ /**
+ * Set the bounds of the stack and its containing tasks.
+ * @param bounds New stack bounds. Passing in null sets the bounds to fullscreen.
+ * @param changedTaskIds Output list of Ids of tasks that changed in bounds.
+ * @param newTaskConfigs Output list of new Configuation of the tasks that changed.
+ * @return True if the stack bounds was changed.
+ * */
+ boolean setBounds(Rect bounds, IntArray changedTaskIds, List<Configuration> newTaskConfigs) {
+ if (!setBounds(bounds)) {
+ return false;
+ }
+
+ // Update bounds of containing tasks.
+ final Rect newBounds = mFullscreen ? null : mBounds;
+ for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ final Task task = mTasks.get(taskNdx);
+ if (task.setBounds(newBounds)) {
+ changedTaskIds.add(task.mTaskId);
+ newTaskConfigs.add(task.mOverrideConfig);
+ }
+ }
+ return true;
+ }
+
+ private boolean setBounds(Rect bounds) {
boolean oldFullscreen = mFullscreen;
- int rotation = Surface.ROTATION_0;
if (mDisplayContent != null) {
mDisplayContent.getLogicalDisplayRect(mTmpRect);
- rotation = mDisplayContent.getDisplayInfo().rotation;
if (bounds == null) {
bounds = mTmpRect;
mFullscreen = true;
@@ -157,15 +133,12 @@
// Can't set to fullscreen if we don't have a display to get bounds from...
return false;
}
- if (mBounds.equals(bounds) && oldFullscreen == mFullscreen && mRotation == rotation) {
+ if (mBounds.equals(bounds) && oldFullscreen == mFullscreen) {
return false;
}
- mDimLayer.setBounds(bounds);
mAnimationBackgroundSurface.setBounds(bounds);
mBounds.set(bounds);
- mRotation = rotation;
- updateOverrideConfiguration();
return true;
}
@@ -173,93 +146,13 @@
out.set(mBounds);
}
- private void updateOverrideConfiguration() {
- final Configuration serviceConfig = mService.mCurConfiguration;
- if (mFullscreen) {
- mOverrideConfig = Configuration.EMPTY;
- return;
- }
-
- if (mOverrideConfig == Configuration.EMPTY) {
- mOverrideConfig = new Configuration();
- }
-
- // TODO(multidisplay): Update Dp to that of display stack is on.
- final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
- mOverrideConfig.screenWidthDp =
- Math.min((int)(mBounds.width() / density), serviceConfig.screenWidthDp);
- mOverrideConfig.screenHeightDp =
- Math.min((int)(mBounds.height() / density), serviceConfig.screenHeightDp);
- mOverrideConfig.smallestScreenWidthDp =
- Math.min(mOverrideConfig.screenWidthDp, mOverrideConfig.screenHeightDp);
- mOverrideConfig.orientation =
- (mOverrideConfig.screenWidthDp <= mOverrideConfig.screenHeightDp)
- ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
- }
-
void updateDisplayInfo() {
- if (mFullscreen) {
- setBounds(null);
- } else if (mDisplayContent != null) {
- final int newRotation = mDisplayContent.getDisplayInfo().rotation;
- if (mRotation == newRotation) {
- return;
- }
-
- // Device rotation changed. We don't want the stack to move around on the screen when
- // this happens, so update the stack bounds so it stays in the same place.
- final int rotationDelta = DisplayContent.deltaRotation(mRotation, newRotation);
+ if (mDisplayContent != null) {
mDisplayContent.getLogicalDisplayRect(mTmpRect);
- switch (rotationDelta) {
- case Surface.ROTATION_0:
- mTmpRect2.set(mBounds);
- break;
- case Surface.ROTATION_90:
- mTmpRect2.top = mTmpRect.bottom - mBounds.right;
- mTmpRect2.left = mBounds.top;
- mTmpRect2.right = mTmpRect2.left + mBounds.height();
- mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
- break;
- case Surface.ROTATION_180:
- mTmpRect2.top = mTmpRect.bottom - mBounds.bottom;
- mTmpRect2.left = mTmpRect.right - mBounds.right;
- mTmpRect2.right = mTmpRect2.left + mBounds.width();
- mTmpRect2.bottom = mTmpRect2.top + mBounds.height();
- break;
- case Surface.ROTATION_270:
- mTmpRect2.top = mBounds.left;
- mTmpRect2.left = mTmpRect.right - mBounds.bottom;
- mTmpRect2.right = mTmpRect2.left + mBounds.height();
- mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
- break;
+ mAnimationBackgroundSurface.setBounds(mTmpRect);
+ for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ mTasks.get(taskNdx).updateDisplayInfo(mDisplayContent);
}
- setBounds(mTmpRect2);
- }
- }
-
- boolean isFullscreen() {
- return mFullscreen;
- }
-
- /** Forces the stack to fullscreen if input is true, else un-forces the stack from fullscreen.
- * Returns true if something happened.
- */
- boolean forceFullscreen(boolean forceFullscreen) {
- if (mForceFullscreen == forceFullscreen) {
- return false;
- }
- mForceFullscreen = forceFullscreen;
- if (forceFullscreen) {
- if (mFullscreen) {
- return false;
- }
- mPreForceFullscreenBounds.set(mBounds);
- return setBounds(null);
- } else {
- if (!mFullscreen || mPreForceFullscreenBounds.isEmpty()) {
- return false;
- }
- return setBounds(mPreForceFullscreenBounds);
}
}
@@ -313,6 +206,7 @@
mTasks.add(stackNdx, task);
task.mStack = this;
+ task.updateDisplayInfo(mDisplayContent);
if (toTop) {
mDisplayContent.moveStack(this, true);
}
@@ -361,8 +255,7 @@
}
mDisplayContent = displayContent;
- mDimLayer = new DimLayer(mService, this, displayContent);
- mAnimationBackgroundSurface = new DimLayer(mService, this, displayContent);
+ mAnimationBackgroundSurface = new DimLayer(mService, this, mDisplayContent.getDisplayId());
updateDisplayInfo();
}
@@ -394,98 +287,6 @@
mAnimationBackgroundSurface.hide();
}
- private long getDimBehindFadeDuration(long duration) {
- TypedValue tv = new TypedValue();
- mService.mContext.getResources().getValue(
- com.android.internal.R.fraction.config_dimBehindFadeDuration, tv, true);
- if (tv.type == TypedValue.TYPE_FRACTION) {
- duration = (long)tv.getFraction(duration, duration);
- } else if (tv.type >= TypedValue.TYPE_FIRST_INT && tv.type <= TypedValue.TYPE_LAST_INT) {
- duration = tv.data;
- }
- return duration;
- }
-
- boolean animateDimLayers() {
- final int dimLayer;
- final float dimAmount;
- if (mDimWinAnimator == null) {
- dimLayer = mDimLayer.getLayer();
- dimAmount = 0;
- } else {
- dimLayer = mDimWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM;
- dimAmount = mDimWinAnimator.mWin.mAttrs.dimAmount;
- }
- final float targetAlpha = mDimLayer.getTargetAlpha();
- if (targetAlpha != dimAmount) {
- if (mDimWinAnimator == null) {
- mDimLayer.hide(DEFAULT_DIM_DURATION);
- } else {
- long duration = (mDimWinAnimator.mAnimating && mDimWinAnimator.mAnimation != null)
- ? mDimWinAnimator.mAnimation.computeDurationHint()
- : DEFAULT_DIM_DURATION;
- if (targetAlpha > dimAmount) {
- duration = getDimBehindFadeDuration(duration);
- }
- mDimLayer.show(dimLayer, dimAmount, duration);
- }
- } else if (mDimLayer.getLayer() != dimLayer) {
- mDimLayer.setLayer(dimLayer);
- }
- if (mDimLayer.isAnimating()) {
- if (!mService.okToDisplay()) {
- // Jump to the end of the animation.
- mDimLayer.show();
- } else {
- return mDimLayer.stepAnimation();
- }
- }
- return false;
- }
-
- void resetDimmingTag() {
- mDimmingTag = false;
- }
-
- void setDimmingTag() {
- mDimmingTag = true;
- }
-
- boolean testDimmingTag() {
- return mDimmingTag;
- }
-
- boolean isDimming() {
- return mDimLayer.isDimming();
- }
-
- boolean isDimming(WindowStateAnimator winAnimator) {
- return mDimWinAnimator == winAnimator && mDimLayer.isDimming();
- }
-
- void startDimmingIfNeeded(WindowStateAnimator newWinAnimator) {
- // Only set dim params on the highest dimmed layer.
- // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
- if (newWinAnimator.mSurfaceShown && (mDimWinAnimator == null
- || !mDimWinAnimator.mSurfaceShown
- || mDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
- mDimWinAnimator = newWinAnimator;
- if (mDimWinAnimator.mWin.mAppToken == null
- && !mFullscreen && mDisplayContent != null) {
- // Dim should cover the entire screen for system windows.
- mDisplayContent.getLogicalDisplayRect(mTmpRect);
- mDimLayer.setBounds(mTmpRect);
- }
- }
- }
-
- void stopDimmingIfNeeded() {
- if (!mDimmingTag && isDimming()) {
- mDimWinAnimator = null;
- mDimLayer.setBounds(mBounds);
- }
- }
-
void setAnimationBackground(WindowStateAnimator winAnimator, int color) {
int animLayer = winAnimator.mAnimLayer;
if (mAnimationBackgroundAnimator == null
@@ -514,9 +315,8 @@
mAnimationBackgroundSurface.destroySurface();
mAnimationBackgroundSurface = null;
}
- if (mDimLayer != null) {
- mDimLayer.destroySurface();
- mDimLayer = null;
+ for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ mTasks.get(taskNdx).close();
}
}
@@ -524,21 +324,17 @@
pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
pw.print(prefix); pw.print("mDeferDetach="); pw.println(mDeferDetach);
for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
- pw.print(prefix); pw.println(mTasks.get(taskNdx));
+ pw.print(prefix);
+ mTasks.get(taskNdx).printTo(prefix + " ", pw);
}
if (mAnimationBackgroundSurface.isDimming()) {
pw.print(prefix); pw.println("mWindowAnimationBackgroundSurface:");
mAnimationBackgroundSurface.printTo(prefix + " ", pw);
}
- if (mDimLayer.isDimming()) {
- pw.print(prefix); pw.println("mDimLayer:");
- mDimLayer.printTo(prefix + " ", pw);
- pw.print(prefix); pw.print("mDimWinAnimator="); pw.println(mDimWinAnimator);
- }
if (!mExitingAppTokens.isEmpty()) {
pw.println();
pw.println(" Exiting application tokens:");
- for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
+ for (int i = mExitingAppTokens.size() - 1; i >= 0; i--) {
WindowToken token = mExitingAppTokens.get(i);
pw.print(" Exiting App #"); pw.print(i);
pw.print(' '); pw.print(token);
@@ -549,6 +345,16 @@
}
@Override
+ public boolean isFullscreen() {
+ return mFullscreen;
+ }
+
+ @Override
+ public DisplayInfo getDisplayInfo() {
+ return mDisplayContent.getDisplayInfo();
+ }
+
+ @Override
public String toString() {
return "{stackId=" + mStackId + " tasks=" + mTasks + "}";
}
diff --git a/services/core/java/com/android/server/wm/StackTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
similarity index 95%
rename from services/core/java/com/android/server/wm/StackTapPointerEventListener.java
rename to services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
index 1a85993..c97d12f 100644
--- a/services/core/java/com/android/server/wm/StackTapPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
@@ -23,7 +23,7 @@
import com.android.server.wm.WindowManagerService.H;
-public class StackTapPointerEventListener implements PointerEventListener {
+public class TaskTapPointerEventListener implements PointerEventListener {
private static final int TAP_TIMEOUT_MSEC = 300;
private static final float TAP_MOTION_SLOP_INCHES = 0.125f;
@@ -35,7 +35,7 @@
private final WindowManagerService mService;
private final DisplayContent mDisplayContent;
- public StackTapPointerEventListener(WindowManagerService service,
+ public TaskTapPointerEventListener(WindowManagerService service,
DisplayContent displayContent) {
mService = service;
mDisplayContent = displayContent;
@@ -77,7 +77,7 @@
&& Math.abs(x - mDownX) < mMotionSlop
&& Math.abs(y - mDownY) < mMotionSlop
&& !mTouchExcludeRegion.contains(x, y)) {
- mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y,
+ mService.mH.obtainMessage(H.TAP_OUTSIDE_TASK, x, y,
mDisplayContent).sendToTarget();
}
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 85a9624..b9740af 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -709,7 +709,7 @@
mService.scheduleAnimationLocked();
}
- mService.setFocusedStackLayer();
+ mService.setFocusedTaskLayer();
if (mService.mWatermark != null) {
mService.mWatermark.drawIfNeeded();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2647244..320edbe 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -70,6 +70,7 @@
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
+import android.util.IntArray;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -155,7 +156,6 @@
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
@@ -184,7 +184,6 @@
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub
@@ -251,9 +250,9 @@
static final int LAYER_OFFSET_DIM = 1;
/**
- * FocusedStackFrame layer is immediately above focused window.
+ * FocusedTaskFrame layer is immediately above focused window.
*/
- static final int LAYER_OFFSET_FOCUSED_STACK = 1;
+ static final int LAYER_OFFSET_FOCUSED_TASK = 1;
/**
* Animation thumbnail is as far as possible below the window above
@@ -446,9 +445,9 @@
StrictModeFlash mStrictModeFlash;
CircularDisplayMask mCircularDisplayMask;
EmulatorDisplayOverlay mEmulatorDisplayOverlay;
- FocusedStackFrame mFocusedStackFrame;
+ FocusedTaskFrame mFocusedTaskFrame;
- int mFocusedStackLayer;
+ int mFocusedTaskLayer;
final float[] mTmpFloats = new float[9];
final Rect mTmpContentRect = new Rect();
@@ -991,7 +990,7 @@
SurfaceControl.openTransaction();
try {
createWatermarkInTransaction();
- mFocusedStackFrame = new FocusedStackFrame(
+ mFocusedTaskFrame = new FocusedTaskFrame(
getDefaultDisplayContentLocked().getDisplay(), mFxSession);
} finally {
SurfaceControl.closeTransaction();
@@ -4063,37 +4062,33 @@
}
/** Call while in a Surface transaction. */
- void setFocusedStackLayer() {
- mFocusedStackLayer = 0;
+ void setFocusedTaskLayer() {
+ mFocusedTaskLayer = 0;
if (mFocusedApp != null) {
final WindowList windows = mFocusedApp.allAppWindows;
for (int i = windows.size() - 1; i >= 0; --i) {
final WindowState win = windows.get(i);
final int animLayer = win.mWinAnimator.mAnimLayer;
if (win.mAttachedWindow == null && win.isVisibleLw() &&
- animLayer > mFocusedStackLayer) {
- mFocusedStackLayer = animLayer + LAYER_OFFSET_FOCUSED_STACK;
+ animLayer > mFocusedTaskLayer) {
+ mFocusedTaskLayer = animLayer + LAYER_OFFSET_FOCUSED_TASK;
}
}
}
- if (DEBUG_LAYERS) Slog.v(TAG, "Setting FocusedStackFrame to layer=" +
- mFocusedStackLayer);
- mFocusedStackFrame.setLayer(mFocusedStackLayer);
+ if (DEBUG_LAYERS) Slog.v(TAG, "Setting FocusedTaskFrame to layer=" + mFocusedTaskLayer);
+ mFocusedTaskFrame.setLayer(mFocusedTaskLayer);
}
- void setFocusedStackFrame() {
- final TaskStack stack;
+ void setFocusedTaskFrame() {
+ Task task = null;
if (mFocusedApp != null) {
- final Task task = mFocusedApp.mTask;
- stack = task.mStack;
+ task = mFocusedApp.mTask;
final DisplayContent displayContent = task.getDisplayContent();
if (displayContent != null) {
- displayContent.setTouchExcludeRegion(stack);
+ displayContent.setTouchExcludeRegion(task);
}
- } else {
- stack = null;
}
- mFocusedStackFrame.setVisibility(stack);
+ mFocusedTaskFrame.setVisibility(task);
}
@Override
@@ -4121,11 +4116,11 @@
if (changed) {
mFocusedApp = newFocus;
mInputMonitor.setFocusedAppLw(newFocus);
- setFocusedStackFrame();
+ setFocusedTaskFrame();
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setFocusedApp");
SurfaceControl.openTransaction();
try {
- setFocusedStackLayer();
+ setFocusedTaskLayer();
} finally {
SurfaceControl.closeTransaction();
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setFocusedApp");
@@ -5233,71 +5228,78 @@
}
}
- /**
- * Re-sizes the specified stack and its containing windows.
- * Returns a {@link Configuration} object that contains configurations settings
- * that should be overridden due to the operation.
- */
- public Configuration resizeStack(int stackId, Rect bounds) {
- synchronized (mWindowMap) {
- final TaskStack stack = mStackIdToStack.get(stackId);
- if (stack == null) {
- throw new IllegalArgumentException("resizeStack: stackId " + stackId
- + " not found.");
- }
- if (stack.setBounds(bounds)) {
- stack.resizeWindows();
- stack.getDisplayContent().layoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
- }
- return new Configuration(stack.mOverrideConfig);
- }
- }
-
public void getStackBounds(int stackId, Rect bounds) {
- final TaskStack stack = mStackIdToStack.get(stackId);
- if (stack != null) {
- stack.getBounds(bounds);
- return;
- }
- bounds.setEmpty();
- }
-
- /** Returns the id of an application (non-home stack) stack that match the input bounds.
- * -1 if no stack matches.*/
- public int getStackIdWithBounds(Rect bounds) {
- Rect stackBounds = new Rect();
synchronized (mWindowMap) {
- for (int i = mStackIdToStack.size() - 1; i >= 0; --i) {
- TaskStack stack = mStackIdToStack.valueAt(i);
- if (stack.mStackId != HOME_STACK_ID) {
- stack.getBounds(stackBounds);
- if (stackBounds.equals(bounds)) {
- return stack.mStackId;
- }
- }
+ final TaskStack stack = mStackIdToStack.get(stackId);
+ if (stack != null) {
+ stack.getBounds(bounds);
+ return;
}
+ bounds.setEmpty();
}
- return -1;
}
- /** Forces the stack to fullscreen if input is true, else un-forces the stack from fullscreen.
- * Returns a {@link Configuration} object that contains configurations settings
- * that should be overridden due to the operation.
- */
- public Configuration forceStackToFullscreen(int stackId, boolean forceFullscreen) {
+ /**
+ * Re-sizes a stack and its containing tasks.
+ * @param stackId Id of stack to resize.
+ * @param bounds New stack bounds. Passing in null sets the bounds to fullscreen.
+ * @param changedTaskIds Output list of Ids of tasks that changed in bounds due to resize.
+ * @param newTaskConfigs Output list of new Configuation of the tasks that changed.
+ * @return True if the stack is now fullscreen.
+ * */
+ public boolean resizeStack(
+ int stackId, Rect bounds, IntArray changedTaskIds, List<Configuration> newTaskConfigs) {
synchronized (mWindowMap) {
final TaskStack stack = mStackIdToStack.get(stackId);
if (stack == null) {
throw new IllegalArgumentException("resizeStack: stackId " + stackId
+ " not found.");
}
- if (stack.forceFullscreen(forceFullscreen)) {
+ if (stack.setBounds(bounds, changedTaskIds, newTaskConfigs)) {
stack.resizeWindows();
stack.getDisplayContent().layoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
}
- return new Configuration(stack.mOverrideConfig);
+ return stack.isFullscreen();
+ }
+ }
+
+ /**
+ * Re-sizes the specified task and its containing windows.
+ * Returns a {@link Configuration} object that contains configurations settings
+ * that should be overridden due to the operation.
+ */
+ public Configuration resizeTask(int taskId, Rect bounds) {
+ synchronized (mWindowMap) {
+ Task task = mTaskIdToTask.get(taskId);
+ if (task == null) {
+ throw new IllegalArgumentException("resizeTask: taskId " + taskId
+ + " not found.");
+ }
+ if (task.setBounds(bounds)) {
+ task.resizeWindows();
+ task.getDisplayContent().layoutNeeded = true;
+ performLayoutAndPlaceSurfacesLocked();
+ }
+ return new Configuration(task.mOverrideConfig);
+ }
+ }
+
+ public void getTaskBounds(int taskId, Rect bounds) {
+ synchronized (mWindowMap) {
+ Task task = mTaskIdToTask.get(taskId);
+ if (task != null) {
+ task.getBounds(bounds);
+ return;
+ }
+ bounds.setEmpty();
+ }
+ }
+
+ /** Return true if the input task id represents a valid window manager task. */
+ public boolean isValidTaskId(int taskId) {
+ synchronized (mWindowMap) {
+ return mTaskIdToTask.get(taskId) != null;
}
}
@@ -6249,7 +6251,7 @@
int right = wf.right - cr.right;
int bottom = wf.bottom - cr.bottom;
frame.union(left, top, right, bottom);
- ws.getStackBounds(stackBounds);
+ ws.getTaskBounds(stackBounds);
if (!frame.intersect(stackBounds)) {
// Set frame empty if there's no intersection.
frame.setEmpty();
@@ -7708,7 +7710,7 @@
public static final int DO_DISPLAY_CHANGED = 29;
public static final int CLIENT_FREEZE_TIMEOUT = 30;
- public static final int TAP_OUTSIDE_STACK = 31;
+ public static final int TAP_OUTSIDE_TASK = 31;
public static final int NOTIFY_ACTIVITY_DRAWN = 32;
public static final int ALL_WINDOWS_DRAWN = 33;
@@ -8170,14 +8172,14 @@
}
break;
- case TAP_OUTSIDE_STACK: {
- int stackId;
+ case TAP_OUTSIDE_TASK: {
+ int taskId;
synchronized (mWindowMap) {
- stackId = ((DisplayContent)msg.obj).stackIdFromPoint(msg.arg1, msg.arg2);
+ taskId = ((DisplayContent)msg.obj).taskIdFromPoint(msg.arg1, msg.arg2);
}
- if (stackId >= 0) {
+ if (taskId >= 0) {
try {
- mActivityManager.setFocusedStack(stackId);
+ mActivityManager.setFocusedTask(taskId);
} catch (RemoteException e) {
}
}
@@ -8877,8 +8879,8 @@
layerChanged = true;
anyLayerChanged = true;
}
- final TaskStack stack = w.getStack();
- if (layerChanged && stack != null && stack.isDimming(winAnimator)) {
+ final Task task = w.getTask();
+ if (layerChanged && task != null && task.isDimming(winAnimator)) {
// Force an animation pass just to update the mDimLayer layer.
scheduleAnimationLocked();
}
@@ -9768,14 +9770,14 @@
&& w.isDisplayedLw()
&& !w.mExiting) {
final WindowStateAnimator winAnimator = w.mWinAnimator;
- final TaskStack stack = w.getStack();
- if (stack == null) {
+ final Task task = w.getTask();
+ if (task == null) {
return;
}
- stack.setDimmingTag();
- if (!stack.isDimming(winAnimator)) {
+ task.setContinueDimming();
+ if (!task.isDimming(winAnimator)) {
if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
- stack.startDimmingIfNeeded(winAnimator);
+ task.startDimmingIfNeeded(winAnimator);
}
}
}
@@ -9927,7 +9929,7 @@
}
// FIRST LOOP: Perform a layout, if needed.
- if (repeats < 4) {
+ if (repeats < LAYOUT_REPEAT_THRESHOLD) {
performLayoutLockedInner(displayContent, repeats == 1,
false /*updateInputWindows*/);
} else {
@@ -9962,8 +9964,8 @@
final int N = windows.size();
for (i=N-1; i>=0; i--) {
WindowState w = windows.get(i);
- final TaskStack stack = w.getStack();
- if (stack == null && w.getAttrs().type != TYPE_PRIVATE_PRESENTATION) {
+ final Task task = w.getTask();
+ if (task == null && w.getAttrs().type != TYPE_PRIVATE_PRESENTATION) {
continue;
}
@@ -9975,7 +9977,7 @@
handleNotObscuredLocked(w, innerDw, innerDh);
}
- if (stack != null && !stack.testDimmingTag()) {
+ if (task != null && !task.getContinueDimming()) {
handleFlagDimBehind(w);
}
@@ -10369,7 +10371,7 @@
if (updateInputWindowsNeeded) {
mInputMonitor.updateInputWindowsLw(false /*force*/);
}
- setFocusedStackFrame();
+ setFocusedTaskFrame();
// Check to see if we are now in a state where the screen should
// be enabled, because the window obscured flags have changed.
@@ -11428,7 +11430,8 @@
boolean dumpWindows(PrintWriter pw, String name, String[] args,
int opti, boolean dumpAll) {
WindowList windows = new WindowList();
- if ("visible".equals(name)) {
+ if ("visible".equals(name) || "visible-apps".equals(name)) {
+ final boolean appsOnly = "visible-apps".equals(name);
synchronized(mWindowMap) {
final int numDisplays = mDisplayContents.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
@@ -11436,7 +11439,8 @@
mDisplayContents.valueAt(displayNdx).getWindowList();
for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
final WindowState w = windowList.get(winNdx);
- if (w.mWinAnimator.mSurfaceShown) {
+ if (w.mWinAnimator.mSurfaceShown
+ && (!appsOnly || (appsOnly && w.mAppToken != null))) {
windows.add(w);
}
}
@@ -11561,6 +11565,7 @@
pw.println(" Window hex object identifier, or");
pw.println(" \"all\" for all windows, or");
pw.println(" \"visible\" for the visible windows.");
+ pw.println(" \"visible-apps\" for the visible app windows.");
pw.println(" -a: include all available server state.");
return;
} else {
@@ -11711,7 +11716,7 @@
// TODO: Create an input channel for each display with touch capability.
if (displayId == Display.DEFAULT_DISPLAY) {
- displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent);
+ displayContent.mTapDetector = new TaskTapPointerEventListener(this, displayContent);
registerPointerEventListener(displayContent.mTapDetector);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c2548de..f7bf6e4 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -535,10 +535,10 @@
Rect osf) {
mHaveFrame = true;
- final TaskStack stack = mAppToken != null ? getStack() : null;
- final boolean nonFullscreenStack = stack != null && !stack.isFullscreen();
- if (nonFullscreenStack) {
- stack.getBounds(mContainingFrame);
+ final Task task = mAppToken != null ? getTask() : null;
+ final boolean nonFullscreenTask = task != null && !task.isFullscreen();
+ if (nonFullscreenTask) {
+ task.getBounds(mContainingFrame);
final WindowState imeWin = mService.mInputMethodWindow;
if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this
&& mContainingFrame.bottom > cf.bottom) {
@@ -626,7 +626,7 @@
y = mAttrs.y;
}
- if (nonFullscreenStack) {
+ if (nonFullscreenTask) {
// Make sure window fits in containing frame since it is in a non-fullscreen stack as
// required by {@link Gravity#apply} call.
w = Math.min(w, pw);
@@ -856,27 +856,33 @@
return displayContent.getDisplayId();
}
- TaskStack getStack() {
+ Task getTask() {
AppWindowToken wtoken = mAppToken == null ? mService.mFocusedApp : mAppToken;
- if (wtoken != null) {
- Task task = wtoken.mTask;
- if (task != null) {
- if (task.mStack != null) {
- return task.mStack;
- }
- Slog.e(TAG, "getStack: mStack null for task=" + task);
- } else {
- Slog.e(TAG, "getStack: " + this + " couldn't find task for " + wtoken
- + " Callers=" + Debug.getCallers(4));
+ if (wtoken == null) {
+ Slog.e(TAG, "getTask: " + this + " null wtoken " + " Callers=" + Debug.getCallers(5));
+ return null;
+ }
+ final Task task = wtoken.mTask;
+ if (task == null) Slog.e(TAG, "getStack: " + this + " couldn't find task for " + wtoken
+ + " Callers=" + Debug.getCallers(5));
+ return task;
+ }
+
+ TaskStack getStack() {
+ Task task = getTask();
+ if (task != null) {
+ if (task.mStack != null) {
+ return task.mStack;
}
+ Slog.e(TAG, "getStack: mStack null for task=" + task);
}
return mDisplayContent.getHomeStack();
}
- void getStackBounds(Rect bounds) {
- final TaskStack stack = getStack();
- if (stack != null) {
- stack.getBounds(bounds);
+ void getTaskBounds(Rect bounds) {
+ final Task task = getTask();
+ if (task != null) {
+ task.getBounds(bounds);
return;
}
bounds.set(mFrame);
@@ -1139,9 +1145,9 @@
}
boolean isConfigChanged() {
- final TaskStack stack = getStack();
+ final Task task = getTask();
final Configuration overrideConfig =
- (stack != null) ? stack.mOverrideConfig : Configuration.EMPTY;
+ (task != null) ? task.mOverrideConfig : Configuration.EMPTY;
final Configuration serviceConfig = mService.mCurConfiguration;
boolean configChanged =
(mConfiguration != serviceConfig && mConfiguration.diff(serviceConfig) != 0)
@@ -1387,11 +1393,11 @@
@Override
public boolean isDimming() {
- TaskStack stack = getStack();
- if (stack == null) {
+ Task task = getTask();
+ if (task == null) {
return false;
}
- return stack.isDimming(mWinAnimator);
+ return task.isDimming(mWinAnimator);
}
public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) {
@@ -1489,9 +1495,9 @@
if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
+ ": " + mCompatFrame);
boolean configChanged = isConfigChanged();
- final TaskStack stack = getStack();
+ final Task task = getTask();
final Configuration overrideConfig =
- (stack != null) ? stack.mOverrideConfig : Configuration.EMPTY;
+ (task != null) ? task.mOverrideConfig : Configuration.EMPTY;
if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) {
Slog.i(TAG, "Sending new config to window " + this + ": "
+ mWinAnimator.mSurfaceW + "x" + mWinAnimator.mSurfaceH + " / config="
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 3251a56..31ee869 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -169,9 +169,6 @@
/** Set when the window has been shown in the screen the first time. */
static final int HAS_DRAWN = 4;
- private static final int SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN =
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
-
String drawStateToString() {
switch (mDrawState) {
case NO_SURFACE: return "NO_SURFACE";
@@ -1418,9 +1415,9 @@
mAnimator.setPendingLayoutChanges(w.getDisplayId(),
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
- final TaskStack stack = w.getStack();
- if (stack != null) {
- stack.startDimmingIfNeeded(this);
+ final Task task = w.getTask();
+ if (task != null) {
+ task.startDimmingIfNeeded(this);
}
}
} catch (RuntimeException e) {