DO NOT MERGE: Eliminate StackBox.
StackBox is too constraining. Adding size and position to TaskStacks directly makes stack positioning and management more flexible and prepares for ActivityView. Change-Id: I33c6b4e1c23a5a8069fd507c160bcb34e4d287b2
This commit is contained in:
committed by
Mike Lockwood
parent
09e9cdcece
commit
bdc748af8c
@@ -19,7 +19,7 @@
|
||||
package com.android.commands.am;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.StackBoxInfo;
|
||||
import android.app.ActivityManager.StackInfo;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.app.IActivityController;
|
||||
import android.app.IActivityManager;
|
||||
@@ -31,6 +31,7 @@ import android.content.IIntentReceiver;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
@@ -106,11 +107,11 @@ public class Am extends BaseCommand {
|
||||
" am to-intent-uri [INTENT]\n" +
|
||||
" am switch-user <USER_ID>\n" +
|
||||
" am stop-user <USER_ID>\n" +
|
||||
" am stack create <TASK_ID> <RELATIVE_STACK_BOX_ID> <POSITION> <WEIGHT>\n" +
|
||||
" am stack create <TASK_ID>\n" +
|
||||
" am stack movetask <TASK_ID> <STACK_ID> [true|false]\n" +
|
||||
" am stack resize <STACK_ID> <WEIGHT>\n" +
|
||||
" am stack boxes\n" +
|
||||
" am stack box <STACK_BOX_ID>\n" +
|
||||
" am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
|
||||
" am stack list\n" +
|
||||
" am stack info <STACK_ID>\n" +
|
||||
"\n" +
|
||||
"am start: start an Activity. Options are:\n" +
|
||||
" -D: enable debugging\n" +
|
||||
@@ -204,24 +205,16 @@ public class Am extends BaseCommand {
|
||||
"am stop-user: stop execution of USER_ID, not allowing it to run any\n" +
|
||||
" code until a later explicit switch to it.\n" +
|
||||
"\n" +
|
||||
"am stack create: create a new stack relative to an existing one.\n" +
|
||||
" <TASK_ID>: the task to populate the new stack with. Must exist.\n" +
|
||||
" <RELATIVE_STACK_BOX_ID>: existing stack box's id.\n" +
|
||||
" <POSITION>: 0: before <RELATIVE_STACK_BOX_ID>, per RTL/LTR configuration,\n" +
|
||||
" 1: after <RELATIVE_STACK_BOX_ID>, per RTL/LTR configuration,\n" +
|
||||
" 2: to left of <RELATIVE_STACK_BOX_ID>,\n" +
|
||||
" 3: to right of <RELATIVE_STACK_BOX_ID>," +
|
||||
" 4: above <RELATIVE_STACK_BOX_ID>, 5: below <RELATIVE_STACK_BOX_ID>\n" +
|
||||
" <WEIGHT>: float between 0.2 and 0.8 inclusive.\n" +
|
||||
"am stack create: create a new stack containing <TASK_ID> which must exist\n" +
|
||||
"\n" +
|
||||
"am stack movetask: move <TASK_ID> from its current stack to the top (true) or" +
|
||||
" bottom (false) of <STACK_ID>.\n" +
|
||||
"\n" +
|
||||
"am stack resize: change <STACK_ID> relative size to new <WEIGHT>.\n" +
|
||||
"am stack resize: change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.\n" +
|
||||
"\n" +
|
||||
"am stack boxes: list the hierarchy of stack boxes and their contents.\n" +
|
||||
"am stack list: list all of the activity stacks and their sizes.\n" +
|
||||
"\n" +
|
||||
"am stack box: list the hierarchy of stack boxes rooted at <STACK_BOX_ID>.\n" +
|
||||
"am stack info: display the information about activity stack <STACK_ID>.\n" +
|
||||
"\n" +
|
||||
"<INTENT> specifications include these flags and arguments:\n" +
|
||||
" [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
|
||||
@@ -1551,11 +1544,11 @@ public class Am extends BaseCommand {
|
||||
} else if (op.equals("movetask")) {
|
||||
runStackMoveTask();
|
||||
} else if (op.equals("resize")) {
|
||||
runStackBoxResize();
|
||||
} else if (op.equals("boxes")) {
|
||||
runStackBoxes();
|
||||
} else if (op.equals("box")) {
|
||||
runStackBoxInfo();
|
||||
runStackResize();
|
||||
} else if (op.equals("list")) {
|
||||
runStackList();
|
||||
} else if (op.equals("info")) {
|
||||
runStackInfo();
|
||||
} else {
|
||||
showError("Error: unknown command '" + op + "'");
|
||||
return;
|
||||
@@ -1565,15 +1558,9 @@ public class Am extends BaseCommand {
|
||||
private void runStackCreate() throws Exception {
|
||||
String taskIdStr = nextArgRequired();
|
||||
int taskId = Integer.valueOf(taskIdStr);
|
||||
String relativeToStr = nextArgRequired();
|
||||
int relativeTo = Integer.valueOf(relativeToStr);
|
||||
String positionStr = nextArgRequired();
|
||||
int position = Integer.valueOf(positionStr);
|
||||
String weightStr = nextArgRequired();
|
||||
float weight = Float.valueOf(weightStr);
|
||||
|
||||
try {
|
||||
int stackId = mAm.createStack(taskId, relativeTo, position, weight);
|
||||
int stackId = mAm.createStack(taskId);
|
||||
System.out.println("createStack returned new stackId=" + stackId + "\n\n");
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
@@ -1601,34 +1588,40 @@ public class Am extends BaseCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private void runStackBoxResize() throws Exception {
|
||||
String stackBoxIdStr = nextArgRequired();
|
||||
int stackBoxId = Integer.valueOf(stackBoxIdStr);
|
||||
String weightStr = nextArgRequired();
|
||||
float weight = Float.valueOf(weightStr);
|
||||
private void runStackResize() throws Exception {
|
||||
String stackIdStr = nextArgRequired();
|
||||
int stackId = Integer.valueOf(stackIdStr);
|
||||
String leftStr = nextArgRequired();
|
||||
int left = Integer.valueOf(leftStr);
|
||||
String topStr = nextArgRequired();
|
||||
int top = Integer.valueOf(topStr);
|
||||
String rightStr = nextArgRequired();
|
||||
int right = Integer.valueOf(rightStr);
|
||||
String bottomStr = nextArgRequired();
|
||||
int bottom = Integer.valueOf(bottomStr);
|
||||
|
||||
try {
|
||||
mAm.resizeStackBox(stackBoxId, weight);
|
||||
mAm.resizeStack(stackId, new Rect(left, top, right, bottom));
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
private void runStackBoxes() throws Exception {
|
||||
private void runStackList() throws Exception {
|
||||
try {
|
||||
List<StackBoxInfo> stackBoxes = mAm.getStackBoxes();
|
||||
for (StackBoxInfo info : stackBoxes) {
|
||||
List<StackInfo> stacks = mAm.getAllStackInfos();
|
||||
for (StackInfo info : stacks) {
|
||||
System.out.println(info);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
private void runStackBoxInfo() throws Exception {
|
||||
private void runStackInfo() throws Exception {
|
||||
try {
|
||||
String stackBoxIdStr = nextArgRequired();
|
||||
int stackBoxId = Integer.valueOf(stackBoxIdStr);
|
||||
StackBoxInfo stackBoxInfo = mAm.getStackBoxInfo(stackBoxId);
|
||||
System.out.println(stackBoxInfo);
|
||||
String stackIdStr = nextArgRequired();
|
||||
int stackId = Integer.valueOf(stackIdStr);
|
||||
StackInfo info = mAm.getStackInfo(stackId);
|
||||
System.out.println(info);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1288,107 +1288,16 @@ public class ActivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Information you can retrieve about the WindowManager StackBox hierarchy.
|
||||
* @hide
|
||||
*/
|
||||
public static class StackBoxInfo implements Parcelable {
|
||||
public int stackBoxId;
|
||||
public float weight;
|
||||
public boolean vertical;
|
||||
public Rect bounds;
|
||||
public StackBoxInfo[] children;
|
||||
public int stackId;
|
||||
public StackInfo stack;
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(stackBoxId);
|
||||
dest.writeFloat(weight);
|
||||
dest.writeInt(vertical ? 1 : 0);
|
||||
bounds.writeToParcel(dest, flags);
|
||||
dest.writeInt(stackId);
|
||||
if (children != null) {
|
||||
children[0].writeToParcel(dest, flags);
|
||||
children[1].writeToParcel(dest, flags);
|
||||
} else {
|
||||
stack.writeToParcel(dest, flags);
|
||||
}
|
||||
}
|
||||
|
||||
public void readFromParcel(Parcel source) {
|
||||
stackBoxId = source.readInt();
|
||||
weight = source.readFloat();
|
||||
vertical = source.readInt() == 1;
|
||||
bounds = Rect.CREATOR.createFromParcel(source);
|
||||
stackId = source.readInt();
|
||||
if (stackId == -1) {
|
||||
children = new StackBoxInfo[2];
|
||||
children[0] = StackBoxInfo.CREATOR.createFromParcel(source);
|
||||
children[1] = StackBoxInfo.CREATOR.createFromParcel(source);
|
||||
} else {
|
||||
stack = StackInfo.CREATOR.createFromParcel(source);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Creator<StackBoxInfo> CREATOR =
|
||||
new Creator<ActivityManager.StackBoxInfo>() {
|
||||
|
||||
@Override
|
||||
public StackBoxInfo createFromParcel(Parcel source) {
|
||||
return new StackBoxInfo(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackBoxInfo[] newArray(int size) {
|
||||
return new StackBoxInfo[size];
|
||||
}
|
||||
};
|
||||
|
||||
public StackBoxInfo() {
|
||||
}
|
||||
|
||||
public StackBoxInfo(Parcel source) {
|
||||
readFromParcel(source);
|
||||
}
|
||||
|
||||
public String toString(String prefix) {
|
||||
StringBuilder sb = new StringBuilder(256);
|
||||
sb.append(prefix); sb.append("Box id=" + stackBoxId); sb.append(" weight=" + weight);
|
||||
sb.append(" vertical=" + vertical); sb.append(" bounds=" + bounds.toShortString());
|
||||
sb.append("\n");
|
||||
if (children != null) {
|
||||
sb.append(prefix); sb.append("First child=\n");
|
||||
sb.append(children[0].toString(prefix + " "));
|
||||
sb.append(prefix); sb.append("Second child=\n");
|
||||
sb.append(children[1].toString(prefix + " "));
|
||||
} else {
|
||||
sb.append(prefix); sb.append("Stack=\n");
|
||||
sb.append(stack.toString(prefix + " "));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString("");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Information you can retrieve about an ActivityStack in the system.
|
||||
* @hide
|
||||
*/
|
||||
public static class StackInfo implements Parcelable {
|
||||
public int stackId;
|
||||
public Rect bounds;
|
||||
public Rect bounds = new Rect();
|
||||
public int[] taskIds;
|
||||
public String[] taskNames;
|
||||
public int displayId;
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
@@ -1404,6 +1313,7 @@ public class ActivityManager {
|
||||
dest.writeInt(bounds.bottom);
|
||||
dest.writeIntArray(taskIds);
|
||||
dest.writeStringArray(taskNames);
|
||||
dest.writeInt(displayId);
|
||||
}
|
||||
|
||||
public void readFromParcel(Parcel source) {
|
||||
@@ -1412,6 +1322,7 @@ public class ActivityManager {
|
||||
source.readInt(), source.readInt(), source.readInt(), source.readInt());
|
||||
taskIds = source.createIntArray();
|
||||
taskNames = source.createStringArray();
|
||||
displayId = source.readInt();
|
||||
}
|
||||
|
||||
public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() {
|
||||
@@ -1435,7 +1346,9 @@ public class ActivityManager {
|
||||
public String toString(String prefix) {
|
||||
StringBuilder sb = new StringBuilder(256);
|
||||
sb.append(prefix); sb.append("Stack id="); sb.append(stackId);
|
||||
sb.append(" bounds="); sb.append(bounds.toShortString()); sb.append("\n");
|
||||
sb.append(" bounds="); sb.append(bounds.toShortString());
|
||||
sb.append(" displayId="); sb.append(displayId);
|
||||
sb.append("\n");
|
||||
prefix = prefix + " ";
|
||||
for (int i = 0; i < taskIds.length; ++i) {
|
||||
sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package android.app;
|
||||
|
||||
import android.app.ActivityManager.StackBoxInfo;
|
||||
import android.app.ActivityManager.StackInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.IIntentReceiver;
|
||||
import android.content.IIntentSender;
|
||||
@@ -31,6 +31,7 @@ import android.content.pm.ParceledListSlice;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
@@ -614,10 +615,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
case CREATE_STACK_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
int taskId = data.readInt();
|
||||
int relativeStackId = data.readInt();
|
||||
int position = data.readInt();
|
||||
float weight = data.readFloat();
|
||||
int res = createStack(taskId, relativeStackId, position, weight);
|
||||
int res = createStack(taskId);
|
||||
reply.writeNoException();
|
||||
reply.writeInt(res);
|
||||
return true;
|
||||
@@ -635,25 +633,26 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
|
||||
case RESIZE_STACK_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
int stackBoxId = data.readInt();
|
||||
int stackId = data.readInt();
|
||||
float weight = data.readFloat();
|
||||
resizeStackBox(stackBoxId, weight);
|
||||
Rect r = Rect.CREATOR.createFromParcel(data);
|
||||
resizeStack(stackId, r);
|
||||
reply.writeNoException();
|
||||
return true;
|
||||
}
|
||||
|
||||
case GET_STACK_BOXES_TRANSACTION: {
|
||||
case GET_ALL_STACK_INFOS_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
List<StackBoxInfo> list = getStackBoxes();
|
||||
List<StackInfo> list = getAllStackInfos();
|
||||
reply.writeNoException();
|
||||
reply.writeTypedList(list);
|
||||
return true;
|
||||
}
|
||||
|
||||
case GET_STACK_BOX_INFO_TRANSACTION: {
|
||||
case GET_STACK_INFO_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
int stackBoxId = data.readInt();
|
||||
StackBoxInfo info = getStackBoxInfo(stackBoxId);
|
||||
int stackId = data.readInt();
|
||||
StackInfo info = getStackInfo(stackId);
|
||||
reply.writeNoException();
|
||||
if (info != null) {
|
||||
reply.writeInt(1);
|
||||
@@ -2715,16 +2714,12 @@ class ActivityManagerProxy implements IActivityManager
|
||||
reply.recycle();
|
||||
}
|
||||
@Override
|
||||
public int createStack(int taskId, int relativeStackBoxId, int position, float weight)
|
||||
throws RemoteException
|
||||
public int createStack(int taskId) throws RemoteException
|
||||
{
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
data.writeInt(taskId);
|
||||
data.writeInt(relativeStackBoxId);
|
||||
data.writeInt(position);
|
||||
data.writeFloat(weight);
|
||||
mRemote.transact(CREATE_STACK_TRANSACTION, data, reply, 0);
|
||||
reply.readException();
|
||||
int res = reply.readInt();
|
||||
@@ -2747,44 +2742,44 @@ class ActivityManagerProxy implements IActivityManager
|
||||
reply.recycle();
|
||||
}
|
||||
@Override
|
||||
public void resizeStackBox(int stackBoxId, float weight) throws RemoteException
|
||||
public void resizeStack(int stackBoxId, Rect r) throws RemoteException
|
||||
{
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
data.writeInt(stackBoxId);
|
||||
data.writeFloat(weight);
|
||||
r.writeToParcel(data, 0);
|
||||
mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
|
||||
reply.readException();
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
}
|
||||
@Override
|
||||
public List<StackBoxInfo> getStackBoxes() throws RemoteException
|
||||
public List<StackInfo> getAllStackInfos() throws RemoteException
|
||||
{
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
mRemote.transact(GET_STACK_BOXES_TRANSACTION, data, reply, 0);
|
||||
mRemote.transact(GET_ALL_STACK_INFOS_TRANSACTION, data, reply, 0);
|
||||
reply.readException();
|
||||
ArrayList<StackBoxInfo> list = reply.createTypedArrayList(StackBoxInfo.CREATOR);
|
||||
ArrayList<StackInfo> list = reply.createTypedArrayList(StackInfo.CREATOR);
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
return list;
|
||||
}
|
||||
@Override
|
||||
public StackBoxInfo getStackBoxInfo(int stackBoxId) throws RemoteException
|
||||
public StackInfo getStackInfo(int stackId) throws RemoteException
|
||||
{
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
data.writeInt(stackBoxId);
|
||||
mRemote.transact(GET_STACK_BOX_INFO_TRANSACTION, data, reply, 0);
|
||||
data.writeInt(stackId);
|
||||
mRemote.transact(GET_STACK_INFO_TRANSACTION, data, reply, 0);
|
||||
reply.readException();
|
||||
int res = reply.readInt();
|
||||
StackBoxInfo info = null;
|
||||
StackInfo info = null;
|
||||
if (res != 0) {
|
||||
info = StackBoxInfo.CREATOR.createFromParcel(reply);
|
||||
info = StackInfo.CREATOR.createFromParcel(reply);
|
||||
}
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
|
||||
@@ -18,7 +18,7 @@ package android.app;
|
||||
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.app.ActivityManager.RunningServiceInfo;
|
||||
import android.app.ActivityManager.StackBoxInfo;
|
||||
import android.app.ActivityManager.StackInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentProviderNative;
|
||||
import android.content.IContentProvider;
|
||||
@@ -36,6 +36,7 @@ import android.content.pm.ProviderInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Debug;
|
||||
@@ -117,12 +118,11 @@ public interface IActivityManager extends IInterface {
|
||||
public void moveTaskToBack(int task) throws RemoteException;
|
||||
public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) throws RemoteException;
|
||||
public void moveTaskBackwards(int task) throws RemoteException;
|
||||
public int createStack(int taskId, int relativeStackBoxId, int position, float weight)
|
||||
throws RemoteException;
|
||||
public int createStack(int taskId) throws RemoteException;
|
||||
public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException;
|
||||
public void resizeStackBox(int stackBoxId, float weight) throws RemoteException;
|
||||
public List<StackBoxInfo> getStackBoxes() throws RemoteException;
|
||||
public StackBoxInfo getStackBoxInfo(int stackBoxId) throws RemoteException;
|
||||
public void resizeStack(int stackId, Rect bounds) throws RemoteException;
|
||||
public List<StackInfo> getAllStackInfos() throws RemoteException;
|
||||
public StackInfo getStackInfo(int stackId) throws RemoteException;
|
||||
public void setFocusedStack(int stackId) throws RemoteException;
|
||||
public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
|
||||
/* oneway */
|
||||
@@ -681,9 +681,9 @@ public interface IActivityManager extends IInterface {
|
||||
int CREATE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+167;
|
||||
int MOVE_TASK_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+168;
|
||||
int RESIZE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+169;
|
||||
int GET_STACK_BOXES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170;
|
||||
int GET_ALL_STACK_INFOS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170;
|
||||
int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171;
|
||||
int GET_STACK_BOX_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172;
|
||||
int GET_STACK_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172;
|
||||
int CONVERT_FROM_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173;
|
||||
int CONVERT_TO_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+174;
|
||||
int NOTIFY_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+175;
|
||||
|
||||
@@ -29,7 +29,9 @@ import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.graphics.Rect;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.Display;
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.app.IAppOpsService;
|
||||
@@ -52,7 +54,6 @@ import com.android.server.am.ActivityStack.ActivityState;
|
||||
import com.android.server.firewall.IntentFirewall;
|
||||
import com.android.server.pm.UserManagerService;
|
||||
import com.android.server.wm.AppTransition;
|
||||
import com.android.server.wm.StackBox;
|
||||
import com.android.server.wm.WindowManagerService;
|
||||
import com.google.android.collect.Lists;
|
||||
import com.google.android.collect.Maps;
|
||||
@@ -68,7 +69,6 @@ import org.xmlpull.v1.XmlSerializer;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.app.ActivityManager.StackBoxInfo;
|
||||
import android.app.ActivityManager.StackInfo;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.app.ActivityOptions;
|
||||
@@ -1770,7 +1770,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
public void setWindowManager(WindowManagerService wm) {
|
||||
mWindowManager = wm;
|
||||
mStackSupervisor.setWindowManager(wm);
|
||||
wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f);
|
||||
wm.createStack(HOME_STACK_ID, Display.DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
public void startObservingNativeCrashes() {
|
||||
@@ -7096,16 +7096,15 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
|
||||
@Override
|
||||
public int createStack(int taskId, int relativeStackBoxId, int position, float weight) {
|
||||
public int createStack(int taskId) {
|
||||
enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
|
||||
"createStack()");
|
||||
if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId + " relStackBoxId=" +
|
||||
relativeStackBoxId + " position=" + position + " weight=" + weight);
|
||||
if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId);
|
||||
synchronized (this) {
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
int stackId = mStackSupervisor.createStack();
|
||||
mWindowManager.createStack(stackId, relativeStackBoxId, position, weight);
|
||||
mWindowManager.createStack(stackId, Display.DEFAULT_DISPLAY);
|
||||
if (taskId > 0) {
|
||||
moveTaskToStack(taskId, stackId, true);
|
||||
}
|
||||
@@ -7137,99 +7136,40 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resizeStackBox(int stackBoxId, float weight) {
|
||||
public void resizeStack(int stackBoxId, Rect bounds) {
|
||||
enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
|
||||
"resizeStackBox()");
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mWindowManager.resizeStackBox(stackBoxId, weight);
|
||||
mWindowManager.resizeStack(stackBoxId, bounds);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<StackInfo> getStacks() {
|
||||
synchronized (this) {
|
||||
ArrayList<ActivityManager.StackInfo> list = new ArrayList<ActivityManager.StackInfo>();
|
||||
ArrayList<ActivityStack> stacks = mStackSupervisor.getStacks();
|
||||
for (ActivityStack stack : stacks) {
|
||||
ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo();
|
||||
int stackId = stack.mStackId;
|
||||
stackInfo.stackId = stackId;
|
||||
stackInfo.bounds = mWindowManager.getStackBounds(stackId);
|
||||
ArrayList<TaskRecord> tasks = stack.getAllTasks();
|
||||
final int numTasks = tasks.size();
|
||||
int[] taskIds = new int[numTasks];
|
||||
String[] taskNames = new String[numTasks];
|
||||
for (int i = 0; i < numTasks; ++i) {
|
||||
final TaskRecord task = tasks.get(i);
|
||||
taskIds[i] = task.taskId;
|
||||
taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
|
||||
: task.realActivity != null ? task.realActivity.flattenToString()
|
||||
: task.getTopActivity() != null ? task.getTopActivity().packageName
|
||||
: "unknown";
|
||||
}
|
||||
stackInfo.taskIds = taskIds;
|
||||
stackInfo.taskNames = taskNames;
|
||||
list.add(stackInfo);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
private void addStackInfoToStackBoxInfo(StackBoxInfo stackBoxInfo, List<StackInfo> stackInfos) {
|
||||
final int stackId = stackBoxInfo.stackId;
|
||||
if (stackId >= 0) {
|
||||
for (StackInfo stackInfo : stackInfos) {
|
||||
if (stackId == stackInfo.stackId) {
|
||||
stackBoxInfo.stack = stackInfo;
|
||||
stackInfos.remove(stackInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addStackInfoToStackBoxInfo(stackBoxInfo.children[0], stackInfos);
|
||||
addStackInfoToStackBoxInfo(stackBoxInfo.children[1], stackInfos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StackBoxInfo> getStackBoxes() {
|
||||
public List<StackInfo> getAllStackInfos() {
|
||||
enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
|
||||
"getStackBoxes()");
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
|
||||
synchronized (this) {
|
||||
List<StackInfo> stackInfos = getStacks();
|
||||
for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
|
||||
addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
|
||||
}
|
||||
return mStackSupervisor.getAllStackInfos();
|
||||
}
|
||||
return stackBoxInfos;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackBoxInfo getStackBoxInfo(int stackBoxId) {
|
||||
public StackInfo getStackInfo(int stackId) {
|
||||
enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
|
||||
"getStackBoxInfo()");
|
||||
"getStackInfo()");
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
|
||||
StackBoxInfo info = null;
|
||||
synchronized (this) {
|
||||
List<StackInfo> stackInfos = getStacks();
|
||||
for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
|
||||
addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
|
||||
if (stackBoxInfo.stackBoxId == stackBoxId) {
|
||||
info = stackBoxInfo;
|
||||
}
|
||||
}
|
||||
return mStackSupervisor.getStackInfo(stackId);
|
||||
}
|
||||
return info;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import static com.android.server.am.ActivityManagerService.TAG;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.StackInfo;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.AppGlobals;
|
||||
import android.app.IActivityManager;
|
||||
@@ -70,11 +71,11 @@ import android.util.EventLog;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import android.view.Display;
|
||||
import com.android.internal.app.HeavyWeightSwitcherActivity;
|
||||
import com.android.internal.os.TransferPipe;
|
||||
import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
|
||||
import com.android.server.am.ActivityStack.ActivityState;
|
||||
import com.android.server.wm.StackBox;
|
||||
import com.android.server.wm.WindowManagerService;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -1288,8 +1289,7 @@ public final class ActivityStackSupervisor {
|
||||
}
|
||||
|
||||
// Time to create the first app stack for this user.
|
||||
int stackId =
|
||||
mService.createStack(-1, HOME_STACK_ID, StackBox.TASK_STACK_GOES_OVER, 1.0f);
|
||||
int stackId = mService.createStack(-1);
|
||||
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
|
||||
" stackId=" + stackId);
|
||||
mFocusedStack = getStack(stackId);
|
||||
@@ -2644,4 +2644,43 @@ public final class ActivityStackSupervisor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StackInfo getStackInfo(ActivityStack stack) {
|
||||
StackInfo info = new StackInfo();
|
||||
mWindowManager.getStackBounds(stack.mStackId, info.bounds);
|
||||
info.displayId = Display.DEFAULT_DISPLAY;
|
||||
info.stackId = stack.mStackId;
|
||||
|
||||
ArrayList<TaskRecord> tasks = stack.getAllTasks();
|
||||
final int numTasks = tasks.size();
|
||||
int[] taskIds = new int[numTasks];
|
||||
String[] taskNames = new String[numTasks];
|
||||
for (int i = 0; i < numTasks; ++i) {
|
||||
final TaskRecord task = tasks.get(i);
|
||||
taskIds[i] = task.taskId;
|
||||
taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
|
||||
: task.realActivity != null ? task.realActivity.flattenToString()
|
||||
: task.getTopActivity() != null ? task.getTopActivity().packageName
|
||||
: "unknown";
|
||||
}
|
||||
info.taskIds = taskIds;
|
||||
info.taskNames = taskNames;
|
||||
return info;
|
||||
}
|
||||
|
||||
StackInfo getStackInfo(int stackId) {
|
||||
ActivityStack stack = getStack(stackId);
|
||||
if (stack != null) {
|
||||
return getStackInfo(stack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
ArrayList<StackInfo> getAllStackInfos() {
|
||||
ArrayList<StackInfo> list = new ArrayList<StackInfo>();
|
||||
for (int ndx = mStacks.size() - 1; ndx >= 0; --ndx) {
|
||||
list.add(getStackInfo(mStacks.get(ndx)));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ public class DimLayer {
|
||||
|
||||
final int dw, dh;
|
||||
final float xPos, yPos;
|
||||
if (mStack.hasSibling()) {
|
||||
if (!mStack.isFullscreen()) {
|
||||
dw = mBounds.width();
|
||||
dh = mBounds.height();
|
||||
xPos = mBounds.left;
|
||||
|
||||
@@ -21,10 +21,8 @@ import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
|
||||
import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
|
||||
import static com.android.server.wm.WindowManagerService.TAG;
|
||||
|
||||
import android.app.ActivityManager.StackBoxInfo;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.os.Debug;
|
||||
import android.util.EventLog;
|
||||
import android.util.Slog;
|
||||
import android.view.Display;
|
||||
@@ -74,6 +72,7 @@ class DisplayContent {
|
||||
private final Display mDisplay;
|
||||
|
||||
Rect mBaseDisplayRect = new Rect();
|
||||
Rect mContentRect = new Rect();
|
||||
|
||||
// Accessed directly by all users.
|
||||
boolean layoutNeeded;
|
||||
@@ -92,11 +91,12 @@ class DisplayContent {
|
||||
*/
|
||||
final AppTokenList mExitingAppTokens = new AppTokenList();
|
||||
|
||||
/** Array containing the home StackBox and possibly one more which would contain apps. Array
|
||||
/** Array containing all TaskStacks on this display. Array
|
||||
* is stored in display order with the current bottom stack at 0. */
|
||||
private ArrayList<StackBox> mStackBoxes = new ArrayList<StackBox>();
|
||||
private ArrayList<TaskStack> mStacks = new ArrayList<TaskStack>();
|
||||
|
||||
/** True when the home StackBox is at the top of mStackBoxes, false otherwise. */
|
||||
/** A special TaskStack with id==HOME_STACK_ID that moves to the bottom whenever any TaskStack
|
||||
* (except a future lockscreen TaskStack) moves to the top. */
|
||||
private TaskStack mHomeStack = null;
|
||||
|
||||
/** Detect user tapping outside of current focused stack bounds .*/
|
||||
@@ -123,13 +123,6 @@ class DisplayContent {
|
||||
display.getDisplayInfo(mDisplayInfo);
|
||||
isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY;
|
||||
mService = service;
|
||||
|
||||
StackBox newBox = new StackBox(service, this, null);
|
||||
mStackBoxes.add(newBox);
|
||||
TaskStack newStack = new TaskStack(service, HOME_STACK_ID, this);
|
||||
newStack.mStackBox = newBox;
|
||||
newBox.mStack = newStack;
|
||||
mHomeStack = newStack;
|
||||
}
|
||||
|
||||
int getDisplayId() {
|
||||
@@ -155,10 +148,6 @@ class DisplayContent {
|
||||
return mDisplay.hasAccess(uid);
|
||||
}
|
||||
|
||||
boolean homeOnTop() {
|
||||
return mStackBoxes.get(0).mStack != mHomeStack;
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return (mDisplay.getFlags() & Display.FLAG_PRIVATE) != 0;
|
||||
}
|
||||
@@ -205,7 +194,18 @@ class DisplayContent {
|
||||
}
|
||||
|
||||
void updateDisplayInfo() {
|
||||
// Save old size.
|
||||
int oldWidth = mDisplayInfo.logicalWidth;
|
||||
int oldHeight = mDisplayInfo.logicalHeight;
|
||||
mDisplay.getDisplayInfo(mDisplayInfo);
|
||||
|
||||
for (int i = mStacks.size() - 1; i >= 0; --i) {
|
||||
final TaskStack stack = mStacks.get(i);
|
||||
if (!stack.isFullscreen()) {
|
||||
stack.resizeBounds(oldWidth, oldHeight, mDisplayInfo.logicalWidth,
|
||||
mDisplayInfo.logicalHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void getLogicalDisplayRect(Rect out) {
|
||||
@@ -227,159 +227,58 @@ class DisplayContent {
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Refer to {@link WindowManagerService#createStack(int, int, int, float)} */
|
||||
TaskStack createStack(int stackId, int relativeStackBoxId, int position, float weight) {
|
||||
TaskStack newStack = null;
|
||||
if (DEBUG_STACK) Slog.d(TAG, "createStack: stackId=" + stackId + " relativeStackBoxId="
|
||||
+ relativeStackBoxId + " position=" + position + " weight=" + weight);
|
||||
/** Refer to {@link WindowManagerService#createStack(int, int)} */
|
||||
TaskStack createStack(int stackId) {
|
||||
if (DEBUG_STACK) Slog.d(TAG, "createStack: stackId=" + stackId);
|
||||
TaskStack newStack = new TaskStack(mService, stackId, this);
|
||||
if (stackId == HOME_STACK_ID) {
|
||||
if (mStackBoxes.size() != 1) {
|
||||
if (mHomeStack != null) {
|
||||
throw new IllegalArgumentException("createStack: HOME_STACK_ID (0) not first.");
|
||||
}
|
||||
newStack = mHomeStack;
|
||||
} else {
|
||||
int stackBoxNdx;
|
||||
for (stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
final StackBox box = mStackBoxes.get(stackBoxNdx);
|
||||
if (position == StackBox.TASK_STACK_GOES_OVER
|
||||
|| position == StackBox.TASK_STACK_GOES_UNDER) {
|
||||
// Position indicates a new box is added at top level only.
|
||||
if (box.contains(relativeStackBoxId)) {
|
||||
StackBox newBox = new StackBox(mService, this, null);
|
||||
newStack = new TaskStack(mService, stackId, this);
|
||||
newStack.mStackBox = newBox;
|
||||
newBox.mStack = newStack;
|
||||
final int offset = position == StackBox.TASK_STACK_GOES_OVER ? 1 : 0;
|
||||
if (DEBUG_STACK) Slog.d(TAG, "createStack: inserting stack at " +
|
||||
(stackBoxNdx + offset));
|
||||
mStackBoxes.add(stackBoxNdx + offset, newBox);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Remaining position values indicate a box must be split.
|
||||
newStack = box.split(stackId, relativeStackBoxId, position, weight);
|
||||
if (newStack != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stackBoxNdx < 0) {
|
||||
throw new IllegalArgumentException("createStack: stackBoxId " + relativeStackBoxId
|
||||
+ " not found.");
|
||||
}
|
||||
mHomeStack = newStack;
|
||||
}
|
||||
if (newStack != null) {
|
||||
layoutNeeded = true;
|
||||
}
|
||||
EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, relativeStackBoxId, position,
|
||||
(int)(weight * 100 + 0.5));
|
||||
mStacks.add(newStack);
|
||||
layoutNeeded = true;
|
||||
return newStack;
|
||||
}
|
||||
|
||||
/** Refer to {@link WindowManagerService#resizeStackBox(int, float)} */
|
||||
boolean resizeStack(int stackBoxId, float weight) {
|
||||
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
final StackBox box = mStackBoxes.get(stackBoxNdx);
|
||||
if (box.resize(stackBoxId, weight)) {
|
||||
layoutNeeded = true;
|
||||
void moveStack(TaskStack stack, boolean toTop) {
|
||||
mStacks.remove(stack);
|
||||
mStacks.add(toTop ? mStacks.size() : 0, stack);
|
||||
}
|
||||
|
||||
TaskStack topStack() {
|
||||
return mStacks.get(mStacks.size() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagate the new bounds to all child stacks.
|
||||
* @param contentRect The bounds to apply at the top level.
|
||||
*/
|
||||
void resize(Rect contentRect) {
|
||||
mContentRect.set(contentRect);
|
||||
}
|
||||
|
||||
boolean getStackBounds(int stackId, Rect bounds) {
|
||||
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
|
||||
final TaskStack stack = mStacks.get(stackNdx);
|
||||
if (stackId == stack.mStackId) {
|
||||
bounds.set(stack.mBounds);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void addStackBox(StackBox box, boolean toTop) {
|
||||
if (mStackBoxes.size() >= 2) {
|
||||
throw new RuntimeException("addStackBox: Too many toplevel StackBoxes!");
|
||||
}
|
||||
mStackBoxes.add(toTop ? mStackBoxes.size() : 0, box);
|
||||
}
|
||||
|
||||
void removeStackBox(StackBox box) {
|
||||
if (DEBUG_STACK) Slog.d(TAG, "removeStackBox: box=" + box);
|
||||
final TaskStack stack = box.mStack;
|
||||
if (stack != null && stack.mStackId == HOME_STACK_ID) {
|
||||
// Never delete the home stack, even if it is empty.
|
||||
if (DEBUG_STACK) Slog.d(TAG, "removeStackBox: Not deleting home stack.");
|
||||
return;
|
||||
}
|
||||
mStackBoxes.remove(box);
|
||||
}
|
||||
|
||||
StackBoxInfo getStackBoxInfo(StackBox box) {
|
||||
StackBoxInfo info = new StackBoxInfo();
|
||||
info.stackBoxId = box.mStackBoxId;
|
||||
info.weight = box.mWeight;
|
||||
info.vertical = box.mVertical;
|
||||
info.bounds = new Rect(box.mBounds);
|
||||
if (box.mStack != null) {
|
||||
info.stackId = box.mStack.mStackId;
|
||||
// ActivityManagerService will fill in the StackInfo.
|
||||
} else {
|
||||
info.stackId = -1;
|
||||
info.children = new StackBoxInfo[2];
|
||||
info.children[0] = getStackBoxInfo(box.mFirst);
|
||||
info.children[1] = getStackBoxInfo(box.mSecond);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
ArrayList<StackBoxInfo> getStackBoxInfos() {
|
||||
ArrayList<StackBoxInfo> list = new ArrayList<StackBoxInfo>();
|
||||
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
list.add(getStackBoxInfo(mStackBoxes.get(stackBoxNdx)));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the home StackBox to the top or bottom of mStackBoxes. That is the only place
|
||||
* it is allowed to be. This is a nop if the home StackBox is already in the correct position.
|
||||
* @param toTop Move home to the top of mStackBoxes if true, to the bottom if false.
|
||||
* @return true if a change was made, false otherwise.
|
||||
*/
|
||||
boolean moveHomeStackBox(boolean toTop) {
|
||||
if (DEBUG_STACK) Slog.d(TAG, "moveHomeStackBox: toTop=" + toTop + " Callers=" +
|
||||
Debug.getCallers(4));
|
||||
EventLog.writeEvent(EventLogTags.WM_HOME_STACK_MOVED, toTop ? 1 : 0);
|
||||
switch (mStackBoxes.size()) {
|
||||
case 0: throw new RuntimeException("moveHomeStackBox: No home StackBox!");
|
||||
case 1: return false; // Only the home StackBox exists.
|
||||
case 2:
|
||||
if (homeOnTop() ^ toTop) {
|
||||
mStackBoxes.add(mStackBoxes.remove(0));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
default: throw new RuntimeException("moveHomeStackBox: Too many toplevel StackBoxes!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagate the new bounds to all child stack boxes, applying weights as we move down.
|
||||
* @param contentRect The bounds to apply at the top level.
|
||||
*/
|
||||
boolean setStackBoxSize(Rect contentRect) {
|
||||
boolean change = false;
|
||||
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
change |= mStackBoxes.get(stackBoxNdx).setStackBoxSizes(contentRect, true);
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
Rect getStackBounds(int stackId) {
|
||||
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
Rect bounds = mStackBoxes.get(stackBoxNdx).getStackBounds(stackId);
|
||||
if (bounds != null) {
|
||||
return bounds;
|
||||
int stackIdFromPoint(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;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
int stackIdFromPoint(int x, int y) {
|
||||
StackBox topBox = mStackBoxes.get(mStackBoxes.size() - 1);
|
||||
return topBox.stackIdFromPoint(x, y);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void setTouchExcludeRegion(TaskStack focusedStack) {
|
||||
@@ -408,48 +307,48 @@ class DisplayContent {
|
||||
}
|
||||
}
|
||||
|
||||
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
mStackBoxes.get(stackBoxNdx).switchUserStacks(newUserId);
|
||||
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
|
||||
mStacks.get(stackNdx).switchUser(newUserId);
|
||||
}
|
||||
}
|
||||
|
||||
void resetAnimationBackgroundAnimator() {
|
||||
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
mStackBoxes.get(stackBoxNdx).resetAnimationBackgroundAnimator();
|
||||
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
|
||||
mStacks.get(stackNdx).resetAnimationBackgroundAnimator();
|
||||
}
|
||||
}
|
||||
|
||||
boolean animateDimLayers() {
|
||||
boolean result = false;
|
||||
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
result |= mStackBoxes.get(stackBoxNdx).animateDimLayers();
|
||||
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
|
||||
result |= mStacks.get(stackNdx).animateDimLayers();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void resetDimming() {
|
||||
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
mStackBoxes.get(stackBoxNdx).resetDimming();
|
||||
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
|
||||
mStacks.get(stackNdx).resetDimmingTag();
|
||||
}
|
||||
}
|
||||
|
||||
boolean isDimming() {
|
||||
boolean result = false;
|
||||
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
result |= mStackBoxes.get(stackBoxNdx).isDimming();
|
||||
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
|
||||
result |= mStacks.get(stackNdx).isDimming();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void stopDimmingIfNeeded() {
|
||||
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
mStackBoxes.get(stackBoxNdx).stopDimmingIfNeeded();
|
||||
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
|
||||
mStacks.get(stackNdx).stopDimmingIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
void close() {
|
||||
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
|
||||
mStackBoxes.get(stackBoxNdx).close();
|
||||
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
|
||||
mStacks.get(stackNdx).close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,9 +376,10 @@ class DisplayContent {
|
||||
pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
|
||||
pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
|
||||
pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded);
|
||||
for (int boxNdx = 0; boxNdx < mStackBoxes.size(); ++boxNdx) {
|
||||
pw.print(prefix); pw.print("StackBox #"); pw.println(boxNdx);
|
||||
mStackBoxes.get(boxNdx).dump(prefix + " ", pw);
|
||||
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
|
||||
final TaskStack stack = mStacks.get(stackNdx);
|
||||
pw.print(prefix); pw.print("mStacks[" + stackNdx + "]"); pw.println(stack.mStackId);
|
||||
stack.dump(prefix + " ", pw);
|
||||
}
|
||||
int ndx = numTokens();
|
||||
if (ndx > 0) {
|
||||
|
||||
@@ -41,7 +41,7 @@ class FocusedStackFrame {
|
||||
private final SurfaceControl mSurfaceControl;
|
||||
private final Surface mSurface = new Surface();
|
||||
private final Rect mLastBounds = new Rect();
|
||||
private final Rect mBounds = new Rect();
|
||||
final Rect mBounds = new Rect();
|
||||
private final Rect mTmpDrawRect = new Rect();
|
||||
|
||||
public FocusedStackFrame(Display display, SurfaceSession session) {
|
||||
@@ -131,9 +131,9 @@ class FocusedStackFrame {
|
||||
}
|
||||
}
|
||||
|
||||
public void setBounds(Rect bounds) {
|
||||
if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + bounds);
|
||||
mBounds.set(bounds);
|
||||
public void setBounds(TaskStack stack) {
|
||||
stack.getBounds(mBounds);
|
||||
if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + mBounds);
|
||||
}
|
||||
|
||||
public void setLayer(int layer) {
|
||||
|
||||
@@ -58,6 +58,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
|
||||
private final Object mInputDevicesReadyMonitor = new Object();
|
||||
private boolean mInputDevicesReady;
|
||||
|
||||
Rect mTmpRect = new Rect();
|
||||
|
||||
public InputMonitor(WindowManagerService service) {
|
||||
mService = service;
|
||||
}
|
||||
@@ -175,7 +177,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
|
||||
if (modal && child.mAppToken != null) {
|
||||
// Limit the outer touch to the activity stack region.
|
||||
flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||
inputWindowHandle.touchableRegion.set(child.getStackBounds());
|
||||
child.getStackBounds(mTmpRect);
|
||||
inputWindowHandle.touchableRegion.set(mTmpRect);
|
||||
} else {
|
||||
// Not modal or full screen modal
|
||||
child.getTouchableRegion(inputWindowHandle.touchableRegion);
|
||||
|
||||
@@ -1,414 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.util.Slog;
|
||||
|
||||
import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
|
||||
import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
|
||||
import static com.android.server.wm.WindowManagerService.TAG;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class StackBox {
|
||||
/** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */
|
||||
public static final int TASK_STACK_GOES_BEFORE = 0;
|
||||
/** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */
|
||||
public static final int TASK_STACK_GOES_AFTER = 1;
|
||||
/** Used with {@link WindowManagerService#createStack}. Horizontal to left of. */
|
||||
public static final int TASK_STACK_TO_LEFT_OF = 2;
|
||||
/** Used with {@link WindowManagerService#createStack}. Horizontal to right of. */
|
||||
public static final int TASK_STACK_TO_RIGHT_OF = 3;
|
||||
/** Used with {@link WindowManagerService#createStack}. Vertical: lower t/b Rect values. */
|
||||
public static final int TASK_STACK_GOES_ABOVE = 4;
|
||||
/** Used with {@link WindowManagerService#createStack}. Vertical: higher t/b Rect values. */
|
||||
public static final int TASK_STACK_GOES_BELOW = 5;
|
||||
/** Used with {@link WindowManagerService#createStack}. Put on a higher layer on display. */
|
||||
public static final int TASK_STACK_GOES_OVER = 6;
|
||||
/** Used with {@link WindowManagerService#createStack}. Put on a lower layer on display. */
|
||||
public static final int TASK_STACK_GOES_UNDER = 7;
|
||||
|
||||
static int sCurrentBoxId = 0;
|
||||
|
||||
/** Unique id for this box */
|
||||
final int mStackBoxId;
|
||||
|
||||
/** The service */
|
||||
final WindowManagerService mService;
|
||||
|
||||
/** The display this box sits in. */
|
||||
final DisplayContent mDisplayContent;
|
||||
|
||||
/** Non-null indicates this is mFirst or mSecond of a parent StackBox. Null indicates this
|
||||
* is this entire size of mDisplayContent. */
|
||||
StackBox mParent;
|
||||
|
||||
/** First child, this is null exactly when mStack is non-null. */
|
||||
StackBox mFirst;
|
||||
|
||||
/** Second child, this is null exactly when mStack is non-null. */
|
||||
StackBox mSecond;
|
||||
|
||||
/** Stack of Tasks, this is null exactly when mFirst and mSecond are non-null. */
|
||||
TaskStack mStack;
|
||||
|
||||
/** Content limits relative to the DisplayContent this sits in. */
|
||||
Rect mBounds = new Rect();
|
||||
|
||||
/** Relative orientation of mFirst and mSecond. */
|
||||
boolean mVertical;
|
||||
|
||||
/** Fraction of mBounds to devote to mFirst, remainder goes to mSecond */
|
||||
float mWeight;
|
||||
|
||||
/** Dirty flag. Something inside this or some descendant of this has changed. */
|
||||
boolean layoutNeeded;
|
||||
|
||||
/** True if this StackBox sits below the Status Bar. */
|
||||
boolean mUnderStatusBar;
|
||||
|
||||
/** Used to keep from reallocating a temporary Rect for propagating bounds to child boxes */
|
||||
Rect mTmpRect = new Rect();
|
||||
|
||||
StackBox(WindowManagerService service, DisplayContent displayContent, StackBox parent) {
|
||||
synchronized (StackBox.class) {
|
||||
mStackBoxId = sCurrentBoxId++;
|
||||
}
|
||||
|
||||
mService = service;
|
||||
mDisplayContent = displayContent;
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
/** Propagate #layoutNeeded bottom up. */
|
||||
void makeDirty() {
|
||||
layoutNeeded = true;
|
||||
if (mParent != null) {
|
||||
mParent.makeDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a particular StackBox is this one or a descendant of this one.
|
||||
* @param stackBoxId The StackBox being searched for.
|
||||
* @return true if the specified StackBox matches this or one of its descendants.
|
||||
*/
|
||||
boolean contains(int stackBoxId) {
|
||||
return mStackBoxId == stackBoxId ||
|
||||
(mStack == null && (mFirst.contains(stackBoxId) || mSecond.contains(stackBoxId)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the stackId of the stack that intersects the passed point.
|
||||
* @param x coordinate of point.
|
||||
* @param y coordinate of point.
|
||||
* @return -1 if point is outside of mBounds, otherwise the stackId of the containing stack.
|
||||
*/
|
||||
int stackIdFromPoint(int x, int y) {
|
||||
if (!mBounds.contains(x, y)) {
|
||||
return -1;
|
||||
}
|
||||
if (mStack != null) {
|
||||
return mStack.mStackId;
|
||||
}
|
||||
int stackId = mFirst.stackIdFromPoint(x, y);
|
||||
if (stackId >= 0) {
|
||||
return stackId;
|
||||
}
|
||||
return mSecond.stackIdFromPoint(x, y);
|
||||
}
|
||||
|
||||
/** Determine if this StackBox is the first child or second child.
|
||||
* @return true if this is the first child.
|
||||
*/
|
||||
boolean isFirstChild() {
|
||||
return mParent != null && mParent.mFirst == this;
|
||||
}
|
||||
|
||||
/** Returns the bounds of the specified TaskStack if it is contained in this StackBox.
|
||||
* @param stackId the TaskStack to find the bounds of.
|
||||
* @return a new Rect with the bounds of stackId if it is within this StackBox, null otherwise.
|
||||
*/
|
||||
Rect getStackBounds(int stackId) {
|
||||
if (mStack != null) {
|
||||
return mStack.mStackId == stackId ? new Rect(mBounds) : null;
|
||||
}
|
||||
Rect bounds = mFirst.getStackBounds(stackId);
|
||||
if (bounds != null) {
|
||||
return bounds;
|
||||
}
|
||||
return mSecond.getStackBounds(stackId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new TaskStack relative to a specified one by splitting the StackBox containing
|
||||
* the specified TaskStack into two children. The size and position each of the new StackBoxes
|
||||
* is determined by the passed parameters.
|
||||
* @param stackId The id of the new TaskStack to create.
|
||||
* @param relativeStackBoxId The id of the StackBox to place the new TaskStack next to.
|
||||
* @param position One of the static TASK_STACK_GOES_xxx positions defined in this class.
|
||||
* @param weight The percentage size of the parent StackBox to devote to the new TaskStack.
|
||||
* @return The new TaskStack.
|
||||
*/
|
||||
TaskStack split(int stackId, int relativeStackBoxId, int position, float weight) {
|
||||
if (mStackBoxId != relativeStackBoxId) {
|
||||
// This is not the targeted StackBox.
|
||||
if (mStack != null) {
|
||||
return null;
|
||||
}
|
||||
// Propagate the split to see if the targeted StackBox is in either sub box.
|
||||
TaskStack stack = mFirst.split(stackId, relativeStackBoxId, position, weight);
|
||||
if (stack != null) {
|
||||
return stack;
|
||||
}
|
||||
return mSecond.split(stackId, relativeStackBoxId, position, weight);
|
||||
}
|
||||
|
||||
// Found it!
|
||||
TaskStack stack = new TaskStack(mService, stackId, mDisplayContent);
|
||||
TaskStack firstStack;
|
||||
TaskStack secondStack;
|
||||
if (position == TASK_STACK_GOES_BEFORE) {
|
||||
// TODO: Test Configuration here for LTR/RTL.
|
||||
position = TASK_STACK_TO_LEFT_OF;
|
||||
} else if (position == TASK_STACK_GOES_AFTER) {
|
||||
// TODO: Test Configuration here for LTR/RTL.
|
||||
position = TASK_STACK_TO_RIGHT_OF;
|
||||
}
|
||||
switch (position) {
|
||||
default:
|
||||
case TASK_STACK_TO_LEFT_OF:
|
||||
case TASK_STACK_TO_RIGHT_OF:
|
||||
mVertical = false;
|
||||
if (position == TASK_STACK_TO_LEFT_OF) {
|
||||
mWeight = weight;
|
||||
firstStack = stack;
|
||||
secondStack = mStack;
|
||||
} else {
|
||||
mWeight = 1.0f - weight;
|
||||
firstStack = mStack;
|
||||
secondStack = stack;
|
||||
}
|
||||
break;
|
||||
case TASK_STACK_GOES_ABOVE:
|
||||
case TASK_STACK_GOES_BELOW:
|
||||
mVertical = true;
|
||||
if (position == TASK_STACK_GOES_ABOVE) {
|
||||
mWeight = weight;
|
||||
firstStack = stack;
|
||||
secondStack = mStack;
|
||||
} else {
|
||||
mWeight = 1.0f - weight;
|
||||
firstStack = mStack;
|
||||
secondStack = stack;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
mFirst = new StackBox(mService, mDisplayContent, this);
|
||||
firstStack.mStackBox = mFirst;
|
||||
mFirst.mStack = firstStack;
|
||||
|
||||
mSecond = new StackBox(mService, mDisplayContent, this);
|
||||
secondStack.mStackBox = mSecond;
|
||||
mSecond.mStack = secondStack;
|
||||
|
||||
mStack = null;
|
||||
return stack;
|
||||
}
|
||||
|
||||
/** Return the stackId of the first mFirst StackBox with a non-null mStack */
|
||||
int getStackId() {
|
||||
if (mStack != null) {
|
||||
return mStack.mStackId;
|
||||
}
|
||||
return mFirst.getStackId();
|
||||
}
|
||||
|
||||
/** Remove this box and propagate its sibling's content up to their parent.
|
||||
* @return The first stackId of the resulting StackBox. */
|
||||
int remove() {
|
||||
mDisplayContent.layoutNeeded = true;
|
||||
|
||||
if (mParent == null) {
|
||||
// This is the top-plane stack.
|
||||
if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: removing top plane.");
|
||||
mDisplayContent.removeStackBox(this);
|
||||
return HOME_STACK_ID;
|
||||
}
|
||||
|
||||
StackBox sibling = isFirstChild() ? mParent.mSecond : mParent.mFirst;
|
||||
StackBox grandparent = mParent.mParent;
|
||||
sibling.mParent = grandparent;
|
||||
if (grandparent == null) {
|
||||
// mParent is a top-plane stack. Now sibling will be.
|
||||
if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent null");
|
||||
mDisplayContent.removeStackBox(mParent);
|
||||
mDisplayContent.addStackBox(sibling, true);
|
||||
} else {
|
||||
if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent getting sibling");
|
||||
if (mParent.isFirstChild()) {
|
||||
grandparent.mFirst = sibling;
|
||||
} else {
|
||||
grandparent.mSecond = sibling;
|
||||
}
|
||||
}
|
||||
return sibling.getStackId();
|
||||
}
|
||||
|
||||
boolean resize(int stackBoxId, float weight) {
|
||||
if (mStackBoxId != stackBoxId) {
|
||||
return mStack == null &&
|
||||
(mFirst.resize(stackBoxId, weight) || mSecond.resize(stackBoxId, weight));
|
||||
}
|
||||
// Don't change weight on topmost stack.
|
||||
if (mParent != null) {
|
||||
mParent.mWeight = isFirstChild() ? weight : 1.0f - weight;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** If this is a terminal StackBox (contains a TaskStack) set the bounds.
|
||||
* @param bounds The rectangle to set the bounds to.
|
||||
* @param underStatusBar True if the StackBox is directly below the Status Bar.
|
||||
* @return True if the bounds changed, false otherwise. */
|
||||
boolean setStackBoxSizes(Rect bounds, boolean underStatusBar) {
|
||||
boolean change = false;
|
||||
if (mUnderStatusBar != underStatusBar) {
|
||||
change = true;
|
||||
mUnderStatusBar = underStatusBar;
|
||||
}
|
||||
if (mStack != null) {
|
||||
change |= !mBounds.equals(bounds);
|
||||
if (change) {
|
||||
mBounds.set(bounds);
|
||||
mStack.setBounds(bounds, underStatusBar);
|
||||
}
|
||||
} else {
|
||||
mTmpRect.set(bounds);
|
||||
if (mVertical) {
|
||||
final int height = bounds.height();
|
||||
int firstHeight = (int)(height * mWeight);
|
||||
mTmpRect.bottom = bounds.top + firstHeight;
|
||||
change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar);
|
||||
mTmpRect.top = mTmpRect.bottom;
|
||||
mTmpRect.bottom = bounds.top + height;
|
||||
change |= mSecond.setStackBoxSizes(mTmpRect, false);
|
||||
} else {
|
||||
final int width = bounds.width();
|
||||
int firstWidth = (int)(width * mWeight);
|
||||
mTmpRect.right = bounds.left + firstWidth;
|
||||
change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar);
|
||||
mTmpRect.left = mTmpRect.right;
|
||||
mTmpRect.right = bounds.left + width;
|
||||
change |= mSecond.setStackBoxSizes(mTmpRect, underStatusBar);
|
||||
}
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
void resetAnimationBackgroundAnimator() {
|
||||
if (mStack != null) {
|
||||
mStack.resetAnimationBackgroundAnimator();
|
||||
return;
|
||||
}
|
||||
mFirst.resetAnimationBackgroundAnimator();
|
||||
mSecond.resetAnimationBackgroundAnimator();
|
||||
}
|
||||
|
||||
boolean animateDimLayers() {
|
||||
if (mStack != null) {
|
||||
return mStack.animateDimLayers();
|
||||
}
|
||||
boolean result = mFirst.animateDimLayers();
|
||||
result |= mSecond.animateDimLayers();
|
||||
return result;
|
||||
}
|
||||
|
||||
void resetDimming() {
|
||||
if (mStack != null) {
|
||||
mStack.resetDimmingTag();
|
||||
return;
|
||||
}
|
||||
mFirst.resetDimming();
|
||||
mSecond.resetDimming();
|
||||
}
|
||||
|
||||
boolean isDimming() {
|
||||
if (mStack != null) {
|
||||
return mStack.isDimming();
|
||||
}
|
||||
boolean result = mFirst.isDimming();
|
||||
result |= mSecond.isDimming();
|
||||
return result;
|
||||
}
|
||||
|
||||
void stopDimmingIfNeeded() {
|
||||
if (mStack != null) {
|
||||
mStack.stopDimmingIfNeeded();
|
||||
return;
|
||||
}
|
||||
mFirst.stopDimmingIfNeeded();
|
||||
mSecond.stopDimmingIfNeeded();
|
||||
}
|
||||
|
||||
void switchUserStacks(int userId) {
|
||||
if (mStack != null) {
|
||||
mStack.switchUser(userId);
|
||||
return;
|
||||
}
|
||||
mFirst.switchUserStacks(userId);
|
||||
mSecond.switchUserStacks(userId);
|
||||
}
|
||||
|
||||
void close() {
|
||||
if (mStack != null) {
|
||||
mStack.mDimLayer.mDimSurface.destroy();
|
||||
mStack.mAnimationBackgroundSurface.mDimSurface.destroy();
|
||||
return;
|
||||
}
|
||||
mFirst.close();
|
||||
mSecond.close();
|
||||
}
|
||||
|
||||
public void dump(String prefix, PrintWriter pw) {
|
||||
pw.print(prefix); pw.print("mParent="); pw.println(mParent);
|
||||
pw.print(prefix); pw.print("mBounds="); pw.print(mBounds.toShortString());
|
||||
pw.print(" mVertical="); pw.print(mVertical);
|
||||
pw.print(" layoutNeeded="); pw.println(layoutNeeded);
|
||||
if (mFirst != null) {
|
||||
pw.print(prefix); pw.print("mFirst="); pw.println(System.identityHashCode(mFirst));
|
||||
mFirst.dump(prefix + " ", pw);
|
||||
pw.print(prefix); pw.print("mSecond="); pw.println(System.identityHashCode(mSecond));
|
||||
mSecond.dump(prefix + " ", pw);
|
||||
} else {
|
||||
pw.print(prefix); pw.print("mStack="); pw.println(mStack);
|
||||
mStack.dump(prefix + " ", pw);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (mStack != null) {
|
||||
return "Box{" + hashCode() + " stack=" + mStack.mStackId + "}";
|
||||
}
|
||||
return "Box{" + hashCode() + " parent=" + System.identityHashCode(mParent)
|
||||
+ " first=" + System.identityHashCode(mFirst)
|
||||
+ " second=" + System.identityHashCode(mSecond) + "}";
|
||||
}
|
||||
}
|
||||
@@ -26,8 +26,6 @@ import android.util.Slog;
|
||||
import android.util.TypedValue;
|
||||
import com.android.server.EventLogTags;
|
||||
|
||||
import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -49,8 +47,9 @@ public class TaskStack {
|
||||
* mTaskHistory in the ActivityStack with the same mStackId */
|
||||
private final ArrayList<Task> mTasks = new ArrayList<Task>();
|
||||
|
||||
/** The StackBox this sits in. */
|
||||
StackBox mStackBox;
|
||||
/** Content limits relative to the DisplayContent this sits in. Empty indicates fullscreen,
|
||||
* Nonempty is size of this TaskStack but is also used to scale if DisplayContent changes. */
|
||||
Rect mBounds = new Rect();
|
||||
|
||||
/** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */
|
||||
final DimLayer mDimLayer;
|
||||
@@ -74,6 +73,9 @@ public class TaskStack {
|
||||
mDisplayContent = displayContent;
|
||||
mDimLayer = new DimLayer(service, this);
|
||||
mAnimationBackgroundSurface = new DimLayer(service, this);
|
||||
// TODO: remove bounds from log, they are always 0.
|
||||
EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, mBounds.left, mBounds.top,
|
||||
mBounds.right, mBounds.bottom);
|
||||
}
|
||||
|
||||
DisplayContent getDisplayContent() {
|
||||
@@ -84,12 +86,64 @@ public class TaskStack {
|
||||
return mTasks;
|
||||
}
|
||||
|
||||
boolean isHomeStack() {
|
||||
return mStackId == HOME_STACK_ID;
|
||||
private void resizeWindows() {
|
||||
final boolean underStatusBar = mBounds.top == 0;
|
||||
|
||||
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);
|
||||
}
|
||||
win.mUnderStatusBar = underStatusBar;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasSibling() {
|
||||
return mStackBox.mParent != null;
|
||||
boolean setBounds(Rect bounds) {
|
||||
if (mBounds.equals(bounds)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mDimLayer.setBounds(bounds);
|
||||
mAnimationBackgroundSurface.setBounds(bounds);
|
||||
mBounds.set(bounds);
|
||||
|
||||
resizeWindows();
|
||||
return true;
|
||||
}
|
||||
|
||||
void getBounds(Rect out) {
|
||||
if (mBounds.isEmpty()) {
|
||||
mDisplayContent.getLogicalDisplayRect(out);
|
||||
} else {
|
||||
out.set(mBounds);
|
||||
}
|
||||
out.intersect(mDisplayContent.mContentRect);
|
||||
}
|
||||
|
||||
boolean isFullscreen() {
|
||||
return mBounds.isEmpty();
|
||||
}
|
||||
|
||||
void resizeBounds(float oldWidth, float oldHeight, float newWidth, float newHeight) {
|
||||
if (oldWidth == newWidth && oldHeight == newHeight) {
|
||||
return;
|
||||
}
|
||||
float widthScale = newWidth / oldWidth;
|
||||
float heightScale = newHeight / oldHeight;
|
||||
mBounds.left = (int)(mBounds.left * widthScale + 0.5);
|
||||
mBounds.top = (int)(mBounds.top * heightScale + 0.5);
|
||||
mBounds.right = (int)(mBounds.right * widthScale + 0.5);
|
||||
mBounds.bottom = (int)(mBounds.bottom * heightScale + 0.5);
|
||||
resizeWindows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,9 +151,7 @@ public class TaskStack {
|
||||
* @param task The task to add.
|
||||
* @param toTop Whether to add it to the top or bottom.
|
||||
*/
|
||||
boolean addTask(Task task, boolean toTop) {
|
||||
mStackBox.makeDirty();
|
||||
|
||||
void addTask(Task task, boolean toTop) {
|
||||
int stackNdx;
|
||||
if (!toTop) {
|
||||
stackNdx = 0;
|
||||
@@ -122,20 +174,20 @@ public class TaskStack {
|
||||
|
||||
task.mStack = this;
|
||||
mDisplayContent.addTask(task, toTop);
|
||||
return mDisplayContent.moveHomeStackBox(mStackId == HOME_STACK_ID);
|
||||
mDisplayContent.moveStack(this, true);
|
||||
}
|
||||
|
||||
boolean moveTaskToTop(Task task) {
|
||||
void moveTaskToTop(Task task) {
|
||||
if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToTop: task=" + task + " Callers="
|
||||
+ Debug.getCallers(6));
|
||||
mTasks.remove(task);
|
||||
return addTask(task, true);
|
||||
addTask(task, true);
|
||||
}
|
||||
|
||||
boolean moveTaskToBottom(Task task) {
|
||||
void moveTaskToBottom(Task task) {
|
||||
if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToBottom: task=" + task);
|
||||
mTasks.remove(task);
|
||||
return addTask(task, false);
|
||||
addTask(task, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,7 +197,6 @@ public class TaskStack {
|
||||
*/
|
||||
void removeTask(Task task) {
|
||||
if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
|
||||
mStackBox.makeDirty();
|
||||
mTasks.remove(task);
|
||||
mDisplayContent.removeTask(task);
|
||||
}
|
||||
@@ -154,7 +205,7 @@ public class TaskStack {
|
||||
mAnimationBackgroundSurface.destroySurface();
|
||||
mDimLayer.destroySurface();
|
||||
EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
|
||||
return mStackBox.remove();
|
||||
return mDisplayContent.topStack().mStackId;
|
||||
}
|
||||
|
||||
void resetAnimationBackgroundAnimator() {
|
||||
@@ -259,28 +310,6 @@ public class TaskStack {
|
||||
}
|
||||
}
|
||||
|
||||
void setBounds(Rect bounds, boolean underStatusBar) {
|
||||
mDimLayer.setBounds(bounds);
|
||||
mAnimationBackgroundSurface.setBounds(bounds);
|
||||
|
||||
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);
|
||||
}
|
||||
win.mUnderStatusBar = underStatusBar;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void switchUser(int userId) {
|
||||
int top = mTasks.size();
|
||||
for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
|
||||
@@ -293,6 +322,11 @@ public class TaskStack {
|
||||
}
|
||||
}
|
||||
|
||||
void close() {
|
||||
mDimLayer.mDimSurface.destroy();
|
||||
mAnimationBackgroundSurface.mDimSurface.destroy();
|
||||
}
|
||||
|
||||
public void dump(String prefix, PrintWriter pw) {
|
||||
pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
|
||||
for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
|
||||
|
||||
@@ -45,7 +45,6 @@ import com.android.server.power.PowerManagerService;
|
||||
import com.android.server.power.ShutdownThread;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.ActivityManager.StackBoxInfo;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.StatusBarManager;
|
||||
@@ -3775,10 +3774,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
if (stack == null) {
|
||||
mFocusedStackFrame.setVisibility(false);
|
||||
} else {
|
||||
final StackBox box = stack.mStackBox;
|
||||
final Rect bounds = box.mBounds;
|
||||
final boolean multipleStacks = box.mParent != null;
|
||||
mFocusedStackFrame.setBounds(bounds);
|
||||
mFocusedStackFrame.setBounds(stack);
|
||||
final boolean multipleStacks = !stack.isFullscreen();
|
||||
mFocusedStackFrame.setVisibility(multipleStacks);
|
||||
}
|
||||
} finally {
|
||||
@@ -4785,10 +4782,12 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
final TaskStack stack = task.mStack;
|
||||
final DisplayContent displayContent = task.getDisplayContent();
|
||||
final boolean isHomeStackTask = stack.isHomeStack();
|
||||
if (isHomeStackTask != displayContent.homeOnTop()) {
|
||||
// First move the stack itself.
|
||||
displayContent.moveHomeStackBox(isHomeStackTask);
|
||||
displayContent.moveStack(stack, true);
|
||||
final TaskStack homeStack = displayContent.getHomeStack();
|
||||
if (homeStack != stack) {
|
||||
// When a non-home stack moves to the top, the home stack moves to the
|
||||
// bottom.
|
||||
displayContent.moveStack(homeStack, false);
|
||||
}
|
||||
stack.moveTaskToTop(task);
|
||||
}
|
||||
@@ -4819,36 +4818,19 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
/**
|
||||
* Create a new TaskStack and place it next to an existing stack.
|
||||
* @param stackId The unique identifier of the new stack.
|
||||
* @param relativeStackBoxId The existing stack that this stack goes before or after.
|
||||
* @param position One of:
|
||||
* {@link StackBox#TASK_STACK_GOES_BEFORE}
|
||||
* {@link StackBox#TASK_STACK_GOES_AFTER}
|
||||
* {@link StackBox#TASK_STACK_GOES_ABOVE}
|
||||
* {@link StackBox#TASK_STACK_GOES_BELOW}
|
||||
* {@link StackBox#TASK_STACK_GOES_UNDER}
|
||||
* {@link StackBox#TASK_STACK_GOES_OVER}
|
||||
* @param weight Relative weight for determining how big to make the new TaskStack.
|
||||
*/
|
||||
public void createStack(int stackId, int relativeStackBoxId, int position, float weight) {
|
||||
public void createStack(int stackId, int displayId) {
|
||||
synchronized (mWindowMap) {
|
||||
if (position <= StackBox.TASK_STACK_GOES_BELOW &&
|
||||
(weight < STACK_WEIGHT_MIN || weight > STACK_WEIGHT_MAX)) {
|
||||
throw new IllegalArgumentException(
|
||||
"createStack: weight must be between " + STACK_WEIGHT_MIN + " and " +
|
||||
STACK_WEIGHT_MAX + ", weight=" + weight);
|
||||
}
|
||||
final int numDisplays = mDisplayContents.size();
|
||||
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
|
||||
final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
|
||||
TaskStack stack = displayContent.createStack(stackId, relativeStackBoxId, position,
|
||||
weight);
|
||||
if (stack != null) {
|
||||
if (displayContent.getDisplayId() == displayId) {
|
||||
TaskStack stack = displayContent.createStack(stackId);
|
||||
mStackIdToStack.put(stackId, stack);
|
||||
performLayoutAndPlaceSurfacesLocked();
|
||||
return;
|
||||
}
|
||||
}
|
||||
Slog.e(TAG, "createStack: Unable to find relativeStackBoxId=" + relativeStackBoxId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4895,40 +4877,27 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
public void resizeStackBox(int stackBoxId, float weight) {
|
||||
if (weight < STACK_WEIGHT_MIN || weight > STACK_WEIGHT_MAX) {
|
||||
throw new IllegalArgumentException(
|
||||
"resizeStack: weight must be between " + STACK_WEIGHT_MIN + " and " +
|
||||
STACK_WEIGHT_MAX + ", weight=" + weight);
|
||||
}
|
||||
public void resizeStack(int stackId, Rect bounds) {
|
||||
synchronized (mWindowMap) {
|
||||
final int numDisplays = mDisplayContents.size();
|
||||
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
|
||||
if (mDisplayContents.valueAt(displayNdx).resizeStack(stackBoxId, weight)) {
|
||||
performLayoutAndPlaceSurfacesLocked();
|
||||
return;
|
||||
}
|
||||
final TaskStack stack = mStackIdToStack.get(stackId);
|
||||
if (stack == null) {
|
||||
throw new IllegalArgumentException("resizeStack: stackId " + stackId
|
||||
+ " not found.");
|
||||
}
|
||||
if (stack.setBounds(bounds)) {
|
||||
stack.getDisplayContent().layoutNeeded = true;
|
||||
performLayoutAndPlaceSurfacesLocked();
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("resizeStack: stackBoxId " + stackBoxId
|
||||
+ " not found.");
|
||||
}
|
||||
|
||||
public ArrayList<StackBoxInfo> getStackBoxInfos() {
|
||||
synchronized(mWindowMap) {
|
||||
return getDefaultDisplayContentLocked().getStackBoxInfos();
|
||||
}
|
||||
}
|
||||
|
||||
public Rect getStackBounds(int stackId) {
|
||||
final int numDisplays = mDisplayContents.size();
|
||||
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
|
||||
Rect bounds = mDisplayContents.valueAt(displayNdx).getStackBounds(stackId);
|
||||
if (bounds != null) {
|
||||
return bounds;
|
||||
}
|
||||
public void getStackBounds(int stackId, Rect bounds) {
|
||||
final TaskStack stack = mStackIdToStack.get(stackId);
|
||||
if (stack != null) {
|
||||
stack.getBounds(bounds);
|
||||
return;
|
||||
}
|
||||
return null;
|
||||
bounds.setEmpty();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
@@ -5585,7 +5554,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
continue;
|
||||
}
|
||||
appWin = ws;
|
||||
stackBounds.set(ws.getStackBounds());
|
||||
ws.getStackBounds(stackBounds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8214,7 +8183,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
mPolicy.getContentRectLw(mTmpContentRect);
|
||||
displayContent.setStackBoxSize(mTmpContentRect);
|
||||
displayContent.resize(mTmpContentRect);
|
||||
|
||||
int seq = mLayoutSeq+1;
|
||||
if (seq < 0) seq = 0;
|
||||
|
||||
@@ -463,8 +463,8 @@ final class WindowState implements WindowManagerPolicy.WindowState {
|
||||
mHaveFrame = true;
|
||||
|
||||
TaskStack stack = mAppToken != null ? getStack() : null;
|
||||
if (stack != null && stack.hasSibling()) {
|
||||
mContainingFrame.set(getStackBounds(stack));
|
||||
if (stack != null && !stack.isFullscreen()) {
|
||||
getStackBounds(stack, mContainingFrame);
|
||||
if (mUnderStatusBar) {
|
||||
mContainingFrame.top = pf.top;
|
||||
}
|
||||
@@ -723,15 +723,16 @@ final class WindowState implements WindowManagerPolicy.WindowState {
|
||||
return mDisplayContent.getHomeStack();
|
||||
}
|
||||
|
||||
Rect getStackBounds() {
|
||||
return getStackBounds(getStack());
|
||||
void getStackBounds(Rect bounds) {
|
||||
getStackBounds(getStack(), bounds);
|
||||
}
|
||||
|
||||
private Rect getStackBounds(TaskStack stack) {
|
||||
private void getStackBounds(TaskStack stack, Rect bounds) {
|
||||
if (stack != null) {
|
||||
return stack.mStackBox.mBounds;
|
||||
stack.getBounds(bounds);
|
||||
return;
|
||||
}
|
||||
return mFrame;
|
||||
bounds.set(mFrame);
|
||||
}
|
||||
|
||||
public long getInputDispatchingTimeoutNanos() {
|
||||
|
||||
Reference in New Issue
Block a user