Merge "Add TestApi interfaces for window organizers" into rvc-dev

This commit is contained in:
Wale Ogunwale
2020-04-01 13:30:47 +00:00
committed by Android (Google) Code Review
43 changed files with 877 additions and 578 deletions

View File

@@ -5158,3 +5158,75 @@ package android.widget {
} }
package android.window {
public class DisplayAreaOrganizer extends android.window.WindowOrganizer {
ctor public DisplayAreaOrganizer();
method public void onDisplayAreaAppeared(@NonNull android.window.WindowContainerToken);
method public void onDisplayAreaVanished(@NonNull android.window.WindowContainerToken);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void registerOrganizer(int);
field public static final int FEATURE_ROOT = 0; // 0x0
field public static final int FEATURE_SYSTEM_FIRST = 0; // 0x0
field public static final int FEATURE_SYSTEM_LAST = 10000; // 0x2710
field public static final int FEATURE_TASK_CONTAINER = 1; // 0x1
field public static final int FEATURE_UNDEFINED = -1; // 0xffffffff
field public static final int FEATURE_VENDOR_FIRST = 10001; // 0x2711
field public static final int FEATURE_WINDOW_TOKENS = 2; // 0x2
}
public class TaskOrganizer extends android.window.WindowOrganizer {
ctor public TaskOrganizer();
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static android.app.ActivityManager.RunningTaskInfo createRootTask(int, int);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static boolean deleteRootTask(@NonNull android.window.WindowContainerToken);
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static java.util.List<android.app.ActivityManager.RunningTaskInfo> getChildTasks(@NonNull android.window.WindowContainerToken, @NonNull int[]);
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static android.window.WindowContainerToken getImeTarget(int);
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static java.util.List<android.app.ActivityManager.RunningTaskInfo> getRootTasks(int, @NonNull int[]);
method public void onBackPressedOnTaskRoot(@NonNull android.app.ActivityManager.RunningTaskInfo);
method public void onTaskAppeared(@NonNull android.app.ActivityManager.RunningTaskInfo);
method public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo);
method public void onTaskVanished(@NonNull android.app.ActivityManager.RunningTaskInfo);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void registerOrganizer(int);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(boolean);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static void setLaunchRoot(int, @NonNull android.window.WindowContainerToken);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void unregisterOrganizer();
}
public final class WindowContainerToken implements android.os.Parcelable {
method public int describeContents();
method @Nullable public android.view.SurfaceControl getLeash();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.window.WindowContainerToken> CREATOR;
}
public final class WindowContainerTransaction implements android.os.Parcelable {
ctor public WindowContainerTransaction();
method public int describeContents();
method @NonNull public android.window.WindowContainerTransaction reorder(@NonNull android.window.WindowContainerToken, boolean);
method @NonNull public android.window.WindowContainerTransaction reparent(@NonNull android.window.WindowContainerToken, @Nullable android.window.WindowContainerToken, boolean);
method @NonNull public android.window.WindowContainerTransaction scheduleFinishEnterPip(@NonNull android.window.WindowContainerToken, @NonNull android.graphics.Rect);
method @NonNull public android.window.WindowContainerTransaction setActivityWindowingMode(@NonNull android.window.WindowContainerToken, int);
method @NonNull public android.window.WindowContainerTransaction setAppBounds(@NonNull android.window.WindowContainerToken, @NonNull android.graphics.Rect);
method @NonNull public android.window.WindowContainerTransaction setBounds(@NonNull android.window.WindowContainerToken, @NonNull android.graphics.Rect);
method @NonNull public android.window.WindowContainerTransaction setBoundsChangeTransaction(@NonNull android.window.WindowContainerToken, @NonNull android.view.SurfaceControl.Transaction);
method @NonNull public android.window.WindowContainerTransaction setFocusable(@NonNull android.window.WindowContainerToken, boolean);
method @NonNull public android.window.WindowContainerTransaction setHidden(@NonNull android.window.WindowContainerToken, boolean);
method @NonNull public android.window.WindowContainerTransaction setScreenSizeDp(@NonNull android.window.WindowContainerToken, int, int);
method @NonNull public android.window.WindowContainerTransaction setSmallestScreenWidthDp(@NonNull android.window.WindowContainerToken, int);
method @NonNull public android.window.WindowContainerTransaction setWindowingMode(@NonNull android.window.WindowContainerToken, int);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.window.WindowContainerTransaction> CREATOR;
}
public abstract class WindowContainerTransactionCallback {
ctor public WindowContainerTransactionCallback();
method public abstract void onTransactionReady(int, @NonNull android.view.SurfaceControl.Transaction);
}
public class WindowOrganizer {
ctor public WindowOrganizer();
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public int applySyncTransaction(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.WindowContainerTransactionCallback);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static void applyTransaction(@NonNull android.window.WindowContainerTransaction);
}
}

View File

@@ -73,7 +73,7 @@ import android.util.ArrayMap;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Singleton; import android.util.Singleton;
import android.util.Size; import android.util.Size;
import android.window.IWindowContainer; import android.window.WindowContainerToken;
import android.view.Surface; import android.view.Surface;
import com.android.internal.app.LocalePicker; import com.android.internal.app.LocalePicker;
@@ -2759,7 +2759,7 @@ public class ActivityManager {
// Index of the stack in the display's stack list, can be used for comparison of stack order // Index of the stack in the display's stack list, can be used for comparison of stack order
@UnsupportedAppUsage @UnsupportedAppUsage
public int position; public int position;
public IWindowContainer stackToken; public WindowContainerToken stackToken;
/** /**
* The full configuration the stack is currently running in. * The full configuration the stack is currently running in.
* @hide * @hide
@@ -2793,7 +2793,7 @@ public class ActivityManager {
dest.writeInt(userId); dest.writeInt(userId);
dest.writeInt(visible ? 1 : 0); dest.writeInt(visible ? 1 : 0);
dest.writeInt(position); dest.writeInt(position);
dest.writeStrongInterface(stackToken); stackToken.writeToParcel(dest, 0);
if (topActivity != null) { if (topActivity != null) {
dest.writeInt(1); dest.writeInt(1);
topActivity.writeToParcel(dest, 0); topActivity.writeToParcel(dest, 0);
@@ -2825,7 +2825,7 @@ public class ActivityManager {
userId = source.readInt(); userId = source.readInt();
visible = source.readInt() > 0; visible = source.readInt() > 0;
position = source.readInt(); position = source.readInt();
stackToken = IWindowContainer.Stub.asInterface(source.readStrongBinder()); stackToken = WindowContainerToken.CREATOR.createFromParcel(source);
if (source.readInt() > 0) { if (source.readInt() > 0) {
topActivity = ComponentName.readFromParcel(source); topActivity = ComponentName.readFromParcel(source);
} }

View File

@@ -42,6 +42,9 @@ import android.view.SurfaceView;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewParent; import android.view.ViewParent;
import android.window.TaskEmbedder;
import android.window.TaskOrganizerTaskEmbedder;
import android.window.VirtualDisplayTaskEmbedder;
import dalvik.system.CloseGuard; import dalvik.system.CloseGuard;
@@ -52,11 +55,11 @@ import dalvik.system.CloseGuard;
* @hide * @hide
*/ */
@TestApi @TestApi
public class ActivityView extends ViewGroup implements TaskEmbedder.Host { public class ActivityView extends ViewGroup implements android.window.TaskEmbedder.Host {
private static final String TAG = "ActivityView"; private static final String TAG = "ActivityView";
private TaskEmbedder mTaskEmbedder; private android.window.TaskEmbedder mTaskEmbedder;
private final SurfaceView mSurfaceView; private final SurfaceView mSurfaceView;
private final SurfaceCallback mSurfaceCallback; private final SurfaceCallback mSurfaceCallback;
@@ -487,7 +490,7 @@ public class ActivityView extends ViewGroup implements TaskEmbedder.Host {
/** @hide */ /** @hide */
@Override @Override
public void onTaskBackgroundColorChanged(TaskEmbedder ts, int bgColor) { public void onTaskBackgroundColorChanged(android.window.TaskEmbedder ts, int bgColor) {
if (mSurfaceView != null) { if (mSurfaceView != null) {
mSurfaceView.setResizeBackgroundColor(bgColor); mSurfaceView.setResizeBackgroundColor(bgColor);
} }

View File

@@ -28,7 +28,7 @@ import android.content.res.Configuration;
import android.os.Parcel; import android.os.Parcel;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import android.window.IWindowContainer; import android.window.WindowContainerToken;
/** /**
* Stores information about a particular Task. * Stores information about a particular Task.
@@ -147,7 +147,7 @@ public class TaskInfo {
* @hide * @hide
*/ */
@NonNull @NonNull
public IWindowContainer token; public WindowContainerToken token;
/** /**
* The PictureInPictureParams for the Task, if set. * The PictureInPictureParams for the Task, if set.
@@ -222,7 +222,7 @@ public class TaskInfo {
supportsSplitScreenMultiWindow = source.readBoolean(); supportsSplitScreenMultiWindow = source.readBoolean();
resizeMode = source.readInt(); resizeMode = source.readInt();
configuration.readFromParcel(source); configuration.readFromParcel(source);
token = IWindowContainer.Stub.asInterface(source.readStrongBinder()); token = WindowContainerToken.CREATOR.createFromParcel(source);
topActivityType = source.readInt(); topActivityType = source.readInt();
pictureInPictureParams = source.readInt() != 0 pictureInPictureParams = source.readInt() != 0
? PictureInPictureParams.CREATOR.createFromParcel(source) ? PictureInPictureParams.CREATOR.createFromParcel(source)
@@ -265,7 +265,7 @@ public class TaskInfo {
dest.writeBoolean(supportsSplitScreenMultiWindow); dest.writeBoolean(supportsSplitScreenMultiWindow);
dest.writeInt(resizeMode); dest.writeInt(resizeMode);
configuration.writeToParcel(dest, flags); configuration.writeToParcel(dest, flags);
dest.writeStrongInterface(token); token.writeToParcel(dest, flags);
dest.writeInt(topActivityType); dest.writeInt(topActivityType);
if (pictureInPictureParams == null) { if (pictureInPictureParams == null) {
dest.writeInt(0); dest.writeInt(0);

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2020 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 android.window;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.os.RemoteException;
import android.util.Singleton;
/**
* Interface for WindowManager to delegate control of display areas.
* @hide
*/
@TestApi
public class DisplayAreaOrganizer extends WindowOrganizer {
public static final int FEATURE_UNDEFINED = -1;
public static final int FEATURE_SYSTEM_FIRST = 0;
// The Root display area on a display
public static final int FEATURE_ROOT = FEATURE_SYSTEM_FIRST;
// Display area hosting the task container.
public static final int FEATURE_TASK_CONTAINER = FEATURE_SYSTEM_FIRST + 1;
// Display area hosting non-activity window tokens.
public static final int FEATURE_WINDOW_TOKENS = FEATURE_SYSTEM_FIRST + 2;
public static final int FEATURE_SYSTEM_LAST = 10_000;
// Vendor specific display area definition can start with this value.
public static final int FEATURE_VENDOR_FIRST = FEATURE_SYSTEM_LAST + 1;
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public void registerOrganizer(int displayAreaFeature) {
try {
getController().registerOrganizer(mInterface, displayAreaFeature);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
public void onDisplayAreaAppeared(@NonNull WindowContainerToken displayArea) {}
public void onDisplayAreaVanished(@NonNull WindowContainerToken displayArea) {}
private final IDisplayAreaOrganizer mInterface = new IDisplayAreaOrganizer.Stub() {
@Override
public void onDisplayAreaAppeared(@NonNull WindowContainerToken displayArea) {
DisplayAreaOrganizer.this.onDisplayAreaAppeared(displayArea);
}
@Override
public void onDisplayAreaVanished(@NonNull WindowContainerToken displayArea) {
DisplayAreaOrganizer.this.onDisplayAreaVanished(displayArea);
}
};
private static IDisplayAreaOrganizerController getController() {
return IDisplayAreaOrganizerControllerSingleton.get();
}
private static final Singleton<IDisplayAreaOrganizerController>
IDisplayAreaOrganizerControllerSingleton =
new Singleton<IDisplayAreaOrganizerController>() {
@Override
protected IDisplayAreaOrganizerController create() {
try {
return getWindowOrganizerController()
.getDisplayAreaOrganizerController();
} catch (RemoteException e) {
return null;
}
}
};
}

View File

@@ -16,13 +16,13 @@
package android.window; package android.window;
import android.window.IWindowContainer; import android.window.WindowContainerToken;
/** /**
* Interface for WindowManager to delegate control of display areas. * Interface for WindowManager to delegate control of display areas.
* {@hide} * {@hide}
*/ */
oneway interface IDisplayAreaOrganizer { oneway interface IDisplayAreaOrganizer {
void onDisplayAreaAppeared(in IWindowContainer displayArea); void onDisplayAreaAppeared(in WindowContainerToken displayArea);
void onDisplayAreaVanished(in IWindowContainer displayArea); void onDisplayAreaVanished(in WindowContainerToken displayArea);
} }

View File

@@ -18,7 +18,7 @@ package android.window;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.window.IWindowContainer; import android.window.WindowContainerToken;
/** /**
* Interface for ActivityTaskManager/WindowManager to delegate control of tasks. * Interface for ActivityTaskManager/WindowManager to delegate control of tasks.

View File

@@ -18,7 +18,7 @@ package android.window;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.window.ITaskOrganizer; import android.window.ITaskOrganizer;
import android.window.IWindowContainer; import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction;
/** @hide */ /** @hide */
@@ -40,23 +40,23 @@ interface ITaskOrganizerController {
ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode); ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode);
/** Deletes a persistent root task in WM */ /** Deletes a persistent root task in WM */
boolean deleteRootTask(IWindowContainer task); boolean deleteRootTask(in WindowContainerToken task);
/** Gets direct child tasks (ordered from top-to-bottom) */ /** Gets direct child tasks (ordered from top-to-bottom) */
List<ActivityManager.RunningTaskInfo> getChildTasks(in IWindowContainer parent, List<ActivityManager.RunningTaskInfo> getChildTasks(in WindowContainerToken parent,
in int[] activityTypes); in int[] activityTypes);
/** Gets all root tasks on a display (ordered from top-to-bottom) */ /** Gets all root tasks on a display (ordered from top-to-bottom) */
List<ActivityManager.RunningTaskInfo> getRootTasks(int displayId, in int[] activityTypes); List<ActivityManager.RunningTaskInfo> getRootTasks(int displayId, in int[] activityTypes);
/** Get the root task which contains the current ime target */ /** Get the root task which contains the current ime target */
IWindowContainer getImeTarget(int display); WindowContainerToken getImeTarget(int display);
/** /**
* Set's the root task to launch new tasks into on a display. {@code null} means no launch root * Set's the root task to launch new tasks into on a display. {@code null} means no launch root
* and thus new tasks just end up directly on the display. * and thus new tasks just end up directly on the display.
*/ */
void setLaunchRoot(int displayId, in IWindowContainer root); void setLaunchRoot(int displayId, in WindowContainerToken root);
/** /**
* Requests that the given task organizer is notified when back is pressed on the root activity * Requests that the given task organizer is notified when back is pressed on the root activity

View File

@@ -23,7 +23,7 @@ import android.view.SurfaceControl;
* token. * token.
* @hide * @hide
*/ */
interface IWindowContainer { interface IWindowContainerToken {
/** /**
* Gets a persistent leash for this container or {@code null}. * Gets a persistent leash for this container or {@code null}.

View File

@@ -24,5 +24,5 @@ import android.view.SurfaceControl;
*/ */
oneway interface IWindowContainerTransactionCallback { oneway interface IWindowContainerTransactionCallback {
/** Called upon completion of WindowOrganizer#applyTransaction */ /** Called upon completion of WindowOrganizer#applyTransaction */
void transactionReady(int id, in SurfaceControl.Transaction t); void onTransactionReady(int id, in SurfaceControl.Transaction t);
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 The Android Open Source Project * Copyright (C) 2020 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -14,13 +14,19 @@
* limitations under the License. * limitations under the License.
*/ */
package android.app; package android.window;
import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.INVALID_DISPLAY;
import android.annotation.CallSuper; import android.annotation.CallSuper;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.ActivityView;
import android.app.IActivityTaskManager;
import android.app.PendingIntent;
import android.app.TaskStackListener;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;

View File

@@ -0,0 +1,188 @@
/*
* Copyright (C) 2020 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 android.window;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.app.ActivityManager;
import android.os.RemoteException;
import android.util.Singleton;
import java.util.List;
/**
* Interface for ActivityTaskManager/WindowManager to delegate control of tasks.
* @hide
*/
@TestApi
public class TaskOrganizer extends WindowOrganizer {
/**
* Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
* If there was already a TaskOrganizer for this windowing mode it will be evicted
* and receive taskVanished callbacks in the process.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public void registerOrganizer(int windowingMode) {
try {
getController().registerTaskOrganizer(mInterface, windowingMode);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Unregisters a previously registered task organizer. */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public void unregisterOrganizer() {
try {
getController().unregisterTaskOrganizer(mInterface);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
public void onTaskAppeared(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
public void onTaskVanished(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
public void onTaskInfoChanged(@NonNull ActivityManager.RunningTaskInfo info) {}
public void onBackPressedOnTaskRoot(@NonNull ActivityManager.RunningTaskInfo info) {}
/** Creates a persistent root task in WM for a particular windowing-mode. */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
@Nullable
public static ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode) {
try {
return getController().createRootTask(displayId, windowingMode);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Deletes a persistent root task in WM */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static boolean deleteRootTask(@NonNull WindowContainerToken task) {
try {
return getController().deleteRootTask(task);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Gets direct child tasks (ordered from top-to-bottom) */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
@Nullable
public static List<ActivityManager.RunningTaskInfo> getChildTasks(
@NonNull WindowContainerToken parent, @NonNull int[] activityTypes) {
try {
return getController().getChildTasks(parent, activityTypes);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Gets all root tasks on a display (ordered from top-to-bottom) */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
@Nullable
public static List<ActivityManager.RunningTaskInfo> getRootTasks(
int displayId, @NonNull int[] activityTypes) {
try {
return getController().getRootTasks(displayId, activityTypes);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Get the root task which contains the current ime target */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
@Nullable
public static WindowContainerToken getImeTarget(int display) {
try {
return getController().getImeTarget(display);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Set's the root task to launch new tasks into on a display. {@code null} means no launch
* root and thus new tasks just end up directly on the display.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static void setLaunchRoot(int displayId, @NonNull WindowContainerToken root) {
try {
getController().setLaunchRoot(displayId, root);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Requests that the given task organizer is notified when back is pressed on the root activity
* of one of its controlled tasks.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) {
try {
getController().setInterceptBackPressedOnTaskRoot(mInterface, interceptBackPressed);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
private final ITaskOrganizer mInterface = new ITaskOrganizer.Stub() {
@Override
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
TaskOrganizer.this.onTaskAppeared(taskInfo);
}
@Override
public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
TaskOrganizer.this.onTaskVanished(taskInfo);
}
@Override
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
TaskOrganizer.this.onTaskInfoChanged(info);
}
@Override
public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo info) {
TaskOrganizer.this.onBackPressedOnTaskRoot(info);
}
};
private static ITaskOrganizerController getController() {
return ITaskOrganizerControllerSingleton.get();
}
private static final Singleton<ITaskOrganizerController> ITaskOrganizerControllerSingleton =
new Singleton<ITaskOrganizerController>() {
@Override
protected ITaskOrganizerController create() {
try {
return getWindowOrganizerController().getTaskOrganizerController();
} catch (RemoteException e) {
return null;
}
}
};
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 The Android Open Source Project * Copyright (C) 2020 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -14,22 +14,20 @@
* limitations under the License. * limitations under the License.
*/ */
package android.app; package android.window;
import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityView;
import android.app.TaskStackListener;
import android.content.Context; import android.content.Context;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.window.ITaskOrganizer;
import android.window.IWindowContainer;
import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer;
import android.window.WindowOrganizer.TaskOrganizer;
/** /**
* A component which handles embedded display of tasks within another window. The embedded task can * A component which handles embedded display of tasks within another window. The embedded task can
@@ -41,9 +39,9 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
private static final String TAG = "TaskOrgTaskEmbedder"; private static final String TAG = "TaskOrgTaskEmbedder";
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
private ITaskOrganizer.Stub mTaskOrganizer; private TaskOrganizer mTaskOrganizer;
private ActivityManager.RunningTaskInfo mTaskInfo; private ActivityManager.RunningTaskInfo mTaskInfo;
private IWindowContainer mTaskToken; private WindowContainerToken mTaskToken;
private SurfaceControl mTaskLeash; private SurfaceControl mTaskLeash;
private boolean mPendingNotifyBoundsChanged; private boolean mPendingNotifyBoundsChanged;
@@ -79,16 +77,11 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
} }
// Register the task organizer // Register the task organizer
mTaskOrganizer = new TaskOrganizerImpl(); mTaskOrganizer = new TaskOrganizerImpl();
try { // TODO(wm-shell): This currently prevents other organizers from controlling MULT_WINDOW
// TODO(wm-shell): This currently prevents other organizers from controlling MULT_WINDOW // windowing mode tasks. Plan is to migrate this to a wm-shell front-end when that
// windowing mode tasks. Plan is to migrate this to a wm-shell front-end when that // infrastructure is ready.
// infrastructure is ready. mTaskOrganizer.registerOrganizer(WINDOWING_MODE_MULTI_WINDOW);
TaskOrganizer.registerOrganizer(mTaskOrganizer, WINDOWING_MODE_MULTI_WINDOW); mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true);
TaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskOrganizer, true);
} catch (RemoteException e) {
Log.e(TAG, "Failed to initialize TaskEmbedder", e);
return false;
}
return true; return true;
} }
@@ -100,11 +93,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
if (!isInitialized()) { if (!isInitialized()) {
return false; return false;
} }
try { mTaskOrganizer.unregisterOrganizer();
TaskOrganizer.unregisterOrganizer(mTaskOrganizer);
} catch (RemoteException e) {
Log.e(TAG, "Failed to remove task");
}
resetTaskInfo(); resetTaskInfo();
return true; return true;
} }
@@ -125,11 +114,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
} }
WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setHidden(mTaskToken, false /* hidden */); wct.setHidden(mTaskToken, false /* hidden */);
try { WindowOrganizer.applyTransaction(wct);
WindowOrganizer.applyTransaction(wct);
} catch (RemoteException e) {
Log.e(TAG, "Failed to unset hidden in transaction");
}
// TODO(b/151449487): Only call callback once we enable synchronization // TODO(b/151449487): Only call callback once we enable synchronization
if (mListener != null) { if (mListener != null) {
mListener.onTaskVisibilityChanged(getTaskId(), true); mListener.onTaskVisibilityChanged(getTaskId(), true);
@@ -152,11 +137,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
} }
WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setHidden(mTaskToken, true /* hidden */); wct.setHidden(mTaskToken, true /* hidden */);
try { WindowOrganizer.applyTransaction(wct);
WindowOrganizer.applyTransaction(wct);
} catch (RemoteException e) {
Log.e(TAG, "Failed to set hidden in transaction");
}
// TODO(b/151449487): Only call callback once we enable synchronization // TODO(b/151449487): Only call callback once we enable synchronization
if (mListener != null) { if (mListener != null) {
mListener.onTaskVisibilityChanged(getTaskId(), false); mListener.onTaskVisibilityChanged(getTaskId(), false);
@@ -186,12 +167,8 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setBounds(mTaskToken, screenBounds); wct.setBounds(mTaskToken, screenBounds);
try { // TODO(b/151449487): Enable synchronization
// TODO(b/151449487): Enable synchronization WindowOrganizer.applyTransaction(wct);
WindowOrganizer.applyTransaction(wct);
} catch (RemoteException e) {
Log.e(TAG, "Failed to set bounds in transaction");
}
} }
/** /**
@@ -253,8 +230,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
private class TaskStackListenerImpl extends TaskStackListener { private class TaskStackListenerImpl extends TaskStackListener {
@Override @Override
public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo) public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo) {
throws RemoteException {
if (!isInitialized()) { if (!isInitialized()) {
return; return;
} }
@@ -266,10 +242,9 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
} }
} }
private class TaskOrganizerImpl extends ITaskOrganizer.Stub { private class TaskOrganizerImpl extends TaskOrganizer {
@Override @Override
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
throws RemoteException {
if (DEBUG) { if (DEBUG) {
log("taskAppeared: " + taskInfo.taskId); log("taskAppeared: " + taskInfo.taskId);
} }
@@ -293,8 +268,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
} }
@Override @Override
public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
throws RemoteException {
if (DEBUG) { if (DEBUG) {
log("taskVanished: " + taskInfo.taskId); log("taskVanished: " + taskInfo.taskId);
} }
@@ -309,14 +283,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
} }
@Override @Override
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) {
throws RemoteException {
// Do nothing
}
@Override
public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo)
throws RemoteException {
if (mListener != null) { if (mListener != null) {
mListener.onBackPressedOnTaskRoot(taskInfo.taskId); mListener.onBackPressedOnTaskRoot(taskInfo.taskId);
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 The Android Open Source Project * Copyright (C) 2020 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package android.app; package android.window;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
@@ -23,6 +23,11 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLI
import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.INVALID_DISPLAY;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.ActivityView;
import android.app.TaskStackListener;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.graphics.Insets; import android.graphics.Insets;
@@ -72,7 +77,7 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
* @param singleTaskInstance whether to apply a single-task constraint to this container, * @param singleTaskInstance whether to apply a single-task constraint to this container,
* only applicable if virtual displays are used * only applicable if virtual displays are used
*/ */
VirtualDisplayTaskEmbedder(Context context, VirtualDisplayTaskEmbedder.Host host, public VirtualDisplayTaskEmbedder(Context context, VirtualDisplayTaskEmbedder.Host host,
boolean singleTaskInstance) { boolean singleTaskInstance) {
super(context, host); super(context, host);
mSingleTaskInstance = singleTaskInstance; mSingleTaskInstance = singleTaskInstance;

View File

@@ -0,0 +1,19 @@
/*
* Copyright (C) 2020 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 android.window;
parcelable WindowContainerToken;

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2020 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 android.window;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.view.SurfaceControl;
import android.window.IWindowContainerToken;
/**
* Interface for a window container to communicate with the window manager. This also acts as a
* token.
* @hide
*/
@TestApi
public final class WindowContainerToken implements Parcelable {
private final IWindowContainerToken mRealToken;
/** @hide */
public WindowContainerToken(IWindowContainerToken realToken) {
mRealToken = realToken;
}
private WindowContainerToken(Parcel in) {
mRealToken = IWindowContainerToken.Stub.asInterface(in.readStrongBinder());
}
@Nullable
public SurfaceControl getLeash() {
try {
return mRealToken.getLeash();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** @hide */
public IBinder asBinder() {
return mRealToken.asBinder();
}
@Override
/** @hide */
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeStrongBinder(mRealToken.asBinder());
}
@NonNull
public static final Creator<WindowContainerToken> CREATOR =
new Creator<WindowContainerToken>() {
@Override
public WindowContainerToken createFromParcel(Parcel in) {
return new WindowContainerToken(in);
}
@Override
public WindowContainerToken[] newArray(int size) {
return new WindowContainerToken[size];
}
};
@Override
/** @hide */
public int describeContents() {
return 0;
}
}

View File

@@ -18,6 +18,7 @@ package android.window;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.TestApi;
import android.app.WindowConfiguration; import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.res.Configuration; import android.content.res.Configuration;
@@ -26,7 +27,6 @@ import android.os.IBinder;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.window.IWindowContainer;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import java.util.ArrayList; import java.util.ArrayList;
@@ -39,7 +39,8 @@ import java.util.Map;
* *
* @hide * @hide
*/ */
public class WindowContainerTransaction implements Parcelable { @TestApi
public final class WindowContainerTransaction implements Parcelable {
private final ArrayMap<IBinder, Change> mChanges = new ArrayMap<>(); private final ArrayMap<IBinder, Change> mChanges = new ArrayMap<>();
// Flat list because re-order operations are order-dependent // Flat list because re-order operations are order-dependent
@@ -47,7 +48,7 @@ public class WindowContainerTransaction implements Parcelable {
public WindowContainerTransaction() {} public WindowContainerTransaction() {}
protected WindowContainerTransaction(Parcel in) { private WindowContainerTransaction(Parcel in) {
in.readMap(mChanges, null /* loader */); in.readMap(mChanges, null /* loader */);
in.readList(mHierarchyOps, null /* loader */); in.readList(mHierarchyOps, null /* loader */);
} }
@@ -64,7 +65,9 @@ public class WindowContainerTransaction implements Parcelable {
/** /**
* Resize a container. * Resize a container.
*/ */
public WindowContainerTransaction setBounds(IWindowContainer container, Rect bounds) { @NonNull
public WindowContainerTransaction setBounds(
@NonNull WindowContainerToken container,@NonNull Rect bounds) {
Change chg = getOrCreateChange(container.asBinder()); Change chg = getOrCreateChange(container.asBinder());
chg.mConfiguration.windowConfiguration.setBounds(bounds); chg.mConfiguration.windowConfiguration.setBounds(bounds);
chg.mConfigSetMask |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION; chg.mConfigSetMask |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
@@ -77,7 +80,9 @@ public class WindowContainerTransaction implements Parcelable {
* app's DisplayInfo. It is derived by subtracting the overlapping portion of the navbar from * app's DisplayInfo. It is derived by subtracting the overlapping portion of the navbar from
* the full bounds. * the full bounds.
*/ */
public WindowContainerTransaction setAppBounds(IWindowContainer container, Rect appBounds) { @NonNull
public WindowContainerTransaction setAppBounds(
@NonNull WindowContainerToken container,@NonNull Rect appBounds) {
Change chg = getOrCreateChange(container.asBinder()); Change chg = getOrCreateChange(container.asBinder());
chg.mConfiguration.windowConfiguration.setAppBounds(appBounds); chg.mConfiguration.windowConfiguration.setAppBounds(appBounds);
chg.mConfigSetMask |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION; chg.mConfigSetMask |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
@@ -91,7 +96,9 @@ public class WindowContainerTransaction implements Parcelable {
* derived by subtracting the overlapping portions of both the statusbar and the navbar from * derived by subtracting the overlapping portions of both the statusbar and the navbar from
* the full bounds. * the full bounds.
*/ */
public WindowContainerTransaction setScreenSizeDp(IWindowContainer container, int w, int h) { @NonNull
public WindowContainerTransaction setScreenSizeDp(
@NonNull WindowContainerToken container, int w, int h) {
Change chg = getOrCreateChange(container.asBinder()); Change chg = getOrCreateChange(container.asBinder());
chg.mConfiguration.screenWidthDp = w; chg.mConfiguration.screenWidthDp = w;
chg.mConfiguration.screenHeightDp = h; chg.mConfiguration.screenHeightDp = h;
@@ -100,11 +107,12 @@ public class WindowContainerTransaction implements Parcelable {
} }
/** /**
* Notify activies within the hiearchy of a container that they have entered picture-in-picture * Notify activities within the hierarchy of a container that they have entered picture-in-picture
* mode with the given bounds. * mode with the given bounds.
*/ */
public WindowContainerTransaction scheduleFinishEnterPip(IWindowContainer container, @NonNull
Rect bounds) { public WindowContainerTransaction scheduleFinishEnterPip(
@NonNull WindowContainerToken container,@NonNull Rect bounds) {
Change chg = getOrCreateChange(container.asBinder()); Change chg = getOrCreateChange(container.asBinder());
chg.mPinnedBounds = new Rect(bounds); chg.mPinnedBounds = new Rect(bounds);
chg.mChangeMask |= Change.CHANGE_PIP_CALLBACK; chg.mChangeMask |= Change.CHANGE_PIP_CALLBACK;
@@ -123,8 +131,9 @@ public class WindowContainerTransaction implements Parcelable {
* that you can call this, apply the WindowContainer transaction, and then later call * that you can call this, apply the WindowContainer transaction, and then later call
* dismissPip() to achieve synchronization. * dismissPip() to achieve synchronization.
*/ */
public WindowContainerTransaction setBoundsChangeTransaction(IWindowContainer container, @NonNull
SurfaceControl.Transaction t) { public WindowContainerTransaction setBoundsChangeTransaction(
@NonNull WindowContainerToken container,@NonNull SurfaceControl.Transaction t) {
Change chg = getOrCreateChange(container.asBinder()); Change chg = getOrCreateChange(container.asBinder());
chg.mBoundsChangeTransaction = t; chg.mBoundsChangeTransaction = t;
chg.mChangeMask |= Change.CHANGE_BOUNDS_TRANSACTION; chg.mChangeMask |= Change.CHANGE_BOUNDS_TRANSACTION;
@@ -139,8 +148,9 @@ public class WindowContainerTransaction implements Parcelable {
* *
* TODO(b/134365562): Can be removed once TaskOrg drives full-screen * TODO(b/134365562): Can be removed once TaskOrg drives full-screen
*/ */
public WindowContainerTransaction setActivityWindowingMode(IWindowContainer container, @NonNull
int windowingMode) { public WindowContainerTransaction setActivityWindowingMode(
@NonNull WindowContainerToken container, int windowingMode) {
Change chg = getOrCreateChange(container.asBinder()); Change chg = getOrCreateChange(container.asBinder());
chg.mActivityWindowingMode = windowingMode; chg.mActivityWindowingMode = windowingMode;
return this; return this;
@@ -149,8 +159,9 @@ public class WindowContainerTransaction implements Parcelable {
/** /**
* Sets the windowing mode of the given container. * Sets the windowing mode of the given container.
*/ */
public WindowContainerTransaction setWindowingMode(IWindowContainer container, @NonNull
int windowingMode) { public WindowContainerTransaction setWindowingMode(
@NonNull WindowContainerToken container, int windowingMode) {
Change chg = getOrCreateChange(container.asBinder()); Change chg = getOrCreateChange(container.asBinder());
chg.mWindowingMode = windowingMode; chg.mWindowingMode = windowingMode;
return this; return this;
@@ -161,7 +172,9 @@ public class WindowContainerTransaction implements Parcelable {
* child can be focused; however, when {@code true}, it is still possible for children to be * child can be focused; however, when {@code true}, it is still possible for children to be
* non-focusable due to WM policy. * non-focusable due to WM policy.
*/ */
public WindowContainerTransaction setFocusable(IWindowContainer container, boolean focusable) { @NonNull
public WindowContainerTransaction setFocusable(
@NonNull WindowContainerToken container, boolean focusable) {
Change chg = getOrCreateChange(container.asBinder()); Change chg = getOrCreateChange(container.asBinder());
chg.mFocusable = focusable; chg.mFocusable = focusable;
chg.mChangeMask |= Change.CHANGE_FOCUSABLE; chg.mChangeMask |= Change.CHANGE_FOCUSABLE;
@@ -173,7 +186,9 @@ public class WindowContainerTransaction implements Parcelable {
* visibility of the container applies, but when {@code true} the container will be forced * visibility of the container applies, but when {@code true} the container will be forced
* to be hidden. * to be hidden.
*/ */
public WindowContainerTransaction setHidden(IWindowContainer container, boolean hidden) { @NonNull
public WindowContainerTransaction setHidden(
@NonNull WindowContainerToken container, boolean hidden) {
Change chg = getOrCreateChange(container.asBinder()); Change chg = getOrCreateChange(container.asBinder());
chg.mHidden = hidden; chg.mHidden = hidden;
chg.mChangeMask |= Change.CHANGE_HIDDEN; chg.mChangeMask |= Change.CHANGE_HIDDEN;
@@ -183,8 +198,9 @@ public class WindowContainerTransaction implements Parcelable {
/** /**
* Set the smallestScreenWidth of a container. * Set the smallestScreenWidth of a container.
*/ */
public WindowContainerTransaction setSmallestScreenWidthDp(IWindowContainer container, @NonNull
int widthDp) { public WindowContainerTransaction setSmallestScreenWidthDp(
@NonNull WindowContainerToken container, int widthDp) {
Change cfg = getOrCreateChange(container.asBinder()); Change cfg = getOrCreateChange(container.asBinder());
cfg.mConfiguration.smallestScreenWidthDp = widthDp; cfg.mConfiguration.smallestScreenWidthDp = widthDp;
cfg.mConfigSetMask |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE; cfg.mConfigSetMask |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
@@ -198,8 +214,9 @@ public class WindowContainerTransaction implements Parcelable {
* @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to * @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to
* the bottom. * the bottom.
*/ */
public WindowContainerTransaction reparent(@NonNull IWindowContainer child, @NonNull
@Nullable IWindowContainer parent, boolean onTop) { public WindowContainerTransaction reparent(@NonNull WindowContainerToken child,
@Nullable WindowContainerToken parent, boolean onTop) {
mHierarchyOps.add(new HierarchyOp(child.asBinder(), mHierarchyOps.add(new HierarchyOp(child.asBinder(),
parent == null ? null : parent.asBinder(), onTop)); parent == null ? null : parent.asBinder(), onTop));
return this; return this;
@@ -211,36 +228,43 @@ public class WindowContainerTransaction implements Parcelable {
* @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to * @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to
* the bottom. * the bottom.
*/ */
public WindowContainerTransaction reorder(@NonNull IWindowContainer child, boolean onTop) { @NonNull
public WindowContainerTransaction reorder(@NonNull WindowContainerToken child, boolean onTop) {
mHierarchyOps.add(new HierarchyOp(child.asBinder(), onTop)); mHierarchyOps.add(new HierarchyOp(child.asBinder(), onTop));
return this; return this;
} }
/** @hide */
public Map<IBinder, Change> getChanges() { public Map<IBinder, Change> getChanges() {
return mChanges; return mChanges;
} }
/** @hide */
public List<HierarchyOp> getHierarchyOps() { public List<HierarchyOp> getHierarchyOps() {
return mHierarchyOps; return mHierarchyOps;
} }
@Override @Override
@NonNull
public String toString() { public String toString() {
return "WindowContainerTransaction { changes = " + mChanges + " hops = " + mHierarchyOps return "WindowContainerTransaction { changes = " + mChanges + " hops = " + mHierarchyOps
+ " }"; + " }";
} }
@Override @Override
public void writeToParcel(Parcel dest, int flags) { /** @hide */
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeMap(mChanges); dest.writeMap(mChanges);
dest.writeList(mHierarchyOps); dest.writeList(mHierarchyOps);
} }
@Override @Override
/** @hide */
public int describeContents() { public int describeContents() {
return 0; return 0;
} }
@NonNull
public static final Creator<WindowContainerTransaction> CREATOR = public static final Creator<WindowContainerTransaction> CREATOR =
new Creator<WindowContainerTransaction>() { new Creator<WindowContainerTransaction>() {
@Override @Override
@@ -256,7 +280,6 @@ public class WindowContainerTransaction implements Parcelable {
/** /**
* Holds changes on a single WindowContainer including Configuration changes. * Holds changes on a single WindowContainer including Configuration changes.
*
* @hide * @hide
*/ */
public static class Change implements Parcelable { public static class Change implements Parcelable {
@@ -430,6 +453,7 @@ public class WindowContainerTransaction implements Parcelable {
/** /**
* Holds information about a reparent/reorder operation in the hierarchy. This is separate from * Holds information about a reparent/reorder operation in the hierarchy. This is separate from
* Changes because they must be executed in the same order that they are added. * Changes because they must be executed in the same order that they are added.
* @hide
*/ */
public static class HierarchyOp implements Parcelable { public static class HierarchyOp implements Parcelable {
private final IBinder mContainer; private final IBinder mContainer;

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2020 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 android.window;
import android.annotation.NonNull;
import android.annotation.TestApi;
import android.view.SurfaceControl;
/**
* See WindowOrganizer#applyTransaction.
* {@hide}
*/
@TestApi
public abstract class WindowContainerTransactionCallback {
public abstract void onTransactionReady(int id, @NonNull SurfaceControl.Transaction t);
/** @hide */
final IWindowContainerTransactionCallback mInterface =
new IWindowContainerTransactionCallback.Stub() {
@Override
public void onTransactionReady(int id, SurfaceControl.Transaction t) {
WindowContainerTransactionCallback.this.onTransactionReady(id, t);
}
};
}

View File

@@ -16,29 +16,32 @@
package android.window; package android.window;
import android.annotation.NonNull;
import android.annotation.RequiresPermission; import android.annotation.RequiresPermission;
import android.app.ActivityManager; import android.annotation.TestApi;
import android.app.ActivityTaskManager; import android.app.ActivityTaskManager;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Singleton; import android.util.Singleton;
import java.util.List;
/** /**
* Class for organizing specific types of windows like Tasks and DisplayAreas * Base class for organizing specific types of windows like Tasks and DisplayAreas
* *
* @hide * @hide
*/ */
@TestApi
public class WindowOrganizer { public class WindowOrganizer {
/** /**
* Apply multiple WindowContainer operations at once. * Apply multiple WindowContainer operations at once.
* @param t The transaction to apply. * @param t The transaction to apply.
* @hide
*/ */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static void applyTransaction(WindowContainerTransaction t) throws RemoteException { public static void applyTransaction(@NonNull WindowContainerTransaction t) {
getWindowOrganizerController().applyTransaction(t); try {
getWindowOrganizerController().applyTransaction(t);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} }
/** /**
@@ -49,17 +52,19 @@ public class WindowOrganizer {
* WindowContainer transaction will be passed to this callback when ready. * WindowContainer transaction will be passed to this callback when ready.
* @return An ID for the sync operation which will later be passed to transactionReady callback. * @return An ID for the sync operation which will later be passed to transactionReady callback.
* This lets the caller differentiate overlapping sync operations. * This lets the caller differentiate overlapping sync operations.
* @hide
*/ */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static int applySyncTransaction(WindowContainerTransaction t, public int applySyncTransaction(@NonNull WindowContainerTransaction t,
IWindowContainerTransactionCallback callback) throws RemoteException { @NonNull WindowContainerTransactionCallback callback) {
return getWindowOrganizerController().applySyncTransaction(t, callback); try {
return getWindowOrganizerController().applySyncTransaction(t, callback.mInterface);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} }
/** @hide */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
private static IWindowOrganizerController getWindowOrganizerController() { static IWindowOrganizerController getWindowOrganizerController() {
return IWindowOrganizerControllerSingleton.get(); return IWindowOrganizerControllerSingleton.get();
} }
@@ -74,138 +79,4 @@ public class WindowOrganizer {
} }
} }
}; };
public static class TaskOrganizer {
/**
* Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
* If there was already a TaskOrganizer for this windowing mode it will be evicted
* and receive taskVanished callbacks in the process.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static void registerOrganizer(ITaskOrganizer organizer, int windowingMode)
throws RemoteException {
getController().registerTaskOrganizer(organizer, windowingMode);
}
/** Unregisters a previously registered task organizer. */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static void unregisterOrganizer(ITaskOrganizer organizer) throws RemoteException {
getController().unregisterTaskOrganizer(organizer);
}
/** Creates a persistent root task in WM for a particular windowing-mode. */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static ActivityManager.RunningTaskInfo createRootTask(
int displayId, int windowingMode) throws RemoteException {
return getController().createRootTask(displayId, windowingMode);
}
/** Deletes a persistent root task in WM */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static boolean deleteRootTask(IWindowContainer task) throws RemoteException {
return getController().deleteRootTask(task);
}
/** Gets direct child tasks (ordered from top-to-bottom) */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static List<ActivityManager.RunningTaskInfo> getChildTasks(IWindowContainer parent,
int[] activityTypes) throws RemoteException {
return getController().getChildTasks(parent, activityTypes);
}
/** Gets all root tasks on a display (ordered from top-to-bottom) */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static List<ActivityManager.RunningTaskInfo> getRootTasks(
int displayId, int[] activityTypes) throws RemoteException {
return getController().getRootTasks(displayId, activityTypes);
}
/** Get the root task which contains the current ime target */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static IWindowContainer getImeTarget(int display) throws RemoteException {
return getController().getImeTarget(display);
}
/**
* Set's the root task to launch new tasks into on a display. {@code null} means no launch
* root and thus new tasks just end up directly on the display.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static void setLaunchRoot(int displayId, IWindowContainer root)
throws RemoteException {
getController().setLaunchRoot(displayId, root);
}
/**
* Requests that the given task organizer is notified when back is pressed on the root
* activity of one of its controlled tasks.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer,
boolean interceptBackPressed) throws RemoteException {
getController().setInterceptBackPressedOnTaskRoot(organizer, interceptBackPressed);
}
private static ITaskOrganizerController getController() {
return ITaskOrganizerControllerSingleton.get();
}
private static final Singleton<ITaskOrganizerController> ITaskOrganizerControllerSingleton =
new Singleton<ITaskOrganizerController>() {
@Override
protected ITaskOrganizerController create() {
try {
return getWindowOrganizerController().getTaskOrganizerController();
} catch (RemoteException e) {
return null;
}
}
};
}
/** Class for organizing display areas. */
public static class DisplayAreaOrganizer {
public static final int FEATURE_UNDEFINED = -1;
public static final int FEATURE_SYSTEM_FIRST = 0;
// The Root display area on a display
public static final int FEATURE_ROOT = FEATURE_SYSTEM_FIRST;
// Display area hosting the task container.
public static final int FEATURE_TASK_CONTAINER = FEATURE_SYSTEM_FIRST + 1;
// Display area hosting non-activity window tokens.
public static final int FEATURE_WINDOW_TOKENS = FEATURE_SYSTEM_FIRST + 2;
public static final int FEATURE_SYSTEM_LAST = 10_000;
// Vendor specific display area definition can start with this value.
public static final int FEATURE_VENDOR_FIRST = FEATURE_SYSTEM_LAST + 1;
/** @hide */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static void registerOrganizer(
IDisplayAreaOrganizer organizer, int displayAreaFeature) throws RemoteException {
getController().registerOrganizer(organizer, displayAreaFeature);
}
/** @hide */
private static IDisplayAreaOrganizerController getController() {
return IDisplayAreaOrganizerControllerSingleton.get();
}
private static final Singleton<IDisplayAreaOrganizerController>
IDisplayAreaOrganizerControllerSingleton =
new Singleton<IDisplayAreaOrganizerController>() {
@Override
protected IDisplayAreaOrganizerController create() {
try {
return getWindowOrganizerController()
.getDisplayAreaOrganizerController();
} catch (RemoteException e) {
return null;
}
}
};
}
} }

View File

@@ -23,8 +23,8 @@ import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.TaskEmbedder; import android.window.TaskEmbedder;
import android.app.TaskOrganizerTaskEmbedder; import android.window.TaskOrganizerTaskEmbedder;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutInfo;

View File

@@ -41,8 +41,8 @@ import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import android.util.Size; import android.util.Size;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.window.ITaskOrganizer; import android.window.TaskOrganizer;
import android.window.IWindowContainer; import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer; import android.window.WindowOrganizer;
@@ -60,7 +60,7 @@ import java.util.function.Consumer;
/** /**
* Manages PiP tasks such as resize and offset. * Manages PiP tasks such as resize and offset.
* *
* This class listens on {@link ITaskOrganizer} callbacks for windowing mode change * This class listens on {@link TaskOrganizer} callbacks for windowing mode change
* both to and from PiP and issues corresponding animation if applicable. * both to and from PiP and issues corresponding animation if applicable.
* Normally, we apply series of {@link SurfaceControl.Transaction} when the animator is running * Normally, we apply series of {@link SurfaceControl.Transaction} when the animator is running
* and files a final {@link WindowContainerTransaction} at the end of the transition. * and files a final {@link WindowContainerTransaction} at the end of the transition.
@@ -68,7 +68,7 @@ import java.util.function.Consumer;
* This class is also responsible for general resize/offset PiP operations within SysUI component, * This class is also responsible for general resize/offset PiP operations within SysUI component,
* see also {@link com.android.systemui.pip.phone.PipMotionHelper}. * see also {@link com.android.systemui.pip.phone.PipMotionHelper}.
*/ */
public class PipTaskOrganizer extends ITaskOrganizer.Stub { public class PipTaskOrganizer extends TaskOrganizer {
private static final String TAG = PipTaskOrganizer.class.getSimpleName(); private static final String TAG = PipTaskOrganizer.class.getSimpleName();
private static final int MSG_RESIZE_IMMEDIATE = 1; private static final int MSG_RESIZE_IMMEDIATE = 1;
@@ -182,7 +182,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
}; };
private ActivityManager.RunningTaskInfo mTaskInfo; private ActivityManager.RunningTaskInfo mTaskInfo;
private IWindowContainer mToken; private WindowContainerToken mToken;
private SurfaceControl mLeash; private SurfaceControl mLeash;
private boolean mInPip; private boolean mInPip;
private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
@@ -234,13 +234,9 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
* @param animationDurationMs duration in millisecond for the exiting PiP transition * @param animationDurationMs duration in millisecond for the exiting PiP transition
*/ */
public void dismissPip(int animationDurationMs) { public void dismissPip(int animationDurationMs) {
try { final WindowContainerTransaction wct = new WindowContainerTransaction();
final WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN);
wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN); WindowOrganizer.applyTransaction(wct);
WindowOrganizer.applyTransaction(wct);
} catch (RemoteException e) {
Log.e(TAG, "Failed to apply container transaction", e);
}
final Rect destinationBounds = mBoundsToRestore.remove(mToken.asBinder()); final Rect destinationBounds = mBoundsToRestore.remove(mToken.asBinder());
scheduleAnimateResizePip(mLastReportedBounds, destinationBounds, scheduleAnimateResizePip(mLastReportedBounds, destinationBounds,
TRANSITION_DIRECTION_TO_FULLSCREEN, animationDurationMs, TRANSITION_DIRECTION_TO_FULLSCREEN, animationDurationMs,
@@ -258,11 +254,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
mTaskInfo = info; mTaskInfo = info;
mToken = mTaskInfo.token; mToken = mTaskInfo.token;
mInPip = true; mInPip = true;
try { mLeash = mToken.getLeash();
mLeash = mToken.getLeash();
} catch (RemoteException e) {
throw new RuntimeException("Unable to get leash", e);
}
final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds(); final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
mBoundsToRestore.put(mToken.asBinder(), currentBounds); mBoundsToRestore.put(mToken.asBinder(), currentBounds);
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) { if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
@@ -290,8 +283,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
*/ */
@Override @Override
public void onTaskVanished(ActivityManager.RunningTaskInfo info) { public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
IWindowContainer token = info.token; WindowContainerToken token = info.token;
Objects.requireNonNull(token, "Requires valid IWindowContainer"); Objects.requireNonNull(token, "Requires valid WindowContainerToken");
if (token.asBinder() != mToken.asBinder()) { if (token.asBinder() != mToken.asBinder()) {
Log.wtf(TAG, "Unrecognized token: " + token); Log.wtf(TAG, "Unrecognized token: " + token);
return; return;
@@ -502,30 +495,26 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
+ "directly"); + "directly");
} }
mLastReportedBounds.set(destinationBounds); mLastReportedBounds.set(destinationBounds);
try { final WindowContainerTransaction wct = new WindowContainerTransaction();
final WindowContainerTransaction wct = new WindowContainerTransaction(); final Rect taskBounds;
final Rect taskBounds; if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) {
if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) { // If we are animating to fullscreen, then we need to reset the override bounds
// If we are animating to fullscreen, then we need to reset the override bounds // on the task to ensure that the task "matches" the parent's bounds, this applies
// on the task to ensure that the task "matches" the parent's bounds, this applies // also to the final windowing mode, which should be reset to undefined rather than
// also to the final windowing mode, which should be reset to undefined rather than // fullscreen.
// fullscreen. taskBounds = null;
taskBounds = null; wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED)
wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED) .setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); } else {
} else { taskBounds = destinationBounds;
taskBounds = destinationBounds;
}
if (direction == TRANSITION_DIRECTION_TO_PIP) {
wct.scheduleFinishEnterPip(mToken, taskBounds);
} else {
wct.setBounds(mToken, taskBounds);
}
wct.setBoundsChangeTransaction(mToken, tx);
WindowOrganizer.applyTransaction(wct);
} catch (RemoteException e) {
Log.e(TAG, "Failed to apply container transaction", e);
} }
if (direction == TRANSITION_DIRECTION_TO_PIP) {
wct.scheduleFinishEnterPip(mToken, taskBounds);
} else {
wct.setBounds(mToken, taskBounds);
}
wct.setBoundsChangeTransaction(mToken, tx);
WindowOrganizer.applyTransaction(wct);
} }
private void animateResizePip(Rect currentBounds, Rect destinationBounds, private void animateResizePip(Rect currentBounds, Rect destinationBounds,

View File

@@ -18,7 +18,6 @@ package com.android.systemui.pip.phone;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.window.WindowOrganizer.TaskOrganizer;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN; import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN;
@@ -234,7 +233,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
mPipBoundsHandler.onDisplayInfoChanged(displayInfo); mPipBoundsHandler.onDisplayInfoChanged(displayInfo);
try { try {
TaskOrganizer.registerOrganizer(mPipTaskOrganizer, WINDOWING_MODE_PINNED); mPipTaskOrganizer.registerOrganizer(WINDOWING_MODE_PINNED);
ActivityManager.StackInfo stackInfo = activityTaskManager.getStackInfo( ActivityManager.StackInfo stackInfo = activityTaskManager.getStackInfo(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
if (stackInfo != null) { if (stackInfo != null) {

View File

@@ -19,7 +19,6 @@ package com.android.systemui.pip.tv;
import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.window.WindowOrganizer.TaskOrganizer;
import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.StackInfo; import android.app.ActivityManager.StackInfo;
@@ -294,7 +293,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
try { try {
WindowManagerWrapper.getInstance().addPinnedStackListener(mPinnedStackListener); WindowManagerWrapper.getInstance().addPinnedStackListener(mPinnedStackListener);
TaskOrganizer.registerOrganizer(mPipTaskOrganizer, WINDOWING_MODE_PINNED); mPipTaskOrganizer.registerOrganizer(WINDOWING_MODE_PINNED);
} catch (RemoteException | UnsupportedOperationException e) { } catch (RemoteException | UnsupportedOperationException e) {
Log.e(TAG, "Failed to register pinned stack listener", e); Log.e(TAG, "Failed to register pinned stack listener", e);
} }

View File

@@ -20,7 +20,6 @@ import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED; import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED; import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.DEFAULT_DISPLAY;
import static android.window.WindowOrganizer.TaskOrganizer;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
@@ -33,11 +32,12 @@ import android.os.Handler;
import android.os.RemoteException; import android.os.RemoteException;
import android.provider.Settings; import android.provider.Settings;
import android.util.Slog; import android.util.Slog;
import android.window.TaskOrganizer;
import android.window.WindowContainerToken;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.view.SurfaceSession; import android.view.SurfaceSession;
import android.view.View; import android.view.View;
import android.window.IWindowContainer;
import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer; import android.window.WindowOrganizer;
@@ -181,14 +181,9 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
private boolean mPausedTargetAdjusted = false; private boolean mPausedTargetAdjusted = false;
private boolean getSecondaryHasFocus(int displayId) { private boolean getSecondaryHasFocus(int displayId) {
try { WindowContainerToken imeSplit = TaskOrganizer.getImeTarget(displayId);
IWindowContainer imeSplit = TaskOrganizer.getImeTarget(displayId); return imeSplit != null
return imeSplit != null && (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder());
&& (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder());
} catch (RemoteException e) {
Slog.w(TAG, "Failed to get IME target", e);
}
return false;
} }
private void updateDimTargets() { private void updateDimTargets() {
@@ -270,10 +265,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
wct.setScreenSizeDp(mSplits.mSecondary.token, wct.setScreenSizeDp(mSplits.mSecondary.token,
SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED); SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
} }
try {
WindowOrganizer.applyTransaction(wct); WindowOrganizer.applyTransaction(wct);
} catch (RemoteException e) {
}
// Update all the adjusted-for-ime states // Update all the adjusted-for-ime states
if (!mPaused) { if (!mPaused) {
@@ -506,12 +499,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position; int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
final WindowContainerTransaction tct = new WindowContainerTransaction(); final WindowContainerTransaction tct = new WindowContainerTransaction();
mSplitLayout.resizeSplits(midPos, tct); mSplitLayout.resizeSplits(midPos, tct);
try { WindowOrganizer.applyTransaction(tct);
WindowOrganizer.applyTransaction(tct); } else if (mSplitLayout.mDisplayLayout.rotation()
} catch (RemoteException e) {
}
} else if (mRotateSplitLayout != null
&& mSplitLayout.mDisplayLayout.rotation()
== mRotateSplitLayout.mDisplayLayout.rotation()) { == mRotateSplitLayout.mDisplayLayout.rotation()) {
mSplitLayout.mPrimary = new Rect(mRotateSplitLayout.mPrimary); mSplitLayout.mPrimary = new Rect(mRotateSplitLayout.mPrimary);
mSplitLayout.mSecondary = new Rect(mRotateSplitLayout.mSecondary); mSplitLayout.mSecondary = new Rect(mRotateSplitLayout.mSecondary);
@@ -653,7 +642,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
} }
} }
updateTouchable(); updateTouchable();
WindowManagerProxy.applyContainerTransaction(wct); WindowOrganizer.applyTransaction(wct);
} }
void setAdjustedForIme(boolean adjustedForIme) { void setAdjustedForIme(boolean adjustedForIme) {

View File

@@ -22,7 +22,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.DEFAULT_DISPLAY;
import static android.window.WindowOrganizer.TaskOrganizer;
import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.RunningTaskInfo;
import android.app.WindowConfiguration; import android.app.WindowConfiguration;
@@ -32,11 +31,11 @@ import android.util.Log;
import android.view.Display; import android.view.Display;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.view.SurfaceSession; import android.view.SurfaceSession;
import android.window.ITaskOrganizer; import android.window.TaskOrganizer;
import java.util.ArrayList; import java.util.ArrayList;
class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub { class SplitScreenTaskOrganizer extends TaskOrganizer {
private static final String TAG = "SplitScreenTaskOrganizer"; private static final String TAG = "SplitScreenTaskOrganizer";
private static final boolean DEBUG = Divider.DEBUG; private static final boolean DEBUG = Divider.DEBUG;
@@ -56,8 +55,8 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
} }
void init(SurfaceSession session) throws RemoteException { void init(SurfaceSession session) throws RemoteException {
TaskOrganizer.registerOrganizer(this, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
TaskOrganizer.registerOrganizer(this, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
try { try {
mPrimary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, mPrimary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY,
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
@@ -65,9 +64,9 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
mPrimarySurface = mPrimary.token.getLeash(); mPrimarySurface = mPrimary.token.getLeash();
mSecondarySurface = mSecondary.token.getLeash(); mSecondarySurface = mSecondary.token.getLeash();
} catch (RemoteException e) { } catch (Exception e) {
// teardown to prevent callbacks // teardown to prevent callbacks
TaskOrganizer.unregisterOrganizer(this); unregisterOrganizer();
throw e; throw e;
} }
mSplitScreenSupported = true; mSplitScreenSupported = true;
@@ -98,14 +97,6 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
mDivider.mTransactionPool.release(t); mDivider.mTransactionPool.release(t);
} }
@Override
public void onTaskAppeared(RunningTaskInfo taskInfo) {
}
@Override
public void onTaskVanished(RunningTaskInfo taskInfo) {
}
@Override @Override
public void onTaskInfoChanged(RunningTaskInfo taskInfo) { public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
if (taskInfo.displayId != DEFAULT_DISPLAY) { if (taskInfo.displayId != DEFAULT_DISPLAY) {

View File

@@ -20,7 +20,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.DEFAULT_DISPLAY;
import static android.window.WindowOrganizer.TaskOrganizer;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.app.ActivityManager; import android.app.ActivityManager;
@@ -30,7 +29,8 @@ import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import android.view.Display; import android.view.Display;
import android.view.WindowManagerGlobal; import android.view.WindowManagerGlobal;
import android.window.IWindowContainer; import android.window.TaskOrganizer;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer; import android.window.WindowOrganizer;
@@ -112,27 +112,21 @@ public class WindowManagerProxy {
static void applyResizeSplits(int position, SplitDisplayLayout splitLayout) { static void applyResizeSplits(int position, SplitDisplayLayout splitLayout) {
WindowContainerTransaction t = new WindowContainerTransaction(); WindowContainerTransaction t = new WindowContainerTransaction();
splitLayout.resizeSplits(position, t); splitLayout.resizeSplits(position, t);
try { WindowOrganizer.applyTransaction(t);
WindowOrganizer.applyTransaction(t);
} catch (RemoteException e) {
}
} }
private static boolean getHomeAndRecentsTasks(List<IWindowContainer> out, private static boolean getHomeAndRecentsTasks(List<WindowContainerToken> out,
IWindowContainer parent) { WindowContainerToken parent) {
boolean resizable = false; boolean resizable = false;
try { List<ActivityManager.RunningTaskInfo> rootTasks = parent == null
List<ActivityManager.RunningTaskInfo> rootTasks = parent == null ? TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS)
? TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS) : TaskOrganizer.getChildTasks(parent, HOME_AND_RECENTS);
: TaskOrganizer.getChildTasks(parent, HOME_AND_RECENTS); for (int i = 0, n = rootTasks.size(); i < n; ++i) {
for (int i = 0, n = rootTasks.size(); i < n; ++i) { final ActivityManager.RunningTaskInfo ti = rootTasks.get(i);
final ActivityManager.RunningTaskInfo ti = rootTasks.get(i); out.add(ti.token);
out.add(ti.token); if (ti.topActivityType == ACTIVITY_TYPE_HOME) {
if (ti.topActivityType == ACTIVITY_TYPE_HOME) { resizable = ti.isResizable();
resizable = ti.isResizable();
}
} }
} catch (RemoteException e) {
} }
return resizable; return resizable;
} }
@@ -142,11 +136,11 @@ public class WindowManagerProxy {
* split is minimized. This actually "sticks out" of the secondary split area, but when in * split is minimized. This actually "sticks out" of the secondary split area, but when in
* minimized mode, the secondary split gets a 'negative' crop to expose it. * minimized mode, the secondary split gets a 'negative' crop to expose it.
*/ */
static boolean applyHomeTasksMinimized(SplitDisplayLayout layout, IWindowContainer parent, static boolean applyHomeTasksMinimized(SplitDisplayLayout layout, WindowContainerToken parent,
@NonNull WindowContainerTransaction wct) { @NonNull WindowContainerTransaction wct) {
// Resize the home/recents stacks to the larger minimized-state size // Resize the home/recents stacks to the larger minimized-state size
final Rect homeBounds; final Rect homeBounds;
final ArrayList<IWindowContainer> homeStacks = new ArrayList<>(); final ArrayList<WindowContainerToken> homeStacks = new ArrayList<>();
boolean isHomeResizable = getHomeAndRecentsTasks(homeStacks, parent); boolean isHomeResizable = getHomeAndRecentsTasks(homeStacks, parent);
if (isHomeResizable) { if (isHomeResizable) {
homeBounds = layout.calcMinimizedHomeStackBounds(); homeBounds = layout.calcMinimizedHomeStackBounds();
@@ -170,36 +164,31 @@ public class WindowManagerProxy {
* @return whether the home stack is resizable * @return whether the home stack is resizable
*/ */
static boolean applyEnterSplit(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout) { static boolean applyEnterSplit(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout) {
try { // Set launchtile first so that any stack created after
// Set launchtile first so that any stack created after // getAllStackInfos and before reparent (even if unlikely) are placed
// getAllStackInfos and before reparent (even if unlikely) are placed // correctly.
// correctly. TaskOrganizer.setLaunchRoot(DEFAULT_DISPLAY, tiles.mSecondary.token);
TaskOrganizer.setLaunchRoot(DEFAULT_DISPLAY, tiles.mSecondary.token); List<ActivityManager.RunningTaskInfo> rootTasks =
List<ActivityManager.RunningTaskInfo> rootTasks = TaskOrganizer.getRootTasks(DEFAULT_DISPLAY, null /* activityTypes */);
TaskOrganizer.getRootTasks(DEFAULT_DISPLAY, null /* activityTypes */); WindowContainerTransaction wct = new WindowContainerTransaction();
WindowContainerTransaction wct = new WindowContainerTransaction(); if (rootTasks.isEmpty()) {
if (rootTasks.isEmpty()) { return false;
return false;
}
tiles.mHomeAndRecentsSurfaces.clear();
for (int i = rootTasks.size() - 1; i >= 0; --i) {
final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i);
if (isHomeOrRecentTask(rootTask)) {
tiles.mHomeAndRecentsSurfaces.add(rootTask.token.getLeash());
}
if (rootTask.configuration.windowConfiguration.getWindowingMode()
!= WINDOWING_MODE_FULLSCREEN) {
continue;
}
wct.reparent(rootTask.token, tiles.mSecondary.token, true /* onTop */);
}
boolean isHomeResizable = applyHomeTasksMinimized(layout, null /* parent */, wct);
WindowOrganizer.applyTransaction(wct);
return isHomeResizable;
} catch (RemoteException e) {
Log.w(TAG, "Error moving fullscreen tasks to secondary split: " + e);
} }
return false; tiles.mHomeAndRecentsSurfaces.clear();
for (int i = rootTasks.size() - 1; i >= 0; --i) {
final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i);
if (isHomeOrRecentTask(rootTask)) {
tiles.mHomeAndRecentsSurfaces.add(rootTask.token.getLeash());
}
if (rootTask.configuration.windowConfiguration.getWindowingMode()
!= WINDOWING_MODE_FULLSCREEN) {
continue;
}
wct.reparent(rootTask.token, tiles.mSecondary.token, true /* onTop */);
}
boolean isHomeResizable = applyHomeTasksMinimized(layout, null /* parent */, wct);
WindowOrganizer.applyTransaction(wct);
return isHomeResizable;
} }
private static boolean isHomeOrRecentTask(ActivityManager.RunningTaskInfo ti) { private static boolean isHomeOrRecentTask(ActivityManager.RunningTaskInfo ti) {
@@ -214,82 +203,70 @@ public class WindowManagerProxy {
* fullscreen. {@code false} resolves the other way. * fullscreen. {@code false} resolves the other way.
*/ */
static void applyDismissSplit(SplitScreenTaskOrganizer tiles, boolean dismissOrMaximize) { static void applyDismissSplit(SplitScreenTaskOrganizer tiles, boolean dismissOrMaximize) {
try { // Set launch root first so that any task created after getChildContainers and
// Set launch root first so that any task created after getChildContainers and // before reparent (pretty unlikely) are put into fullscreen.
// before reparent (pretty unlikely) are put into fullscreen. TaskOrganizer.setLaunchRoot(Display.DEFAULT_DISPLAY, null);
TaskOrganizer.setLaunchRoot(Display.DEFAULT_DISPLAY, null); tiles.mHomeAndRecentsSurfaces.clear();
tiles.mHomeAndRecentsSurfaces.clear(); // TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished
// TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished // plus specific APIs to clean this up.
// plus specific APIs to clean this up. List<ActivityManager.RunningTaskInfo> primaryChildren =
List<ActivityManager.RunningTaskInfo> primaryChildren = TaskOrganizer.getChildTasks(tiles.mPrimary.token, null /* activityTypes */);
TaskOrganizer.getChildTasks(tiles.mPrimary.token, null /* activityTypes */); List<ActivityManager.RunningTaskInfo> secondaryChildren =
List<ActivityManager.RunningTaskInfo> secondaryChildren = TaskOrganizer.getChildTasks(tiles.mSecondary.token, null /* activityTypes */);
TaskOrganizer.getChildTasks(tiles.mSecondary.token, null /* activityTypes */); // In some cases (eg. non-resizable is launched), system-server will leave split-screen.
// In some cases (eg. non-resizable is launched), system-server will leave split-screen. // as a result, the above will not capture any tasks; yet, we need to clean-up the
// as a result, the above will not capture any tasks; yet, we need to clean-up the // home task bounds.
// home task bounds. List<ActivityManager.RunningTaskInfo> freeHomeAndRecents =
List<ActivityManager.RunningTaskInfo> freeHomeAndRecents = TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS);
TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS); if (primaryChildren.isEmpty() && secondaryChildren.isEmpty()
if (primaryChildren.isEmpty() && secondaryChildren.isEmpty() && freeHomeAndRecents.isEmpty()) {
&& freeHomeAndRecents.isEmpty()) { return;
return; }
WindowContainerTransaction wct = new WindowContainerTransaction();
if (dismissOrMaximize) {
// Dismissing, so move all primary split tasks first
for (int i = primaryChildren.size() - 1; i >= 0; --i) {
wct.reparent(primaryChildren.get(i).token, null /* parent */,
true /* onTop */);
} }
WindowContainerTransaction wct = new WindowContainerTransaction(); // Don't need to worry about home tasks because they are already in the "proper"
if (dismissOrMaximize) { // order within the secondary split.
// Dismissing, so move all primary split tasks first for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
for (int i = primaryChildren.size() - 1; i >= 0; --i) { final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
wct.reparent(primaryChildren.get(i).token, null /* parent */, wct.reparent(ti.token, null /* parent */, true /* onTop */);
true /* onTop */); if (isHomeOrRecentTask(ti)) {
wct.setBounds(ti.token, null);
} }
// Don't need to worry about home tasks because they are already in the "proper" }
// order within the secondary split. } else {
for (int i = secondaryChildren.size() - 1; i >= 0; --i) { // Maximize, so move non-home secondary split first
final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i); for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
if (isHomeOrRecentTask(secondaryChildren.get(i))) {
continue;
}
wct.reparent(secondaryChildren.get(i).token, null /* parent */,
true /* onTop */);
}
// Find and place home tasks in-between. This simulates the fact that there was
// nothing behind the primary split's tasks.
for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
if (isHomeOrRecentTask(ti)) {
wct.reparent(ti.token, null /* parent */, true /* onTop */); wct.reparent(ti.token, null /* parent */, true /* onTop */);
if (isHomeOrRecentTask(ti)) { // reset bounds too
wct.setBounds(ti.token, null); wct.setBounds(ti.token, null);
}
}
} else {
// Maximize, so move non-home secondary split first
for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
if (isHomeOrRecentTask(secondaryChildren.get(i))) {
continue;
}
wct.reparent(secondaryChildren.get(i).token, null /* parent */,
true /* onTop */);
}
// Find and place home tasks in-between. This simulates the fact that there was
// nothing behind the primary split's tasks.
for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
if (isHomeOrRecentTask(ti)) {
wct.reparent(ti.token, null /* parent */, true /* onTop */);
// reset bounds too
wct.setBounds(ti.token, null);
}
}
for (int i = primaryChildren.size() - 1; i >= 0; --i) {
wct.reparent(primaryChildren.get(i).token, null /* parent */,
true /* onTop */);
} }
} }
for (int i = freeHomeAndRecents.size() - 1; i >= 0; --i) { for (int i = primaryChildren.size() - 1; i >= 0; --i) {
wct.setBounds(freeHomeAndRecents.get(i).token, null); wct.reparent(primaryChildren.get(i).token, null /* parent */,
true /* onTop */);
} }
// Reset focusable to true
wct.setFocusable(tiles.mPrimary.token, true /* focusable */);
WindowOrganizer.applyTransaction(wct);
} catch (RemoteException e) {
Log.w(TAG, "Failed to remove stack: " + e);
} }
} for (int i = freeHomeAndRecents.size() - 1; i >= 0; --i) {
wct.setBounds(freeHomeAndRecents.get(i).token, null);
static void applyContainerTransaction(WindowContainerTransaction wct) {
try {
WindowOrganizer.applyTransaction(wct);
} catch (RemoteException e) {
Log.w(TAG, "Error setting focusability: " + e);
} }
// Reset focusable to true
wct.setFocusable(tiles.mPrimary.token, true /* focusable */);
WindowOrganizer.applyTransaction(wct);
} }
} }

View File

@@ -2802,7 +2802,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
false /* includingParents */); false /* includingParents */);
} }
WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction();
wct.reparent(task.getStack().mRemoteToken, primarySplitTask.mRemoteToken, toTop); wct.reparent(task.getStack().mRemoteToken.toWindowContainerToken(),
primarySplitTask.mRemoteToken.toWindowContainerToken(), toTop);
mWindowOrganizerController.applyTransaction(wct); mWindowOrganizerController.applyTransaction(wct);
} }
@@ -4291,7 +4292,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
tempDockedTaskInsetBounds != null ? tempDockedTaskInsetBounds tempDockedTaskInsetBounds != null ? tempDockedTaskInsetBounds
: (tempDockedTaskBounds != null ? tempDockedTaskBounds : (tempDockedTaskBounds != null ? tempDockedTaskBounds
: dockedBounds); : dockedBounds);
wct.setBounds(primary.mRemoteToken, primaryRect); wct.setBounds(primary.mRemoteToken.toWindowContainerToken(), primaryRect);
Rect otherRect = tempOtherTaskInsetBounds != null ? tempOtherTaskInsetBounds Rect otherRect = tempOtherTaskInsetBounds != null ? tempOtherTaskInsetBounds
: tempOtherTaskBounds; : tempOtherTaskBounds;
if (otherRect == null) { if (otherRect == null) {
@@ -4303,7 +4304,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
otherRect.top = primaryRect.bottom + 6; otherRect.top = primaryRect.bottom + 6;
} }
} }
wct.setBounds(secondary.mRemoteToken, otherRect); wct.setBounds(secondary.mRemoteToken.toWindowContainerToken(), otherRect);
mWindowOrganizerController.applyTransaction(wct); mWindowOrganizerController.applyTransaction(wct);
} }
} finally { } finally {

View File

@@ -16,10 +16,6 @@
package com.android.server.wm; package com.android.server.wm;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
import android.window.ITaskOrganizer;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import java.util.HashMap; import java.util.HashMap;
@@ -50,7 +46,7 @@ class BLASTSyncEngine {
private static final String TAG = "BLASTSyncEngine"; private static final String TAG = "BLASTSyncEngine";
interface TransactionReadyListener { interface TransactionReadyListener {
void transactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction); void onTransactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction);
}; };
// Holds state associated with a single synchronous set of operations. // Holds state associated with a single synchronous set of operations.
@@ -63,12 +59,12 @@ class BLASTSyncEngine {
private void tryFinish() { private void tryFinish() {
if (mRemainingTransactions == 0 && mReady) { if (mRemainingTransactions == 0 && mReady) {
mListener.transactionReady(mSyncId, mMergedTransaction); mListener.onTransactionReady(mSyncId, mMergedTransaction);
mPendingSyncs.remove(mSyncId); mPendingSyncs.remove(mSyncId);
} }
} }
public void transactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) { public void onTransactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
mRemainingTransactions--; mRemainingTransactions--;
mMergedTransaction.merge(mergedTransaction); mMergedTransaction.merge(mergedTransaction);
tryFinish(); tryFinish();

View File

@@ -21,9 +21,9 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE; import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER; import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER;
import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_ROOT; import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;
import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_UNDEFINED; import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_WINDOW_TOKENS; import static android.window.DisplayAreaOrganizer.FEATURE_WINDOW_TOKENS;
import static com.android.internal.util.Preconditions.checkState; import static com.android.internal.util.Preconditions.checkState;
import static com.android.server.wm.DisplayAreaProto.NAME; import static com.android.server.wm.DisplayAreaProto.NAME;

View File

@@ -94,7 +94,7 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
void onDisplayAreaAppeared(IDisplayAreaOrganizer organizer, DisplayArea da) { void onDisplayAreaAppeared(IDisplayAreaOrganizer organizer, DisplayArea da) {
try { try {
organizer.onDisplayAreaAppeared(da.mRemoteToken); organizer.onDisplayAreaAppeared(da.mRemoteToken.toWindowContainerToken());
} catch (RemoteException e) { } catch (RemoteException e) {
// Oh well... // Oh well...
} }
@@ -102,7 +102,7 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
void onDisplayAreaVanished(IDisplayAreaOrganizer organizer, DisplayArea da) { void onDisplayAreaVanished(IDisplayAreaOrganizer organizer, DisplayArea da) {
try { try {
organizer.onDisplayAreaVanished(da.mRemoteToken); organizer.onDisplayAreaVanished(da.mRemoteToken.toWindowContainerToken());
} catch (RemoteException e) { } catch (RemoteException e) {
// Oh well... // Oh well...
} }

View File

@@ -87,8 +87,8 @@ class DisplayAreaPolicyBuilder {
* *
* Must be unique among the features added to a {@link DisplayAreaPolicyBuilder}. * Must be unique among the features added to a {@link DisplayAreaPolicyBuilder}.
* *
* @see android.window.WindowOrganizer.DisplayAreaOrganizer#FEATURE_SYSTEM_FIRST * @see android.window.DisplayAreaOrganizer#FEATURE_SYSTEM_FIRST
* @see android.window.WindowOrganizer.DisplayAreaOrganizer#FEATURE_VENDOR_FIRST * @see android.window.DisplayAreaOrganizer#FEATURE_VENDOR_FIRST
*/ */
public int getId() { public int getId() {
return mId; return mId;

View File

@@ -2346,7 +2346,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
stack.getBounds(info.bounds); stack.getBounds(info.bounds);
info.displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId() : INVALID_DISPLAY; info.displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId() : INVALID_DISPLAY;
info.stackId = stack.mTaskId; info.stackId = stack.mTaskId;
info.stackToken = stack.mRemoteToken; info.stackToken = stack.mRemoteToken.toWindowContainerToken();
info.userId = stack.mCurrentUser; info.userId = stack.mCurrentUser;
info.visible = stack.shouldBeVisible(null); info.visible = stack.shouldBeVisible(null);
// A stack might be not attached to a display. // A stack might be not attached to a display.

View File

@@ -478,7 +478,7 @@ class Task extends WindowContainer<WindowContainer> {
/** /**
* The TaskOrganizer which is delegated presentation of this task. If set the Task will * The TaskOrganizer which is delegated presentation of this task. If set the Task will
* emit an IWindowContainer (allowing access to it's SurfaceControl leash) to the organizers * emit an WindowContainerToken (allowing access to it's SurfaceControl leash) to the organizers
* taskAppeared callback, and emit a taskRemoved callback when the Task is vanished. * taskAppeared callback, and emit a taskRemoved callback when the Task is vanished.
*/ */
ITaskOrganizer mTaskOrganizer; ITaskOrganizer mTaskOrganizer;
@@ -3435,7 +3435,7 @@ class Task extends WindowContainer<WindowContainer> {
info.taskDescription = new ActivityManager.TaskDescription(getTaskDescription()); info.taskDescription = new ActivityManager.TaskDescription(getTaskDescription());
info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode(); info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
info.configuration.setTo(getConfiguration()); info.configuration.setTo(getConfiguration());
info.token = mRemoteToken; info.token = mRemoteToken.toWindowContainerToken();
//TODO (AM refactor): Just use local once updateEffectiveIntent is run during all child //TODO (AM refactor): Just use local once updateEffectiveIntent is run during all child
// order changes. // order changes.

View File

@@ -31,7 +31,7 @@ import static android.app.WindowConfiguration.isSplitScreenWindowingMode;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_TASK_CONTAINER; import static android.window.DisplayAreaOrganizer.FEATURE_TASK_CONTAINER;
import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE; import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
@@ -1183,7 +1183,8 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
for (int i = mTmpTasks.size() - 1; i >= 0; i--) { for (int i = mTmpTasks.size() - 1; i >= 0; i--) {
final Task root = mTmpTasks.get(i); final Task root = mTmpTasks.get(i);
for (int j = 0; j < root.getChildCount(); j++) { for (int j = 0; j < root.getChildCount(); j++) {
wct.reparent(root.getChildAt(j).mRemoteToken, null, true /* toTop */); wct.reparent(root.getChildAt(j).mRemoteToken.toWindowContainerToken(),
null, true /* toTop */);
} }
} }
mAtmService.mWindowOrganizerController.applyTransaction(wct); mAtmService.mWindowOrganizerController.applyTransaction(wct);

View File

@@ -36,7 +36,7 @@ import android.util.Slog;
import android.util.SparseArray; import android.util.SparseArray;
import android.window.ITaskOrganizer; import android.window.ITaskOrganizer;
import android.window.ITaskOrganizerController; import android.window.ITaskOrganizerController;
import android.window.IWindowContainer; import android.window.WindowContainerToken;
import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils;
@@ -290,7 +290,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
} }
@Override @Override
public boolean deleteRootTask(IWindowContainer token) { public boolean deleteRootTask(WindowContainerToken token) {
enforceStackPermission("deleteRootTask()"); enforceStackPermission("deleteRootTask()");
final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity();
try { try {
@@ -367,7 +367,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
} }
@Override @Override
public IWindowContainer getImeTarget(int displayId) { public WindowContainerToken getImeTarget(int displayId) {
enforceStackPermission("getImeTarget()"); enforceStackPermission("getImeTarget()");
final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity();
try { try {
@@ -382,7 +382,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
if (task == null) { if (task == null) {
return null; return null;
} }
return task.getRootTask().mRemoteToken; return task.getRootTask().mRemoteToken.toWindowContainerToken();
} }
} finally { } finally {
Binder.restoreCallingIdentity(origId); Binder.restoreCallingIdentity(origId);
@@ -390,7 +390,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
} }
@Override @Override
public void setLaunchRoot(int displayId, @Nullable IWindowContainer token) { public void setLaunchRoot(int displayId, @Nullable WindowContainerToken token) {
enforceStackPermission("setLaunchRoot()"); enforceStackPermission("setLaunchRoot()");
final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity();
try { try {
@@ -422,7 +422,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
} }
@Override @Override
public List<RunningTaskInfo> getChildTasks(IWindowContainer parent, public List<RunningTaskInfo> getChildTasks(WindowContainerToken parent,
@Nullable int[] activityTypes) { @Nullable int[] activityTypes) {
enforceStackPermission("getChildTasks()"); enforceStackPermission("getChildTasks()");
final long ident = Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity();

View File

@@ -76,7 +76,8 @@ import android.view.SurfaceControl.Builder;
import android.view.SurfaceSession; import android.view.SurfaceSession;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.window.IWindowContainer; import android.window.IWindowContainerToken;
import android.window.WindowContainerToken;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ToBooleanFunction; import com.android.internal.util.ToBooleanFunction;
@@ -2449,8 +2450,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
return RemoteToken.fromBinder(binder).getContainer(); return RemoteToken.fromBinder(binder).getContainer();
} }
static class RemoteToken extends IWindowContainer.Stub { static class RemoteToken extends IWindowContainerToken.Stub {
final WeakReference<WindowContainer> mWeakRef; final WeakReference<WindowContainer> mWeakRef;
private WindowContainerToken mWindowContainerToken;
RemoteToken(WindowContainer container) { RemoteToken(WindowContainer container) {
mWeakRef = new WeakReference<>(container); mWeakRef = new WeakReference<>(container);
@@ -2476,6 +2479,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
return sc; return sc;
} }
WindowContainerToken toWindowContainerToken() {
if (mWindowContainerToken == null) {
mWindowContainerToken = new WindowContainerToken(this);
}
return mWindowContainerToken;
}
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(128); StringBuilder sb = new StringBuilder(128);
@@ -2489,11 +2499,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
} }
@Override @Override
public void transactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) { public void onTransactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
mergedTransaction.merge(mBLASTSyncTransaction); mergedTransaction.merge(mBLASTSyncTransaction);
mUsingBLASTSyncTransaction = false; mUsingBLASTSyncTransaction = false;
mWaitingListener.transactionReady(mWaitingSyncId, mergedTransaction); mWaitingListener.onTransactionReady(mWaitingSyncId, mergedTransaction);
mWaitingListener = null; mWaitingListener = null;
mWaitingSyncId = -1; mWaitingSyncId = -1;

View File

@@ -340,12 +340,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
} }
@Override @Override
public void transactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) { public void onTransactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
final IWindowContainerTransactionCallback callback = final IWindowContainerTransactionCallback callback =
mTransactionCallbacksByPendingSyncId.get(mSyncId); mTransactionCallbacksByPendingSyncId.get(mSyncId);
try { try {
callback.transactionReady(mSyncId, mergedTransaction); callback.onTransactionReady(mSyncId, mergedTransaction);
} catch (RemoteException e) { } catch (RemoteException e) {
} }

View File

@@ -5723,7 +5723,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (mLocalSyncId >= 0) { if (mLocalSyncId >= 0) {
mBLASTSyncEngine.setReady(mLocalSyncId); mBLASTSyncEngine.setReady(mLocalSyncId);
} else { } else {
mWaitingListener.transactionReady(mWaitingSyncId, mBLASTSyncTransaction); mWaitingListener.onTransactionReady(mWaitingSyncId, mBLASTSyncTransaction);
} }
mUsingBLASTSyncTransaction = false; mUsingBLASTSyncTransaction = false;

View File

@@ -83,7 +83,7 @@ import android.platform.test.annotations.Presubmit;
import android.service.voice.IVoiceInteractionSession; import android.service.voice.IVoiceInteractionSession;
import android.view.Gravity; import android.view.Gravity;
import android.window.ITaskOrganizer; import android.window.ITaskOrganizer;
import android.window.IWindowContainer; import android.window.WindowContainerToken;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
@@ -1014,10 +1014,10 @@ public class ActivityStarterTests extends ActivityTestsBase {
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
mService.mTaskOrganizerController.registerTaskOrganizer(this, mService.mTaskOrganizerController.registerTaskOrganizer(this,
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
IWindowContainer primary = mService.mTaskOrganizerController.createRootTask( WindowContainerToken primary = mService.mTaskOrganizerController.createRootTask(
displayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).token; displayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).token;
mPrimary = WindowContainer.fromBinder(primary.asBinder()).asTask(); mPrimary = WindowContainer.fromBinder(primary.asBinder()).asTask();
IWindowContainer secondary = mService.mTaskOrganizerController.createRootTask( WindowContainerToken secondary = mService.mTaskOrganizerController.createRootTask(
displayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token; displayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token;
mSecondary = WindowContainer.fromBinder(secondary.asBinder()).asTask(); mSecondary = WindowContainer.fromBinder(secondary.asBinder()).asTask();
} }
@@ -1037,7 +1037,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
== WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
mInSplit = true; mInSplit = true;
mService.mTaskOrganizerController.setLaunchRoot(mDisplayId, mService.mTaskOrganizerController.setLaunchRoot(mDisplayId,
mSecondary.mRemoteToken); mSecondary.mRemoteToken.toWindowContainerToken());
// move everything to secondary because test expects this but usually sysui // move everything to secondary because test expects this but usually sysui
// does it. // does it.
DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId); DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId);

View File

@@ -26,6 +26,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
@@ -282,7 +284,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
final Task task = stack.getTopMostTask(); final Task task = stack.getTopMostTask();
WindowContainerTransaction t = new WindowContainerTransaction(); WindowContainerTransaction t = new WindowContainerTransaction();
Rect newBounds = new Rect(10, 10, 100, 100); Rect newBounds = new Rect(10, 10, 100, 100);
t.setBounds(task.mRemoteToken, new Rect(10, 10, 100, 100)); t.setBounds(task.mRemoteToken.toWindowContainerToken(), new Rect(10, 10, 100, 100));
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
assertEquals(newBounds, task.getBounds()); assertEquals(newBounds, task.getBounds());
} }
@@ -295,7 +297,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
StackInfo info = StackInfo info =
mWm.mAtmService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD); mWm.mAtmService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
WindowContainerTransaction t = new WindowContainerTransaction(); WindowContainerTransaction t = new WindowContainerTransaction();
assertEquals(stack.mRemoteToken, info.stackToken); assertEquals(stack.mRemoteToken.toWindowContainerToken(), info.stackToken);
Rect newBounds = new Rect(10, 10, 100, 100); Rect newBounds = new Rect(10, 10, 100, 100);
t.setBounds(info.stackToken, new Rect(10, 10, 100, 100)); t.setBounds(info.stackToken, new Rect(10, 10, 100, 100));
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
@@ -308,7 +310,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
.setWindowingMode(WINDOWING_MODE_FREEFORM).build(); .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
final WindowContainerTransaction t = new WindowContainerTransaction(); final WindowContainerTransaction t = new WindowContainerTransaction();
t.setWindowingMode(stack.mRemoteToken, WINDOWING_MODE_FULLSCREEN); t.setWindowingMode(stack.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_FULLSCREEN);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
assertEquals(WINDOWING_MODE_FULLSCREEN, stack.getWindowingMode()); assertEquals(WINDOWING_MODE_FULLSCREEN, stack.getWindowingMode());
@@ -320,8 +322,9 @@ public class TaskOrganizerTests extends WindowTestsBase {
final ActivityStack stack = record.getStack(); final ActivityStack stack = record.getStack();
final WindowContainerTransaction t = new WindowContainerTransaction(); final WindowContainerTransaction t = new WindowContainerTransaction();
t.setWindowingMode(stack.mRemoteToken, WINDOWING_MODE_PINNED); t.setWindowingMode(stack.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_PINNED);
t.setActivityWindowingMode(stack.mRemoteToken, WINDOWING_MODE_FULLSCREEN); t.setActivityWindowingMode(
stack.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_FULLSCREEN);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
assertEquals(WINDOWING_MODE_FULLSCREEN, record.getWindowingMode()); assertEquals(WINDOWING_MODE_FULLSCREEN, record.getWindowingMode());
@@ -336,10 +339,10 @@ public class TaskOrganizerTests extends WindowTestsBase {
final Task task = stack.getTopMostTask(); final Task task = stack.getTopMostTask();
WindowContainerTransaction t = new WindowContainerTransaction(); WindowContainerTransaction t = new WindowContainerTransaction();
assertTrue(task.isFocusable()); assertTrue(task.isFocusable());
t.setFocusable(stack.mRemoteToken, false); t.setFocusable(stack.mRemoteToken.toWindowContainerToken(), false);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
assertFalse(task.isFocusable()); assertFalse(task.isFocusable());
t.setFocusable(stack.mRemoteToken, true); t.setFocusable(stack.mRemoteToken.toWindowContainerToken(), true);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
assertTrue(task.isFocusable()); assertTrue(task.isFocusable());
} }
@@ -351,10 +354,10 @@ public class TaskOrganizerTests extends WindowTestsBase {
.setWindowingMode(WINDOWING_MODE_FREEFORM).build(); .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
WindowContainerTransaction t = new WindowContainerTransaction(); WindowContainerTransaction t = new WindowContainerTransaction();
assertTrue(stack.shouldBeVisible(null)); assertTrue(stack.shouldBeVisible(null));
t.setHidden(stack.mRemoteToken, true); t.setHidden(stack.mRemoteToken.toWindowContainerToken(), true);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
assertFalse(stack.shouldBeVisible(null)); assertFalse(stack.shouldBeVisible(null));
t.setHidden(stack.mRemoteToken, false); t.setHidden(stack.mRemoteToken.toWindowContainerToken(), false);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
assertTrue(stack.shouldBeVisible(null)); assertTrue(stack.shouldBeVisible(null));
} }
@@ -366,19 +369,19 @@ public class TaskOrganizerTests extends WindowTestsBase {
.setWindowingMode(WINDOWING_MODE_FREEFORM).build(); .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
final Task task = stack.getTopMostTask(); final Task task = stack.getTopMostTask();
WindowContainerTransaction t = new WindowContainerTransaction(); WindowContainerTransaction t = new WindowContainerTransaction();
t.setBounds(task.mRemoteToken, new Rect(10, 10, 100, 100)); t.setBounds(task.mRemoteToken.toWindowContainerToken(), new Rect(10, 10, 100, 100));
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
final int origScreenWDp = task.getConfiguration().screenHeightDp; final int origScreenWDp = task.getConfiguration().screenHeightDp;
final int origScreenHDp = task.getConfiguration().screenHeightDp; final int origScreenHDp = task.getConfiguration().screenHeightDp;
t = new WindowContainerTransaction(); t = new WindowContainerTransaction();
// verify that setting config overrides on parent restricts children. // verify that setting config overrides on parent restricts children.
t.setScreenSizeDp(stack.mRemoteToken, origScreenWDp, origScreenHDp); t.setScreenSizeDp(stack.mRemoteToken.toWindowContainerToken(), origScreenWDp, origScreenHDp);
t.setBounds(task.mRemoteToken, new Rect(10, 10, 150, 200)); t.setBounds(task.mRemoteToken.toWindowContainerToken(), new Rect(10, 10, 150, 200));
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
assertEquals(origScreenHDp, task.getConfiguration().screenHeightDp); assertEquals(origScreenHDp, task.getConfiguration().screenHeightDp);
t = new WindowContainerTransaction(); t = new WindowContainerTransaction();
t.setScreenSizeDp(stack.mRemoteToken, Configuration.SCREEN_WIDTH_DP_UNDEFINED, t.setScreenSizeDp(stack.mRemoteToken.toWindowContainerToken(), SCREEN_WIDTH_DP_UNDEFINED,
Configuration.SCREEN_HEIGHT_DP_UNDEFINED); SCREEN_HEIGHT_DP_UNDEFINED);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
assertNotEquals(origScreenHDp, task.getConfiguration().screenHeightDp); assertNotEquals(origScreenHDp, task.getConfiguration().screenHeightDp);
} }
@@ -435,7 +438,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent); WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
assertEquals(mDisplayContent.getWindowingMode(), stack.getWindowingMode()); assertEquals(mDisplayContent.getWindowingMode(), stack.getWindowingMode());
WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction();
wct.reparent(stack.mRemoteToken, info1.token, true /* onTop */); wct.reparent(stack.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
assertEquals(info1.configuration.windowConfiguration.getWindowingMode(), assertEquals(info1.configuration.windowConfiguration.getWindowingMode(),
stack.getWindowingMode()); stack.getWindowingMode());
@@ -455,7 +458,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
assertEquals(newSize, stack.getBounds()); assertEquals(newSize, stack.getBounds());
wct = new WindowContainerTransaction(); wct = new WindowContainerTransaction();
wct.reparent(stack.mRemoteToken, null, true /* onTop */); wct.reparent(stack.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
assertEquals(mDisplayContent.getWindowingMode(), stack.getWindowingMode()); assertEquals(mDisplayContent.getWindowingMode(), stack.getWindowingMode());
infos = getTasksCreatedByOrganizer(mDisplayContent); infos = getTasksCreatedByOrganizer(mDisplayContent);
@@ -495,7 +498,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent); WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
Task task1 = WindowContainer.fromBinder(info1.token.asBinder()).asTask(); Task task1 = WindowContainer.fromBinder(info1.token.asBinder()).asTask();
WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction();
wct.reparent(stack.mRemoteToken, info1.token, true /* onTop */); wct.reparent(stack.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
assertTrue(called[0]); assertTrue(called[0]);
assertEquals(ACTIVITY_TYPE_STANDARD, lastReportedTiles.get(0).topActivityType); assertEquals(ACTIVITY_TYPE_STANDARD, lastReportedTiles.get(0).topActivityType);
@@ -505,7 +508,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
final ActivityStack stack2 = createTaskStackOnDisplay( final ActivityStack stack2 = createTaskStackOnDisplay(
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, mDisplayContent); WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, mDisplayContent);
wct = new WindowContainerTransaction(); wct = new WindowContainerTransaction();
wct.reparent(stack2.mRemoteToken, info1.token, true /* onTop */); wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
assertTrue(called[0]); assertTrue(called[0]);
assertEquals(ACTIVITY_TYPE_HOME, lastReportedTiles.get(0).topActivityType); assertEquals(ACTIVITY_TYPE_HOME, lastReportedTiles.get(0).topActivityType);
@@ -519,8 +522,8 @@ public class TaskOrganizerTests extends WindowTestsBase {
lastReportedTiles.clear(); lastReportedTiles.clear();
called[0] = false; called[0] = false;
wct = new WindowContainerTransaction(); wct = new WindowContainerTransaction();
wct.reparent(stack.mRemoteToken, null, true /* onTop */); wct.reparent(stack.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
wct.reparent(stack2.mRemoteToken, null, true /* onTop */); wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
assertTrue(called[0]); assertTrue(called[0]);
assertEquals(ACTIVITY_TYPE_UNDEFINED, lastReportedTiles.get(0).topActivityType); assertEquals(ACTIVITY_TYPE_UNDEFINED, lastReportedTiles.get(0).topActivityType);
@@ -569,8 +572,8 @@ public class TaskOrganizerTests extends WindowTestsBase {
lastReportedTiles.clear(); lastReportedTiles.clear();
WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction();
wct.reparent(stack.mRemoteToken, info1.token, true /* onTop */); wct.reparent(stack.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */);
wct.reparent(stack2.mRemoteToken, info2.token, true /* onTop */); wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), info2.token, true /* onTop */);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
assertFalse(lastReportedTiles.isEmpty()); assertFalse(lastReportedTiles.isEmpty());
assertEquals(ACTIVITY_TYPE_STANDARD, assertEquals(ACTIVITY_TYPE_STANDARD,
@@ -580,7 +583,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
lastReportedTiles.clear(); lastReportedTiles.clear();
wct = new WindowContainerTransaction(); wct = new WindowContainerTransaction();
wct.reparent(stack2.mRemoteToken, info1.token, false /* onTop */); wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), info1.token, false /* onTop */);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
assertFalse(lastReportedTiles.isEmpty()); assertFalse(lastReportedTiles.isEmpty());
// Standard should still be on top of tile 1, so no change there // Standard should still be on top of tile 1, so no change there
@@ -605,7 +608,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
lastReportedTiles.clear(); lastReportedTiles.clear();
wct = new WindowContainerTransaction(); wct = new WindowContainerTransaction();
wct.reorder(stack2.mRemoteToken, true /* onTop */); wct.reorder(stack2.mRemoteToken.toWindowContainerToken(), true /* onTop */);
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
// Home should now be on top. No change occurs in second tile, so not reported // Home should now be on top. No change occurs in second tile, so not reported
assertEquals(1, lastReportedTiles.size()); assertEquals(1, lastReportedTiles.size());
@@ -641,7 +644,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
bse.setReady(id); bse.setReady(id);
// Since this task has no windows the sync is trivial and completes immediately. // Since this task has no windows the sync is trivial and completes immediately.
verify(transactionListener) verify(transactionListener)
.transactionReady(anyInt(), any()); .onTransactionReady(anyInt(), any());
} }
@Test @Test
@@ -691,10 +694,10 @@ public class TaskOrganizerTests extends WindowTestsBase {
bse.setReady(id); bse.setReady(id);
// Since we have a window we have to wait for it to draw to finish sync. // Since we have a window we have to wait for it to draw to finish sync.
verify(transactionListener, never()) verify(transactionListener, never())
.transactionReady(anyInt(), any()); .onTransactionReady(anyInt(), any());
w.finishDrawing(null); w.finishDrawing(null);
verify(transactionListener) verify(transactionListener)
.transactionReady(anyInt(), any()); .onTransactionReady(anyInt(), any());
} }
@Test @Test
@@ -716,7 +719,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
// Since the window was invisible, the Task had no visible leaves and the sync should // Since the window was invisible, the Task had no visible leaves and the sync should
// complete as soon as we call setReady. // complete as soon as we call setReady.
verify(transactionListener) verify(transactionListener)
.transactionReady(anyInt(), any()); .onTransactionReady(anyInt(), any());
} }
@Test @Test
@@ -742,13 +745,13 @@ public class TaskOrganizerTests extends WindowTestsBase {
// Since we have a child window we still shouldn't be done. // Since we have a child window we still shouldn't be done.
verify(transactionListener, never()) verify(transactionListener, never())
.transactionReady(anyInt(), any()); .onTransactionReady(anyInt(), any());
reset(transactionListener); reset(transactionListener);
child.finishDrawing(null); child.finishDrawing(null);
// Ah finally! Done // Ah finally! Done
verify(transactionListener) verify(transactionListener)
.transactionReady(anyInt(), any()); .onTransactionReady(anyInt(), any());
} }
class StubOrganizer extends ITaskOrganizer.Stub { class StubOrganizer extends ITaskOrganizer.Stub {

View File

@@ -17,10 +17,9 @@
package com.android.test.taskembed; package com.android.test.taskembed;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.window.WindowOrganizer.TaskOrganizer;
import android.app.Activity;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.Activity;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -35,10 +34,12 @@ import android.view.SurfaceControl;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.window.ITaskOrganizer; import android.window.ITaskOrganizer;
import android.window.IWindowContainerTransactionCallback; import android.window.IWindowContainerTransactionCallback;
import android.window.TaskOrganizer;
import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction;
import android.widget.LinearLayout;
import android.window.WindowContainerTransactionCallback;
import android.window.WindowOrganizer; import android.window.WindowOrganizer;
public class TaskOrganizerMultiWindowTest extends Activity { public class TaskOrganizerMultiWindowTest extends Activity {
@@ -97,7 +98,7 @@ public class TaskOrganizerMultiWindowTest extends Activity {
class ResizingTaskView extends TaskView { class ResizingTaskView extends TaskView {
final Intent mIntent; final Intent mIntent;
boolean launched = false; boolean launched = false;
ResizingTaskView(Context c, ITaskOrganizer o, int windowingMode, Intent i) { ResizingTaskView(Context c, TaskOrganizer o, int windowingMode, Intent i) {
super(c, o, windowingMode); super(c, o, windowingMode);
mIntent = i; mIntent = i;
} }
@@ -116,7 +117,7 @@ public class TaskOrganizerMultiWindowTest extends Activity {
final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setBounds(mWc, new Rect(0, 0, width, height)); wct.setBounds(mWc, new Rect(0, 0, width, height));
try { try {
WindowOrganizer.applySyncTransaction(wct, mOrganizer.mTransactionCallback); mOrganizer.applySyncTransaction(wct, mOrganizer.mTransactionCallback);
} catch (Exception e) { } catch (Exception e) {
// Oh well // Oh well
} }
@@ -127,14 +128,13 @@ public class TaskOrganizerMultiWindowTest extends Activity {
TaskView mTaskView2; TaskView mTaskView2;
boolean gotFirstTask = false; boolean gotFirstTask = false;
class Organizer extends ITaskOrganizer.Stub { class Organizer extends TaskOrganizer {
private int receivedTransactions = 0; private int receivedTransactions = 0;
SurfaceControl.Transaction mergedTransaction = new SurfaceControl.Transaction(); SurfaceControl.Transaction mergedTransaction = new SurfaceControl.Transaction();
IWindowContainerTransactionCallback mTransactionCallback = WindowContainerTransactionCallback mTransactionCallback =
new IWindowContainerTransactionCallback() { new WindowContainerTransactionCallback() {
@Override @Override
public void transactionReady(int id, SurfaceControl.Transaction t) public void onTransactionReady(int id, SurfaceControl.Transaction t) {
throws RemoteException {
mergedTransaction.merge(t); mergedTransaction.merge(t);
receivedTransactions++; receivedTransactions++;
if (receivedTransactions == 2) { if (receivedTransactions == 2) {
@@ -142,11 +142,6 @@ public class TaskOrganizerMultiWindowTest extends Activity {
receivedTransactions = 0; receivedTransactions = 0;
} }
} }
@Override
public IBinder asBinder() {
return null;
}
}; };
@Override @Override
@@ -158,14 +153,6 @@ public class TaskOrganizerMultiWindowTest extends Activity {
mTaskView2.reparentTask(ti.token); mTaskView2.reparentTask(ti.token);
} }
} }
public void onTaskVanished(ActivityManager.RunningTaskInfo ti) {
}
@Override
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
}
@Override
public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) {
}
} }
Organizer mOrganizer = new Organizer(); Organizer mOrganizer = new Organizer();
@@ -174,10 +161,7 @@ public class TaskOrganizerMultiWindowTest extends Activity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
try { mOrganizer.registerOrganizer(WINDOWING_MODE_MULTI_WINDOW);
TaskOrganizer.registerOrganizer(mOrganizer, WINDOWING_MODE_MULTI_WINDOW);
} catch (Exception e) {
}
mTaskView1 = new ResizingTaskView(this, mOrganizer, WINDOWING_MODE_MULTI_WINDOW, mTaskView1 = new ResizingTaskView(this, mOrganizer, WINDOWING_MODE_MULTI_WINDOW,
makeSettingsIntent()); makeSettingsIntent());

View File

@@ -17,7 +17,6 @@
package com.android.test.taskembed; package com.android.test.taskembed;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.window.WindowOrganizer.TaskOrganizer;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.Service; import android.app.Service;
@@ -25,11 +24,10 @@ import android.content.Intent;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.IBinder; import android.os.IBinder;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.window.TaskOrganizer;
import android.window.WindowContainerTransaction;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.window.ITaskOrganizer;
import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer;
public class TaskOrganizerPipTest extends Service { public class TaskOrganizerPipTest extends Service {
static final int PIP_WIDTH = 640; static final int PIP_WIDTH = 640;
@@ -37,23 +35,13 @@ public class TaskOrganizerPipTest extends Service {
TaskView mTaskView; TaskView mTaskView;
class Organizer extends ITaskOrganizer.Stub { class Organizer extends TaskOrganizer {
public void onTaskAppeared(ActivityManager.RunningTaskInfo ti) { public void onTaskAppeared(ActivityManager.RunningTaskInfo ti) {
mTaskView.reparentTask(ti.token); mTaskView.reparentTask(ti.token);
final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction();
wct.scheduleFinishEnterPip(ti.token, new Rect(0, 0, PIP_WIDTH, PIP_HEIGHT)); wct.scheduleFinishEnterPip(ti.token, new Rect(0, 0, PIP_WIDTH, PIP_HEIGHT));
try { applyTransaction(wct);
WindowOrganizer.applyTransaction(wct);
} catch (Exception e) {
}
}
public void onTaskVanished(ActivityManager.RunningTaskInfo ti) {
}
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
}
@Override
public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) {
} }
} }
@@ -68,10 +56,7 @@ public class TaskOrganizerPipTest extends Service {
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
try { mOrganizer.registerOrganizer(WINDOWING_MODE_PINNED);
TaskOrganizer.registerOrganizer(mOrganizer, WINDOWING_MODE_PINNED);
} catch (Exception e) {
}
final WindowManager.LayoutParams wlp = new WindowManager.LayoutParams(); final WindowManager.LayoutParams wlp = new WindowManager.LayoutParams();
wlp.setTitle("TaskOrganizerPipTest"); wlp.setTitle("TaskOrganizerPipTest");

View File

@@ -18,7 +18,8 @@ package com.android.test.taskembed;
import android.app.ActivityTaskManager; import android.app.ActivityTaskManager;
import android.content.Context; import android.content.Context;
import android.window.IWindowContainer; import android.window.TaskOrganizer;
import android.window.WindowContainerToken;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import android.view.SurfaceView; import android.view.SurfaceView;
@@ -29,14 +30,14 @@ import android.window.ITaskOrganizer;
* after it's Surface is ready. * after it's Surface is ready.
*/ */
class TaskView extends SurfaceView implements SurfaceHolder.Callback { class TaskView extends SurfaceView implements SurfaceHolder.Callback {
final ITaskOrganizer mTaskOrganizer; final TaskOrganizer mTaskOrganizer;
final int mWindowingMode; final int mWindowingMode;
IWindowContainer mWc; WindowContainerToken mWc;
boolean mSurfaceCreated = false; boolean mSurfaceCreated = false;
boolean mNeedsReparent; boolean mNeedsReparent;
TaskView(Context c, ITaskOrganizer o, int windowingMode) { TaskView(Context c, TaskOrganizer o, int windowingMode) {
super(c); super(c);
getHolder().addCallback(this); getHolder().addCallback(this);
setZOrderOnTop(true); setZOrderOnTop(true);
@@ -62,7 +63,7 @@ class TaskView extends SurfaceView implements SurfaceHolder.Callback {
public void surfaceDestroyed(SurfaceHolder holder) { public void surfaceDestroyed(SurfaceHolder holder) {
} }
void reparentTask(IWindowContainer wc) { void reparentTask(WindowContainerToken wc) {
mWc = wc; mWc = wc;
if (mSurfaceCreated == false) { if (mSurfaceCreated == false) {
mNeedsReparent = true; mNeedsReparent = true;