diff options
| -rw-r--r-- | core/java/android/app/Activity.java | 25 | ||||
| -rw-r--r-- | core/java/android/app/ActivityManager.java | 2 | ||||
| -rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 43 | ||||
| -rw-r--r-- | core/java/android/app/IActivityManager.java | 5 | ||||
| -rw-r--r-- | core/java/android/view/Window.java | 16 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 29 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityStackSupervisor.java | 20 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/TaskStack.java | 3 |
8 files changed, 130 insertions, 13 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 5463638ca35a..b11bb2b9a0df 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -31,6 +31,7 @@ import android.transition.Scene; import android.transition.TransitionManager; import android.util.ArrayMap; import android.util.SuperNotCalledException; +import android.view.Window.WindowStackCallback; import android.widget.Toolbar; import com.android.internal.app.IVoiceInteractor; @@ -672,7 +673,7 @@ public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory2, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, ComponentCallbacks2, - Window.OnWindowDismissedCallback { + Window.OnWindowDismissedCallback, WindowStackCallback { private static final String TAG = "Activity"; private static final boolean DEBUG_LIFECYCLE = false; @@ -2700,6 +2701,28 @@ public class Activity extends ContextThemeWrapper finish(finishTask ? FINISH_TASK_WITH_ACTIVITY : DONT_FINISH_TASK_WITH_ACTIVITY); } + + /** Called to move the window and its activity/task to a different stack container. + * For example, a window can move between + * {@link android.app.ActivityManager#FULLSCREEN_WORKSPACE_STACK_ID} stack and + * {@link android.app.ActivityManager#FREEFORM_WORKSPACE_STACK_ID} stack. + * + * @param stackId stack Id to change to. + * @hide + */ + @Override + public void changeWindowStack(int stackId) throws RemoteException { + ActivityManagerNative.getDefault().moveActivityToStack(mToken, stackId); + } + + /** Returns the current stack Id for the window. + * @hide + */ + @Override + public int getWindowStackId() throws RemoteException { + return ActivityManagerNative.getDefault().getActivityStackId(mToken); + } + /** * Called to process key events. You can override this to intercept all * key events before they are dispatched to the window. Be sure to call diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index b7a7d075afc7..78e1b761382b 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -405,7 +405,7 @@ public class ActivityManager { public static final int COMPAT_MODE_TOGGLE = 2; /** - * First static stack stack ID. + * First static stack ID. * @hide */ public static final int FIRST_STATIC_STACK_ID = 0; diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 9bf2f6423798..4232db474820 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -2636,6 +2636,22 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeInt(res ? 1 : 0); return true; } + case GET_ACTIVITY_STACK_ID_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IBinder token = data.readStrongBinder(); + int stackId = getActivityStackId(token); + reply.writeNoException(); + reply.writeInt(stackId); + return true; + } + case MOVE_ACTIVITY_TO_STACK_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IBinder token = data.readStrongBinder(); + int stackId = data.readInt(); + moveActivityToStack(token, stackId); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -6101,5 +6117,32 @@ class ActivityManagerProxy implements IActivityManager return res != 0; } + @Override + public void moveActivityToStack(IBinder token, int stackId) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(token); + data.writeInt(stackId); + mRemote.transact(MOVE_ACTIVITY_TO_STACK_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } + + @Override + public int getActivityStackId(IBinder token) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(token); + mRemote.transact(GET_ACTIVITY_STACK_ID_TRANSACTION, data, reply, 0); + reply.readException(); + int stackId = reply.readInt(); + data.recycle(); + reply.recycle(); + return stackId; + } + private IBinder mRemote; } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 3e5ecbbe5ac5..00e397dee3cc 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -527,6 +527,9 @@ public interface IActivityManager extends IInterface { // descriptor. public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException; + public int getActivityStackId(IBinder token) throws RemoteException; + public void moveActivityToStack(IBinder token, int stackId) throws RemoteException; + /* * Private non-Binder interfaces */ @@ -879,4 +882,6 @@ public interface IActivityManager extends IInterface { int START_BINDER_TRACKING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 340; int STOP_BINDER_TRACKING_AND_DUMP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 341; int POSITION_TASK_IN_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 342; + int GET_ACTIVITY_STACK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 343; + int MOVE_ACTIVITY_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 344; } diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 7dd9948ddad0..4fc2ad320af1 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -34,6 +34,7 @@ import android.media.session.MediaController; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; +import android.os.RemoteException; import android.os.SystemProperties; import android.transition.Scene; import android.transition.Transition; @@ -476,6 +477,21 @@ public abstract class Window { void onWindowDismissed(boolean finishTask); } + /** @hide */ + public interface WindowStackCallback { + /** Called to move the window and its activity/task to a different stack container. + * For example, a window can move between + * {@link android.app.ActivityManager#FULLSCREEN_WORKSPACE_STACK_ID} stack and + * {@link android.app.ActivityManager#FREEFORM_WORKSPACE_STACK_ID} stack. + * + * @param stackId stack Id to change to. + */ + void changeWindowStack(int stackId) throws RemoteException; + + /** Returns the current stack Id for the window. */ + int getWindowStackId() throws RemoteException; + } + public Window(Context context) { mContext = context; mFeatures = mLocalFeatures = getDefaultFeatures(context); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0afda1dfc281..147a5fdd6116 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -8930,6 +8930,35 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override + public int getActivityStackId(IBinder token) throws RemoteException { + synchronized (this) { + ActivityStack stack = ActivityRecord.getStackLocked(token); + if (stack == null) { + throw new IllegalArgumentException( + "getActivityStackId: No stack for token=" + token); + } + return stack.mStackId; + } + } + + @Override + public void moveActivityToStack(IBinder token, int stackId) throws RemoteException { + synchronized(this) { + final long origId = Binder.clearCallingIdentity(); + try { + final ActivityRecord r = ActivityRecord.forTokenLocked(token); + if (r == null) { + throw new IllegalArgumentException( + "moveActivityToStack: No activity record matching token=" + token); + } + moveTaskToStack(r.task.taskId, stackId, true /*toTop*/); + } finally { + Binder.restoreCallingIdentity(origId); + } + } + } + + @Override public void moveTaskToStack(int taskId, int stackId, boolean toTop) { enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, "moveTaskToStack()"); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 296f16c87227..4a0fd8941399 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -17,15 +17,7 @@ package com.android.server.am; import static android.Manifest.permission.START_ANY_ACTIVITY; -import static android.app.ActivityManager.FIRST_DYNAMIC_STACK_ID; -import static android.app.ActivityManager.FIRST_STATIC_STACK_ID; -import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID; -import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID; -import static android.app.ActivityManager.HOME_STACK_ID; -import static android.app.ActivityManager.LAST_STATIC_STACK_ID; -import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; -import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; -import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; +import static android.app.ActivityManager.*; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; @@ -3024,6 +3016,15 @@ public final class ActivityStackSupervisor implements DisplayListener { task.stack.removeTask(task, "moveTaskToStack", false /* notMoving */); } stack.addTask(task, toTop, true); + + // Make sure the task has the appropriate bounds/size for the stack it is in. + if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) { + resizeTaskLocked(task, null); + } else if (stackId == FREEFORM_WORKSPACE_STACK_ID + && task.mBounds == null && task.mLastNonFullscreenBounds != null) { + resizeTaskLocked(task, task.mLastNonFullscreenBounds); + } + // The task might have already been running and its visibility needs to be synchronized with // the visibility of the stack / windows. stack.ensureActivitiesVisibleLocked(null, 0); @@ -3828,6 +3829,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } info.taskIds = taskIds; info.taskNames = taskNames; + info.taskBounds = taskBounds; return info; } diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index aef99bc2d6b1..90d2593654d2 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -148,8 +148,7 @@ public class TaskStack implements DimLayer.DimLayerUser { void updateDisplayInfo() { if (mDisplayContent != null) { - mDisplayContent.getLogicalDisplayRect(mTmpRect); - mAnimationBackgroundSurface.setBounds(mTmpRect); + setBounds(mFullscreen ? null : mBounds); for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) { mTasks.get(taskNdx).updateDisplayInfo(mDisplayContent); } |