summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/Activity.java25
-rw-r--r--core/java/android/app/ActivityManager.java2
-rw-r--r--core/java/android/app/ActivityManagerNative.java43
-rw-r--r--core/java/android/app/IActivityManager.java5
-rw-r--r--core/java/android/view/Window.java16
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java29
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java20
-rw-r--r--services/core/java/com/android/server/wm/TaskStack.java3
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);
}