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