Merge "Add TestApi interfaces for window organizers" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
1df5eb0130
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ import android.util.ArrayMap;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Singleton;
|
||||
import android.util.Size;
|
||||
import android.window.IWindowContainer;
|
||||
import android.window.WindowContainerToken;
|
||||
import android.view.Surface;
|
||||
|
||||
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
|
||||
@UnsupportedAppUsage
|
||||
public int position;
|
||||
public IWindowContainer stackToken;
|
||||
public WindowContainerToken stackToken;
|
||||
/**
|
||||
* The full configuration the stack is currently running in.
|
||||
* @hide
|
||||
@@ -2793,7 +2793,7 @@ public class ActivityManager {
|
||||
dest.writeInt(userId);
|
||||
dest.writeInt(visible ? 1 : 0);
|
||||
dest.writeInt(position);
|
||||
dest.writeStrongInterface(stackToken);
|
||||
stackToken.writeToParcel(dest, 0);
|
||||
if (topActivity != null) {
|
||||
dest.writeInt(1);
|
||||
topActivity.writeToParcel(dest, 0);
|
||||
@@ -2825,7 +2825,7 @@ public class ActivityManager {
|
||||
userId = source.readInt();
|
||||
visible = source.readInt() > 0;
|
||||
position = source.readInt();
|
||||
stackToken = IWindowContainer.Stub.asInterface(source.readStrongBinder());
|
||||
stackToken = WindowContainerToken.CREATOR.createFromParcel(source);
|
||||
if (source.readInt() > 0) {
|
||||
topActivity = ComponentName.readFromParcel(source);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.window.TaskEmbedder;
|
||||
import android.window.TaskOrganizerTaskEmbedder;
|
||||
import android.window.VirtualDisplayTaskEmbedder;
|
||||
|
||||
import dalvik.system.CloseGuard;
|
||||
|
||||
@@ -52,11 +55,11 @@ import dalvik.system.CloseGuard;
|
||||
* @hide
|
||||
*/
|
||||
@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 TaskEmbedder mTaskEmbedder;
|
||||
private android.window.TaskEmbedder mTaskEmbedder;
|
||||
|
||||
private final SurfaceView mSurfaceView;
|
||||
private final SurfaceCallback mSurfaceCallback;
|
||||
@@ -487,7 +490,7 @@ public class ActivityView extends ViewGroup implements TaskEmbedder.Host {
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
public void onTaskBackgroundColorChanged(TaskEmbedder ts, int bgColor) {
|
||||
public void onTaskBackgroundColorChanged(android.window.TaskEmbedder ts, int bgColor) {
|
||||
if (mSurfaceView != null) {
|
||||
mSurfaceView.setResizeBackgroundColor(bgColor);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import android.content.res.Configuration;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.window.IWindowContainer;
|
||||
import android.window.WindowContainerToken;
|
||||
|
||||
/**
|
||||
* Stores information about a particular Task.
|
||||
@@ -147,7 +147,7 @@ public class TaskInfo {
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public IWindowContainer token;
|
||||
public WindowContainerToken token;
|
||||
|
||||
/**
|
||||
* The PictureInPictureParams for the Task, if set.
|
||||
@@ -222,7 +222,7 @@ public class TaskInfo {
|
||||
supportsSplitScreenMultiWindow = source.readBoolean();
|
||||
resizeMode = source.readInt();
|
||||
configuration.readFromParcel(source);
|
||||
token = IWindowContainer.Stub.asInterface(source.readStrongBinder());
|
||||
token = WindowContainerToken.CREATOR.createFromParcel(source);
|
||||
topActivityType = source.readInt();
|
||||
pictureInPictureParams = source.readInt() != 0
|
||||
? PictureInPictureParams.CREATOR.createFromParcel(source)
|
||||
@@ -265,7 +265,7 @@ public class TaskInfo {
|
||||
dest.writeBoolean(supportsSplitScreenMultiWindow);
|
||||
dest.writeInt(resizeMode);
|
||||
configuration.writeToParcel(dest, flags);
|
||||
dest.writeStrongInterface(token);
|
||||
token.writeToParcel(dest, flags);
|
||||
dest.writeInt(topActivityType);
|
||||
if (pictureInPictureParams == null) {
|
||||
dest.writeInt(0);
|
||||
|
||||
91
core/java/android/window/DisplayAreaOrganizer.java
Normal file
91
core/java/android/window/DisplayAreaOrganizer.java
Normal 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
package android.window;
|
||||
|
||||
import android.window.IWindowContainer;
|
||||
import android.window.WindowContainerToken;
|
||||
|
||||
/**
|
||||
* Interface for WindowManager to delegate control of display areas.
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface IDisplayAreaOrganizer {
|
||||
void onDisplayAreaAppeared(in IWindowContainer displayArea);
|
||||
void onDisplayAreaVanished(in IWindowContainer displayArea);
|
||||
void onDisplayAreaAppeared(in WindowContainerToken displayArea);
|
||||
void onDisplayAreaVanished(in WindowContainerToken displayArea);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package android.window;
|
||||
|
||||
import android.view.SurfaceControl;
|
||||
import android.app.ActivityManager;
|
||||
import android.window.IWindowContainer;
|
||||
import android.window.WindowContainerToken;
|
||||
|
||||
/**
|
||||
* Interface for ActivityTaskManager/WindowManager to delegate control of tasks.
|
||||
|
||||
@@ -18,7 +18,7 @@ package android.window;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.window.ITaskOrganizer;
|
||||
import android.window.IWindowContainer;
|
||||
import android.window.WindowContainerToken;
|
||||
import android.window.WindowContainerTransaction;
|
||||
|
||||
/** @hide */
|
||||
@@ -40,23 +40,23 @@ interface ITaskOrganizerController {
|
||||
ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode);
|
||||
|
||||
/** 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) */
|
||||
List<ActivityManager.RunningTaskInfo> getChildTasks(in IWindowContainer parent,
|
||||
List<ActivityManager.RunningTaskInfo> getChildTasks(in WindowContainerToken parent,
|
||||
in int[] activityTypes);
|
||||
|
||||
/** Gets all root tasks on a display (ordered from top-to-bottom) */
|
||||
List<ActivityManager.RunningTaskInfo> getRootTasks(int displayId, in int[] activityTypes);
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.view.SurfaceControl;
|
||||
* token.
|
||||
* @hide
|
||||
*/
|
||||
interface IWindowContainer {
|
||||
interface IWindowContainerToken {
|
||||
|
||||
/**
|
||||
* Gets a persistent leash for this container or {@code null}.
|
||||
@@ -24,5 +24,5 @@ import android.view.SurfaceControl;
|
||||
*/
|
||||
oneway interface IWindowContainerTransactionCallback {
|
||||
/** Called upon completion of WindowOrganizer#applyTransaction */
|
||||
void transactionReady(int id, in SurfaceControl.Transaction t);
|
||||
void onTransactionReady(int id, in SurfaceControl.Transaction t);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,13 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.app;
|
||||
package android.window;
|
||||
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
|
||||
import android.annotation.CallSuper;
|
||||
import android.annotation.NonNull;
|
||||
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.Context;
|
||||
import android.content.Intent;
|
||||
188
core/java/android/window/TaskOrganizer.java
Normal file
188
core/java/android/window/TaskOrganizer.java
Normal 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,22 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.app;
|
||||
package android.window;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
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.graphics.Rect;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
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
|
||||
@@ -41,9 +39,9 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
|
||||
private static final String TAG = "TaskOrgTaskEmbedder";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private ITaskOrganizer.Stub mTaskOrganizer;
|
||||
private TaskOrganizer mTaskOrganizer;
|
||||
private ActivityManager.RunningTaskInfo mTaskInfo;
|
||||
private IWindowContainer mTaskToken;
|
||||
private WindowContainerToken mTaskToken;
|
||||
private SurfaceControl mTaskLeash;
|
||||
private boolean mPendingNotifyBoundsChanged;
|
||||
|
||||
@@ -79,16 +77,11 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
|
||||
}
|
||||
// Register the task organizer
|
||||
mTaskOrganizer = new TaskOrganizerImpl();
|
||||
try {
|
||||
// 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
|
||||
// infrastructure is ready.
|
||||
TaskOrganizer.registerOrganizer(mTaskOrganizer, WINDOWING_MODE_MULTI_WINDOW);
|
||||
TaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskOrganizer, true);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to initialize TaskEmbedder", e);
|
||||
return false;
|
||||
}
|
||||
// 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
|
||||
// infrastructure is ready.
|
||||
mTaskOrganizer.registerOrganizer(WINDOWING_MODE_MULTI_WINDOW);
|
||||
mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -100,11 +93,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
|
||||
if (!isInitialized()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
TaskOrganizer.unregisterOrganizer(mTaskOrganizer);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to remove task");
|
||||
}
|
||||
mTaskOrganizer.unregisterOrganizer();
|
||||
resetTaskInfo();
|
||||
return true;
|
||||
}
|
||||
@@ -125,11 +114,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
|
||||
}
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.setHidden(mTaskToken, false /* hidden */);
|
||||
try {
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to unset hidden in transaction");
|
||||
}
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
// TODO(b/151449487): Only call callback once we enable synchronization
|
||||
if (mListener != null) {
|
||||
mListener.onTaskVisibilityChanged(getTaskId(), true);
|
||||
@@ -152,11 +137,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
|
||||
}
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.setHidden(mTaskToken, true /* hidden */);
|
||||
try {
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to set hidden in transaction");
|
||||
}
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
// TODO(b/151449487): Only call callback once we enable synchronization
|
||||
if (mListener != null) {
|
||||
mListener.onTaskVisibilityChanged(getTaskId(), false);
|
||||
@@ -186,12 +167,8 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
|
||||
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.setBounds(mTaskToken, screenBounds);
|
||||
try {
|
||||
// TODO(b/151449487): Enable synchronization
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to set bounds in transaction");
|
||||
}
|
||||
// TODO(b/151449487): Enable synchronization
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,8 +230,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
|
||||
private class TaskStackListenerImpl extends TaskStackListener {
|
||||
|
||||
@Override
|
||||
public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo)
|
||||
throws RemoteException {
|
||||
public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo) {
|
||||
if (!isInitialized()) {
|
||||
return;
|
||||
}
|
||||
@@ -266,10 +242,9 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
|
||||
}
|
||||
}
|
||||
|
||||
private class TaskOrganizerImpl extends ITaskOrganizer.Stub {
|
||||
private class TaskOrganizerImpl extends TaskOrganizer {
|
||||
@Override
|
||||
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo)
|
||||
throws RemoteException {
|
||||
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
|
||||
if (DEBUG) {
|
||||
log("taskAppeared: " + taskInfo.taskId);
|
||||
}
|
||||
@@ -293,8 +268,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo)
|
||||
throws RemoteException {
|
||||
public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
|
||||
if (DEBUG) {
|
||||
log("taskVanished: " + taskInfo.taskId);
|
||||
}
|
||||
@@ -309,14 +283,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo)
|
||||
throws RemoteException {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo)
|
||||
throws RemoteException {
|
||||
public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) {
|
||||
if (mListener != null) {
|
||||
mListener.onBackPressedOnTaskRoot(taskInfo.taskId);
|
||||
}
|
||||
@@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.app;
|
||||
package android.window;
|
||||
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||
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 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.Context;
|
||||
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,
|
||||
* only applicable if virtual displays are used
|
||||
*/
|
||||
VirtualDisplayTaskEmbedder(Context context, VirtualDisplayTaskEmbedder.Host host,
|
||||
public VirtualDisplayTaskEmbedder(Context context, VirtualDisplayTaskEmbedder.Host host,
|
||||
boolean singleTaskInstance) {
|
||||
super(context, host);
|
||||
mSingleTaskInstance = singleTaskInstance;
|
||||
19
core/java/android/window/WindowContainerToken.aidl
Normal file
19
core/java/android/window/WindowContainerToken.aidl
Normal 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;
|
||||
87
core/java/android/window/WindowContainerToken.java
Normal file
87
core/java/android/window/WindowContainerToken.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package android.window;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
@@ -26,7 +27,6 @@ import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.ArrayMap;
|
||||
import android.window.IWindowContainer;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -39,7 +39,8 @@ import java.util.Map;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class WindowContainerTransaction implements Parcelable {
|
||||
@TestApi
|
||||
public final class WindowContainerTransaction implements Parcelable {
|
||||
private final ArrayMap<IBinder, Change> mChanges = new ArrayMap<>();
|
||||
|
||||
// Flat list because re-order operations are order-dependent
|
||||
@@ -47,7 +48,7 @@ public class WindowContainerTransaction implements Parcelable {
|
||||
|
||||
public WindowContainerTransaction() {}
|
||||
|
||||
protected WindowContainerTransaction(Parcel in) {
|
||||
private WindowContainerTransaction(Parcel in) {
|
||||
in.readMap(mChanges, null /* loader */);
|
||||
in.readList(mHierarchyOps, null /* loader */);
|
||||
}
|
||||
@@ -64,7 +65,9 @@ public class WindowContainerTransaction implements Parcelable {
|
||||
/**
|
||||
* 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());
|
||||
chg.mConfiguration.windowConfiguration.setBounds(bounds);
|
||||
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
|
||||
* 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());
|
||||
chg.mConfiguration.windowConfiguration.setAppBounds(appBounds);
|
||||
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
|
||||
* 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());
|
||||
chg.mConfiguration.screenWidthDp = w;
|
||||
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.
|
||||
*/
|
||||
public WindowContainerTransaction scheduleFinishEnterPip(IWindowContainer container,
|
||||
Rect bounds) {
|
||||
@NonNull
|
||||
public WindowContainerTransaction scheduleFinishEnterPip(
|
||||
@NonNull WindowContainerToken container,@NonNull Rect bounds) {
|
||||
Change chg = getOrCreateChange(container.asBinder());
|
||||
chg.mPinnedBounds = new Rect(bounds);
|
||||
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
|
||||
* dismissPip() to achieve synchronization.
|
||||
*/
|
||||
public WindowContainerTransaction setBoundsChangeTransaction(IWindowContainer container,
|
||||
SurfaceControl.Transaction t) {
|
||||
@NonNull
|
||||
public WindowContainerTransaction setBoundsChangeTransaction(
|
||||
@NonNull WindowContainerToken container,@NonNull SurfaceControl.Transaction t) {
|
||||
Change chg = getOrCreateChange(container.asBinder());
|
||||
chg.mBoundsChangeTransaction = t;
|
||||
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
|
||||
*/
|
||||
public WindowContainerTransaction setActivityWindowingMode(IWindowContainer container,
|
||||
int windowingMode) {
|
||||
@NonNull
|
||||
public WindowContainerTransaction setActivityWindowingMode(
|
||||
@NonNull WindowContainerToken container, int windowingMode) {
|
||||
Change chg = getOrCreateChange(container.asBinder());
|
||||
chg.mActivityWindowingMode = windowingMode;
|
||||
return this;
|
||||
@@ -149,8 +159,9 @@ public class WindowContainerTransaction implements Parcelable {
|
||||
/**
|
||||
* Sets the windowing mode of the given container.
|
||||
*/
|
||||
public WindowContainerTransaction setWindowingMode(IWindowContainer container,
|
||||
int windowingMode) {
|
||||
@NonNull
|
||||
public WindowContainerTransaction setWindowingMode(
|
||||
@NonNull WindowContainerToken container, int windowingMode) {
|
||||
Change chg = getOrCreateChange(container.asBinder());
|
||||
chg.mWindowingMode = windowingMode;
|
||||
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
|
||||
* 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());
|
||||
chg.mFocusable = 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
|
||||
* to be hidden.
|
||||
*/
|
||||
public WindowContainerTransaction setHidden(IWindowContainer container, boolean hidden) {
|
||||
@NonNull
|
||||
public WindowContainerTransaction setHidden(
|
||||
@NonNull WindowContainerToken container, boolean hidden) {
|
||||
Change chg = getOrCreateChange(container.asBinder());
|
||||
chg.mHidden = hidden;
|
||||
chg.mChangeMask |= Change.CHANGE_HIDDEN;
|
||||
@@ -183,8 +198,9 @@ public class WindowContainerTransaction implements Parcelable {
|
||||
/**
|
||||
* Set the smallestScreenWidth of a container.
|
||||
*/
|
||||
public WindowContainerTransaction setSmallestScreenWidthDp(IWindowContainer container,
|
||||
int widthDp) {
|
||||
@NonNull
|
||||
public WindowContainerTransaction setSmallestScreenWidthDp(
|
||||
@NonNull WindowContainerToken container, int widthDp) {
|
||||
Change cfg = getOrCreateChange(container.asBinder());
|
||||
cfg.mConfiguration.smallestScreenWidthDp = widthDp;
|
||||
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
|
||||
* the bottom.
|
||||
*/
|
||||
public WindowContainerTransaction reparent(@NonNull IWindowContainer child,
|
||||
@Nullable IWindowContainer parent, boolean onTop) {
|
||||
@NonNull
|
||||
public WindowContainerTransaction reparent(@NonNull WindowContainerToken child,
|
||||
@Nullable WindowContainerToken parent, boolean onTop) {
|
||||
mHierarchyOps.add(new HierarchyOp(child.asBinder(),
|
||||
parent == null ? null : parent.asBinder(), onTop));
|
||||
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
|
||||
* 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));
|
||||
return this;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public Map<IBinder, Change> getChanges() {
|
||||
return mChanges;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public List<HierarchyOp> getHierarchyOps() {
|
||||
return mHierarchyOps;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return "WindowContainerTransaction { changes = " + mChanges + " hops = " + mHierarchyOps
|
||||
+ " }";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
/** @hide */
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeMap(mChanges);
|
||||
dest.writeList(mHierarchyOps);
|
||||
}
|
||||
|
||||
@Override
|
||||
/** @hide */
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Creator<WindowContainerTransaction> CREATOR =
|
||||
new Creator<WindowContainerTransaction>() {
|
||||
@Override
|
||||
@@ -256,7 +280,6 @@ public class WindowContainerTransaction implements Parcelable {
|
||||
|
||||
/**
|
||||
* Holds changes on a single WindowContainer including Configuration changes.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
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
|
||||
* Changes because they must be executed in the same order that they are added.
|
||||
* @hide
|
||||
*/
|
||||
public static class HierarchyOp implements Parcelable {
|
||||
private final IBinder mContainer;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -16,29 +16,32 @@
|
||||
|
||||
package android.window;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.app.ActivityManager;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.os.RemoteException;
|
||||
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
|
||||
*/
|
||||
@TestApi
|
||||
public class WindowOrganizer {
|
||||
|
||||
/**
|
||||
* Apply multiple WindowContainer operations at once.
|
||||
* @param t The transaction to apply.
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
|
||||
public static void applyTransaction(WindowContainerTransaction t) throws RemoteException {
|
||||
getWindowOrganizerController().applyTransaction(t);
|
||||
public static void applyTransaction(@NonNull WindowContainerTransaction 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.
|
||||
* @return An ID for the sync operation which will later be passed to transactionReady callback.
|
||||
* This lets the caller differentiate overlapping sync operations.
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
|
||||
public static int applySyncTransaction(WindowContainerTransaction t,
|
||||
IWindowContainerTransactionCallback callback) throws RemoteException {
|
||||
return getWindowOrganizerController().applySyncTransaction(t, callback);
|
||||
public int applySyncTransaction(@NonNull WindowContainerTransaction t,
|
||||
@NonNull WindowContainerTransactionCallback callback) {
|
||||
try {
|
||||
return getWindowOrganizerController().applySyncTransaction(t, callback.mInterface);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
|
||||
private static IWindowOrganizerController getWindowOrganizerController() {
|
||||
static IWindowOrganizerController getWindowOrganizerController() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.TaskEmbedder;
|
||||
import android.app.TaskOrganizerTaskEmbedder;
|
||||
import android.window.TaskEmbedder;
|
||||
import android.window.TaskOrganizerTaskEmbedder;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
|
||||
@@ -41,8 +41,8 @@ import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.util.Size;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.ITaskOrganizer;
|
||||
import android.window.IWindowContainer;
|
||||
import android.window.TaskOrganizer;
|
||||
import android.window.WindowContainerToken;
|
||||
import android.window.WindowContainerTransaction;
|
||||
import android.window.WindowOrganizer;
|
||||
|
||||
@@ -60,7 +60,7 @@ import java.util.function.Consumer;
|
||||
/**
|
||||
* 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.
|
||||
* 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.
|
||||
@@ -68,7 +68,7 @@ import java.util.function.Consumer;
|
||||
* This class is also responsible for general resize/offset PiP operations within SysUI component,
|
||||
* 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 int MSG_RESIZE_IMMEDIATE = 1;
|
||||
@@ -182,7 +182,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
|
||||
};
|
||||
|
||||
private ActivityManager.RunningTaskInfo mTaskInfo;
|
||||
private IWindowContainer mToken;
|
||||
private WindowContainerToken mToken;
|
||||
private SurfaceControl mLeash;
|
||||
private boolean mInPip;
|
||||
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
|
||||
*/
|
||||
public void dismissPip(int animationDurationMs) {
|
||||
try {
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN);
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to apply container transaction", e);
|
||||
}
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN);
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
final Rect destinationBounds = mBoundsToRestore.remove(mToken.asBinder());
|
||||
scheduleAnimateResizePip(mLastReportedBounds, destinationBounds,
|
||||
TRANSITION_DIRECTION_TO_FULLSCREEN, animationDurationMs,
|
||||
@@ -258,11 +254,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
|
||||
mTaskInfo = info;
|
||||
mToken = mTaskInfo.token;
|
||||
mInPip = true;
|
||||
try {
|
||||
mLeash = mToken.getLeash();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("Unable to get leash", e);
|
||||
}
|
||||
mLeash = mToken.getLeash();
|
||||
|
||||
final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
|
||||
mBoundsToRestore.put(mToken.asBinder(), currentBounds);
|
||||
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
|
||||
@@ -290,8 +283,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
|
||||
*/
|
||||
@Override
|
||||
public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
|
||||
IWindowContainer token = info.token;
|
||||
Objects.requireNonNull(token, "Requires valid IWindowContainer");
|
||||
WindowContainerToken token = info.token;
|
||||
Objects.requireNonNull(token, "Requires valid WindowContainerToken");
|
||||
if (token.asBinder() != mToken.asBinder()) {
|
||||
Log.wtf(TAG, "Unrecognized token: " + token);
|
||||
return;
|
||||
@@ -502,30 +495,26 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
|
||||
+ "directly");
|
||||
}
|
||||
mLastReportedBounds.set(destinationBounds);
|
||||
try {
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
final Rect taskBounds;
|
||||
if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) {
|
||||
// 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
|
||||
// also to the final windowing mode, which should be reset to undefined rather than
|
||||
// fullscreen.
|
||||
taskBounds = null;
|
||||
wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED)
|
||||
.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
|
||||
} else {
|
||||
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);
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
final Rect taskBounds;
|
||||
if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) {
|
||||
// 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
|
||||
// also to the final windowing mode, which should be reset to undefined rather than
|
||||
// fullscreen.
|
||||
taskBounds = null;
|
||||
wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED)
|
||||
.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
|
||||
} else {
|
||||
taskBounds = destinationBounds;
|
||||
}
|
||||
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,
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.systemui.pip.phone;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
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;
|
||||
|
||||
@@ -234,7 +233,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
|
||||
mPipBoundsHandler.onDisplayInfoChanged(displayInfo);
|
||||
|
||||
try {
|
||||
TaskOrganizer.registerOrganizer(mPipTaskOrganizer, WINDOWING_MODE_PINNED);
|
||||
mPipTaskOrganizer.registerOrganizer(WINDOWING_MODE_PINNED);
|
||||
ActivityManager.StackInfo stackInfo = activityTaskManager.getStackInfo(
|
||||
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
|
||||
if (stackInfo != null) {
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.android.systemui.pip.tv;
|
||||
import static android.app.ActivityTaskManager.INVALID_STACK_ID;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.window.WindowOrganizer.TaskOrganizer;
|
||||
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.app.ActivityManager.StackInfo;
|
||||
@@ -294,7 +293,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
|
||||
|
||||
try {
|
||||
WindowManagerWrapper.getInstance().addPinnedStackListener(mPinnedStackListener);
|
||||
TaskOrganizer.registerOrganizer(mPipTaskOrganizer, WINDOWING_MODE_PINNED);
|
||||
mPipTaskOrganizer.registerOrganizer(WINDOWING_MODE_PINNED);
|
||||
} catch (RemoteException | UnsupportedOperationException e) {
|
||||
Log.e(TAG, "Failed to register pinned stack listener", e);
|
||||
}
|
||||
|
||||
@@ -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_WIDTH_DP_UNDEFINED;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.window.WindowOrganizer.TaskOrganizer;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
@@ -33,11 +32,12 @@ import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.util.Slog;
|
||||
import android.window.TaskOrganizer;
|
||||
import android.window.WindowContainerToken;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceSession;
|
||||
import android.view.View;
|
||||
import android.window.IWindowContainer;
|
||||
import android.window.WindowContainerTransaction;
|
||||
import android.window.WindowOrganizer;
|
||||
|
||||
@@ -181,14 +181,9 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
|
||||
private boolean mPausedTargetAdjusted = false;
|
||||
|
||||
private boolean getSecondaryHasFocus(int displayId) {
|
||||
try {
|
||||
IWindowContainer imeSplit = TaskOrganizer.getImeTarget(displayId);
|
||||
return imeSplit != null
|
||||
&& (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder());
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed to get IME target", e);
|
||||
}
|
||||
return false;
|
||||
WindowContainerToken imeSplit = TaskOrganizer.getImeTarget(displayId);
|
||||
return imeSplit != null
|
||||
&& (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder());
|
||||
}
|
||||
|
||||
private void updateDimTargets() {
|
||||
@@ -270,10 +265,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
|
||||
wct.setScreenSizeDp(mSplits.mSecondary.token,
|
||||
SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
|
||||
}
|
||||
try {
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
|
||||
// Update all the adjusted-for-ime states
|
||||
if (!mPaused) {
|
||||
@@ -506,12 +499,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
|
||||
int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
|
||||
final WindowContainerTransaction tct = new WindowContainerTransaction();
|
||||
mSplitLayout.resizeSplits(midPos, tct);
|
||||
try {
|
||||
WindowOrganizer.applyTransaction(tct);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
} else if (mRotateSplitLayout != null
|
||||
&& mSplitLayout.mDisplayLayout.rotation()
|
||||
WindowOrganizer.applyTransaction(tct);
|
||||
} else if (mSplitLayout.mDisplayLayout.rotation()
|
||||
== mRotateSplitLayout.mDisplayLayout.rotation()) {
|
||||
mSplitLayout.mPrimary = new Rect(mRotateSplitLayout.mPrimary);
|
||||
mSplitLayout.mSecondary = new Rect(mRotateSplitLayout.mSecondary);
|
||||
@@ -653,7 +642,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
|
||||
}
|
||||
}
|
||||
updateTouchable();
|
||||
WindowManagerProxy.applyContainerTransaction(wct);
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
}
|
||||
|
||||
void setAdjustedForIme(boolean adjustedForIme) {
|
||||
|
||||
@@ -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_SECONDARY;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.window.WindowOrganizer.TaskOrganizer;
|
||||
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.app.WindowConfiguration;
|
||||
@@ -32,11 +31,11 @@ import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceSession;
|
||||
import android.window.ITaskOrganizer;
|
||||
import android.window.TaskOrganizer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
|
||||
class SplitScreenTaskOrganizer extends TaskOrganizer {
|
||||
private static final String TAG = "SplitScreenTaskOrganizer";
|
||||
private static final boolean DEBUG = Divider.DEBUG;
|
||||
|
||||
@@ -56,8 +55,8 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
|
||||
}
|
||||
|
||||
void init(SurfaceSession session) throws RemoteException {
|
||||
TaskOrganizer.registerOrganizer(this, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
TaskOrganizer.registerOrganizer(this, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
|
||||
registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
|
||||
try {
|
||||
mPrimary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY,
|
||||
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
@@ -65,9 +64,9 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
|
||||
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
|
||||
mPrimarySurface = mPrimary.token.getLeash();
|
||||
mSecondarySurface = mSecondary.token.getLeash();
|
||||
} catch (RemoteException e) {
|
||||
} catch (Exception e) {
|
||||
// teardown to prevent callbacks
|
||||
TaskOrganizer.unregisterOrganizer(this);
|
||||
unregisterOrganizer();
|
||||
throw e;
|
||||
}
|
||||
mSplitScreenSupported = true;
|
||||
@@ -98,14 +97,6 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
|
||||
mDivider.mTransactionPool.release(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskAppeared(RunningTaskInfo taskInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskVanished(RunningTaskInfo taskInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
|
||||
if (taskInfo.displayId != DEFAULT_DISPLAY) {
|
||||
|
||||
@@ -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.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.window.WindowOrganizer.TaskOrganizer;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityManager;
|
||||
@@ -30,7 +29,8 @@ import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.WindowManagerGlobal;
|
||||
import android.window.IWindowContainer;
|
||||
import android.window.TaskOrganizer;
|
||||
import android.window.WindowContainerToken;
|
||||
import android.window.WindowContainerTransaction;
|
||||
import android.window.WindowOrganizer;
|
||||
|
||||
@@ -112,27 +112,21 @@ public class WindowManagerProxy {
|
||||
static void applyResizeSplits(int position, SplitDisplayLayout splitLayout) {
|
||||
WindowContainerTransaction t = new WindowContainerTransaction();
|
||||
splitLayout.resizeSplits(position, t);
|
||||
try {
|
||||
WindowOrganizer.applyTransaction(t);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
WindowOrganizer.applyTransaction(t);
|
||||
}
|
||||
|
||||
private static boolean getHomeAndRecentsTasks(List<IWindowContainer> out,
|
||||
IWindowContainer parent) {
|
||||
private static boolean getHomeAndRecentsTasks(List<WindowContainerToken> out,
|
||||
WindowContainerToken parent) {
|
||||
boolean resizable = false;
|
||||
try {
|
||||
List<ActivityManager.RunningTaskInfo> rootTasks = parent == null
|
||||
? TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS)
|
||||
: TaskOrganizer.getChildTasks(parent, HOME_AND_RECENTS);
|
||||
for (int i = 0, n = rootTasks.size(); i < n; ++i) {
|
||||
final ActivityManager.RunningTaskInfo ti = rootTasks.get(i);
|
||||
out.add(ti.token);
|
||||
if (ti.topActivityType == ACTIVITY_TYPE_HOME) {
|
||||
resizable = ti.isResizable();
|
||||
}
|
||||
List<ActivityManager.RunningTaskInfo> rootTasks = parent == null
|
||||
? TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS)
|
||||
: TaskOrganizer.getChildTasks(parent, HOME_AND_RECENTS);
|
||||
for (int i = 0, n = rootTasks.size(); i < n; ++i) {
|
||||
final ActivityManager.RunningTaskInfo ti = rootTasks.get(i);
|
||||
out.add(ti.token);
|
||||
if (ti.topActivityType == ACTIVITY_TYPE_HOME) {
|
||||
resizable = ti.isResizable();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
return resizable;
|
||||
}
|
||||
@@ -142,11 +136,11 @@ public class WindowManagerProxy {
|
||||
* 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.
|
||||
*/
|
||||
static boolean applyHomeTasksMinimized(SplitDisplayLayout layout, IWindowContainer parent,
|
||||
static boolean applyHomeTasksMinimized(SplitDisplayLayout layout, WindowContainerToken parent,
|
||||
@NonNull WindowContainerTransaction wct) {
|
||||
// Resize the home/recents stacks to the larger minimized-state size
|
||||
final Rect homeBounds;
|
||||
final ArrayList<IWindowContainer> homeStacks = new ArrayList<>();
|
||||
final ArrayList<WindowContainerToken> homeStacks = new ArrayList<>();
|
||||
boolean isHomeResizable = getHomeAndRecentsTasks(homeStacks, parent);
|
||||
if (isHomeResizable) {
|
||||
homeBounds = layout.calcMinimizedHomeStackBounds();
|
||||
@@ -170,36 +164,31 @@ public class WindowManagerProxy {
|
||||
* @return whether the home stack is resizable
|
||||
*/
|
||||
static boolean applyEnterSplit(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout) {
|
||||
try {
|
||||
// Set launchtile first so that any stack created after
|
||||
// getAllStackInfos and before reparent (even if unlikely) are placed
|
||||
// correctly.
|
||||
TaskOrganizer.setLaunchRoot(DEFAULT_DISPLAY, tiles.mSecondary.token);
|
||||
List<ActivityManager.RunningTaskInfo> rootTasks =
|
||||
TaskOrganizer.getRootTasks(DEFAULT_DISPLAY, null /* activityTypes */);
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
if (rootTasks.isEmpty()) {
|
||||
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);
|
||||
// Set launchtile first so that any stack created after
|
||||
// getAllStackInfos and before reparent (even if unlikely) are placed
|
||||
// correctly.
|
||||
TaskOrganizer.setLaunchRoot(DEFAULT_DISPLAY, tiles.mSecondary.token);
|
||||
List<ActivityManager.RunningTaskInfo> rootTasks =
|
||||
TaskOrganizer.getRootTasks(DEFAULT_DISPLAY, null /* activityTypes */);
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
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;
|
||||
}
|
||||
|
||||
private static boolean isHomeOrRecentTask(ActivityManager.RunningTaskInfo ti) {
|
||||
@@ -214,82 +203,70 @@ public class WindowManagerProxy {
|
||||
* fullscreen. {@code false} resolves the other way.
|
||||
*/
|
||||
static void applyDismissSplit(SplitScreenTaskOrganizer tiles, boolean dismissOrMaximize) {
|
||||
try {
|
||||
// Set launch root first so that any task created after getChildContainers and
|
||||
// before reparent (pretty unlikely) are put into fullscreen.
|
||||
TaskOrganizer.setLaunchRoot(Display.DEFAULT_DISPLAY, null);
|
||||
tiles.mHomeAndRecentsSurfaces.clear();
|
||||
// TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished
|
||||
// plus specific APIs to clean this up.
|
||||
List<ActivityManager.RunningTaskInfo> primaryChildren =
|
||||
TaskOrganizer.getChildTasks(tiles.mPrimary.token, null /* activityTypes */);
|
||||
List<ActivityManager.RunningTaskInfo> secondaryChildren =
|
||||
TaskOrganizer.getChildTasks(tiles.mSecondary.token, null /* activityTypes */);
|
||||
// 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
|
||||
// home task bounds.
|
||||
List<ActivityManager.RunningTaskInfo> freeHomeAndRecents =
|
||||
TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS);
|
||||
if (primaryChildren.isEmpty() && secondaryChildren.isEmpty()
|
||||
&& freeHomeAndRecents.isEmpty()) {
|
||||
return;
|
||||
// Set launch root first so that any task created after getChildContainers and
|
||||
// before reparent (pretty unlikely) are put into fullscreen.
|
||||
TaskOrganizer.setLaunchRoot(Display.DEFAULT_DISPLAY, null);
|
||||
tiles.mHomeAndRecentsSurfaces.clear();
|
||||
// TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished
|
||||
// plus specific APIs to clean this up.
|
||||
List<ActivityManager.RunningTaskInfo> primaryChildren =
|
||||
TaskOrganizer.getChildTasks(tiles.mPrimary.token, null /* activityTypes */);
|
||||
List<ActivityManager.RunningTaskInfo> secondaryChildren =
|
||||
TaskOrganizer.getChildTasks(tiles.mSecondary.token, null /* activityTypes */);
|
||||
// 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
|
||||
// home task bounds.
|
||||
List<ActivityManager.RunningTaskInfo> freeHomeAndRecents =
|
||||
TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS);
|
||||
if (primaryChildren.isEmpty() && secondaryChildren.isEmpty()
|
||||
&& freeHomeAndRecents.isEmpty()) {
|
||||
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();
|
||||
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 */);
|
||||
// Don't need to worry about home tasks because they are already in the "proper"
|
||||
// order within the secondary split.
|
||||
for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
|
||||
final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
|
||||
wct.reparent(ti.token, null /* parent */, 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.
|
||||
for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
|
||||
final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
|
||||
}
|
||||
} 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 */);
|
||||
if (isHomeOrRecentTask(ti)) {
|
||||
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 */);
|
||||
// reset bounds too
|
||||
wct.setBounds(ti.token, null);
|
||||
}
|
||||
}
|
||||
for (int i = freeHomeAndRecents.size() - 1; i >= 0; --i) {
|
||||
wct.setBounds(freeHomeAndRecents.get(i).token, null);
|
||||
for (int i = primaryChildren.size() - 1; i >= 0; --i) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void applyContainerTransaction(WindowContainerTransaction wct) {
|
||||
try {
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Error setting focusability: " + e);
|
||||
for (int i = freeHomeAndRecents.size() - 1; i >= 0; --i) {
|
||||
wct.setBounds(freeHomeAndRecents.get(i).token, null);
|
||||
}
|
||||
// Reset focusable to true
|
||||
wct.setFocusable(tiles.mPrimary.token, true /* focusable */);
|
||||
WindowOrganizer.applyTransaction(wct);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2802,7 +2802,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
false /* includingParents */);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -4291,7 +4292,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
tempDockedTaskInsetBounds != null ? tempDockedTaskInsetBounds
|
||||
: (tempDockedTaskBounds != null ? tempDockedTaskBounds
|
||||
: dockedBounds);
|
||||
wct.setBounds(primary.mRemoteToken, primaryRect);
|
||||
wct.setBounds(primary.mRemoteToken.toWindowContainerToken(), primaryRect);
|
||||
Rect otherRect = tempOtherTaskInsetBounds != null ? tempOtherTaskInsetBounds
|
||||
: tempOtherTaskBounds;
|
||||
if (otherRect == null) {
|
||||
@@ -4303,7 +4304,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
otherRect.top = primaryRect.bottom + 6;
|
||||
}
|
||||
}
|
||||
wct.setBounds(secondary.mRemoteToken, otherRect);
|
||||
wct.setBounds(secondary.mRemoteToken.toWindowContainerToken(), otherRect);
|
||||
mWindowOrganizerController.applyTransaction(wct);
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
|
||||
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 java.util.HashMap;
|
||||
@@ -50,7 +46,7 @@ class BLASTSyncEngine {
|
||||
private static final String TAG = "BLASTSyncEngine";
|
||||
|
||||
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.
|
||||
@@ -63,12 +59,12 @@ class BLASTSyncEngine {
|
||||
|
||||
private void tryFinish() {
|
||||
if (mRemainingTransactions == 0 && mReady) {
|
||||
mListener.transactionReady(mSyncId, mMergedTransaction);
|
||||
mListener.onTransactionReady(mSyncId, mMergedTransaction);
|
||||
mPendingSyncs.remove(mSyncId);
|
||||
}
|
||||
}
|
||||
|
||||
public void transactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
|
||||
public void onTransactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
|
||||
mRemainingTransactions--;
|
||||
mMergedTransaction.merge(mergedTransaction);
|
||||
tryFinish();
|
||||
|
||||
@@ -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.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
|
||||
import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER;
|
||||
import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_ROOT;
|
||||
import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_UNDEFINED;
|
||||
import static android.window.WindowOrganizer.DisplayAreaOrganizer.FEATURE_WINDOW_TOKENS;
|
||||
import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;
|
||||
import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
|
||||
import static android.window.DisplayAreaOrganizer.FEATURE_WINDOW_TOKENS;
|
||||
|
||||
import static com.android.internal.util.Preconditions.checkState;
|
||||
import static com.android.server.wm.DisplayAreaProto.NAME;
|
||||
|
||||
@@ -94,7 +94,7 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
|
||||
|
||||
void onDisplayAreaAppeared(IDisplayAreaOrganizer organizer, DisplayArea da) {
|
||||
try {
|
||||
organizer.onDisplayAreaAppeared(da.mRemoteToken);
|
||||
organizer.onDisplayAreaAppeared(da.mRemoteToken.toWindowContainerToken());
|
||||
} catch (RemoteException e) {
|
||||
// Oh well...
|
||||
}
|
||||
@@ -102,7 +102,7 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
|
||||
|
||||
void onDisplayAreaVanished(IDisplayAreaOrganizer organizer, DisplayArea da) {
|
||||
try {
|
||||
organizer.onDisplayAreaVanished(da.mRemoteToken);
|
||||
organizer.onDisplayAreaVanished(da.mRemoteToken.toWindowContainerToken());
|
||||
} catch (RemoteException e) {
|
||||
// Oh well...
|
||||
}
|
||||
|
||||
@@ -87,8 +87,8 @@ class DisplayAreaPolicyBuilder {
|
||||
*
|
||||
* Must be unique among the features added to a {@link DisplayAreaPolicyBuilder}.
|
||||
*
|
||||
* @see android.window.WindowOrganizer.DisplayAreaOrganizer#FEATURE_SYSTEM_FIRST
|
||||
* @see android.window.WindowOrganizer.DisplayAreaOrganizer#FEATURE_VENDOR_FIRST
|
||||
* @see android.window.DisplayAreaOrganizer#FEATURE_SYSTEM_FIRST
|
||||
* @see android.window.DisplayAreaOrganizer#FEATURE_VENDOR_FIRST
|
||||
*/
|
||||
public int getId() {
|
||||
return mId;
|
||||
|
||||
@@ -2346,7 +2346,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
|
||||
stack.getBounds(info.bounds);
|
||||
info.displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId() : INVALID_DISPLAY;
|
||||
info.stackId = stack.mTaskId;
|
||||
info.stackToken = stack.mRemoteToken;
|
||||
info.stackToken = stack.mRemoteToken.toWindowContainerToken();
|
||||
info.userId = stack.mCurrentUser;
|
||||
info.visible = stack.shouldBeVisible(null);
|
||||
// A stack might be not attached to a display.
|
||||
|
||||
@@ -478,7 +478,7 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
ITaskOrganizer mTaskOrganizer;
|
||||
@@ -3435,7 +3435,7 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
info.taskDescription = new ActivityManager.TaskDescription(getTaskDescription());
|
||||
info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
|
||||
info.configuration.setTo(getConfiguration());
|
||||
info.token = mRemoteToken;
|
||||
info.token = mRemoteToken.toWindowContainerToken();
|
||||
|
||||
//TODO (AM refactor): Just use local once updateEffectiveIntent is run during all child
|
||||
// order changes.
|
||||
|
||||
@@ -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_UNSET;
|
||||
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.STACK_VISIBILITY_VISIBLE;
|
||||
@@ -1183,7 +1183,8 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
|
||||
for (int i = mTmpTasks.size() - 1; i >= 0; i--) {
|
||||
final Task root = mTmpTasks.get(i);
|
||||
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);
|
||||
|
||||
@@ -36,7 +36,7 @@ import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.window.ITaskOrganizer;
|
||||
import android.window.ITaskOrganizerController;
|
||||
import android.window.IWindowContainer;
|
||||
import android.window.WindowContainerToken;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
|
||||
@@ -290,7 +290,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteRootTask(IWindowContainer token) {
|
||||
public boolean deleteRootTask(WindowContainerToken token) {
|
||||
enforceStackPermission("deleteRootTask()");
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -367,7 +367,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWindowContainer getImeTarget(int displayId) {
|
||||
public WindowContainerToken getImeTarget(int displayId) {
|
||||
enforceStackPermission("getImeTarget()");
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -382,7 +382,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
||||
if (task == null) {
|
||||
return null;
|
||||
}
|
||||
return task.getRootTask().mRemoteToken;
|
||||
return task.getRootTask().mRemoteToken.toWindowContainerToken();
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
@@ -390,7 +390,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLaunchRoot(int displayId, @Nullable IWindowContainer token) {
|
||||
public void setLaunchRoot(int displayId, @Nullable WindowContainerToken token) {
|
||||
enforceStackPermission("setLaunchRoot()");
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -422,7 +422,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RunningTaskInfo> getChildTasks(IWindowContainer parent,
|
||||
public List<RunningTaskInfo> getChildTasks(WindowContainerToken parent,
|
||||
@Nullable int[] activityTypes) {
|
||||
enforceStackPermission("getChildTasks()");
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
|
||||
@@ -76,7 +76,8 @@ import android.view.SurfaceControl.Builder;
|
||||
import android.view.SurfaceSession;
|
||||
import android.view.WindowManager;
|
||||
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.util.ToBooleanFunction;
|
||||
@@ -2449,8 +2450,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
||||
return RemoteToken.fromBinder(binder).getContainer();
|
||||
}
|
||||
|
||||
static class RemoteToken extends IWindowContainer.Stub {
|
||||
static class RemoteToken extends IWindowContainerToken.Stub {
|
||||
|
||||
final WeakReference<WindowContainer> mWeakRef;
|
||||
private WindowContainerToken mWindowContainerToken;
|
||||
|
||||
RemoteToken(WindowContainer container) {
|
||||
mWeakRef = new WeakReference<>(container);
|
||||
@@ -2476,6 +2479,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
||||
return sc;
|
||||
}
|
||||
|
||||
WindowContainerToken toWindowContainerToken() {
|
||||
if (mWindowContainerToken == null) {
|
||||
mWindowContainerToken = new WindowContainerToken(this);
|
||||
}
|
||||
return mWindowContainerToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
@@ -2489,11 +2499,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
|
||||
public void onTransactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
|
||||
mergedTransaction.merge(mBLASTSyncTransaction);
|
||||
mUsingBLASTSyncTransaction = false;
|
||||
|
||||
mWaitingListener.transactionReady(mWaitingSyncId, mergedTransaction);
|
||||
mWaitingListener.onTransactionReady(mWaitingSyncId, mergedTransaction);
|
||||
|
||||
mWaitingListener = null;
|
||||
mWaitingSyncId = -1;
|
||||
|
||||
@@ -340,12 +340,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
|
||||
public void onTransactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
|
||||
final IWindowContainerTransactionCallback callback =
|
||||
mTransactionCallbacksByPendingSyncId.get(mSyncId);
|
||||
|
||||
try {
|
||||
callback.transactionReady(mSyncId, mergedTransaction);
|
||||
callback.onTransactionReady(mSyncId, mergedTransaction);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
|
||||
|
||||
@@ -5723,7 +5723,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
if (mLocalSyncId >= 0) {
|
||||
mBLASTSyncEngine.setReady(mLocalSyncId);
|
||||
} else {
|
||||
mWaitingListener.transactionReady(mWaitingSyncId, mBLASTSyncTransaction);
|
||||
mWaitingListener.onTransactionReady(mWaitingSyncId, mBLASTSyncTransaction);
|
||||
}
|
||||
|
||||
mUsingBLASTSyncTransaction = false;
|
||||
|
||||
@@ -83,7 +83,7 @@ import android.platform.test.annotations.Presubmit;
|
||||
import android.service.voice.IVoiceInteractionSession;
|
||||
import android.view.Gravity;
|
||||
import android.window.ITaskOrganizer;
|
||||
import android.window.IWindowContainer;
|
||||
import android.window.WindowContainerToken;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
@@ -1014,10 +1014,10 @@ public class ActivityStarterTests extends ActivityTestsBase {
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
mService.mTaskOrganizerController.registerTaskOrganizer(this,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
|
||||
IWindowContainer primary = mService.mTaskOrganizerController.createRootTask(
|
||||
WindowContainerToken primary = mService.mTaskOrganizerController.createRootTask(
|
||||
displayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).token;
|
||||
mPrimary = WindowContainer.fromBinder(primary.asBinder()).asTask();
|
||||
IWindowContainer secondary = mService.mTaskOrganizerController.createRootTask(
|
||||
WindowContainerToken secondary = mService.mTaskOrganizerController.createRootTask(
|
||||
displayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token;
|
||||
mSecondary = WindowContainer.fromBinder(secondary.asBinder()).asTask();
|
||||
}
|
||||
@@ -1037,7 +1037,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
|
||||
== WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
|
||||
mInSplit = true;
|
||||
mService.mTaskOrganizerController.setLaunchRoot(mDisplayId,
|
||||
mSecondary.mRemoteToken);
|
||||
mSecondary.mRemoteToken.toWindowContainerToken());
|
||||
// move everything to secondary because test expects this but usually sysui
|
||||
// does it.
|
||||
DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId);
|
||||
|
||||
@@ -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_SECONDARY;
|
||||
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 com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
|
||||
@@ -282,7 +284,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
final Task task = stack.getTopMostTask();
|
||||
WindowContainerTransaction t = new WindowContainerTransaction();
|
||||
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);
|
||||
assertEquals(newBounds, task.getBounds());
|
||||
}
|
||||
@@ -295,7 +297,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
StackInfo info =
|
||||
mWm.mAtmService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
|
||||
WindowContainerTransaction t = new WindowContainerTransaction();
|
||||
assertEquals(stack.mRemoteToken, info.stackToken);
|
||||
assertEquals(stack.mRemoteToken.toWindowContainerToken(), info.stackToken);
|
||||
Rect newBounds = new Rect(10, 10, 100, 100);
|
||||
t.setBounds(info.stackToken, new Rect(10, 10, 100, 100));
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
|
||||
@@ -308,7 +310,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
|
||||
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);
|
||||
|
||||
assertEquals(WINDOWING_MODE_FULLSCREEN, stack.getWindowingMode());
|
||||
@@ -320,8 +322,9 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
final ActivityStack stack = record.getStack();
|
||||
final WindowContainerTransaction t = new WindowContainerTransaction();
|
||||
|
||||
t.setWindowingMode(stack.mRemoteToken, WINDOWING_MODE_PINNED);
|
||||
t.setActivityWindowingMode(stack.mRemoteToken, WINDOWING_MODE_FULLSCREEN);
|
||||
t.setWindowingMode(stack.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_PINNED);
|
||||
t.setActivityWindowingMode(
|
||||
stack.mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_FULLSCREEN);
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
|
||||
|
||||
assertEquals(WINDOWING_MODE_FULLSCREEN, record.getWindowingMode());
|
||||
@@ -336,10 +339,10 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
final Task task = stack.getTopMostTask();
|
||||
WindowContainerTransaction t = new WindowContainerTransaction();
|
||||
assertTrue(task.isFocusable());
|
||||
t.setFocusable(stack.mRemoteToken, false);
|
||||
t.setFocusable(stack.mRemoteToken.toWindowContainerToken(), false);
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
|
||||
assertFalse(task.isFocusable());
|
||||
t.setFocusable(stack.mRemoteToken, true);
|
||||
t.setFocusable(stack.mRemoteToken.toWindowContainerToken(), true);
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
|
||||
assertTrue(task.isFocusable());
|
||||
}
|
||||
@@ -351,10 +354,10 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
|
||||
WindowContainerTransaction t = new WindowContainerTransaction();
|
||||
assertTrue(stack.shouldBeVisible(null));
|
||||
t.setHidden(stack.mRemoteToken, true);
|
||||
t.setHidden(stack.mRemoteToken.toWindowContainerToken(), true);
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
|
||||
assertFalse(stack.shouldBeVisible(null));
|
||||
t.setHidden(stack.mRemoteToken, false);
|
||||
t.setHidden(stack.mRemoteToken.toWindowContainerToken(), false);
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
|
||||
assertTrue(stack.shouldBeVisible(null));
|
||||
}
|
||||
@@ -366,19 +369,19 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
|
||||
final Task task = stack.getTopMostTask();
|
||||
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);
|
||||
final int origScreenWDp = task.getConfiguration().screenHeightDp;
|
||||
final int origScreenHDp = task.getConfiguration().screenHeightDp;
|
||||
t = new WindowContainerTransaction();
|
||||
// verify that setting config overrides on parent restricts children.
|
||||
t.setScreenSizeDp(stack.mRemoteToken, origScreenWDp, origScreenHDp);
|
||||
t.setBounds(task.mRemoteToken, new Rect(10, 10, 150, 200));
|
||||
t.setScreenSizeDp(stack.mRemoteToken.toWindowContainerToken(), origScreenWDp, origScreenHDp);
|
||||
t.setBounds(task.mRemoteToken.toWindowContainerToken(), new Rect(10, 10, 150, 200));
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
|
||||
assertEquals(origScreenHDp, task.getConfiguration().screenHeightDp);
|
||||
t = new WindowContainerTransaction();
|
||||
t.setScreenSizeDp(stack.mRemoteToken, Configuration.SCREEN_WIDTH_DP_UNDEFINED,
|
||||
Configuration.SCREEN_HEIGHT_DP_UNDEFINED);
|
||||
t.setScreenSizeDp(stack.mRemoteToken.toWindowContainerToken(), SCREEN_WIDTH_DP_UNDEFINED,
|
||||
SCREEN_HEIGHT_DP_UNDEFINED);
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
|
||||
assertNotEquals(origScreenHDp, task.getConfiguration().screenHeightDp);
|
||||
}
|
||||
@@ -435,7 +438,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
|
||||
assertEquals(mDisplayContent.getWindowingMode(), stack.getWindowingMode());
|
||||
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);
|
||||
assertEquals(info1.configuration.windowConfiguration.getWindowingMode(),
|
||||
stack.getWindowingMode());
|
||||
@@ -455,7 +458,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
assertEquals(newSize, stack.getBounds());
|
||||
|
||||
wct = new WindowContainerTransaction();
|
||||
wct.reparent(stack.mRemoteToken, null, true /* onTop */);
|
||||
wct.reparent(stack.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
|
||||
assertEquals(mDisplayContent.getWindowingMode(), stack.getWindowingMode());
|
||||
infos = getTasksCreatedByOrganizer(mDisplayContent);
|
||||
@@ -495,7 +498,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
|
||||
Task task1 = WindowContainer.fromBinder(info1.token.asBinder()).asTask();
|
||||
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);
|
||||
assertTrue(called[0]);
|
||||
assertEquals(ACTIVITY_TYPE_STANDARD, lastReportedTiles.get(0).topActivityType);
|
||||
@@ -505,7 +508,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
final ActivityStack stack2 = createTaskStackOnDisplay(
|
||||
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, mDisplayContent);
|
||||
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);
|
||||
assertTrue(called[0]);
|
||||
assertEquals(ACTIVITY_TYPE_HOME, lastReportedTiles.get(0).topActivityType);
|
||||
@@ -519,8 +522,8 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
lastReportedTiles.clear();
|
||||
called[0] = false;
|
||||
wct = new WindowContainerTransaction();
|
||||
wct.reparent(stack.mRemoteToken, null, true /* onTop */);
|
||||
wct.reparent(stack2.mRemoteToken, null, true /* onTop */);
|
||||
wct.reparent(stack.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
|
||||
wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
|
||||
assertTrue(called[0]);
|
||||
assertEquals(ACTIVITY_TYPE_UNDEFINED, lastReportedTiles.get(0).topActivityType);
|
||||
@@ -569,8 +572,8 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
|
||||
lastReportedTiles.clear();
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.reparent(stack.mRemoteToken, info1.token, true /* onTop */);
|
||||
wct.reparent(stack2.mRemoteToken, info2.token, true /* onTop */);
|
||||
wct.reparent(stack.mRemoteToken.toWindowContainerToken(), info1.token, true /* onTop */);
|
||||
wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), info2.token, true /* onTop */);
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
|
||||
assertFalse(lastReportedTiles.isEmpty());
|
||||
assertEquals(ACTIVITY_TYPE_STANDARD,
|
||||
@@ -580,7 +583,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
|
||||
lastReportedTiles.clear();
|
||||
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);
|
||||
assertFalse(lastReportedTiles.isEmpty());
|
||||
// Standard should still be on top of tile 1, so no change there
|
||||
@@ -605,7 +608,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
|
||||
lastReportedTiles.clear();
|
||||
wct = new WindowContainerTransaction();
|
||||
wct.reorder(stack2.mRemoteToken, true /* onTop */);
|
||||
wct.reorder(stack2.mRemoteToken.toWindowContainerToken(), true /* onTop */);
|
||||
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
|
||||
// Home should now be on top. No change occurs in second tile, so not reported
|
||||
assertEquals(1, lastReportedTiles.size());
|
||||
@@ -641,7 +644,7 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
bse.setReady(id);
|
||||
// Since this task has no windows the sync is trivial and completes immediately.
|
||||
verify(transactionListener)
|
||||
.transactionReady(anyInt(), any());
|
||||
.onTransactionReady(anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -691,10 +694,10 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
bse.setReady(id);
|
||||
// Since we have a window we have to wait for it to draw to finish sync.
|
||||
verify(transactionListener, never())
|
||||
.transactionReady(anyInt(), any());
|
||||
.onTransactionReady(anyInt(), any());
|
||||
w.finishDrawing(null);
|
||||
verify(transactionListener)
|
||||
.transactionReady(anyInt(), any());
|
||||
.onTransactionReady(anyInt(), any());
|
||||
}
|
||||
|
||||
@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
|
||||
// complete as soon as we call setReady.
|
||||
verify(transactionListener)
|
||||
.transactionReady(anyInt(), any());
|
||||
.onTransactionReady(anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -742,13 +745,13 @@ public class TaskOrganizerTests extends WindowTestsBase {
|
||||
|
||||
// Since we have a child window we still shouldn't be done.
|
||||
verify(transactionListener, never())
|
||||
.transactionReady(anyInt(), any());
|
||||
.onTransactionReady(anyInt(), any());
|
||||
reset(transactionListener);
|
||||
|
||||
child.finishDrawing(null);
|
||||
// Ah finally! Done
|
||||
verify(transactionListener)
|
||||
.transactionReady(anyInt(), any());
|
||||
.onTransactionReady(anyInt(), any());
|
||||
}
|
||||
|
||||
class StubOrganizer extends ITaskOrganizer.Stub {
|
||||
|
||||
@@ -17,10 +17,9 @@
|
||||
package com.android.test.taskembed;
|
||||
|
||||
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.Activity;
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -35,10 +34,12 @@ import android.view.SurfaceControl;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.window.ITaskOrganizer;
|
||||
import android.window.IWindowContainerTransactionCallback;
|
||||
import android.window.TaskOrganizer;
|
||||
import android.window.WindowContainerTransaction;
|
||||
import android.widget.LinearLayout;
|
||||
import android.window.WindowContainerTransactionCallback;
|
||||
import android.window.WindowOrganizer;
|
||||
|
||||
public class TaskOrganizerMultiWindowTest extends Activity {
|
||||
@@ -97,7 +98,7 @@ public class TaskOrganizerMultiWindowTest extends Activity {
|
||||
class ResizingTaskView extends TaskView {
|
||||
final Intent mIntent;
|
||||
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);
|
||||
mIntent = i;
|
||||
}
|
||||
@@ -116,7 +117,7 @@ public class TaskOrganizerMultiWindowTest extends Activity {
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.setBounds(mWc, new Rect(0, 0, width, height));
|
||||
try {
|
||||
WindowOrganizer.applySyncTransaction(wct, mOrganizer.mTransactionCallback);
|
||||
mOrganizer.applySyncTransaction(wct, mOrganizer.mTransactionCallback);
|
||||
} catch (Exception e) {
|
||||
// Oh well
|
||||
}
|
||||
@@ -127,14 +128,13 @@ public class TaskOrganizerMultiWindowTest extends Activity {
|
||||
TaskView mTaskView2;
|
||||
boolean gotFirstTask = false;
|
||||
|
||||
class Organizer extends ITaskOrganizer.Stub {
|
||||
class Organizer extends TaskOrganizer {
|
||||
private int receivedTransactions = 0;
|
||||
SurfaceControl.Transaction mergedTransaction = new SurfaceControl.Transaction();
|
||||
IWindowContainerTransactionCallback mTransactionCallback =
|
||||
new IWindowContainerTransactionCallback() {
|
||||
WindowContainerTransactionCallback mTransactionCallback =
|
||||
new WindowContainerTransactionCallback() {
|
||||
@Override
|
||||
public void transactionReady(int id, SurfaceControl.Transaction t)
|
||||
throws RemoteException {
|
||||
public void onTransactionReady(int id, SurfaceControl.Transaction t) {
|
||||
mergedTransaction.merge(t);
|
||||
receivedTransactions++;
|
||||
if (receivedTransactions == 2) {
|
||||
@@ -142,11 +142,6 @@ public class TaskOrganizerMultiWindowTest extends Activity {
|
||||
receivedTransactions = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder asBinder() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
@@ -158,14 +153,6 @@ public class TaskOrganizerMultiWindowTest extends Activity {
|
||||
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();
|
||||
@@ -174,10 +161,7 @@ public class TaskOrganizerMultiWindowTest extends Activity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
try {
|
||||
TaskOrganizer.registerOrganizer(mOrganizer, WINDOWING_MODE_MULTI_WINDOW);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
mOrganizer.registerOrganizer(WINDOWING_MODE_MULTI_WINDOW);
|
||||
|
||||
mTaskView1 = new ResizingTaskView(this, mOrganizer, WINDOWING_MODE_MULTI_WINDOW,
|
||||
makeSettingsIntent());
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.test.taskembed;
|
||||
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.window.WindowOrganizer.TaskOrganizer;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Service;
|
||||
@@ -25,11 +24,10 @@ import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
import android.view.ViewGroup;
|
||||
import android.window.TaskOrganizer;
|
||||
import android.window.WindowContainerTransaction;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.window.ITaskOrganizer;
|
||||
import android.window.WindowContainerTransaction;
|
||||
import android.window.WindowOrganizer;
|
||||
|
||||
public class TaskOrganizerPipTest extends Service {
|
||||
static final int PIP_WIDTH = 640;
|
||||
@@ -37,23 +35,13 @@ public class TaskOrganizerPipTest extends Service {
|
||||
|
||||
TaskView mTaskView;
|
||||
|
||||
class Organizer extends ITaskOrganizer.Stub {
|
||||
class Organizer extends TaskOrganizer {
|
||||
public void onTaskAppeared(ActivityManager.RunningTaskInfo ti) {
|
||||
mTaskView.reparentTask(ti.token);
|
||||
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.scheduleFinishEnterPip(ti.token, new Rect(0, 0, PIP_WIDTH, PIP_HEIGHT));
|
||||
try {
|
||||
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) {
|
||||
applyTransaction(wct);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,10 +56,7 @@ public class TaskOrganizerPipTest extends Service {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
try {
|
||||
TaskOrganizer.registerOrganizer(mOrganizer, WINDOWING_MODE_PINNED);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
mOrganizer.registerOrganizer(WINDOWING_MODE_PINNED);
|
||||
|
||||
final WindowManager.LayoutParams wlp = new WindowManager.LayoutParams();
|
||||
wlp.setTitle("TaskOrganizerPipTest");
|
||||
|
||||
@@ -18,7 +18,8 @@ package com.android.test.taskembed;
|
||||
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.content.Context;
|
||||
import android.window.IWindowContainer;
|
||||
import android.window.TaskOrganizer;
|
||||
import android.window.WindowContainerToken;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
@@ -29,14 +30,14 @@ import android.window.ITaskOrganizer;
|
||||
* after it's Surface is ready.
|
||||
*/
|
||||
class TaskView extends SurfaceView implements SurfaceHolder.Callback {
|
||||
final ITaskOrganizer mTaskOrganizer;
|
||||
final TaskOrganizer mTaskOrganizer;
|
||||
final int mWindowingMode;
|
||||
IWindowContainer mWc;
|
||||
WindowContainerToken mWc;
|
||||
|
||||
boolean mSurfaceCreated = false;
|
||||
boolean mNeedsReparent;
|
||||
|
||||
TaskView(Context c, ITaskOrganizer o, int windowingMode) {
|
||||
TaskView(Context c, TaskOrganizer o, int windowingMode) {
|
||||
super(c);
|
||||
getHolder().addCallback(this);
|
||||
setZOrderOnTop(true);
|
||||
@@ -62,7 +63,7 @@ class TaskView extends SurfaceView implements SurfaceHolder.Callback {
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
}
|
||||
|
||||
void reparentTask(IWindowContainer wc) {
|
||||
void reparentTask(WindowContainerToken wc) {
|
||||
mWc = wc;
|
||||
if (mSurfaceCreated == false) {
|
||||
mNeedsReparent = true;
|
||||
|
||||
Reference in New Issue
Block a user