diff options
author | Craig Mautner <cmautner@google.com> | 2013-04-17 01:58:15 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-04-17 01:58:15 +0000 |
commit | 53078b25c91660e30849861e88da1a33998c554f (patch) | |
tree | 7a953bff348848c49c1582ecb2c961fa9fe01537 | |
parent | e76dd37bdb75e7ed757e1284249c64f0c58e869d (diff) | |
parent | 967212cb542e6eeb308678367b53381bff984c31 (diff) | |
download | frameworks_base-53078b25c91660e30849861e88da1a33998c554f.zip frameworks_base-53078b25c91660e30849861e88da1a33998c554f.tar.gz frameworks_base-53078b25c91660e30849861e88da1a33998c554f.tar.bz2 |
Merge "Implement stack splitting and task movement."
15 files changed, 503 insertions, 135 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index ccb9e1f..5f5c337 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -74,6 +74,7 @@ public class Am extends BaseCommand { (new Am()).run(args); } + @Override public void onShowUsage(PrintStream out) { out.println( "usage: am [subcommand] [options]\n" + @@ -99,6 +100,9 @@ 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 <RELATIVE_STACK_ID> <POSITION> <WEIGHT>\n" + + " am stack movetask <STACK_ID> <TASK_ID> [true|false]\n" + + " am stack dump\n" + "\n" + "am start: start an Activity. Options are:\n" + " -D: enable debugging\n" + @@ -181,6 +185,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" + + " <RELATIVE_STACK_ID>: existing stack's id.\n" + + " <POSITION>: 0: to left of, 1: to right of, 2: above, 3: below\n" + + " <WEIGHT>: float between 0.2 and 0.8 inclusive.\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 dump: list the hierarchy of stacks.\n" + + "\n" + "<INTENT> specifications include these flags and arguments:\n" + " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" + " [-c <CATEGORY> [-c <CATEGORY>] ...]\n" + @@ -213,6 +227,7 @@ public class Am extends BaseCommand { ); } + @Override public void onRun() throws Exception { mAm = ActivityManagerNative.getDefault(); @@ -259,6 +274,8 @@ public class Am extends BaseCommand { runSwitchUser(); } else if (op.equals("stop-user")) { runStopUser(); + } else if (op.equals("stack")) { + runStack(); } else { showError("Error: unknown command '" + op + "'"); } @@ -1029,7 +1046,7 @@ public class Am extends BaseCommand { } @Override - public boolean activityResuming(String pkg) throws RemoteException { + public boolean activityResuming(String pkg) { synchronized (this) { System.out.println("** Activity resuming: " + pkg); } @@ -1037,7 +1054,7 @@ public class Am extends BaseCommand { } @Override - public boolean activityStarting(Intent intent, String pkg) throws RemoteException { + public boolean activityStarting(Intent intent, String pkg) { synchronized (this) { System.out.println("** Activity starting: " + pkg); } @@ -1046,7 +1063,7 @@ public class Am extends BaseCommand { @Override public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg, - long timeMillis, String stackTrace) throws RemoteException { + long timeMillis, String stackTrace) { synchronized (this) { System.out.println("** ERROR: PROCESS CRASHED"); System.out.println("processName: " + processName); @@ -1063,8 +1080,7 @@ public class Am extends BaseCommand { } @Override - public int appEarlyNotResponding(String processName, int pid, String annotation) - throws RemoteException { + public int appEarlyNotResponding(String processName, int pid, String annotation) { synchronized (this) { System.out.println("** ERROR: EARLY PROCESS NOT RESPONDING"); System.out.println("processName: " + processName); @@ -1077,8 +1093,7 @@ public class Am extends BaseCommand { } @Override - public int appNotResponding(String processName, int pid, String processStats) - throws RemoteException { + public int appNotResponding(String processName, int pid, String processStats) { synchronized (this) { System.out.println("** ERROR: PROCESS NOT RESPONDING"); System.out.println("processName: " + processName); @@ -1326,7 +1341,7 @@ public class Am extends BaseCommand { @Override public void performReceive(Intent intent, int resultCode, String data, Bundle extras, - boolean ordered, boolean sticky, int sendingUser) throws RemoteException { + boolean ordered, boolean sticky, int sendingUser) { String line = "Broadcast completed: result=" + resultCode; if (data != null) line = line + ", data=\"" + data + "\""; if (extras != null) line = line + ", extras: " + extras; @@ -1359,6 +1374,7 @@ public class Am extends BaseCommand { mRawMode = rawMode; } + @Override public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) { synchronized (this) { // pretty printer mode? @@ -1381,6 +1397,7 @@ public class Am extends BaseCommand { } } + @Override public void instrumentationFinished(ComponentName name, int resultCode, Bundle results) { synchronized (this) { @@ -1421,4 +1438,65 @@ public class Am extends BaseCommand { return true; } } + + private void runStack() throws Exception { + String op = nextArgRequired(); + if (op.equals("create")) { + runStackCreate(); + } else if (op.equals("movetask")) { + runStackMoveTask(); + } else if (op.equals("dump")) { + runStackDump(); + } else { + showError("Error: unknown command '" + op + "'"); + return; + } + } + + private void runStackCreate() throws Exception { + 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(relativeTo, position, weight); + System.out.println("createStack returned " + stackId + "\n\n"); + } catch (RemoteException e) { + } + } + + private void runStackMoveTask() throws Exception { + String taskIdStr = nextArgRequired(); + int taskId = Integer.valueOf(taskIdStr); + String stackIdStr = nextArgRequired(); + int stackId = Integer.valueOf(stackIdStr); + String toTopStr = nextArgRequired(); + final boolean toTop; + if ("true".equals(toTopStr)) { + toTop = true; + } else if ("false".equals(toTopStr)) { + toTop = false; + } else { + System.err.println("Error: bad toTop arg: " + toTopStr); + return; + } + + try { + mAm.moveTaskToStack(taskId, stackId, toTop); + } catch (RemoteException e) { + } + } + + private void runStackDump() throws Exception { + try { + List<ActivityManager.StackInfo> stacks = mAm.getStacks(); + for (ActivityManager.StackInfo stack : stacks) { + System.out.println(stack); + } + } catch (RemoteException e) { + } + } } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index bb9e19f..729ebd7 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -31,9 +31,8 @@ import android.content.pm.UserInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; -import android.hardware.display.DisplayManager; +import android.graphics.Rect; import android.hardware.display.DisplayManagerGlobal; -import android.os.Binder; import android.os.Bundle; import android.os.Debug; import android.os.Handler; @@ -1229,7 +1228,74 @@ public class ActivityManager { } catch (RemoteException e) { } } - + + + /** + * Information you can retrieve about an ActivityStack in the system. + * @hide + */ + public static class StackInfo implements Parcelable { + public int stackId; + public Rect bounds; + public int[] taskIds; + public String[] taskNames; + + public StackInfo() { + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(stackId); + dest.writeInt(bounds.left); + dest.writeInt(bounds.top); + dest.writeInt(bounds.right); + dest.writeInt(bounds.bottom); + dest.writeIntArray(taskIds); + dest.writeStringArray(taskNames); + } + + public void readFromParcel(Parcel source) { + stackId = source.readInt(); + bounds = new Rect( + source.readInt(), source.readInt(), source.readInt(), source.readInt()); + taskIds = source.createIntArray(); + taskNames = source.createStringArray(); + } + + public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() { + @Override + public StackInfo createFromParcel(Parcel source) { + return new StackInfo(source); + } + @Override + public StackInfo[] newArray(int size) { + return new StackInfo[size]; + } + }; + + private StackInfo(Parcel source) { + readFromParcel(source); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(256); + sb.append("Stack id="); sb.append(stackId); + sb.append(" bounds="); sb.append(bounds.toShortString()); sb.append("\n"); + final String 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"); + } + return sb.toString(); + } + } + /** * @hide */ diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index f35584b..b089e2a 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -639,6 +639,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case GET_STACKS_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + List<ActivityManager.StackInfo> list = getStacks(); + reply.writeNoException(); + reply.writeTypedList(list); + return true; + } + case GET_TASK_FOR_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); @@ -2591,6 +2599,7 @@ class ActivityManagerProxy implements IActivityManager { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(position); data.writeInt(relativeStackId); data.writeFloat(weight); @@ -2606,6 +2615,7 @@ class ActivityManagerProxy implements IActivityManager { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(taskId); data.writeInt(stackId); data.writeInt(toTop ? 1 : 0); @@ -2619,6 +2629,7 @@ class ActivityManagerProxy implements IActivityManager { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(stackId); data.writeFloat(weight); mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, 0); @@ -2626,6 +2637,20 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } + @Override + public List<ActivityManager.StackInfo> getStacks() throws RemoteException + { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + mRemote.transact(GET_STACKS_TRANSACTION, data, reply, 0); + reply.readException(); + ArrayList<ActivityManager.StackInfo> list + = reply.createTypedArrayList(ActivityManager.StackInfo.CREATOR); + data.recycle(); + reply.recycle(); + return list; + } public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException { Parcel data = Parcel.obtain(); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 1e74c60..c52a35a 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -18,6 +18,7 @@ package android.app; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.RunningServiceInfo; +import android.app.ActivityManager.StackInfo; import android.content.ComponentName; import android.content.ContentProviderNative; import android.content.IContentProvider; @@ -114,9 +115,10 @@ 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 position, int relativeStackId, float weight) throws RemoteException; + public int createStack(int relativeStackId, int position, float weight) throws RemoteException; public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException; public void resizeStack(int stackId, float weight) throws RemoteException; + public List<StackInfo> getStacks() throws RemoteException; public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException; /* oneway */ public void reportThumbnail(IBinder token, @@ -646,4 +648,5 @@ public interface IActivityManager extends IInterface { int MOVE_TASK_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+166; int RESIZE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+167; int SET_USER_IS_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+168; + int GET_STACKS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+169; } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index c0044b6..b9f9e80 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -816,6 +816,14 @@ public interface WindowManagerPolicy { public int getSystemDecorRectLw(Rect systemRect); /** + * Return the rectangle of the screen that is available for applications to run in. + * This will be called immediately after {@link #beginLayoutLw}. + * + * @param r The rectangle to be filled with the boundaries available to applications. + */ + public void getContentRectLw(Rect r); + + /** * Called for each window attached to the window manager as layout is * proceeding. The implementation of this function must take care of * setting the window's frame, either here or in finishLayout(). diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 2988727..0f719db 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -87,7 +87,6 @@ import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.WindowManagerPolicy; import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; @@ -204,13 +203,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Vibrator pattern for haptic feedback of virtual key press. long[] mVirtualKeyVibePattern; - + // Vibrator pattern for a short vibration. long[] mKeyboardTapVibePattern; // Vibrator pattern for haptic feedback during boot when safe mode is disabled. long[] mSafeModeDisabledVibePattern; - + // Vibrator pattern for haptic feedback during boot when safe mode is enabled. long[] mSafeModeEnabledVibePattern; @@ -277,7 +276,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mOrientationSensorEnabled = false; int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; boolean mHasSoftInput = false; - + int mPointerLocationMode = 0; // guarded by mLock // The last window we were told about in focusChanged. @@ -374,7 +373,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final Rect mTmpContentFrame = new Rect(); static final Rect mTmpVisibleFrame = new Rect(); static final Rect mTmpNavigationFrame = new Rect(); - + WindowState mTopFullscreenOpaqueWindowState; boolean mTopIsFullscreen; boolean mForceStatusBar; @@ -532,12 +531,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { updateRotation(false); } } - + class MyOrientationListener extends WindowOrientationListener { MyOrientationListener(Context context, Handler handler) { super(context, handler); } - + @Override public void onProposedRotationChanged(int rotation) { if (localLOGV) Log.v(TAG, "onProposedRotationChanged, rotation=" + rotation); @@ -1283,6 +1282,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { != PackageManager.PERMISSION_GRANTED; } + @Override public void adjustWindowParamsLw(WindowManager.LayoutParams attrs) { switch (attrs.type) { case TYPE_SYSTEM_OVERLAY: @@ -1311,11 +1311,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - private boolean isBuiltInKeyboardVisible() { - return mHaveBuiltInKeyboard && !isHidden(mLidKeyboardAccessibility); - } - /** {@inheritDoc} */ + @Override public void adjustConfigurationLw(Configuration config, int keyboardPresence, int navigationPresence) { mHaveBuiltInKeyboard = (keyboardPresence & PRESENCE_INTERNAL) != 0; @@ -1340,6 +1337,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } /** {@inheritDoc} */ + @Override public int windowTypeToLayerLw(int type) { if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { return 2; @@ -2776,6 +2774,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } /** {@inheritDoc} */ + @Override public int getSystemDecorRectLw(Rect systemRect) { systemRect.left = mSystemLeft; systemRect.top = mSystemTop; @@ -2786,6 +2785,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { return 0; } + @Override + public void getContentRectLw(Rect r) { + r.set(mContentLeft, mContentTop, mContentRight, mContentBottom); + } + void setAttachedWindowFrames(WindowState win, int fl, int adjust, WindowState attached, boolean insetDecors, Rect pf, Rect df, Rect of, Rect cf, Rect vf) { if (win.getSurfaceLayer() > mDockLayer && attached.getSurfaceLayer() < mDockLayer) { diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 3d81135..52b933f 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -2866,11 +2866,11 @@ public final class ActivityManagerService extends ActivityManagerNative /** * This is the internal entry point for handling Activity.finish(). - * + * * @param token The Binder token referencing the Activity we want to finish. * @param resultCode Result code, if any, from this Activity. * @param resultData Result data (Intent), if any, from this Activity. - * + * * @return Returns true if the activity successfully finished, or false if it is still running. */ @Override @@ -2896,7 +2896,7 @@ public final class ActivityManagerService extends ActivityManagerNative } catch (RemoteException e) { mController = null; } - + if (!resumeOK) { return false; } @@ -2921,12 +2921,12 @@ public final class ActivityManagerService extends ActivityManagerNative Slog.w(TAG, msg); throw new SecurityException(msg); } - + synchronized(this) { if (mHeavyWeightProcess == null) { return; } - + ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( mHeavyWeightProcess.activities); for (int i=0; i<activities.size(); i++) { @@ -2936,13 +2936,13 @@ public final class ActivityManagerService extends ActivityManagerNative null, "finish-heavy", true); } } - + mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, mHeavyWeightProcess.userId, 0)); mHeavyWeightProcess = null; } } - + @Override public void crashApplication(int uid, int initialPid, String packageName, String message) { @@ -4632,6 +4632,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } + @Override public String getCallingPackage(IBinder token) { synchronized (this) { ActivityRecord r = getCallingRecordLocked(token); @@ -4639,6 +4640,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } + @Override public ComponentName getCallingActivity(IBinder token) { synchronized (this) { ActivityRecord r = getCallingRecordLocked(token); @@ -4665,6 +4667,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } + @Override public String getPackageForToken(IBinder token) { synchronized(this) { ActivityRecord r = ActivityRecord.isInStackLocked(token); @@ -4675,6 +4678,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } + @Override public IIntentSender getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, @@ -5961,6 +5965,7 @@ public final class ActivityManagerService extends ActivityManagerNative return list; } + @Override public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, @@ -6262,7 +6267,10 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public int createStack(int relativeStackId, int position, float weight) { synchronized (this) { - int stackId = mStackSupervisor.createStack(relativeStackId, position, weight); + if (mStackSupervisor.getStack(relativeStackId) == null) { + return -1; + } + int stackId = mStackSupervisor.createStack(); mWindowManager.createStack(stackId, relativeStackId, position, weight); return stackId; } @@ -6271,8 +6279,8 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void moveTaskToStack(int taskId, int stackId, boolean toTop) { synchronized (this) { - mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); mWindowManager.moveTaskToStack(taskId, stackId, toTop); + mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); } } @@ -6282,6 +6290,36 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override + public List<ActivityManager.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; + } + } + + @Override public int getTaskForActivity(IBinder token, boolean onlyRoot) { synchronized(this) { return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 568689f..0ca5db5 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -1358,7 +1358,7 @@ final class ActivityStack { // We need to start pausing the current activity so the top one // can be resumed... final ActivityStack lastStack = mStackSupervisor.getLastStack(); - if (lastStack.mResumedActivity != null) { + if ((isHomeStack() ^ lastStack.isHomeStack()) && lastStack.mResumedActivity != null) { if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing"); // At this point we want to put the upcoming activity's process // at the top of the LRU list, since we know we will be needing it @@ -1464,7 +1464,7 @@ final class ActivityStack { mService.mWindowManager.setAppWillBeHidden(prev.appToken); mService.mWindowManager.setAppVisibility(prev.appToken, false); } - } else if (numActivities() > 1) { + } else { if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: no previous"); if (mNoAnimActivities.contains(next)) { diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java index d3e5b48..7b8ad43 100644 --- a/services/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/java/com/android/server/am/ActivityStackSupervisor.java @@ -167,7 +167,7 @@ public class ActivityStackSupervisor { } boolean isFrontStack(ActivityStack stack) { - return stack == getTopStack(); + return !(stack.isHomeStack() ^ getTopStack().isHomeStack()); } boolean homeIsInFront() { @@ -299,10 +299,9 @@ public class ActivityStackSupervisor { } boolean allResumedActivitiesComplete() { - final boolean homeInBack = !homeIsInFront(); for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); - if (stack.isHomeStack() ^ homeInBack) { + if (isFrontStack(stack)) { final ActivityRecord r = stack.mResumedActivity; if (r != null && r.state != ActivityState.RESUMED) { return false; @@ -1512,7 +1511,7 @@ public class ActivityStackSupervisor { } } - private ActivityStack getStack(int stackId) { + ActivityStack getStack(int stackId) { for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); if (stack.getStackId() == stackId) { @@ -1522,7 +1521,11 @@ public class ActivityStackSupervisor { return null; } - int createStack(int relativeStackId, int position, float weight) { + ArrayList<ActivityStack> getStacks() { + return new ArrayList<ActivityStack>(mStacks); + } + + int createStack() { synchronized (this) { while (true) { if (++mLastStackId <= HOME_STACK_ID) { @@ -1545,6 +1548,7 @@ public class ActivityStackSupervisor { return; } stack.moveTask(taskId, toTop); + stack.resumeTopActivityLocked(null); } ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) { diff --git a/services/java/com/android/server/wm/DimLayer.java b/services/java/com/android/server/wm/DimLayer.java index 9bd36ba..91d6995 100644 --- a/services/java/com/android/server/wm/DimLayer.java +++ b/services/java/com/android/server/wm/DimLayer.java @@ -6,7 +6,6 @@ import android.graphics.PixelFormat; import android.os.SystemClock; import android.util.Slog; import android.view.DisplayInfo; -import android.view.Surface; import android.view.SurfaceControl; import java.io.PrintWriter; @@ -255,15 +254,16 @@ public class DimLayer { } public void printTo(String prefix, PrintWriter pw) { - pw.print(prefix); pw.print("mDimSurface="); pw.println(mDimSurface); - pw.print(prefix); pw.print(" mLayer="); pw.print(mLayer); + pw.print(prefix); pw.print("mDimSurface="); pw.print(mDimSurface); + pw.print(" mLayer="); pw.print(mLayer); pw.print(" mAlpha="); pw.println(mAlpha); pw.print(prefix); pw.print("mLastDimWidth="); pw.print(mLastDimWidth); - pw.print(" mLastDimWidth="); pw.println(mLastDimWidth); - pw.print(prefix); pw.print("Last animation: mStartTime="); pw.print(mStartTime); + pw.print(" mLastDimHeight="); pw.println(mLastDimHeight); + pw.print(prefix); pw.print("Last animation: "); pw.print(" mDuration="); pw.print(mDuration); + pw.print(" mStartTime="); pw.print(mStartTime); pw.print(" curTime="); pw.println(SystemClock.uptimeMillis()); - pw.print(" mStartAlpha="); pw.println(mStartAlpha); - pw.print(" mTargetAlpha="); pw.print(mTargetAlpha); + pw.print(prefix); pw.print(" mStartAlpha="); pw.print(mStartAlpha); + pw.print(" mTargetAlpha="); pw.println(mTargetAlpha); } } diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java index 5b2cf50..edf3d3b 100644 --- a/services/java/com/android/server/wm/DisplayContent.java +++ b/services/java/com/android/server/wm/DisplayContent.java @@ -167,10 +167,10 @@ class DisplayContent { throw new IllegalArgumentException("createStack: First stackId not " + HOME_STACK_ID); } - StackBox newBox = new StackBox(this, new Rect(0, 0, mDisplayInfo.logicalWidth, - mDisplayInfo.logicalHeight)); + StackBox newBox = new StackBox(this, null); mStackBoxes.add(newBox); - newStack = new TaskStack(stackId, newBox); + newStack = new TaskStack(stackId, this); + newStack.mStackBox = newBox; newBox.mStack = newStack; mHomeStack = newStack; } else { @@ -181,8 +181,9 @@ class DisplayContent { || position == StackBox.TASK_STACK_GOES_UNDER) { // Position indicates a new box is added at top level only. if (box.contains(relativeStackId)) { - StackBox newBox = new StackBox(this, box.mBounds); - newStack = new TaskStack(stackId, newBox); + StackBox newBox = new StackBox(this, null); + newStack = new TaskStack(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 " + @@ -203,13 +204,15 @@ class DisplayContent { + " not found."); } } + if (newStack != null) { + layoutNeeded = true; + } return newStack; } /** Refer to {@link WindowManagerService#resizeStack(int, float)} */ boolean resizeStack(int stackId, float weight) { - int stackBoxNdx; - for (stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { + for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { final StackBox box = mStackBoxes.get(stackBoxNdx); if (box.resize(stackId, weight)) { return true; @@ -250,6 +253,26 @@ class DisplayContent { } } + /** + * 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. + */ + void setStackBoxSize(Rect contentRect) { + for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { + mStackBoxes.get(stackBoxNdx).setStackBoxSizes(contentRect); + } + } + + 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; + } + } + return null; + } + public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId); final String subPrefix = " " + prefix; diff --git a/services/java/com/android/server/wm/StackBox.java b/services/java/com/android/server/wm/StackBox.java index 9525d7c..bcc5137 100644 --- a/services/java/com/android/server/wm/StackBox.java +++ b/services/java/com/android/server/wm/StackBox.java @@ -24,12 +24,17 @@ import java.io.PrintWriter; import java.util.ArrayList; public class StackBox { - /** For use with {@link WindowManagerService#createStack} */ - public static final int TASK_STACK_GOES_BEFORE = 0; + /** Used with {@link WindowManagerService#createStack}. To left of, lower l/r Rect values. */ + public static final int TASK_STACK_GOES_BEFORE = 0; // + /** Used with {@link WindowManagerService#createStack}. To right of, higher l/r Rect values. */ public static final int TASK_STACK_GOES_AFTER = 1; + /** Used with {@link WindowManagerService#createStack}. Vertical: lower t/b Rect values. */ public static final int TASK_STACK_GOES_ABOVE = 2; + /** Used with {@link WindowManagerService#createStack}. Vertical: higher t/b Rect values. */ public static final int TASK_STACK_GOES_BELOW = 3; + /** Used with {@link WindowManagerService#createStack}. Put on a higher layer on display. */ public static final int TASK_STACK_GOES_OVER = 4; + /** Used with {@link WindowManagerService#createStack}. Put on a lower layer on display. */ public static final int TASK_STACK_GOES_UNDER = 5; /** The display this box sits in. */ @@ -37,7 +42,7 @@ public class StackBox { /** Non-null indicates this is mFirst or mSecond of a parent StackBox. Null indicates this * is this entire size of mDisplayContent. */ - StackBox mParent; + final StackBox mParent; /** First child, this is null exactly when mStack is non-null. */ StackBox mFirst; @@ -49,20 +54,26 @@ public class StackBox { TaskStack mStack; /** Content limits relative to the DisplayContent this sits in. */ - Rect mBounds; + 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; /** Used to keep from reallocating a temporary array to hold the list of Tasks below */ ArrayList<Task> mTmpTasks = new ArrayList<Task>(); - StackBox(DisplayContent displayContent, Rect bounds) { + /** Used to keep from reallocating a temporary Rect for propagating bounds to child boxes */ + Rect mTmpRect = new Rect(); + + StackBox(DisplayContent displayContent, StackBox parent) { mDisplayContent = displayContent; - mBounds = bounds; + mParent = parent; } /** Propagate #layoutNeeded bottom up. */ @@ -83,7 +94,7 @@ public class StackBox { } /** - * Detremine if a particular TaskStack is in this StackBox or any of its descendants. + * Determine if a particular TaskStack is in this StackBox or any of its descendants. * @param stackId The TaskStack being considered. * @return true if the specified TaskStack is in this box or its descendants. False otherwise. */ @@ -94,6 +105,30 @@ public class StackBox { return mFirst.contains(stackId) || mSecond.contains(stackId); } + /** Determine if the specified stack is the first child or second child. Presumes that this + * is called on mParent of the specified stack. + * @param stack the stack to determine. + * @return true if stack is the first child. + */ + boolean isFirstChild(TaskStack stack) { + return mFirst.mStack == stack; + } + + /** 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 @@ -105,65 +140,65 @@ public class StackBox { * @return The new TaskStack. */ TaskStack split(int stackId, int relativeStackId, int position, float weight) { - if (mStack != null) { - if (mStack.mStackId == relativeStackId) { - // Found it! - TaskStack stack = new TaskStack(stackId, this); - TaskStack firstStack; - TaskStack secondStack; - int width, height, split; - switch (position) { - default: - case TASK_STACK_GOES_BEFORE: - case TASK_STACK_GOES_AFTER: - mVertical = false; - width = (int)(weight * mBounds.width()); - height = mBounds.height(); - if (position == TASK_STACK_GOES_BEFORE) { - firstStack = stack; - secondStack = mStack; - split = mBounds.left + width; - } else { - firstStack = mStack; - secondStack = stack; - split = mBounds.right - width; - } - break; - case TASK_STACK_GOES_ABOVE: - case TASK_STACK_GOES_BELOW: - mVertical = true; - width = mBounds.width(); - height = (int)(weight * mBounds.height()); - if (position == TASK_STACK_GOES_ABOVE) { - firstStack = stack; - secondStack = mStack; - split = mBounds.top + height; - } else { - firstStack = mStack; - secondStack = stack; - split = mBounds.bottom - height; - } - break; - } - mFirst = new StackBox(mDisplayContent, new Rect(mBounds.left, mBounds.top, - mVertical ? mBounds.right : split, mVertical ? split : mBounds.bottom)); - mFirst.mStack = firstStack; - mSecond = new StackBox(mDisplayContent, new Rect(mVertical ? mBounds.left : split, - mVertical ? split : mBounds.top, mBounds.right, mBounds.bottom)); - mSecond.mStack = secondStack; - mStack = null; + if (mStack == null) { + // Propagate the split to see if the target task stack is in either sub box. + TaskStack stack = mFirst.split(stackId, relativeStackId, position, weight); + if (stack != null) { return stack; } - // Not the intended TaskStack. + return mSecond.split(stackId, relativeStackId, position, weight); + } + + // This StackBox contains just a TaskStack. + if (mStack.mStackId != relativeStackId) { + // Barking down the wrong stack. return null; } - // Propagate the split to see if the target task stack is in either sub box. - TaskStack stack = mFirst.split(stackId, relativeStackId, position, weight); - if (stack != null) { - return stack; + // Found it! + TaskStack stack = new TaskStack(stackId, mDisplayContent); + TaskStack firstStack; + TaskStack secondStack; + switch (position) { + default: + case TASK_STACK_GOES_AFTER: + case TASK_STACK_GOES_BEFORE: + mVertical = false; + if (position == TASK_STACK_GOES_BEFORE) { + 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; } - return mSecond.split(stackId, relativeStackId, position, weight); + + mFirst = new StackBox(mDisplayContent, this); + firstStack.mStackBox = mFirst; + mFirst.mStack = firstStack; + + mSecond = new StackBox(mDisplayContent, this); + secondStack.mStackBox = mSecond; + mSecond.mStack = secondStack; + + mStack = null; + return stack; } /** @@ -215,20 +250,57 @@ public class StackBox { return mParent.getStackId(); } - /** TODO: */ boolean resize(int stackId, float weight) { + if (mStack == null) { + return mFirst.resize(stackId, weight) || mSecond.resize(stackId, weight); + } + if (mStack.mStackId == stackId) { + mParent.mWeight = mParent.isFirstChild(mStack) ? weight : 1.0f - weight; + return true; + } return false; } + /** If this is a terminal StackBox (contains a TaskStack) set the bounds. + * @param bounds The rectangle to set the bounds to. + * @return True if the bounds changed, false otherwise. */ + boolean setStackBoxSizes(Rect bounds) { + boolean change; + if (mStack != null) { + change = !mBounds.equals(bounds); + mBounds.set(bounds); + } 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); + mTmpRect.top = mTmpRect.bottom; + mTmpRect.bottom = bounds.top + height; + change |= mSecond.setStackBoxSizes(mTmpRect); + } else { + final int width = bounds.width(); + int firstWidth = (int)(width * mWeight); + mTmpRect.right = bounds.left + firstWidth; + change = mFirst.setStackBoxSizes(mTmpRect); + mTmpRect.left = mTmpRect.right; + mTmpRect.right = bounds.left + width; + change |= mSecond.setStackBoxSizes(mTmpRect); + } + } + return change; + } + 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(mStack); + pw.print(prefix); pw.print("mFirst="); pw.println(System.identityHashCode(mFirst)); mFirst.dump(prefix + " ", pw); - pw.print(prefix); pw.print("mSecond="); pw.println(mStack); + 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); @@ -241,7 +313,8 @@ public class StackBox { if (mStack != null) { return "Box{" + hashCode() + " stack=" + mStack.mStackId + "}"; } - return "Box{" + hashCode() + " parent=" + mParent.hashCode() - + " first=" + mFirst.hashCode() + " second=" + mSecond.hashCode() + "}"; + return "Box{" + hashCode() + " parent=" + System.identityHashCode(mParent) + + " first=" + System.identityHashCode(mFirst) + + " second=" + System.identityHashCode(mSecond) + "}"; } } diff --git a/services/java/com/android/server/wm/TaskStack.java b/services/java/com/android/server/wm/TaskStack.java index 3e5a933..1c49e7d 100644 --- a/services/java/com/android/server/wm/TaskStack.java +++ b/services/java/com/android/server/wm/TaskStack.java @@ -33,12 +33,11 @@ public class TaskStack { private ArrayList<Task> mTasks = new ArrayList<Task>(); /** The StackBox this sits in. */ - private final StackBox mParent; + StackBox mStackBox; - TaskStack(int stackId, StackBox parent) { + TaskStack(int stackId, DisplayContent displayContent) { mStackId = stackId; - mParent = parent; - mDisplayContent = mParent.mDisplayContent; + mDisplayContent = displayContent; } DisplayContent getDisplayContent() { @@ -66,8 +65,9 @@ public class TaskStack { * @param toTop Whether to add it to the top or bottom. */ boolean addTask(Task task, boolean toTop) { - mParent.makeDirty(); + mStackBox.makeDirty(); mTasks.add(toTop ? mTasks.size() : 0, task); + task.mStack = this; return mDisplayContent.moveHomeStackBox(mStackId == HOME_STACK_ID); } @@ -87,12 +87,12 @@ public class TaskStack { * @param task The Task to delete. */ void removeTask(Task task) { - mParent.makeDirty(); + mStackBox.makeDirty(); mTasks.remove(task); } int remove() { - return mParent.removeStack(); + return mStackBox.removeStack(); } int numTokens() { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index ad49d0a..a00fb7b 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -261,6 +261,12 @@ public class WindowManagerService extends IWindowManager.Stub // Default input dispatching timeout in nanoseconds. static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L; + /** Minimum value for createStack and resizeStack weight value */ + public static final float STACK_WEIGHT_MIN = 0.2f; + + /** Maximum value for createStack and resizeStack weight value */ + public static final float STACK_WEIGHT_MAX = 0.8f; + static final int UPDATE_FOCUS_NORMAL = 0; static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1; static final int UPDATE_FOCUS_PLACING_SURFACES = 2; @@ -4708,11 +4714,22 @@ public class WindowManagerService extends IWindowManager.Stub * @param weight Relative weight for determining how big to make the new TaskStack. */ public void createStack(int stackId, int relativeStackId, int position, float weight) { - // TODO: Create a stack on other displays. synchronized (mWindowMap) { - TaskStack stack = getDefaultDisplayContentLocked().createStack(stackId, - relativeStackId, position, weight); - mStackIdToStack.put(stackId, stack); + 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 TaskStack relativeStack = mStackIdToStack.get(relativeStackId); + DisplayContent displayContent = relativeStack != null ? + relativeStack.getDisplayContent() : getDefaultDisplayContentLocked(); + TaskStack stack = displayContent.createStack(stackId, relativeStackId, position, + weight); + if (stack != null) { + mStackIdToStack.put(stackId, stack); + performLayoutAndPlaceSurfacesLocked(); + } } } @@ -4720,7 +4737,10 @@ public class WindowManagerService extends IWindowManager.Stub final TaskStack stack = mStackIdToStack.get(stackId); if (stack != null) { mStackIdToStack.delete(stackId); - return stack.remove(); + int nextStackId = stack.remove(); + stack.getDisplayContent().layoutNeeded = true; + performLayoutAndPlaceSurfacesLocked(); + return nextStackId; } return HOME_STACK_ID; } @@ -4731,11 +4751,17 @@ public class WindowManagerService extends IWindowManager.Stub task.mStack.removeTask(task); TaskStack newStack = mStackIdToStack.get(stackId); newStack.addTask(task, toTop); + newStack.getDisplayContent().layoutNeeded = true; performLayoutAndPlaceSurfacesLocked(); } } public void resizeStack(int stackId, 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); + } synchronized (mWindowMap) { Task task = null; DisplayContentsIterator iterator = new DisplayContentsIterator(); @@ -4750,6 +4776,17 @@ public class WindowManagerService extends IWindowManager.Stub } } + public Rect getStackBounds(int stackId) { + DisplayContentsIterator iterator = new DisplayContentsIterator(); + while (iterator.hasNext()) { + Rect bounds = iterator.next().getStackBounds(stackId); + if (bounds != null) { + return bounds; + } + } + return null; + } + // ------------------------------------------------------------- // Misc IWindowSession methods // ------------------------------------------------------------- @@ -7935,6 +7972,10 @@ public class WindowManagerService extends IWindowManager.Stub mScreenRect.set(0, 0, dw, dh); } + Rect contentRect = new Rect(); + mPolicy.getContentRectLw(contentRect); + displayContent.setStackBoxSize(contentRect); + int seq = mLayoutSeq+1; if (seq < 0) seq = 0; mLayoutSeq = seq; diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index 7ea36ef..8be424b 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -440,14 +440,19 @@ final class WindowState implements WindowManagerPolicy.WindowState { public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf) { mHaveFrame = true; - final Rect container = mContainingFrame; - container.set(pf); + final int type = mAttrs.type; + if (mAppToken != null) { + StackBox stack = mService.mTaskIdToTask.get(mAppToken.groupId).mStack.mStackBox; + mContainingFrame.set(stack.mBounds); + } else { + mContainingFrame.set(pf); + } final Rect display = mDisplayFrame; display.set(df); - final int pw = container.right - container.left; - final int ph = container.bottom - container.top; + final int pw = mContainingFrame.width(); + final int ph = mContainingFrame.height(); int w,h; if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) { @@ -519,7 +524,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { y = mAttrs.y; } - Gravity.apply(mAttrs.gravity, w, h, container, + Gravity.apply(mAttrs.gravity, w, h, mContainingFrame, (int) (x + mAttrs.horizontalMargin * pw), (int) (y + mAttrs.verticalMargin * ph), frame); |