Simplify exposing external interfaces to Launcher
- Currently, the collection of binders to send to Launcher is inverted and managed by OverviewProxyService which has to know about each component directly (and a SysUI interface has to be created to support this even if there are no other calls in SysUI to that component). Instead, we should have each component register itself with the ShellController for controllers which can be exposed to an external process, and each product can customize which set of controllers it needs to support. - Add missing dump registration for ShellController - Updating docs for creating remote callable controllers Bug: 238217847 Test: atest WMShellUnitTests Change-Id: Icd0ed33bdbd68b1dd9d782b9ba1f5b4a604479ba
This commit is contained in:
@@ -44,6 +44,7 @@ filegroup {
|
|||||||
srcs: [
|
srcs: [
|
||||||
"src/com/android/wm/shell/util/**/*.java",
|
"src/com/android/wm/shell/util/**/*.java",
|
||||||
"src/com/android/wm/shell/common/split/SplitScreenConstants.java",
|
"src/com/android/wm/shell/common/split/SplitScreenConstants.java",
|
||||||
|
"src/com/android/wm/shell/sysui/ShellSharedConstants.java",
|
||||||
],
|
],
|
||||||
path: "src",
|
path: "src",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,13 +28,6 @@ import com.android.wm.shell.common.annotations.ExternalThread;
|
|||||||
@ExternalThread
|
@ExternalThread
|
||||||
public interface BackAnimation {
|
public interface BackAnimation {
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a binder that can be passed to an external process to update back animations.
|
|
||||||
*/
|
|
||||||
default IBackAnimation createExternalInterface() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a {@link MotionEvent} is generated by a back gesture.
|
* Called when a {@link MotionEvent} is generated by a back gesture.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.wm.shell.back;
|
|||||||
|
|
||||||
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
||||||
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;
|
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;
|
||||||
|
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_BACK_ANIMATION;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
@@ -53,10 +54,12 @@ import android.window.IOnBackInvokedCallback;
|
|||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
|
import com.android.wm.shell.common.ExternalInterfaceBinder;
|
||||||
import com.android.wm.shell.common.RemoteCallable;
|
import com.android.wm.shell.common.RemoteCallable;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.annotations.ShellBackgroundThread;
|
import com.android.wm.shell.common.annotations.ShellBackgroundThread;
|
||||||
import com.android.wm.shell.common.annotations.ShellMainThread;
|
import com.android.wm.shell.common.annotations.ShellMainThread;
|
||||||
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
import com.android.wm.shell.transition.Transitions;
|
import com.android.wm.shell.transition.Transitions;
|
||||||
|
|
||||||
@@ -102,6 +105,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
private final IActivityTaskManager mActivityTaskManager;
|
private final IActivityTaskManager mActivityTaskManager;
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final ContentResolver mContentResolver;
|
private final ContentResolver mContentResolver;
|
||||||
|
private final ShellController mShellController;
|
||||||
private final ShellExecutor mShellExecutor;
|
private final ShellExecutor mShellExecutor;
|
||||||
private final Handler mBgHandler;
|
private final Handler mBgHandler;
|
||||||
private final Runnable mResetTransitionRunnable = () -> {
|
private final Runnable mResetTransitionRunnable = () -> {
|
||||||
@@ -188,11 +192,12 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
|
|
||||||
public BackAnimationController(
|
public BackAnimationController(
|
||||||
@NonNull ShellInit shellInit,
|
@NonNull ShellInit shellInit,
|
||||||
|
@NonNull ShellController shellController,
|
||||||
@NonNull @ShellMainThread ShellExecutor shellExecutor,
|
@NonNull @ShellMainThread ShellExecutor shellExecutor,
|
||||||
@NonNull @ShellBackgroundThread Handler backgroundHandler,
|
@NonNull @ShellBackgroundThread Handler backgroundHandler,
|
||||||
Context context,
|
Context context,
|
||||||
Transitions transitions) {
|
Transitions transitions) {
|
||||||
this(shellInit, shellExecutor, backgroundHandler,
|
this(shellInit, shellController, shellExecutor, backgroundHandler,
|
||||||
ActivityTaskManager.getService(), context, context.getContentResolver(),
|
ActivityTaskManager.getService(), context, context.getContentResolver(),
|
||||||
transitions);
|
transitions);
|
||||||
}
|
}
|
||||||
@@ -200,11 +205,13 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
BackAnimationController(
|
BackAnimationController(
|
||||||
@NonNull ShellInit shellInit,
|
@NonNull ShellInit shellInit,
|
||||||
|
@NonNull ShellController shellController,
|
||||||
@NonNull @ShellMainThread ShellExecutor shellExecutor,
|
@NonNull @ShellMainThread ShellExecutor shellExecutor,
|
||||||
@NonNull @ShellBackgroundThread Handler bgHandler,
|
@NonNull @ShellBackgroundThread Handler bgHandler,
|
||||||
@NonNull IActivityTaskManager activityTaskManager,
|
@NonNull IActivityTaskManager activityTaskManager,
|
||||||
Context context, ContentResolver contentResolver,
|
Context context, ContentResolver contentResolver,
|
||||||
Transitions transitions) {
|
Transitions transitions) {
|
||||||
|
mShellController = shellController;
|
||||||
mShellExecutor = shellExecutor;
|
mShellExecutor = shellExecutor;
|
||||||
mActivityTaskManager = activityTaskManager;
|
mActivityTaskManager = activityTaskManager;
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@@ -221,6 +228,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
mBackTransitionHandler = new BackTransitionHandler(this);
|
mBackTransitionHandler = new BackTransitionHandler(this);
|
||||||
mTransitions.addHandler(mBackTransitionHandler);
|
mTransitions.addHandler(mBackTransitionHandler);
|
||||||
}
|
}
|
||||||
|
mShellController.addExternalInterface(KEY_EXTRA_SHELL_BACK_ANIMATION,
|
||||||
|
this::createExternalInterface, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupAnimationDeveloperSettingsObserver(
|
private void setupAnimationDeveloperSettingsObserver(
|
||||||
@@ -253,7 +262,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
return mBackAnimation;
|
return mBackAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final BackAnimation mBackAnimation = new BackAnimationImpl();
|
private ExternalInterfaceBinder createExternalInterface() {
|
||||||
|
return new IBackAnimationImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BackAnimationImpl mBackAnimation = new BackAnimationImpl();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Context getContext() {
|
public Context getContext() {
|
||||||
@@ -266,17 +279,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class BackAnimationImpl implements BackAnimation {
|
private class BackAnimationImpl implements BackAnimation {
|
||||||
private IBackAnimationImpl mBackAnimation;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBackAnimation createExternalInterface() {
|
|
||||||
if (mBackAnimation != null) {
|
|
||||||
mBackAnimation.invalidate();
|
|
||||||
}
|
|
||||||
mBackAnimation = new IBackAnimationImpl(BackAnimationController.this);
|
|
||||||
return mBackAnimation;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackMotion(
|
public void onBackMotion(
|
||||||
float touchX, float touchY, int keyAction, @BackEvent.SwipeEdge int swipeEdge) {
|
float touchX, float touchY, int keyAction, @BackEvent.SwipeEdge int swipeEdge) {
|
||||||
@@ -295,7 +297,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class IBackAnimationImpl extends IBackAnimation.Stub {
|
private static class IBackAnimationImpl extends IBackAnimation.Stub
|
||||||
|
implements ExternalInterfaceBinder {
|
||||||
private BackAnimationController mController;
|
private BackAnimationController mController;
|
||||||
|
|
||||||
IBackAnimationImpl(BackAnimationController controller) {
|
IBackAnimationImpl(BackAnimationController controller) {
|
||||||
@@ -315,7 +318,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
(controller) -> controller.clearBackToLauncherCallback());
|
(controller) -> controller.clearBackToLauncherCallback());
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidate() {
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
mController = null;
|
mController = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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 com.android.wm.shell.common;
|
||||||
|
|
||||||
|
import android.os.IBinder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface for binders which can be registered to be sent to other processes.
|
||||||
|
*/
|
||||||
|
public interface ExternalInterfaceBinder {
|
||||||
|
/**
|
||||||
|
* Invalidates this binder (detaches it from the controller it would call).
|
||||||
|
*/
|
||||||
|
void invalidate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the IBinder to send.
|
||||||
|
*/
|
||||||
|
IBinder asBinder();
|
||||||
|
}
|
||||||
@@ -258,14 +258,15 @@ public abstract class WMShellBaseModule {
|
|||||||
static Optional<BackAnimationController> provideBackAnimationController(
|
static Optional<BackAnimationController> provideBackAnimationController(
|
||||||
Context context,
|
Context context,
|
||||||
ShellInit shellInit,
|
ShellInit shellInit,
|
||||||
|
ShellController shellController,
|
||||||
@ShellMainThread ShellExecutor shellExecutor,
|
@ShellMainThread ShellExecutor shellExecutor,
|
||||||
@ShellBackgroundThread Handler backgroundHandler,
|
@ShellBackgroundThread Handler backgroundHandler,
|
||||||
Transitions transitions
|
Transitions transitions
|
||||||
) {
|
) {
|
||||||
if (BackAnimationController.IS_ENABLED) {
|
if (BackAnimationController.IS_ENABLED) {
|
||||||
return Optional.of(
|
return Optional.of(
|
||||||
new BackAnimationController(shellInit, shellExecutor, backgroundHandler,
|
new BackAnimationController(shellInit, shellController, shellExecutor,
|
||||||
context, transitions));
|
backgroundHandler, context, transitions));
|
||||||
}
|
}
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
@@ -469,6 +470,7 @@ public abstract class WMShellBaseModule {
|
|||||||
static Optional<RecentTasksController> provideRecentTasksController(
|
static Optional<RecentTasksController> provideRecentTasksController(
|
||||||
Context context,
|
Context context,
|
||||||
ShellInit shellInit,
|
ShellInit shellInit,
|
||||||
|
ShellController shellController,
|
||||||
ShellCommandHandler shellCommandHandler,
|
ShellCommandHandler shellCommandHandler,
|
||||||
TaskStackListenerImpl taskStackListener,
|
TaskStackListenerImpl taskStackListener,
|
||||||
ActivityTaskManager activityTaskManager,
|
ActivityTaskManager activityTaskManager,
|
||||||
@@ -476,9 +478,9 @@ public abstract class WMShellBaseModule {
|
|||||||
@ShellMainThread ShellExecutor mainExecutor
|
@ShellMainThread ShellExecutor mainExecutor
|
||||||
) {
|
) {
|
||||||
return Optional.ofNullable(
|
return Optional.ofNullable(
|
||||||
RecentTasksController.create(context, shellInit, shellCommandHandler,
|
RecentTasksController.create(context, shellInit, shellController,
|
||||||
taskStackListener, activityTaskManager, desktopModeTaskRepository,
|
shellCommandHandler, taskStackListener, activityTaskManager,
|
||||||
mainExecutor));
|
desktopModeTaskRepository, mainExecutor));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -495,14 +497,15 @@ public abstract class WMShellBaseModule {
|
|||||||
@Provides
|
@Provides
|
||||||
static Transitions provideTransitions(Context context,
|
static Transitions provideTransitions(Context context,
|
||||||
ShellInit shellInit,
|
ShellInit shellInit,
|
||||||
|
ShellController shellController,
|
||||||
ShellTaskOrganizer organizer,
|
ShellTaskOrganizer organizer,
|
||||||
TransactionPool pool,
|
TransactionPool pool,
|
||||||
DisplayController displayController,
|
DisplayController displayController,
|
||||||
@ShellMainThread ShellExecutor mainExecutor,
|
@ShellMainThread ShellExecutor mainExecutor,
|
||||||
@ShellMainThread Handler mainHandler,
|
@ShellMainThread Handler mainHandler,
|
||||||
@ShellAnimationThread ShellExecutor animExecutor) {
|
@ShellAnimationThread ShellExecutor animExecutor) {
|
||||||
return new Transitions(context, shellInit, organizer, pool, displayController, mainExecutor,
|
return new Transitions(context, shellInit, shellController, organizer, pool,
|
||||||
mainHandler, animExecutor);
|
displayController, mainExecutor, mainHandler, animExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@WMSingleton
|
@WMSingleton
|
||||||
@@ -619,13 +622,15 @@ public abstract class WMShellBaseModule {
|
|||||||
|
|
||||||
@WMSingleton
|
@WMSingleton
|
||||||
@Provides
|
@Provides
|
||||||
static StartingWindowController provideStartingWindowController(Context context,
|
static StartingWindowController provideStartingWindowController(
|
||||||
|
Context context,
|
||||||
ShellInit shellInit,
|
ShellInit shellInit,
|
||||||
|
ShellController shellController,
|
||||||
ShellTaskOrganizer shellTaskOrganizer,
|
ShellTaskOrganizer shellTaskOrganizer,
|
||||||
@ShellSplashscreenThread ShellExecutor splashScreenExecutor,
|
@ShellSplashscreenThread ShellExecutor splashScreenExecutor,
|
||||||
StartingWindowTypeAlgorithm startingWindowTypeAlgorithm, IconProvider iconProvider,
|
StartingWindowTypeAlgorithm startingWindowTypeAlgorithm, IconProvider iconProvider,
|
||||||
TransactionPool pool) {
|
TransactionPool pool) {
|
||||||
return new StartingWindowController(context, shellInit, shellTaskOrganizer,
|
return new StartingWindowController(context, shellInit, shellController, shellTaskOrganizer,
|
||||||
splashScreenExecutor, startingWindowTypeAlgorithm, iconProvider, pool);
|
splashScreenExecutor, startingWindowTypeAlgorithm, iconProvider, pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -600,7 +600,9 @@ public abstract class WMShellModule {
|
|||||||
@WMSingleton
|
@WMSingleton
|
||||||
@Provides
|
@Provides
|
||||||
@DynamicOverride
|
@DynamicOverride
|
||||||
static DesktopModeController provideDesktopModeController(Context context, ShellInit shellInit,
|
static DesktopModeController provideDesktopModeController(Context context,
|
||||||
|
ShellInit shellInit,
|
||||||
|
ShellController shellController,
|
||||||
ShellTaskOrganizer shellTaskOrganizer,
|
ShellTaskOrganizer shellTaskOrganizer,
|
||||||
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
|
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
|
||||||
Transitions transitions,
|
Transitions transitions,
|
||||||
@@ -608,7 +610,7 @@ public abstract class WMShellModule {
|
|||||||
@ShellMainThread Handler mainHandler,
|
@ShellMainThread Handler mainHandler,
|
||||||
@ShellMainThread ShellExecutor mainExecutor
|
@ShellMainThread ShellExecutor mainExecutor
|
||||||
) {
|
) {
|
||||||
return new DesktopModeController(context, shellInit, shellTaskOrganizer,
|
return new DesktopModeController(context, shellInit, shellController, shellTaskOrganizer,
|
||||||
rootTaskDisplayAreaOrganizer, transitions, desktopModeTaskRepository, mainHandler,
|
rootTaskDisplayAreaOrganizer, transitions, desktopModeTaskRepository, mainHandler,
|
||||||
mainExecutor);
|
mainExecutor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,4 @@ import com.android.wm.shell.common.annotations.ExternalThread;
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
public interface DesktopMode {
|
public interface DesktopMode {
|
||||||
|
|
||||||
/** Returns a binder that can be passed to an external process to manipulate DesktopMode. */
|
|
||||||
default IDesktopMode createExternalInterface() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import static android.view.WindowManager.TRANSIT_CHANGE;
|
|||||||
|
|
||||||
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
||||||
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
|
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
|
||||||
|
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_DESKTOP_MODE;
|
||||||
|
|
||||||
import android.app.ActivityManager.RunningTaskInfo;
|
import android.app.ActivityManager.RunningTaskInfo;
|
||||||
import android.app.WindowConfiguration;
|
import android.app.WindowConfiguration;
|
||||||
@@ -42,10 +43,12 @@ import com.android.internal.annotations.VisibleForTesting;
|
|||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
|
import com.android.wm.shell.common.ExternalInterfaceBinder;
|
||||||
import com.android.wm.shell.common.RemoteCallable;
|
import com.android.wm.shell.common.RemoteCallable;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||||
import com.android.wm.shell.common.annotations.ShellMainThread;
|
import com.android.wm.shell.common.annotations.ShellMainThread;
|
||||||
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
import com.android.wm.shell.transition.Transitions;
|
import com.android.wm.shell.transition.Transitions;
|
||||||
|
|
||||||
@@ -58,15 +61,18 @@ import java.util.Comparator;
|
|||||||
public class DesktopModeController implements RemoteCallable<DesktopModeController> {
|
public class DesktopModeController implements RemoteCallable<DesktopModeController> {
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
private final ShellController mShellController;
|
||||||
private final ShellTaskOrganizer mShellTaskOrganizer;
|
private final ShellTaskOrganizer mShellTaskOrganizer;
|
||||||
private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
|
private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
|
||||||
private final Transitions mTransitions;
|
private final Transitions mTransitions;
|
||||||
private final DesktopModeTaskRepository mDesktopModeTaskRepository;
|
private final DesktopModeTaskRepository mDesktopModeTaskRepository;
|
||||||
private final ShellExecutor mMainExecutor;
|
private final ShellExecutor mMainExecutor;
|
||||||
private final DesktopMode mDesktopModeImpl = new DesktopModeImpl();
|
private final DesktopModeImpl mDesktopModeImpl = new DesktopModeImpl();
|
||||||
private final SettingsObserver mSettingsObserver;
|
private final SettingsObserver mSettingsObserver;
|
||||||
|
|
||||||
public DesktopModeController(Context context, ShellInit shellInit,
|
public DesktopModeController(Context context,
|
||||||
|
ShellInit shellInit,
|
||||||
|
ShellController shellController,
|
||||||
ShellTaskOrganizer shellTaskOrganizer,
|
ShellTaskOrganizer shellTaskOrganizer,
|
||||||
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
|
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
|
||||||
Transitions transitions,
|
Transitions transitions,
|
||||||
@@ -74,6 +80,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
|||||||
@ShellMainThread Handler mainHandler,
|
@ShellMainThread Handler mainHandler,
|
||||||
@ShellMainThread ShellExecutor mainExecutor) {
|
@ShellMainThread ShellExecutor mainExecutor) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mShellController = shellController;
|
||||||
mShellTaskOrganizer = shellTaskOrganizer;
|
mShellTaskOrganizer = shellTaskOrganizer;
|
||||||
mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
|
mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
|
||||||
mTransitions = transitions;
|
mTransitions = transitions;
|
||||||
@@ -85,6 +92,8 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
|||||||
|
|
||||||
private void onInit() {
|
private void onInit() {
|
||||||
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopModeController");
|
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopModeController");
|
||||||
|
mShellController.addExternalInterface(KEY_EXTRA_SHELL_DESKTOP_MODE,
|
||||||
|
this::createExternalInterface, this);
|
||||||
mSettingsObserver.observe();
|
mSettingsObserver.observe();
|
||||||
if (DesktopModeStatus.isActive(mContext)) {
|
if (DesktopModeStatus.isActive(mContext)) {
|
||||||
updateDesktopModeActive(true);
|
updateDesktopModeActive(true);
|
||||||
@@ -108,6 +117,13 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
|||||||
return mDesktopModeImpl;
|
return mDesktopModeImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of the external interface to pass to another process.
|
||||||
|
*/
|
||||||
|
private ExternalInterfaceBinder createExternalInterface() {
|
||||||
|
return new IDesktopModeImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void updateDesktopModeActive(boolean active) {
|
void updateDesktopModeActive(boolean active) {
|
||||||
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "updateDesktopModeActive: active=%s", active);
|
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "updateDesktopModeActive: active=%s", active);
|
||||||
@@ -235,24 +251,15 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
private final class DesktopModeImpl implements DesktopMode {
|
private final class DesktopModeImpl implements DesktopMode {
|
||||||
|
// Do nothing
|
||||||
private IDesktopModeImpl mIDesktopMode;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDesktopMode createExternalInterface() {
|
|
||||||
if (mIDesktopMode != null) {
|
|
||||||
mIDesktopMode.invalidate();
|
|
||||||
}
|
|
||||||
mIDesktopMode = new IDesktopModeImpl(DesktopModeController.this);
|
|
||||||
return mIDesktopMode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface for calls from outside the host process.
|
* The interface for calls from outside the host process.
|
||||||
*/
|
*/
|
||||||
@BinderThread
|
@BinderThread
|
||||||
private static class IDesktopModeImpl extends IDesktopMode.Stub {
|
private static class IDesktopModeImpl extends IDesktopMode.Stub
|
||||||
|
implements ExternalInterfaceBinder {
|
||||||
|
|
||||||
private DesktopModeController mController;
|
private DesktopModeController mController;
|
||||||
|
|
||||||
@@ -263,7 +270,8 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
|||||||
/**
|
/**
|
||||||
* Invalidates this instance, preventing future calls from updating the controller.
|
* Invalidates this instance, preventing future calls from updating the controller.
|
||||||
*/
|
*/
|
||||||
void invalidate() {
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
mController = null;
|
mController = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,19 +29,37 @@ As mentioned in the [Dagger usage](dagger.md) docs, you need to determine whethe
|
|||||||
### SysUI accessible components
|
### SysUI accessible components
|
||||||
In addition to doing the above, you will also need to provide an interface for calling to SysUI
|
In addition to doing the above, you will also need to provide an interface for calling to SysUI
|
||||||
from the Shell and vice versa. The current pattern is to have a parallel `Optional<Component name>`
|
from the Shell and vice versa. The current pattern is to have a parallel `Optional<Component name>`
|
||||||
interface that the `<Component name>Controller` implements and handles on the main Shell thread.
|
interface that the `<Component name>Controller` implements and handles on the main Shell thread
|
||||||
|
(see [SysUI/Shell threading](threading.md)).
|
||||||
|
|
||||||
In addition, because components accessible to SysUI injection are explicitly listed, you'll have to
|
In addition, because components accessible to SysUI injection are explicitly listed, you'll have to
|
||||||
add an appropriate method in `WMComponent` to get the interface and update the `Builder` in
|
add an appropriate method in `WMComponent` to get the interface and update the `Builder` in
|
||||||
`SysUIComponent` to take the interface so it can be injected in SysUI code. The binding between
|
`SysUIComponent` to take the interface so it can be injected in SysUI code. The binding between
|
||||||
the two is done in `SystemUIFactory#init()` which will need to be updated as well.
|
the two is done in `SystemUIFactory#init()` which will need to be updated as well.
|
||||||
|
|
||||||
|
Specifically, to support calling into a controller from an external process (like Launcher):
|
||||||
|
- Create an implementation of the external interface within the controller
|
||||||
|
- Have all incoming calls post to the main shell thread (inject @ShellMainThread Executor into the
|
||||||
|
controller if needed)
|
||||||
|
- Note that callbacks into SysUI should take an associated executor to call back on
|
||||||
|
|
||||||
### Launcher accessible components
|
### Launcher accessible components
|
||||||
Because Launcher is not a part of SystemUI and is a separate process, exposing controllers to
|
Because Launcher is not a part of SystemUI and is a separate process, exposing controllers to
|
||||||
Launcher requires a new AIDL interface to be created and implemented by the controller. The
|
Launcher requires a new AIDL interface to be created and implemented by the controller. The
|
||||||
implementation of the stub interface in the controller otherwise behaves similar to the interface
|
implementation of the stub interface in the controller otherwise behaves similar to the interface
|
||||||
to SysUI where it posts the work to the main Shell thread.
|
to SysUI where it posts the work to the main Shell thread.
|
||||||
|
|
||||||
|
Specifically, to support calling into a controller from an external process (like Launcher):
|
||||||
|
- Create an implementation of the interface binder's `Stub` class within the controller, have it
|
||||||
|
extend `ExternalInterfaceBinder` and implement `invalidate()` to ensure it doesn't hold long
|
||||||
|
references to the outer controller
|
||||||
|
- Make the controller implement `RemoteCallable<T>`, and have all incoming calls use one of
|
||||||
|
the `ExecutorUtils.executeRemoteCallWithTaskPermission()` calls to verify the caller's identity
|
||||||
|
and ensure the call happens on the main shell thread and not the binder thread
|
||||||
|
- Inject `ShellController` and add the instance of the implementation as external interface
|
||||||
|
- In Launcher, update `TouchInteractionService` to pass the interface to `SystemUIProxy`, and then
|
||||||
|
call the SystemUIProxy method as needed in that code
|
||||||
|
|
||||||
### Component initialization
|
### Component initialization
|
||||||
To initialize the component:
|
To initialize the component:
|
||||||
- On the Shell side, you potentially need to do two things to initialize the component:
|
- On the Shell side, you potentially need to do two things to initialize the component:
|
||||||
@@ -64,8 +82,9 @@ adb logcat *:S WindowManagerShell
|
|||||||
|
|
||||||
### General Do's & Dont's
|
### General Do's & Dont's
|
||||||
Do:
|
Do:
|
||||||
- Do add unit tests for all new components
|
- Add unit tests for all new components
|
||||||
- Do keep controllers simple and break them down as needed
|
- Keep controllers simple and break them down as needed
|
||||||
|
- Any SysUI callbacks should also take an associated executor to run the callback on
|
||||||
|
|
||||||
Don't:
|
Don't:
|
||||||
- **Don't** do initialization in the constructor, only do initialization in the init callbacks.
|
- **Don't** do initialization in the constructor, only do initialization in the init callbacks.
|
||||||
|
|||||||
@@ -33,9 +33,4 @@ public interface FloatingTasks {
|
|||||||
* - If there is a floating task for this intent, and it's not stashed, this stashes it.
|
* - If there is a floating task for this intent, and it's not stashed, this stashes it.
|
||||||
*/
|
*/
|
||||||
void showOrSetStashed(Intent intent);
|
void showOrSetStashed(Intent intent);
|
||||||
|
|
||||||
/** Returns a binder that can be passed to an external process to manipulate FloatingTasks. */
|
|
||||||
default IFloatingTasks createExternalInterface() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M
|
|||||||
|
|
||||||
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
||||||
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_FLOATING_APPS;
|
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_FLOATING_APPS;
|
||||||
|
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_FLOATING_TASKS;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -40,6 +41,7 @@ import com.android.internal.protolog.common.ProtoLog;
|
|||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
import com.android.wm.shell.TaskViewTransitions;
|
import com.android.wm.shell.TaskViewTransitions;
|
||||||
import com.android.wm.shell.bubbles.BubbleController;
|
import com.android.wm.shell.bubbles.BubbleController;
|
||||||
|
import com.android.wm.shell.common.ExternalInterfaceBinder;
|
||||||
import com.android.wm.shell.common.RemoteCallable;
|
import com.android.wm.shell.common.RemoteCallable;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||||
@@ -136,11 +138,13 @@ public class FloatingTasksController implements RemoteCallable<FloatingTasksCont
|
|||||||
if (isFloatingTasksEnabled()) {
|
if (isFloatingTasksEnabled()) {
|
||||||
shellInit.addInitCallback(this::onInit, this);
|
shellInit.addInitCallback(this::onInit, this);
|
||||||
}
|
}
|
||||||
mShellCommandHandler.addDumpCallback(this::dump, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onInit() {
|
protected void onInit() {
|
||||||
mShellController.addConfigurationChangeListener(this);
|
mShellController.addConfigurationChangeListener(this);
|
||||||
|
mShellController.addExternalInterface(KEY_EXTRA_SHELL_FLOATING_TASKS,
|
||||||
|
this::createExternalInterface, this);
|
||||||
|
mShellCommandHandler.addDumpCallback(this::dump, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Only used for testing. */
|
/** Only used for testing. */
|
||||||
@@ -168,6 +172,10 @@ public class FloatingTasksController implements RemoteCallable<FloatingTasksCont
|
|||||||
return FLOATING_TASKS_ENABLED || mFloatingTasksEnabledForTests;
|
return FLOATING_TASKS_ENABLED || mFloatingTasksEnabledForTests;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExternalInterfaceBinder createExternalInterface() {
|
||||||
|
return new IFloatingTasksImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onThemeChanged() {
|
public void onThemeChanged() {
|
||||||
if (mIsFloatingLayerAdded) {
|
if (mIsFloatingLayerAdded) {
|
||||||
@@ -412,28 +420,18 @@ public class FloatingTasksController implements RemoteCallable<FloatingTasksCont
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
private class FloatingTaskImpl implements FloatingTasks {
|
private class FloatingTaskImpl implements FloatingTasks {
|
||||||
private IFloatingTasksImpl mIFloatingTasks;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showOrSetStashed(Intent intent) {
|
public void showOrSetStashed(Intent intent) {
|
||||||
mMainExecutor.execute(() -> FloatingTasksController.this.showOrSetStashed(intent));
|
mMainExecutor.execute(() -> FloatingTasksController.this.showOrSetStashed(intent));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IFloatingTasks createExternalInterface() {
|
|
||||||
if (mIFloatingTasks != null) {
|
|
||||||
mIFloatingTasks.invalidate();
|
|
||||||
}
|
|
||||||
mIFloatingTasks = new IFloatingTasksImpl(FloatingTasksController.this);
|
|
||||||
return mIFloatingTasks;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface for calls from outside the host process.
|
* The interface for calls from outside the host process.
|
||||||
*/
|
*/
|
||||||
@BinderThread
|
@BinderThread
|
||||||
private static class IFloatingTasksImpl extends IFloatingTasks.Stub {
|
private static class IFloatingTasksImpl extends IFloatingTasks.Stub
|
||||||
|
implements ExternalInterfaceBinder {
|
||||||
private FloatingTasksController mController;
|
private FloatingTasksController mController;
|
||||||
|
|
||||||
IFloatingTasksImpl(FloatingTasksController controller) {
|
IFloatingTasksImpl(FloatingTasksController controller) {
|
||||||
@@ -443,7 +441,8 @@ public class FloatingTasksController implements RemoteCallable<FloatingTasksCont
|
|||||||
/**
|
/**
|
||||||
* Invalidates this instance, preventing future calls from updating the controller.
|
* Invalidates this instance, preventing future calls from updating the controller.
|
||||||
*/
|
*/
|
||||||
void invalidate() {
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
mController = null;
|
mController = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,13 +29,6 @@ public interface OneHanded {
|
|||||||
boolean sIsSupportOneHandedMode = SystemProperties.getBoolean(
|
boolean sIsSupportOneHandedMode = SystemProperties.getBoolean(
|
||||||
OneHandedController.SUPPORT_ONE_HANDED_MODE, false);
|
OneHandedController.SUPPORT_ONE_HANDED_MODE, false);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a binder that can be passed to an external process to manipulate OneHanded.
|
|
||||||
*/
|
|
||||||
default IOneHanded createExternalInterface() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enters one handed mode.
|
* Enters one handed mode.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE;
|
|||||||
import static com.android.wm.shell.onehanded.OneHandedState.STATE_ENTERING;
|
import static com.android.wm.shell.onehanded.OneHandedState.STATE_ENTERING;
|
||||||
import static com.android.wm.shell.onehanded.OneHandedState.STATE_EXITING;
|
import static com.android.wm.shell.onehanded.OneHandedState.STATE_EXITING;
|
||||||
import static com.android.wm.shell.onehanded.OneHandedState.STATE_NONE;
|
import static com.android.wm.shell.onehanded.OneHandedState.STATE_NONE;
|
||||||
|
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_ONE_HANDED;
|
||||||
|
|
||||||
import android.annotation.BinderThread;
|
import android.annotation.BinderThread;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
@@ -49,6 +50,7 @@ import com.android.wm.shell.R;
|
|||||||
import com.android.wm.shell.common.DisplayChangeController;
|
import com.android.wm.shell.common.DisplayChangeController;
|
||||||
import com.android.wm.shell.common.DisplayController;
|
import com.android.wm.shell.common.DisplayController;
|
||||||
import com.android.wm.shell.common.DisplayLayout;
|
import com.android.wm.shell.common.DisplayLayout;
|
||||||
|
import com.android.wm.shell.common.ExternalInterfaceBinder;
|
||||||
import com.android.wm.shell.common.RemoteCallable;
|
import com.android.wm.shell.common.RemoteCallable;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.TaskStackListenerCallback;
|
import com.android.wm.shell.common.TaskStackListenerCallback;
|
||||||
@@ -296,12 +298,18 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
|
|||||||
mShellController.addConfigurationChangeListener(this);
|
mShellController.addConfigurationChangeListener(this);
|
||||||
mShellController.addKeyguardChangeListener(this);
|
mShellController.addKeyguardChangeListener(this);
|
||||||
mShellController.addUserChangeListener(this);
|
mShellController.addUserChangeListener(this);
|
||||||
|
mShellController.addExternalInterface(KEY_EXTRA_SHELL_ONE_HANDED,
|
||||||
|
this::createExternalInterface, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OneHanded asOneHanded() {
|
public OneHanded asOneHanded() {
|
||||||
return mImpl;
|
return mImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExternalInterfaceBinder createExternalInterface() {
|
||||||
|
return new IOneHandedImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Context getContext() {
|
public Context getContext() {
|
||||||
return mContext;
|
return mContext;
|
||||||
@@ -709,17 +717,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
private class OneHandedImpl implements OneHanded {
|
private class OneHandedImpl implements OneHanded {
|
||||||
private IOneHandedImpl mIOneHanded;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IOneHanded createExternalInterface() {
|
|
||||||
if (mIOneHanded != null) {
|
|
||||||
mIOneHanded.invalidate();
|
|
||||||
}
|
|
||||||
mIOneHanded = new IOneHandedImpl(OneHandedController.this);
|
|
||||||
return mIOneHanded;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startOneHanded() {
|
public void startOneHanded() {
|
||||||
mMainExecutor.execute(() -> {
|
mMainExecutor.execute(() -> {
|
||||||
@@ -767,7 +764,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
|
|||||||
* The interface for calls from outside the host process.
|
* The interface for calls from outside the host process.
|
||||||
*/
|
*/
|
||||||
@BinderThread
|
@BinderThread
|
||||||
private static class IOneHandedImpl extends IOneHanded.Stub {
|
private static class IOneHandedImpl extends IOneHanded.Stub implements ExternalInterfaceBinder {
|
||||||
private OneHandedController mController;
|
private OneHandedController mController;
|
||||||
|
|
||||||
IOneHandedImpl(OneHandedController controller) {
|
IOneHandedImpl(OneHandedController controller) {
|
||||||
@@ -777,7 +774,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
|
|||||||
/**
|
/**
|
||||||
* Invalidates this instance, preventing future calls from updating the controller.
|
* Invalidates this instance, preventing future calls from updating the controller.
|
||||||
*/
|
*/
|
||||||
void invalidate() {
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
mController = null;
|
mController = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,14 +27,6 @@ import java.util.function.Consumer;
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
public interface Pip {
|
public interface Pip {
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a binder that can be passed to an external process to manipulate PIP.
|
|
||||||
*/
|
|
||||||
default IPip createExternalInterface() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand PIP, it's possible that specific request to activate the window via Alt-tab.
|
* Expand PIP, it's possible that specific request to activate the window via Alt-tab.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTI
|
|||||||
import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
|
import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
|
||||||
import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_USER_RESIZE;
|
import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_USER_RESIZE;
|
||||||
import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection;
|
import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection;
|
||||||
|
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_PIP;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityTaskManager;
|
import android.app.ActivityTaskManager;
|
||||||
@@ -68,6 +69,7 @@ import com.android.wm.shell.common.DisplayChangeController;
|
|||||||
import com.android.wm.shell.common.DisplayController;
|
import com.android.wm.shell.common.DisplayController;
|
||||||
import com.android.wm.shell.common.DisplayInsetsController;
|
import com.android.wm.shell.common.DisplayInsetsController;
|
||||||
import com.android.wm.shell.common.DisplayLayout;
|
import com.android.wm.shell.common.DisplayLayout;
|
||||||
|
import com.android.wm.shell.common.ExternalInterfaceBinder;
|
||||||
import com.android.wm.shell.common.RemoteCallable;
|
import com.android.wm.shell.common.RemoteCallable;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.SingleInstanceRemoteListener;
|
import com.android.wm.shell.common.SingleInstanceRemoteListener;
|
||||||
@@ -632,6 +634,12 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
|||||||
mShellController.addConfigurationChangeListener(this);
|
mShellController.addConfigurationChangeListener(this);
|
||||||
mShellController.addKeyguardChangeListener(this);
|
mShellController.addKeyguardChangeListener(this);
|
||||||
mShellController.addUserChangeListener(this);
|
mShellController.addUserChangeListener(this);
|
||||||
|
mShellController.addExternalInterface(KEY_EXTRA_SHELL_PIP,
|
||||||
|
this::createExternalInterface, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExternalInterfaceBinder createExternalInterface() {
|
||||||
|
return new IPipImpl(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1040,17 +1048,6 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
|||||||
* The interface for calls from outside the Shell, within the host process.
|
* The interface for calls from outside the Shell, within the host process.
|
||||||
*/
|
*/
|
||||||
private class PipImpl implements Pip {
|
private class PipImpl implements Pip {
|
||||||
private IPipImpl mIPip;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPip createExternalInterface() {
|
|
||||||
if (mIPip != null) {
|
|
||||||
mIPip.invalidate();
|
|
||||||
}
|
|
||||||
mIPip = new IPipImpl(PipController.this);
|
|
||||||
return mIPip;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void expandPip() {
|
public void expandPip() {
|
||||||
mMainExecutor.execute(() -> {
|
mMainExecutor.execute(() -> {
|
||||||
@@ -1098,7 +1095,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
|||||||
* The interface for calls from outside the host process.
|
* The interface for calls from outside the host process.
|
||||||
*/
|
*/
|
||||||
@BinderThread
|
@BinderThread
|
||||||
private static class IPipImpl extends IPip.Stub {
|
private static class IPipImpl extends IPip.Stub implements ExternalInterfaceBinder {
|
||||||
private PipController mController;
|
private PipController mController;
|
||||||
private final SingleInstanceRemoteListener<PipController,
|
private final SingleInstanceRemoteListener<PipController,
|
||||||
IPipAnimationListener> mListener;
|
IPipAnimationListener> mListener;
|
||||||
@@ -1129,7 +1126,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
|||||||
/**
|
/**
|
||||||
* Invalidates this instance, preventing future calls from updating the controller.
|
* Invalidates this instance, preventing future calls from updating the controller.
|
||||||
*/
|
*/
|
||||||
void invalidate() {
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
mController = null;
|
mController = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,13 +28,6 @@ import java.util.function.Consumer;
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
public interface RecentTasks {
|
public interface RecentTasks {
|
||||||
/**
|
|
||||||
* Returns a binder that can be passed to an external process to fetch recent tasks.
|
|
||||||
*/
|
|
||||||
default IRecentTasks createExternalInterface() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the set of recent tasks.
|
* Gets the set of recent tasks.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
|||||||
import static android.content.pm.PackageManager.FEATURE_PC;
|
import static android.content.pm.PackageManager.FEATURE_PC;
|
||||||
|
|
||||||
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
||||||
|
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_RECENT_TASKS;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityTaskManager;
|
import android.app.ActivityTaskManager;
|
||||||
@@ -37,6 +38,7 @@ import androidx.annotation.Nullable;
|
|||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
|
import com.android.wm.shell.common.ExternalInterfaceBinder;
|
||||||
import com.android.wm.shell.common.RemoteCallable;
|
import com.android.wm.shell.common.RemoteCallable;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.SingleInstanceRemoteListener;
|
import com.android.wm.shell.common.SingleInstanceRemoteListener;
|
||||||
@@ -48,6 +50,7 @@ import com.android.wm.shell.desktopmode.DesktopModeStatus;
|
|||||||
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
|
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
|
||||||
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||||
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
import com.android.wm.shell.util.GroupedRecentTaskInfo;
|
import com.android.wm.shell.util.GroupedRecentTaskInfo;
|
||||||
import com.android.wm.shell.util.SplitBounds;
|
import com.android.wm.shell.util.SplitBounds;
|
||||||
@@ -69,11 +72,12 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
private static final String TAG = RecentTasksController.class.getSimpleName();
|
private static final String TAG = RecentTasksController.class.getSimpleName();
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
private final ShellController mShellController;
|
||||||
private final ShellCommandHandler mShellCommandHandler;
|
private final ShellCommandHandler mShellCommandHandler;
|
||||||
private final Optional<DesktopModeTaskRepository> mDesktopModeTaskRepository;
|
private final Optional<DesktopModeTaskRepository> mDesktopModeTaskRepository;
|
||||||
private final ShellExecutor mMainExecutor;
|
private final ShellExecutor mMainExecutor;
|
||||||
private final TaskStackListenerImpl mTaskStackListener;
|
private final TaskStackListenerImpl mTaskStackListener;
|
||||||
private final RecentTasks mImpl = new RecentTasksImpl();
|
private final RecentTasksImpl mImpl = new RecentTasksImpl();
|
||||||
private final ActivityTaskManager mActivityTaskManager;
|
private final ActivityTaskManager mActivityTaskManager;
|
||||||
private IRecentTasksListener mListener;
|
private IRecentTasksListener mListener;
|
||||||
private final boolean mIsDesktopMode;
|
private final boolean mIsDesktopMode;
|
||||||
@@ -97,6 +101,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
public static RecentTasksController create(
|
public static RecentTasksController create(
|
||||||
Context context,
|
Context context,
|
||||||
ShellInit shellInit,
|
ShellInit shellInit,
|
||||||
|
ShellController shellController,
|
||||||
ShellCommandHandler shellCommandHandler,
|
ShellCommandHandler shellCommandHandler,
|
||||||
TaskStackListenerImpl taskStackListener,
|
TaskStackListenerImpl taskStackListener,
|
||||||
ActivityTaskManager activityTaskManager,
|
ActivityTaskManager activityTaskManager,
|
||||||
@@ -106,18 +111,20 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
if (!context.getResources().getBoolean(com.android.internal.R.bool.config_hasRecents)) {
|
if (!context.getResources().getBoolean(com.android.internal.R.bool.config_hasRecents)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new RecentTasksController(context, shellInit, shellCommandHandler, taskStackListener,
|
return new RecentTasksController(context, shellInit, shellController, shellCommandHandler,
|
||||||
activityTaskManager, desktopModeTaskRepository, mainExecutor);
|
taskStackListener, activityTaskManager, desktopModeTaskRepository, mainExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
RecentTasksController(Context context,
|
RecentTasksController(Context context,
|
||||||
ShellInit shellInit,
|
ShellInit shellInit,
|
||||||
|
ShellController shellController,
|
||||||
ShellCommandHandler shellCommandHandler,
|
ShellCommandHandler shellCommandHandler,
|
||||||
TaskStackListenerImpl taskStackListener,
|
TaskStackListenerImpl taskStackListener,
|
||||||
ActivityTaskManager activityTaskManager,
|
ActivityTaskManager activityTaskManager,
|
||||||
Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
|
Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
|
||||||
ShellExecutor mainExecutor) {
|
ShellExecutor mainExecutor) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mShellController = shellController;
|
||||||
mShellCommandHandler = shellCommandHandler;
|
mShellCommandHandler = shellCommandHandler;
|
||||||
mActivityTaskManager = activityTaskManager;
|
mActivityTaskManager = activityTaskManager;
|
||||||
mIsDesktopMode = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
|
mIsDesktopMode = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
|
||||||
@@ -131,7 +138,13 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
return mImpl;
|
return mImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExternalInterfaceBinder createExternalInterface() {
|
||||||
|
return new IRecentTasksImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
private void onInit() {
|
private void onInit() {
|
||||||
|
mShellController.addExternalInterface(KEY_EXTRA_SHELL_RECENT_TASKS,
|
||||||
|
this::createExternalInterface, this);
|
||||||
mShellCommandHandler.addDumpCallback(this::dump, this);
|
mShellCommandHandler.addDumpCallback(this::dump, this);
|
||||||
mTaskStackListener.addListener(this);
|
mTaskStackListener.addListener(this);
|
||||||
mDesktopModeTaskRepository.ifPresent(it -> it.addListener(this));
|
mDesktopModeTaskRepository.ifPresent(it -> it.addListener(this));
|
||||||
@@ -366,17 +379,6 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
private class RecentTasksImpl implements RecentTasks {
|
private class RecentTasksImpl implements RecentTasks {
|
||||||
private IRecentTasksImpl mIRecentTasks;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IRecentTasks createExternalInterface() {
|
|
||||||
if (mIRecentTasks != null) {
|
|
||||||
mIRecentTasks.invalidate();
|
|
||||||
}
|
|
||||||
mIRecentTasks = new IRecentTasksImpl(RecentTasksController.this);
|
|
||||||
return mIRecentTasks;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getRecentTasks(int maxNum, int flags, int userId, Executor executor,
|
public void getRecentTasks(int maxNum, int flags, int userId, Executor executor,
|
||||||
Consumer<List<GroupedRecentTaskInfo>> callback) {
|
Consumer<List<GroupedRecentTaskInfo>> callback) {
|
||||||
@@ -393,7 +395,8 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
* The interface for calls from outside the host process.
|
* The interface for calls from outside the host process.
|
||||||
*/
|
*/
|
||||||
@BinderThread
|
@BinderThread
|
||||||
private static class IRecentTasksImpl extends IRecentTasks.Stub {
|
private static class IRecentTasksImpl extends IRecentTasks.Stub
|
||||||
|
implements ExternalInterfaceBinder {
|
||||||
private RecentTasksController mController;
|
private RecentTasksController mController;
|
||||||
private final SingleInstanceRemoteListener<RecentTasksController,
|
private final SingleInstanceRemoteListener<RecentTasksController,
|
||||||
IRecentTasksListener> mListener;
|
IRecentTasksListener> mListener;
|
||||||
@@ -424,7 +427,8 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
/**
|
/**
|
||||||
* Invalidates this instance, preventing future calls from updating the controller.
|
* Invalidates this instance, preventing future calls from updating the controller.
|
||||||
*/
|
*/
|
||||||
void invalidate() {
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
mController = null;
|
mController = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,13 +70,6 @@ public interface SplitScreen {
|
|||||||
/** Unregisters listener that gets split screen callback. */
|
/** Unregisters listener that gets split screen callback. */
|
||||||
void unregisterSplitScreenListener(@NonNull SplitScreenListener listener);
|
void unregisterSplitScreenListener(@NonNull SplitScreenListener listener);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a binder that can be passed to an external process to manipulate SplitScreen.
|
|
||||||
*/
|
|
||||||
default ISplitScreen createExternalInterface() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called when device waking up finished. */
|
/** Called when device waking up finished. */
|
||||||
void onFinishedWakingUp();
|
void onFinishedWakingUp();
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT
|
|||||||
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
|
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
|
||||||
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
|
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
|
||||||
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
|
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
|
||||||
|
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SPLIT_SCREEN;
|
||||||
import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
|
import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
@@ -71,6 +72,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
|
|||||||
import com.android.wm.shell.common.DisplayController;
|
import com.android.wm.shell.common.DisplayController;
|
||||||
import com.android.wm.shell.common.DisplayImeController;
|
import com.android.wm.shell.common.DisplayImeController;
|
||||||
import com.android.wm.shell.common.DisplayInsetsController;
|
import com.android.wm.shell.common.DisplayInsetsController;
|
||||||
|
import com.android.wm.shell.common.ExternalInterfaceBinder;
|
||||||
import com.android.wm.shell.common.RemoteCallable;
|
import com.android.wm.shell.common.RemoteCallable;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.SingleInstanceRemoteListener;
|
import com.android.wm.shell.common.SingleInstanceRemoteListener;
|
||||||
@@ -214,6 +216,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
return mImpl;
|
return mImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExternalInterfaceBinder createExternalInterface() {
|
||||||
|
return new ISplitScreenImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will be called after ShellTaskOrganizer has initialized/registered because of the
|
* This will be called after ShellTaskOrganizer has initialized/registered because of the
|
||||||
* dependency order.
|
* dependency order.
|
||||||
@@ -224,6 +230,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
mShellCommandHandler.addCommandCallback("splitscreen", mSplitScreenShellCommandHandler,
|
mShellCommandHandler.addCommandCallback("splitscreen", mSplitScreenShellCommandHandler,
|
||||||
this);
|
this);
|
||||||
mShellController.addKeyguardChangeListener(this);
|
mShellController.addKeyguardChangeListener(this);
|
||||||
|
mShellController.addExternalInterface(KEY_EXTRA_SHELL_SPLIT_SCREEN,
|
||||||
|
this::createExternalInterface, this);
|
||||||
if (mStageCoordinator == null) {
|
if (mStageCoordinator == null) {
|
||||||
// TODO: Multi-display
|
// TODO: Multi-display
|
||||||
mStageCoordinator = createStageCoordinator();
|
mStageCoordinator = createStageCoordinator();
|
||||||
@@ -658,7 +666,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
private class SplitScreenImpl implements SplitScreen {
|
private class SplitScreenImpl implements SplitScreen {
|
||||||
private ISplitScreenImpl mISplitScreen;
|
|
||||||
private final ArrayMap<SplitScreenListener, Executor> mExecutors = new ArrayMap<>();
|
private final ArrayMap<SplitScreenListener, Executor> mExecutors = new ArrayMap<>();
|
||||||
private final SplitScreen.SplitScreenListener mListener = new SplitScreenListener() {
|
private final SplitScreen.SplitScreenListener mListener = new SplitScreenListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -703,15 +710,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
|
||||||
public ISplitScreen createExternalInterface() {
|
|
||||||
if (mISplitScreen != null) {
|
|
||||||
mISplitScreen.invalidate();
|
|
||||||
}
|
|
||||||
mISplitScreen = new ISplitScreenImpl(SplitScreenController.this);
|
|
||||||
return mISplitScreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerSplitScreenListener(SplitScreenListener listener, Executor executor) {
|
public void registerSplitScreenListener(SplitScreenListener listener, Executor executor) {
|
||||||
if (mExecutors.containsKey(listener)) return;
|
if (mExecutors.containsKey(listener)) return;
|
||||||
@@ -752,7 +750,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
* The interface for calls from outside the host process.
|
* The interface for calls from outside the host process.
|
||||||
*/
|
*/
|
||||||
@BinderThread
|
@BinderThread
|
||||||
private static class ISplitScreenImpl extends ISplitScreen.Stub {
|
private static class ISplitScreenImpl extends ISplitScreen.Stub
|
||||||
|
implements ExternalInterfaceBinder {
|
||||||
private SplitScreenController mController;
|
private SplitScreenController mController;
|
||||||
private final SingleInstanceRemoteListener<SplitScreenController,
|
private final SingleInstanceRemoteListener<SplitScreenController,
|
||||||
ISplitScreenListener> mListener;
|
ISplitScreenListener> mListener;
|
||||||
@@ -779,7 +778,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
/**
|
/**
|
||||||
* Invalidates this instance, preventing future calls from updating the controller.
|
* Invalidates this instance, preventing future calls from updating the controller.
|
||||||
*/
|
*/
|
||||||
void invalidate() {
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
mController = null;
|
mController = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,14 +22,6 @@ import android.graphics.Color;
|
|||||||
* Interface to engage starting window feature.
|
* Interface to engage starting window feature.
|
||||||
*/
|
*/
|
||||||
public interface StartingSurface {
|
public interface StartingSurface {
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a binder that can be passed to an external process to manipulate starting windows.
|
|
||||||
*/
|
|
||||||
default IStartingWindow createExternalInterface() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the background color for a starting window if existing.
|
* Returns the background color for a starting window if existing.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SOLID_COLOR
|
|||||||
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
|
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
|
||||||
|
|
||||||
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
||||||
|
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_STARTING_WINDOW;
|
||||||
|
|
||||||
import android.app.ActivityManager.RunningTaskInfo;
|
import android.app.ActivityManager.RunningTaskInfo;
|
||||||
import android.app.TaskInfo;
|
import android.app.TaskInfo;
|
||||||
@@ -43,10 +44,12 @@ import com.android.internal.annotations.GuardedBy;
|
|||||||
import com.android.internal.util.function.TriConsumer;
|
import com.android.internal.util.function.TriConsumer;
|
||||||
import com.android.launcher3.icons.IconProvider;
|
import com.android.launcher3.icons.IconProvider;
|
||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
|
import com.android.wm.shell.common.ExternalInterfaceBinder;
|
||||||
import com.android.wm.shell.common.RemoteCallable;
|
import com.android.wm.shell.common.RemoteCallable;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.SingleInstanceRemoteListener;
|
import com.android.wm.shell.common.SingleInstanceRemoteListener;
|
||||||
import com.android.wm.shell.common.TransactionPool;
|
import com.android.wm.shell.common.TransactionPool;
|
||||||
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,6 +79,7 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
|
|||||||
private TriConsumer<Integer, Integer, Integer> mTaskLaunchingCallback;
|
private TriConsumer<Integer, Integer, Integer> mTaskLaunchingCallback;
|
||||||
private final StartingSurfaceImpl mImpl = new StartingSurfaceImpl();
|
private final StartingSurfaceImpl mImpl = new StartingSurfaceImpl();
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
private final ShellController mShellController;
|
||||||
private final ShellTaskOrganizer mShellTaskOrganizer;
|
private final ShellTaskOrganizer mShellTaskOrganizer;
|
||||||
private final ShellExecutor mSplashScreenExecutor;
|
private final ShellExecutor mSplashScreenExecutor;
|
||||||
/**
|
/**
|
||||||
@@ -86,12 +90,14 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
|
|||||||
|
|
||||||
public StartingWindowController(Context context,
|
public StartingWindowController(Context context,
|
||||||
ShellInit shellInit,
|
ShellInit shellInit,
|
||||||
|
ShellController shellController,
|
||||||
ShellTaskOrganizer shellTaskOrganizer,
|
ShellTaskOrganizer shellTaskOrganizer,
|
||||||
ShellExecutor splashScreenExecutor,
|
ShellExecutor splashScreenExecutor,
|
||||||
StartingWindowTypeAlgorithm startingWindowTypeAlgorithm,
|
StartingWindowTypeAlgorithm startingWindowTypeAlgorithm,
|
||||||
IconProvider iconProvider,
|
IconProvider iconProvider,
|
||||||
TransactionPool pool) {
|
TransactionPool pool) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mShellController = shellController;
|
||||||
mShellTaskOrganizer = shellTaskOrganizer;
|
mShellTaskOrganizer = shellTaskOrganizer;
|
||||||
mStartingSurfaceDrawer = new StartingSurfaceDrawer(context, splashScreenExecutor,
|
mStartingSurfaceDrawer = new StartingSurfaceDrawer(context, splashScreenExecutor,
|
||||||
iconProvider, pool);
|
iconProvider, pool);
|
||||||
@@ -107,8 +113,14 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
|
|||||||
return mImpl;
|
return mImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExternalInterfaceBinder createExternalInterface() {
|
||||||
|
return new IStartingWindowImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
private void onInit() {
|
private void onInit() {
|
||||||
mShellTaskOrganizer.initStartingWindow(this);
|
mShellTaskOrganizer.initStartingWindow(this);
|
||||||
|
mShellController.addExternalInterface(KEY_EXTRA_SHELL_STARTING_WINDOW,
|
||||||
|
this::createExternalInterface, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -222,17 +234,6 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
|
|||||||
* The interface for calls from outside the Shell, within the host process.
|
* The interface for calls from outside the Shell, within the host process.
|
||||||
*/
|
*/
|
||||||
private class StartingSurfaceImpl implements StartingSurface {
|
private class StartingSurfaceImpl implements StartingSurface {
|
||||||
private IStartingWindowImpl mIStartingWindow;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IStartingWindowImpl createExternalInterface() {
|
|
||||||
if (mIStartingWindow != null) {
|
|
||||||
mIStartingWindow.invalidate();
|
|
||||||
}
|
|
||||||
mIStartingWindow = new IStartingWindowImpl(StartingWindowController.this);
|
|
||||||
return mIStartingWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBackgroundColor(TaskInfo taskInfo) {
|
public int getBackgroundColor(TaskInfo taskInfo) {
|
||||||
synchronized (mTaskBackgroundColors) {
|
synchronized (mTaskBackgroundColors) {
|
||||||
@@ -256,7 +257,8 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
|
|||||||
* The interface for calls from outside the host process.
|
* The interface for calls from outside the host process.
|
||||||
*/
|
*/
|
||||||
@BinderThread
|
@BinderThread
|
||||||
private static class IStartingWindowImpl extends IStartingWindow.Stub {
|
private static class IStartingWindowImpl extends IStartingWindow.Stub
|
||||||
|
implements ExternalInterfaceBinder {
|
||||||
private StartingWindowController mController;
|
private StartingWindowController mController;
|
||||||
private SingleInstanceRemoteListener<StartingWindowController,
|
private SingleInstanceRemoteListener<StartingWindowController,
|
||||||
IStartingWindowListener> mListener;
|
IStartingWindowListener> mListener;
|
||||||
@@ -276,7 +278,8 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
|
|||||||
/**
|
/**
|
||||||
* Invalidates this instance, preventing future calls from updating the controller.
|
* Invalidates this instance, preventing future calls from updating the controller.
|
||||||
*/
|
*/
|
||||||
void invalidate() {
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
mController = null;
|
mController = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,23 +23,28 @@ import static android.content.pm.ActivityInfo.CONFIG_LOCALE;
|
|||||||
import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
|
import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
|
||||||
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
|
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
|
||||||
|
|
||||||
|
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_INIT;
|
||||||
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SYSUI_EVENTS;
|
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SYSUI_EVENTS;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.ArrayMap;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
|
import com.android.wm.shell.common.ExternalInterfaceBinder;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles event callbacks from SysUI that can be used within the Shell.
|
* Handles event callbacks from SysUI that can be used within the Shell.
|
||||||
@@ -59,6 +64,11 @@ public class ShellController {
|
|||||||
private final CopyOnWriteArrayList<UserChangeListener> mUserChangeListeners =
|
private final CopyOnWriteArrayList<UserChangeListener> mUserChangeListeners =
|
||||||
new CopyOnWriteArrayList<>();
|
new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
private ArrayMap<String, Supplier<ExternalInterfaceBinder>> mExternalInterfaceSuppliers =
|
||||||
|
new ArrayMap<>();
|
||||||
|
// References to the existing interfaces, to be invalidated when they are recreated
|
||||||
|
private ArrayMap<String, ExternalInterfaceBinder> mExternalInterfaces = new ArrayMap<>();
|
||||||
|
|
||||||
private Configuration mLastConfiguration;
|
private Configuration mLastConfiguration;
|
||||||
|
|
||||||
|
|
||||||
@@ -67,6 +77,11 @@ public class ShellController {
|
|||||||
mShellInit = shellInit;
|
mShellInit = shellInit;
|
||||||
mShellCommandHandler = shellCommandHandler;
|
mShellCommandHandler = shellCommandHandler;
|
||||||
mMainExecutor = mainExecutor;
|
mMainExecutor = mainExecutor;
|
||||||
|
shellInit.addInitCallback(this::onInit, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onInit() {
|
||||||
|
mShellCommandHandler.addDumpCallback(this::dump, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,6 +139,47 @@ public class ShellController {
|
|||||||
mUserChangeListeners.remove(listener);
|
mUserChangeListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an interface that can be called from a remote process. This method takes a supplier
|
||||||
|
* because each binder reference is valid for a single process, and in multi-user mode, SysUI
|
||||||
|
* will request new binder instances for each instance of Launcher that it provides binders
|
||||||
|
* to.
|
||||||
|
*
|
||||||
|
* @param extra the key for the interface, {@see ShellSharedConstants}
|
||||||
|
* @param binderSupplier the supplier of the binder to pass to the external process
|
||||||
|
* @param callerInstance the instance of the caller, purely for logging
|
||||||
|
*/
|
||||||
|
public void addExternalInterface(String extra, Supplier<ExternalInterfaceBinder> binderSupplier,
|
||||||
|
Object callerInstance) {
|
||||||
|
ProtoLog.v(WM_SHELL_INIT, "Adding external interface from %s with key %s",
|
||||||
|
callerInstance.getClass().getSimpleName(), extra);
|
||||||
|
if (mExternalInterfaceSuppliers.containsKey(extra)) {
|
||||||
|
throw new IllegalArgumentException("Supplier with same key already exists: "
|
||||||
|
+ extra);
|
||||||
|
}
|
||||||
|
mExternalInterfaceSuppliers.put(extra, binderSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the given bundle with the set of external interfaces, invalidating the old set of
|
||||||
|
* binders.
|
||||||
|
*/
|
||||||
|
private void createExternalInterfaces(Bundle output) {
|
||||||
|
// Invalidate the old binders
|
||||||
|
for (int i = 0; i < mExternalInterfaces.size(); i++) {
|
||||||
|
mExternalInterfaces.valueAt(i).invalidate();
|
||||||
|
}
|
||||||
|
mExternalInterfaces.clear();
|
||||||
|
|
||||||
|
// Create new binders for each key
|
||||||
|
for (int i = 0; i < mExternalInterfaceSuppliers.size(); i++) {
|
||||||
|
final String key = mExternalInterfaceSuppliers.keyAt(i);
|
||||||
|
final ExternalInterfaceBinder b = mExternalInterfaceSuppliers.valueAt(i).get();
|
||||||
|
mExternalInterfaces.put(key, b);
|
||||||
|
output.putBinder(key, b.asBinder());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void onConfigurationChanged(Configuration newConfig) {
|
void onConfigurationChanged(Configuration newConfig) {
|
||||||
// The initial config is send on startup and doesn't trigger listener callbacks
|
// The initial config is send on startup and doesn't trigger listener callbacks
|
||||||
@@ -204,6 +260,14 @@ public class ShellController {
|
|||||||
pw.println(innerPrefix + "mLastConfiguration=" + mLastConfiguration);
|
pw.println(innerPrefix + "mLastConfiguration=" + mLastConfiguration);
|
||||||
pw.println(innerPrefix + "mKeyguardChangeListeners=" + mKeyguardChangeListeners.size());
|
pw.println(innerPrefix + "mKeyguardChangeListeners=" + mKeyguardChangeListeners.size());
|
||||||
pw.println(innerPrefix + "mUserChangeListeners=" + mUserChangeListeners.size());
|
pw.println(innerPrefix + "mUserChangeListeners=" + mUserChangeListeners.size());
|
||||||
|
|
||||||
|
if (!mExternalInterfaces.isEmpty()) {
|
||||||
|
pw.println(innerPrefix + "mExternalInterfaces={");
|
||||||
|
for (String key : mExternalInterfaces.keySet()) {
|
||||||
|
pw.println(innerPrefix + "\t" + key + ": " + mExternalInterfaces.get(key));
|
||||||
|
}
|
||||||
|
pw.println(innerPrefix + "}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,7 +275,6 @@ public class ShellController {
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
private class ShellInterfaceImpl implements ShellInterface {
|
private class ShellInterfaceImpl implements ShellInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInit() {
|
public void onInit() {
|
||||||
try {
|
try {
|
||||||
@@ -221,28 +284,6 @@ public class ShellController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dump(PrintWriter pw) {
|
|
||||||
try {
|
|
||||||
mMainExecutor.executeBlocking(() -> mShellCommandHandler.dump(pw));
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException("Failed to dump the Shell in 2s", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean handleCommand(String[] args, PrintWriter pw) {
|
|
||||||
try {
|
|
||||||
boolean[] result = new boolean[1];
|
|
||||||
mMainExecutor.executeBlocking(() -> {
|
|
||||||
result[0] = mShellCommandHandler.handleCommand(args, pw);
|
|
||||||
});
|
|
||||||
return result[0];
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException("Failed to handle Shell command in 2s", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigurationChanged(Configuration newConfiguration) {
|
public void onConfigurationChanged(Configuration newConfiguration) {
|
||||||
mMainExecutor.execute(() ->
|
mMainExecutor.execute(() ->
|
||||||
@@ -274,5 +315,38 @@ public class ShellController {
|
|||||||
mMainExecutor.execute(() ->
|
mMainExecutor.execute(() ->
|
||||||
ShellController.this.onUserProfilesChanged(profiles));
|
ShellController.this.onUserProfilesChanged(profiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleCommand(String[] args, PrintWriter pw) {
|
||||||
|
try {
|
||||||
|
boolean[] result = new boolean[1];
|
||||||
|
mMainExecutor.executeBlocking(() -> {
|
||||||
|
result[0] = mShellCommandHandler.handleCommand(args, pw);
|
||||||
|
});
|
||||||
|
return result[0];
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException("Failed to handle Shell command in 2s", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createExternalInterfaces(Bundle bundle) {
|
||||||
|
try {
|
||||||
|
mMainExecutor.executeBlocking(() -> {
|
||||||
|
ShellController.this.createExternalInterfaces(bundle);
|
||||||
|
});
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException("Failed to get Shell command in 2s", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dump(PrintWriter pw) {
|
||||||
|
try {
|
||||||
|
mMainExecutor.executeBlocking(() -> mShellCommandHandler.dump(pw));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException("Failed to dump the Shell in 2s", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.wm.shell.sysui;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
@@ -36,18 +37,6 @@ public interface ShellInterface {
|
|||||||
*/
|
*/
|
||||||
default void onInit() {}
|
default void onInit() {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Dumps the shell state.
|
|
||||||
*/
|
|
||||||
default void dump(PrintWriter pw) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles a shell command.
|
|
||||||
*/
|
|
||||||
default boolean handleCommand(final String[] args, PrintWriter pw) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the Shell that the configuration has changed.
|
* Notifies the Shell that the configuration has changed.
|
||||||
*/
|
*/
|
||||||
@@ -74,4 +63,21 @@ public interface ShellInterface {
|
|||||||
* Notifies the Shell when a profile belonging to the user changes.
|
* Notifies the Shell when a profile belonging to the user changes.
|
||||||
*/
|
*/
|
||||||
default void onUserProfilesChanged(@NonNull List<UserInfo> profiles) {}
|
default void onUserProfilesChanged(@NonNull List<UserInfo> profiles) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a shell command.
|
||||||
|
*/
|
||||||
|
default boolean handleCommand(final String[] args, PrintWriter pw) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the given {@param bundle} with the set of exposed interfaces.
|
||||||
|
*/
|
||||||
|
default void createExternalInterfaces(Bundle bundle) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dumps the shell state.
|
||||||
|
*/
|
||||||
|
default void dump(PrintWriter pw) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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 com.android.wm.shell.sysui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General shell-related constants that are shared with users of the library.
|
||||||
|
*/
|
||||||
|
public class ShellSharedConstants {
|
||||||
|
// See IPip.aidl
|
||||||
|
public static final String KEY_EXTRA_SHELL_PIP = "extra_shell_pip";
|
||||||
|
// See ISplitScreen.aidl
|
||||||
|
public static final String KEY_EXTRA_SHELL_SPLIT_SCREEN = "extra_shell_split_screen";
|
||||||
|
// See IOneHanded.aidl
|
||||||
|
public static final String KEY_EXTRA_SHELL_ONE_HANDED = "extra_shell_one_handed";
|
||||||
|
// See IShellTransitions.aidl
|
||||||
|
public static final String KEY_EXTRA_SHELL_SHELL_TRANSITIONS =
|
||||||
|
"extra_shell_shell_transitions";
|
||||||
|
// See IStartingWindow.aidl
|
||||||
|
public static final String KEY_EXTRA_SHELL_STARTING_WINDOW =
|
||||||
|
"extra_shell_starting_window";
|
||||||
|
// See IRecentTasks.aidl
|
||||||
|
public static final String KEY_EXTRA_SHELL_RECENT_TASKS = "extra_shell_recent_tasks";
|
||||||
|
// See IBackAnimation.aidl
|
||||||
|
public static final String KEY_EXTRA_SHELL_BACK_ANIMATION = "extra_shell_back_animation";
|
||||||
|
// See IFloatingTasks.aidl
|
||||||
|
public static final String KEY_EXTRA_SHELL_FLOATING_TASKS = "extra_shell_floating_tasks";
|
||||||
|
// See IDesktopMode.aidl
|
||||||
|
public static final String KEY_EXTRA_SHELL_DESKTOP_MODE = "extra_shell_desktop_mode";
|
||||||
|
}
|
||||||
@@ -27,14 +27,6 @@ import com.android.wm.shell.common.annotations.ExternalThread;
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
public interface ShellTransitions {
|
public interface ShellTransitions {
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a binder that can be passed to an external process to manipulate remote transitions.
|
|
||||||
*/
|
|
||||||
default IShellTransitions createExternalInterface() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a remote transition.
|
* Registers a remote transition.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
|
|||||||
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
|
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
|
||||||
|
|
||||||
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
||||||
|
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SHELL_TRANSITIONS;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
@@ -61,11 +62,13 @@ import com.android.internal.R;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
import com.android.wm.shell.common.DisplayController;
|
import com.android.wm.shell.common.DisplayController;
|
||||||
|
import com.android.wm.shell.common.ExternalInterfaceBinder;
|
||||||
import com.android.wm.shell.common.RemoteCallable;
|
import com.android.wm.shell.common.RemoteCallable;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.TransactionPool;
|
import com.android.wm.shell.common.TransactionPool;
|
||||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||||
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||||
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -115,6 +118,7 @@ public class Transitions implements RemoteCallable<Transitions> {
|
|||||||
private final DefaultTransitionHandler mDefaultTransitionHandler;
|
private final DefaultTransitionHandler mDefaultTransitionHandler;
|
||||||
private final RemoteTransitionHandler mRemoteTransitionHandler;
|
private final RemoteTransitionHandler mRemoteTransitionHandler;
|
||||||
private final DisplayController mDisplayController;
|
private final DisplayController mDisplayController;
|
||||||
|
private final ShellController mShellController;
|
||||||
private final ShellTransitionImpl mImpl = new ShellTransitionImpl();
|
private final ShellTransitionImpl mImpl = new ShellTransitionImpl();
|
||||||
|
|
||||||
/** List of possible handlers. Ordered by specificity (eg. tapped back to front). */
|
/** List of possible handlers. Ordered by specificity (eg. tapped back to front). */
|
||||||
@@ -142,6 +146,7 @@ public class Transitions implements RemoteCallable<Transitions> {
|
|||||||
|
|
||||||
public Transitions(@NonNull Context context,
|
public Transitions(@NonNull Context context,
|
||||||
@NonNull ShellInit shellInit,
|
@NonNull ShellInit shellInit,
|
||||||
|
@NonNull ShellController shellController,
|
||||||
@NonNull WindowOrganizer organizer,
|
@NonNull WindowOrganizer organizer,
|
||||||
@NonNull TransactionPool pool,
|
@NonNull TransactionPool pool,
|
||||||
@NonNull DisplayController displayController,
|
@NonNull DisplayController displayController,
|
||||||
@@ -156,10 +161,14 @@ public class Transitions implements RemoteCallable<Transitions> {
|
|||||||
mDefaultTransitionHandler = new DefaultTransitionHandler(context, shellInit,
|
mDefaultTransitionHandler = new DefaultTransitionHandler(context, shellInit,
|
||||||
displayController, pool, mainExecutor, mainHandler, animExecutor);
|
displayController, pool, mainExecutor, mainHandler, animExecutor);
|
||||||
mRemoteTransitionHandler = new RemoteTransitionHandler(mMainExecutor);
|
mRemoteTransitionHandler = new RemoteTransitionHandler(mMainExecutor);
|
||||||
|
mShellController = shellController;
|
||||||
shellInit.addInitCallback(this::onInit, this);
|
shellInit.addInitCallback(this::onInit, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onInit() {
|
private void onInit() {
|
||||||
|
mShellController.addExternalInterface(KEY_EXTRA_SHELL_SHELL_TRANSITIONS,
|
||||||
|
this::createExternalInterface, this);
|
||||||
|
|
||||||
// The very last handler (0 in the list) should be the default one.
|
// The very last handler (0 in the list) should be the default one.
|
||||||
mHandlers.add(mDefaultTransitionHandler);
|
mHandlers.add(mDefaultTransitionHandler);
|
||||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "addHandler: Default");
|
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "addHandler: Default");
|
||||||
@@ -193,6 +202,10 @@ public class Transitions implements RemoteCallable<Transitions> {
|
|||||||
return mImpl;
|
return mImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExternalInterfaceBinder createExternalInterface() {
|
||||||
|
return new IShellTransitionsImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Context getContext() {
|
public Context getContext() {
|
||||||
return mContext;
|
return mContext;
|
||||||
@@ -897,17 +910,6 @@ public class Transitions implements RemoteCallable<Transitions> {
|
|||||||
*/
|
*/
|
||||||
@ExternalThread
|
@ExternalThread
|
||||||
private class ShellTransitionImpl implements ShellTransitions {
|
private class ShellTransitionImpl implements ShellTransitions {
|
||||||
private IShellTransitionsImpl mIShellTransitions;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IShellTransitions createExternalInterface() {
|
|
||||||
if (mIShellTransitions != null) {
|
|
||||||
mIShellTransitions.invalidate();
|
|
||||||
}
|
|
||||||
mIShellTransitions = new IShellTransitionsImpl(Transitions.this);
|
|
||||||
return mIShellTransitions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerRemote(@NonNull TransitionFilter filter,
|
public void registerRemote(@NonNull TransitionFilter filter,
|
||||||
@NonNull RemoteTransition remoteTransition) {
|
@NonNull RemoteTransition remoteTransition) {
|
||||||
@@ -928,7 +930,8 @@ public class Transitions implements RemoteCallable<Transitions> {
|
|||||||
* The interface for calls from outside the host process.
|
* The interface for calls from outside the host process.
|
||||||
*/
|
*/
|
||||||
@BinderThread
|
@BinderThread
|
||||||
private static class IShellTransitionsImpl extends IShellTransitions.Stub {
|
private static class IShellTransitionsImpl extends IShellTransitions.Stub
|
||||||
|
implements ExternalInterfaceBinder {
|
||||||
private Transitions mTransitions;
|
private Transitions mTransitions;
|
||||||
|
|
||||||
IShellTransitionsImpl(Transitions transitions) {
|
IShellTransitionsImpl(Transitions transitions) {
|
||||||
@@ -938,7 +941,8 @@ public class Transitions implements RemoteCallable<Transitions> {
|
|||||||
/**
|
/**
|
||||||
* Invalidates this instance, preventing future calls from updating the controller.
|
* Invalidates this instance, preventing future calls from updating the controller.
|
||||||
*/
|
*/
|
||||||
void invalidate() {
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
mTransitions = null;
|
mTransitions = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import static android.window.BackNavigationInfo.KEY_TRIGGER_BACK;
|
|||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -60,7 +61,9 @@ import androidx.test.platform.app.InstrumentationRegistry;
|
|||||||
import com.android.internal.util.test.FakeSettingsProvider;
|
import com.android.internal.util.test.FakeSettingsProvider;
|
||||||
import com.android.wm.shell.ShellTestCase;
|
import com.android.wm.shell.ShellTestCase;
|
||||||
import com.android.wm.shell.TestShellExecutor;
|
import com.android.wm.shell.TestShellExecutor;
|
||||||
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
|
import com.android.wm.shell.sysui.ShellSharedConstants;
|
||||||
import com.android.wm.shell.transition.Transitions;
|
import com.android.wm.shell.transition.Transitions;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -102,6 +105,9 @@ public class BackAnimationControllerTest extends ShellTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private Transitions mTransitions;
|
private Transitions mTransitions;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ShellController mShellController;
|
||||||
|
|
||||||
private BackAnimationController mController;
|
private BackAnimationController mController;
|
||||||
|
|
||||||
private int mEventTime = 0;
|
private int mEventTime = 0;
|
||||||
@@ -118,7 +124,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
|
|||||||
ANIMATION_ENABLED);
|
ANIMATION_ENABLED);
|
||||||
mTestableLooper = TestableLooper.get(this);
|
mTestableLooper = TestableLooper.get(this);
|
||||||
mShellInit = spy(new ShellInit(mShellExecutor));
|
mShellInit = spy(new ShellInit(mShellExecutor));
|
||||||
mController = new BackAnimationController(mShellInit,
|
mController = new BackAnimationController(mShellInit, mShellController,
|
||||||
mShellExecutor, new Handler(mTestableLooper.getLooper()),
|
mShellExecutor, new Handler(mTestableLooper.getLooper()),
|
||||||
mActivityTaskManager, mContext,
|
mActivityTaskManager, mContext,
|
||||||
mContentResolver, mTransitions);
|
mContentResolver, mTransitions);
|
||||||
@@ -166,6 +172,12 @@ public class BackAnimationControllerTest extends ShellTestCase {
|
|||||||
verify(mShellInit, times(1)).addInitCallback(any(), any());
|
verify(mShellInit, times(1)).addInitCallback(any(), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void instantiateController_addExternalInterface() {
|
||||||
|
verify(mShellController, times(1)).addExternalInterface(
|
||||||
|
eq(ShellSharedConstants.KEY_EXTRA_SHELL_BACK_ANIMATION), any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void verifyAnimationFinishes() {
|
public void verifyAnimationFinishes() {
|
||||||
RemoteAnimationTarget animationTarget = createAnimationTarget();
|
RemoteAnimationTarget animationTarget = createAnimationTarget();
|
||||||
@@ -210,7 +222,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
|
|||||||
// Toggle the setting off
|
// Toggle the setting off
|
||||||
Settings.Global.putString(mContentResolver, Settings.Global.ENABLE_BACK_ANIMATION, "0");
|
Settings.Global.putString(mContentResolver, Settings.Global.ENABLE_BACK_ANIMATION, "0");
|
||||||
ShellInit shellInit = new ShellInit(mShellExecutor);
|
ShellInit shellInit = new ShellInit(mShellExecutor);
|
||||||
mController = new BackAnimationController(shellInit,
|
mController = new BackAnimationController(shellInit, mShellController,
|
||||||
mShellExecutor, new Handler(mTestableLooper.getLooper()),
|
mShellExecutor, new Handler(mTestableLooper.getLooper()),
|
||||||
mActivityTaskManager, mContext,
|
mActivityTaskManager, mContext,
|
||||||
mContentResolver, mTransitions);
|
mContentResolver, mTransitions);
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import com.android.wm.shell.ShellTestCase;
|
|||||||
import com.android.wm.shell.TestRunningTaskInfoBuilder;
|
import com.android.wm.shell.TestRunningTaskInfoBuilder;
|
||||||
import com.android.wm.shell.TestShellExecutor;
|
import com.android.wm.shell.TestShellExecutor;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
import com.android.wm.shell.transition.Transitions;
|
import com.android.wm.shell.transition.Transitions;
|
||||||
|
|
||||||
@@ -67,6 +68,8 @@ import org.mockito.Mockito;
|
|||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
public class DesktopModeControllerTest extends ShellTestCase {
|
public class DesktopModeControllerTest extends ShellTestCase {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ShellController mShellController;
|
||||||
@Mock
|
@Mock
|
||||||
private ShellTaskOrganizer mShellTaskOrganizer;
|
private ShellTaskOrganizer mShellTaskOrganizer;
|
||||||
@Mock
|
@Mock
|
||||||
@@ -94,8 +97,8 @@ public class DesktopModeControllerTest extends ShellTestCase {
|
|||||||
|
|
||||||
mDesktopModeTaskRepository = new DesktopModeTaskRepository();
|
mDesktopModeTaskRepository = new DesktopModeTaskRepository();
|
||||||
|
|
||||||
mController = new DesktopModeController(mContext, mShellInit, mShellTaskOrganizer,
|
mController = new DesktopModeController(mContext, mShellInit, mShellController,
|
||||||
mRootTaskDisplayAreaOrganizer, mMockTransitions,
|
mShellTaskOrganizer, mRootTaskDisplayAreaOrganizer, mMockTransitions,
|
||||||
mDesktopModeTaskRepository, mMockHandler, mExecutor);
|
mDesktopModeTaskRepository, mMockHandler, mExecutor);
|
||||||
|
|
||||||
when(mShellTaskOrganizer.prepareClearFreeformForStandardTasks(anyInt())).thenReturn(
|
when(mShellTaskOrganizer.prepareClearFreeformForStandardTasks(anyInt())).thenReturn(
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import com.android.wm.shell.floating.views.FloatingTaskLayer;
|
|||||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||||
import com.android.wm.shell.sysui.ShellController;
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
|
import com.android.wm.shell.sysui.ShellSharedConstants;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -168,6 +169,18 @@ public class FloatingTasksControllerTest extends ShellTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onInit_addExternalInterface() {
|
||||||
|
if (FLOATING_TASKS_ACTUALLY_ENABLED) {
|
||||||
|
createController();
|
||||||
|
setUpTabletConfig();
|
||||||
|
mController.onInit();
|
||||||
|
|
||||||
|
verify(mShellController, times(1)).addExternalInterface(
|
||||||
|
ShellSharedConstants.KEY_EXTRA_SHELL_FLOATING_TASKS, any(), any());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Tests for floating layer, which is only available for tablets.
|
// Tests for floating layer, which is only available for tablets.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import com.android.wm.shell.common.TaskStackListenerImpl;
|
|||||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||||
import com.android.wm.shell.sysui.ShellController;
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
|
import com.android.wm.shell.sysui.ShellSharedConstants;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -175,6 +176,12 @@ public class OneHandedControllerTest extends OneHandedTestCase {
|
|||||||
verify(mMockShellController, times(1)).addUserChangeListener(any());
|
verify(mMockShellController, times(1)).addUserChangeListener(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testControllerRegisteresExternalInterface() {
|
||||||
|
verify(mMockShellController, times(1)).addExternalInterface(
|
||||||
|
eq(ShellSharedConstants.KEY_EXTRA_SHELL_ONE_HANDED), any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultShouldNotInOneHanded() {
|
public void testDefaultShouldNotInOneHanded() {
|
||||||
// Assert default transition state is STATE_NONE
|
// Assert default transition state is STATE_NONE
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
@@ -61,6 +62,7 @@ import com.android.wm.shell.pip.PipTransitionState;
|
|||||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||||
import com.android.wm.shell.sysui.ShellController;
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
|
import com.android.wm.shell.sysui.ShellSharedConstants;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -151,6 +153,12 @@ public class PipControllerTest extends ShellTestCase {
|
|||||||
verify(mShellController, times(1)).addKeyguardChangeListener(any());
|
verify(mShellController, times(1)).addKeyguardChangeListener(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void instantiatePipController_registerExternalInterface() {
|
||||||
|
verify(mShellController, times(1)).addExternalInterface(
|
||||||
|
eq(ShellSharedConstants.KEY_EXTRA_SHELL_PIP), any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void instantiatePipController_registerUserChangeListener() {
|
public void instantiatePipController_registerUserChangeListener() {
|
||||||
verify(mShellController, times(1)).addUserChangeListener(any());
|
verify(mShellController, times(1)).addUserChangeListener(any());
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import static org.junit.Assert.assertNull;
|
|||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.ArgumentMatchers.isA;
|
import static org.mockito.ArgumentMatchers.isA;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -57,7 +58,9 @@ import com.android.wm.shell.common.TaskStackListenerImpl;
|
|||||||
import com.android.wm.shell.desktopmode.DesktopModeStatus;
|
import com.android.wm.shell.desktopmode.DesktopModeStatus;
|
||||||
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
|
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
|
||||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||||
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
|
import com.android.wm.shell.sysui.ShellSharedConstants;
|
||||||
import com.android.wm.shell.util.GroupedRecentTaskInfo;
|
import com.android.wm.shell.util.GroupedRecentTaskInfo;
|
||||||
import com.android.wm.shell.util.SplitBounds;
|
import com.android.wm.shell.util.SplitBounds;
|
||||||
|
|
||||||
@@ -84,6 +87,8 @@ public class RecentTasksControllerTest extends ShellTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private TaskStackListenerImpl mTaskStackListener;
|
private TaskStackListenerImpl mTaskStackListener;
|
||||||
@Mock
|
@Mock
|
||||||
|
private ShellController mShellController;
|
||||||
|
@Mock
|
||||||
private ShellCommandHandler mShellCommandHandler;
|
private ShellCommandHandler mShellCommandHandler;
|
||||||
@Mock
|
@Mock
|
||||||
private DesktopModeTaskRepository mDesktopModeTaskRepository;
|
private DesktopModeTaskRepository mDesktopModeTaskRepository;
|
||||||
@@ -101,7 +106,7 @@ public class RecentTasksControllerTest extends ShellTestCase {
|
|||||||
when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
|
when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
|
||||||
mShellInit = spy(new ShellInit(mMainExecutor));
|
mShellInit = spy(new ShellInit(mMainExecutor));
|
||||||
mRecentTasksController = spy(new RecentTasksController(mContext, mShellInit,
|
mRecentTasksController = spy(new RecentTasksController(mContext, mShellInit,
|
||||||
mShellCommandHandler, mTaskStackListener, mActivityTaskManager,
|
mShellController, mShellCommandHandler, mTaskStackListener, mActivityTaskManager,
|
||||||
Optional.of(mDesktopModeTaskRepository), mMainExecutor));
|
Optional.of(mDesktopModeTaskRepository), mMainExecutor));
|
||||||
mShellTaskOrganizer = new ShellTaskOrganizer(mShellInit, mShellCommandHandler,
|
mShellTaskOrganizer = new ShellTaskOrganizer(mShellInit, mShellCommandHandler,
|
||||||
null /* sizeCompatUI */, Optional.empty(), Optional.of(mRecentTasksController),
|
null /* sizeCompatUI */, Optional.empty(), Optional.of(mRecentTasksController),
|
||||||
@@ -120,6 +125,12 @@ public class RecentTasksControllerTest extends ShellTestCase {
|
|||||||
isA(RecentTasksController.class));
|
isA(RecentTasksController.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void instantiateController_addExternalInterface() {
|
||||||
|
verify(mShellController, times(1)).addExternalInterface(
|
||||||
|
eq(ShellSharedConstants.KEY_EXTRA_SHELL_RECENT_TASKS), any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddRemoveSplitNotifyChange() {
|
public void testAddRemoveSplitNotifyChange() {
|
||||||
ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
|
ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import com.android.wm.shell.recents.RecentTasksController;
|
|||||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||||
import com.android.wm.shell.sysui.ShellController;
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
|
import com.android.wm.shell.sysui.ShellSharedConstants;
|
||||||
import com.android.wm.shell.transition.Transitions;
|
import com.android.wm.shell.transition.Transitions;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -132,6 +133,15 @@ public class SplitScreenControllerTests extends ShellTestCase {
|
|||||||
verify(mShellController, times(1)).addKeyguardChangeListener(any());
|
verify(mShellController, times(1)).addKeyguardChangeListener(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void instantiateController_addExternalInterface() {
|
||||||
|
doReturn(mMainExecutor).when(mTaskOrganizer).getExecutor();
|
||||||
|
when(mDisplayController.getDisplayLayout(anyInt())).thenReturn(new DisplayLayout());
|
||||||
|
mSplitScreenController.onInit();
|
||||||
|
verify(mShellController, times(1)).addExternalInterface(
|
||||||
|
eq(ShellSharedConstants.KEY_EXTRA_SHELL_SPLIT_SCREEN), any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShouldAddMultipleTaskFlag_notInSplitScreen() {
|
public void testShouldAddMultipleTaskFlag_notInSplitScreen() {
|
||||||
doReturn(false).when(mSplitScreenController).isSplitScreenVisible();
|
doReturn(false).when(mSplitScreenController).isSplitScreenVisible();
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
|
|||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
@@ -36,7 +37,9 @@ import com.android.wm.shell.ShellTaskOrganizer;
|
|||||||
import com.android.wm.shell.ShellTestCase;
|
import com.android.wm.shell.ShellTestCase;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.TransactionPool;
|
import com.android.wm.shell.common.TransactionPool;
|
||||||
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
|
import com.android.wm.shell.sysui.ShellSharedConstants;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -56,25 +59,34 @@ public class StartingWindowControllerTests extends ShellTestCase {
|
|||||||
|
|
||||||
private @Mock Context mContext;
|
private @Mock Context mContext;
|
||||||
private @Mock DisplayManager mDisplayManager;
|
private @Mock DisplayManager mDisplayManager;
|
||||||
private @Mock ShellInit mShellInit;
|
private @Mock ShellController mShellController;
|
||||||
private @Mock ShellTaskOrganizer mTaskOrganizer;
|
private @Mock ShellTaskOrganizer mTaskOrganizer;
|
||||||
private @Mock ShellExecutor mMainExecutor;
|
private @Mock ShellExecutor mMainExecutor;
|
||||||
private @Mock StartingWindowTypeAlgorithm mTypeAlgorithm;
|
private @Mock StartingWindowTypeAlgorithm mTypeAlgorithm;
|
||||||
private @Mock IconProvider mIconProvider;
|
private @Mock IconProvider mIconProvider;
|
||||||
private @Mock TransactionPool mTransactionPool;
|
private @Mock TransactionPool mTransactionPool;
|
||||||
private StartingWindowController mController;
|
private StartingWindowController mController;
|
||||||
|
private ShellInit mShellInit;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
doReturn(mock(Display.class)).when(mDisplayManager).getDisplay(anyInt());
|
doReturn(mock(Display.class)).when(mDisplayManager).getDisplay(anyInt());
|
||||||
doReturn(mDisplayManager).when(mContext).getSystemService(eq(DisplayManager.class));
|
doReturn(mDisplayManager).when(mContext).getSystemService(eq(DisplayManager.class));
|
||||||
mController = new StartingWindowController(mContext, mShellInit, mTaskOrganizer,
|
mShellInit = spy(new ShellInit(mMainExecutor));
|
||||||
mMainExecutor, mTypeAlgorithm, mIconProvider, mTransactionPool);
|
mController = new StartingWindowController(mContext, mShellInit, mShellController,
|
||||||
|
mTaskOrganizer, mMainExecutor, mTypeAlgorithm, mIconProvider, mTransactionPool);
|
||||||
|
mShellInit.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void instantiate_addInitCallback() {
|
public void instantiateController_addInitCallback() {
|
||||||
verify(mShellInit, times(1)).addInitCallback(any(), any());
|
verify(mShellInit, times(1)).addInitCallback(any(), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void instantiateController_addExternalInterface() {
|
||||||
|
verify(mShellController, times(1)).addExternalInterface(
|
||||||
|
eq(ShellSharedConstants.KEY_EXTRA_SHELL_STARTING_WINDOW), any(), any());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,16 @@
|
|||||||
|
|
||||||
package com.android.wm.shell.sysui;
|
package com.android.wm.shell.sysui;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertThrows;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
|
|
||||||
@@ -30,6 +34,7 @@ import androidx.test.filters.SmallTest;
|
|||||||
import androidx.test.platform.app.InstrumentationRegistry;
|
import androidx.test.platform.app.InstrumentationRegistry;
|
||||||
|
|
||||||
import com.android.wm.shell.ShellTestCase;
|
import com.android.wm.shell.ShellTestCase;
|
||||||
|
import com.android.wm.shell.common.ExternalInterfaceBinder;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -49,6 +54,7 @@ import java.util.Locale;
|
|||||||
public class ShellControllerTest extends ShellTestCase {
|
public class ShellControllerTest extends ShellTestCase {
|
||||||
|
|
||||||
private static final int TEST_USER_ID = 100;
|
private static final int TEST_USER_ID = 100;
|
||||||
|
private static final String EXTRA_TEST_BINDER = "test_binder";
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private ShellInit mShellInit;
|
private ShellInit mShellInit;
|
||||||
@@ -80,6 +86,47 @@ public class ShellControllerTest extends ShellTestCase {
|
|||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddExternalInterface_ensureCallback() {
|
||||||
|
Binder callback = new Binder();
|
||||||
|
ExternalInterfaceBinder wrapper = new ExternalInterfaceBinder() {
|
||||||
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder asBinder() {
|
||||||
|
return callback;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mController.addExternalInterface(EXTRA_TEST_BINDER, () -> wrapper, this);
|
||||||
|
|
||||||
|
Bundle b = new Bundle();
|
||||||
|
mController.asShell().createExternalInterfaces(b);
|
||||||
|
assertTrue(b.getIBinder(EXTRA_TEST_BINDER) == callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddExternalInterface_disallowDuplicateKeys() {
|
||||||
|
Binder callback = new Binder();
|
||||||
|
ExternalInterfaceBinder wrapper = new ExternalInterfaceBinder() {
|
||||||
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder asBinder() {
|
||||||
|
return callback;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mController.addExternalInterface(EXTRA_TEST_BINDER, () -> wrapper, this);
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
|
mController.addExternalInterface(EXTRA_TEST_BINDER, () -> wrapper, this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddUserChangeListener_ensureCallback() {
|
public void testAddUserChangeListener_ensureCallback() {
|
||||||
mController.addUserChangeListener(mUserChangeListener);
|
mController.addUserChangeListener(mUserChangeListener);
|
||||||
|
|||||||
@@ -86,7 +86,9 @@ import com.android.wm.shell.common.DisplayController;
|
|||||||
import com.android.wm.shell.common.DisplayLayout;
|
import com.android.wm.shell.common.DisplayLayout;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.TransactionPool;
|
import com.android.wm.shell.common.TransactionPool;
|
||||||
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
import com.android.wm.shell.sysui.ShellInit;
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
|
import com.android.wm.shell.sysui.ShellSharedConstants;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -123,11 +125,24 @@ public class ShellTransitionTests extends ShellTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void instantiate_addInitCallback() {
|
public void instantiate_addInitCallback() {
|
||||||
ShellInit shellInit = mock(ShellInit.class);
|
ShellInit shellInit = mock(ShellInit.class);
|
||||||
final Transitions t = new Transitions(mContext, shellInit, mOrganizer, mTransactionPool,
|
final Transitions t = new Transitions(mContext, shellInit, mock(ShellController.class),
|
||||||
createTestDisplayController(), mMainExecutor, mMainHandler, mAnimExecutor);
|
mOrganizer, mTransactionPool, createTestDisplayController(), mMainExecutor,
|
||||||
|
mMainHandler, mAnimExecutor);
|
||||||
verify(shellInit, times(1)).addInitCallback(any(), eq(t));
|
verify(shellInit, times(1)).addInitCallback(any(), eq(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void instantiateController_addExternalInterface() {
|
||||||
|
ShellInit shellInit = new ShellInit(mMainExecutor);
|
||||||
|
ShellController shellController = mock(ShellController.class);
|
||||||
|
final Transitions t = new Transitions(mContext, shellInit, shellController,
|
||||||
|
mOrganizer, mTransactionPool, createTestDisplayController(), mMainExecutor,
|
||||||
|
mMainHandler, mAnimExecutor);
|
||||||
|
shellInit.init();
|
||||||
|
verify(shellController, times(1)).addExternalInterface(
|
||||||
|
eq(ShellSharedConstants.KEY_EXTRA_SHELL_SHELL_TRANSITIONS), any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicTransitionFlow() {
|
public void testBasicTransitionFlow() {
|
||||||
Transitions transitions = createTestTransitions();
|
Transitions transitions = createTestTransitions();
|
||||||
@@ -1060,8 +1075,9 @@ public class ShellTransitionTests extends ShellTestCase {
|
|||||||
|
|
||||||
private Transitions createTestTransitions() {
|
private Transitions createTestTransitions() {
|
||||||
ShellInit shellInit = new ShellInit(mMainExecutor);
|
ShellInit shellInit = new ShellInit(mMainExecutor);
|
||||||
final Transitions t = new Transitions(mContext, shellInit, mOrganizer, mTransactionPool,
|
final Transitions t = new Transitions(mContext, shellInit, mock(ShellController.class),
|
||||||
createTestDisplayController(), mMainExecutor, mMainHandler, mAnimExecutor);
|
mOrganizer, mTransactionPool, createTestDisplayController(), mMainExecutor,
|
||||||
|
mMainHandler, mAnimExecutor);
|
||||||
shellInit.init();
|
shellInit.init();
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,27 +43,8 @@ public class QuickStepContract {
|
|||||||
public static final String KEY_EXTRA_SYSUI_PROXY = "extra_sysui_proxy";
|
public static final String KEY_EXTRA_SYSUI_PROXY = "extra_sysui_proxy";
|
||||||
public static final String KEY_EXTRA_WINDOW_CORNER_RADIUS = "extra_window_corner_radius";
|
public static final String KEY_EXTRA_WINDOW_CORNER_RADIUS = "extra_window_corner_radius";
|
||||||
public static final String KEY_EXTRA_SUPPORTS_WINDOW_CORNERS = "extra_supports_window_corners";
|
public static final String KEY_EXTRA_SUPPORTS_WINDOW_CORNERS = "extra_supports_window_corners";
|
||||||
// See IPip.aidl
|
|
||||||
public static final String KEY_EXTRA_SHELL_PIP = "extra_shell_pip";
|
|
||||||
// See ISplitScreen.aidl
|
|
||||||
public static final String KEY_EXTRA_SHELL_SPLIT_SCREEN = "extra_shell_split_screen";
|
|
||||||
// See IFloatingTasks.aidl
|
|
||||||
public static final String KEY_EXTRA_SHELL_FLOATING_TASKS = "extra_shell_floating_tasks";
|
|
||||||
// See IOneHanded.aidl
|
|
||||||
public static final String KEY_EXTRA_SHELL_ONE_HANDED = "extra_shell_one_handed";
|
|
||||||
// See IShellTransitions.aidl
|
|
||||||
public static final String KEY_EXTRA_SHELL_SHELL_TRANSITIONS =
|
|
||||||
"extra_shell_shell_transitions";
|
|
||||||
// See IStartingWindow.aidl
|
|
||||||
public static final String KEY_EXTRA_SHELL_STARTING_WINDOW =
|
|
||||||
"extra_shell_starting_window";
|
|
||||||
// See ISysuiUnlockAnimationController.aidl
|
// See ISysuiUnlockAnimationController.aidl
|
||||||
public static final String KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER = "unlock_animation";
|
public static final String KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER = "unlock_animation";
|
||||||
// See IRecentTasks.aidl
|
|
||||||
public static final String KEY_EXTRA_RECENT_TASKS = "recent_tasks";
|
|
||||||
public static final String KEY_EXTRA_SHELL_BACK_ANIMATION = "extra_shell_back_animation";
|
|
||||||
// See IDesktopMode.aidl
|
|
||||||
public static final String KEY_EXTRA_SHELL_DESKTOP_MODE = "extra_shell_desktop_mode";
|
|
||||||
|
|
||||||
public static final String NAV_BAR_MODE_3BUTTON_OVERLAY =
|
public static final String NAV_BAR_MODE_3BUTTON_OVERLAY =
|
||||||
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
|
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
|
||||||
|
|||||||
@@ -25,15 +25,6 @@ import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_OVERVIEW;
|
|||||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
|
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
|
||||||
|
|
||||||
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
|
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_RECENT_TASKS;
|
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_BACK_ANIMATION;
|
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_DESKTOP_MODE;
|
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_FLOATING_TASKS;
|
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_ONE_HANDED;
|
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_PIP;
|
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SHELL_TRANSITIONS;
|
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SPLIT_SCREEN;
|
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_STARTING_WINDOW;
|
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS;
|
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
|
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER;
|
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER;
|
||||||
@@ -110,16 +101,7 @@ import com.android.systemui.statusbar.NotificationShadeWindowController;
|
|||||||
import com.android.systemui.statusbar.phone.CentralSurfaces;
|
import com.android.systemui.statusbar.phone.CentralSurfaces;
|
||||||
import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
|
import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
|
||||||
import com.android.systemui.statusbar.policy.CallbackController;
|
import com.android.systemui.statusbar.policy.CallbackController;
|
||||||
import com.android.wm.shell.back.BackAnimation;
|
import com.android.wm.shell.sysui.ShellInterface;
|
||||||
import com.android.wm.shell.desktopmode.DesktopMode;
|
|
||||||
import com.android.wm.shell.floating.FloatingTasks;
|
|
||||||
import com.android.wm.shell.onehanded.OneHanded;
|
|
||||||
import com.android.wm.shell.pip.Pip;
|
|
||||||
import com.android.wm.shell.pip.PipAnimationController;
|
|
||||||
import com.android.wm.shell.recents.RecentTasks;
|
|
||||||
import com.android.wm.shell.splitscreen.SplitScreen;
|
|
||||||
import com.android.wm.shell.startingsurface.StartingSurface;
|
|
||||||
import com.android.wm.shell.transition.ShellTransitions;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -151,10 +133,8 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
|||||||
private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000;
|
private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000;
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final Optional<Pip> mPipOptional;
|
private final ShellInterface mShellInterface;
|
||||||
private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
|
private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
|
||||||
private final Optional<SplitScreen> mSplitScreenOptional;
|
|
||||||
private final Optional<FloatingTasks> mFloatingTasksOptional;
|
|
||||||
private SysUiState mSysUiState;
|
private SysUiState mSysUiState;
|
||||||
private final Handler mHandler;
|
private final Handler mHandler;
|
||||||
private final Lazy<NavigationBarController> mNavBarControllerLazy;
|
private final Lazy<NavigationBarController> mNavBarControllerLazy;
|
||||||
@@ -164,14 +144,8 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
|||||||
private final List<OverviewProxyListener> mConnectionCallbacks = new ArrayList<>();
|
private final List<OverviewProxyListener> mConnectionCallbacks = new ArrayList<>();
|
||||||
private final Intent mQuickStepIntent;
|
private final Intent mQuickStepIntent;
|
||||||
private final ScreenshotHelper mScreenshotHelper;
|
private final ScreenshotHelper mScreenshotHelper;
|
||||||
private final Optional<OneHanded> mOneHandedOptional;
|
|
||||||
private final CommandQueue mCommandQueue;
|
private final CommandQueue mCommandQueue;
|
||||||
private final ShellTransitions mShellTransitions;
|
|
||||||
private final Optional<StartingSurface> mStartingSurface;
|
|
||||||
private final KeyguardUnlockAnimationController mSysuiUnlockAnimationController;
|
private final KeyguardUnlockAnimationController mSysuiUnlockAnimationController;
|
||||||
private final Optional<RecentTasks> mRecentTasks;
|
|
||||||
private final Optional<BackAnimation> mBackAnimation;
|
|
||||||
private final Optional<DesktopMode> mDesktopModeOptional;
|
|
||||||
private final UiEventLogger mUiEventLogger;
|
private final UiEventLogger mUiEventLogger;
|
||||||
|
|
||||||
private Region mActiveNavBarRegion;
|
private Region mActiveNavBarRegion;
|
||||||
@@ -456,36 +430,10 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
|||||||
params.putBinder(KEY_EXTRA_SYSUI_PROXY, mSysUiProxy.asBinder());
|
params.putBinder(KEY_EXTRA_SYSUI_PROXY, mSysUiProxy.asBinder());
|
||||||
params.putFloat(KEY_EXTRA_WINDOW_CORNER_RADIUS, mWindowCornerRadius);
|
params.putFloat(KEY_EXTRA_WINDOW_CORNER_RADIUS, mWindowCornerRadius);
|
||||||
params.putBoolean(KEY_EXTRA_SUPPORTS_WINDOW_CORNERS, mSupportsRoundedCornersOnWindows);
|
params.putBoolean(KEY_EXTRA_SUPPORTS_WINDOW_CORNERS, mSupportsRoundedCornersOnWindows);
|
||||||
|
params.putBinder(KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER,
|
||||||
mPipOptional.ifPresent((pip) -> params.putBinder(
|
|
||||||
KEY_EXTRA_SHELL_PIP,
|
|
||||||
pip.createExternalInterface().asBinder()));
|
|
||||||
mSplitScreenOptional.ifPresent((splitscreen) -> params.putBinder(
|
|
||||||
KEY_EXTRA_SHELL_SPLIT_SCREEN,
|
|
||||||
splitscreen.createExternalInterface().asBinder()));
|
|
||||||
mFloatingTasksOptional.ifPresent(floatingTasks -> params.putBinder(
|
|
||||||
KEY_EXTRA_SHELL_FLOATING_TASKS,
|
|
||||||
floatingTasks.createExternalInterface().asBinder()));
|
|
||||||
mOneHandedOptional.ifPresent((onehanded) -> params.putBinder(
|
|
||||||
KEY_EXTRA_SHELL_ONE_HANDED,
|
|
||||||
onehanded.createExternalInterface().asBinder()));
|
|
||||||
params.putBinder(KEY_EXTRA_SHELL_SHELL_TRANSITIONS,
|
|
||||||
mShellTransitions.createExternalInterface().asBinder());
|
|
||||||
mStartingSurface.ifPresent((startingwindow) -> params.putBinder(
|
|
||||||
KEY_EXTRA_SHELL_STARTING_WINDOW,
|
|
||||||
startingwindow.createExternalInterface().asBinder()));
|
|
||||||
params.putBinder(
|
|
||||||
KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER,
|
|
||||||
mSysuiUnlockAnimationController.asBinder());
|
mSysuiUnlockAnimationController.asBinder());
|
||||||
mRecentTasks.ifPresent(recentTasks -> params.putBinder(
|
// Add all the interfaces exposed by the shell
|
||||||
KEY_EXTRA_RECENT_TASKS,
|
mShellInterface.createExternalInterfaces(params);
|
||||||
recentTasks.createExternalInterface().asBinder()));
|
|
||||||
mBackAnimation.ifPresent((backAnimation) -> params.putBinder(
|
|
||||||
KEY_EXTRA_SHELL_BACK_ANIMATION,
|
|
||||||
backAnimation.createExternalInterface().asBinder()));
|
|
||||||
mDesktopModeOptional.ifPresent((desktopMode -> params.putBinder(
|
|
||||||
KEY_EXTRA_SHELL_DESKTOP_MODE,
|
|
||||||
desktopMode.createExternalInterface().asBinder())));
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Log.d(TAG_OPS, "OverviewProxyService connected, initializing overview proxy");
|
Log.d(TAG_OPS, "OverviewProxyService connected, initializing overview proxy");
|
||||||
@@ -559,21 +507,14 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
|||||||
|
|
||||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||||
@Inject
|
@Inject
|
||||||
public OverviewProxyService(Context context, CommandQueue commandQueue,
|
public OverviewProxyService(Context context,
|
||||||
|
CommandQueue commandQueue,
|
||||||
|
ShellInterface shellInterface,
|
||||||
Lazy<NavigationBarController> navBarControllerLazy,
|
Lazy<NavigationBarController> navBarControllerLazy,
|
||||||
Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
|
Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
|
||||||
NavigationModeController navModeController,
|
NavigationModeController navModeController,
|
||||||
NotificationShadeWindowController statusBarWinController, SysUiState sysUiState,
|
NotificationShadeWindowController statusBarWinController, SysUiState sysUiState,
|
||||||
Optional<Pip> pipOptional,
|
|
||||||
Optional<SplitScreen> splitScreenOptional,
|
|
||||||
Optional<FloatingTasks> floatingTasksOptional,
|
|
||||||
Optional<OneHanded> oneHandedOptional,
|
|
||||||
Optional<RecentTasks> recentTasks,
|
|
||||||
Optional<BackAnimation> backAnimation,
|
|
||||||
Optional<StartingSurface> startingSurface,
|
|
||||||
Optional<DesktopMode> desktopModeOptional,
|
|
||||||
BroadcastDispatcher broadcastDispatcher,
|
BroadcastDispatcher broadcastDispatcher,
|
||||||
ShellTransitions shellTransitions,
|
|
||||||
ScreenLifecycle screenLifecycle,
|
ScreenLifecycle screenLifecycle,
|
||||||
UiEventLogger uiEventLogger,
|
UiEventLogger uiEventLogger,
|
||||||
KeyguardUnlockAnimationController sysuiUnlockAnimationController,
|
KeyguardUnlockAnimationController sysuiUnlockAnimationController,
|
||||||
@@ -587,7 +528,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mPipOptional = pipOptional;
|
mShellInterface = shellInterface;
|
||||||
mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
|
mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
|
||||||
mHandler = new Handler();
|
mHandler = new Handler();
|
||||||
mNavBarControllerLazy = navBarControllerLazy;
|
mNavBarControllerLazy = navBarControllerLazy;
|
||||||
@@ -602,11 +543,6 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
|||||||
.supportsRoundedCornersOnWindows(mContext.getResources());
|
.supportsRoundedCornersOnWindows(mContext.getResources());
|
||||||
mSysUiState = sysUiState;
|
mSysUiState = sysUiState;
|
||||||
mSysUiState.addCallback(this::notifySystemUiStateFlags);
|
mSysUiState.addCallback(this::notifySystemUiStateFlags);
|
||||||
mOneHandedOptional = oneHandedOptional;
|
|
||||||
mShellTransitions = shellTransitions;
|
|
||||||
mRecentTasks = recentTasks;
|
|
||||||
mBackAnimation = backAnimation;
|
|
||||||
mDesktopModeOptional = desktopModeOptional;
|
|
||||||
mUiEventLogger = uiEventLogger;
|
mUiEventLogger = uiEventLogger;
|
||||||
|
|
||||||
dumpManager.registerDumpable(getClass().getSimpleName(), this);
|
dumpManager.registerDumpable(getClass().getSimpleName(), this);
|
||||||
@@ -636,9 +572,6 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
|||||||
});
|
});
|
||||||
mCommandQueue = commandQueue;
|
mCommandQueue = commandQueue;
|
||||||
|
|
||||||
mSplitScreenOptional = splitScreenOptional;
|
|
||||||
mFloatingTasksOptional = floatingTasksOptional;
|
|
||||||
|
|
||||||
// Listen for user setup
|
// Listen for user setup
|
||||||
startTracking();
|
startTracking();
|
||||||
|
|
||||||
@@ -647,7 +580,6 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
|||||||
// Connect to the service
|
// Connect to the service
|
||||||
updateEnabledState();
|
updateEnabledState();
|
||||||
startConnectionToCurrentUser();
|
startConnectionToCurrentUser();
|
||||||
mStartingSurface = startingSurface;
|
|
||||||
mSysuiUnlockAnimationController = sysuiUnlockAnimationController;
|
mSysuiUnlockAnimationController = sysuiUnlockAnimationController;
|
||||||
|
|
||||||
// Listen for assistant changes
|
// Listen for assistant changes
|
||||||
|
|||||||
Reference in New Issue
Block a user