Merge changes Ie8c5a77b,I96125e9f into tm-qpr-dev

* changes:
  Remove unused interfaces and controllers
  Add keyguard callbacks to ShellInterface
This commit is contained in:
Winson Chung
2022-07-20 15:40:52 +00:00
committed by Android (Google) Code Review
33 changed files with 343 additions and 622 deletions

View File

@@ -28,6 +28,13 @@ import com.android.wm.shell.common.annotations.ExternalThread;
@ExternalThread
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.
*
@@ -46,13 +53,6 @@ public interface BackAnimation {
*/
void setTriggerBack(boolean triggerBack);
/**
* Returns a binder that can be passed to an external process to update back animations.
*/
default IBackAnimation createExternalInterface() {
return null;
}
/**
* Sets the threshold values that defining edge swipe behavior.
* @param triggerThreshold the min threshold to trigger back.

View File

@@ -1,35 +0,0 @@
/*
* Copyright (C) 2021 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.compatui;
import com.android.wm.shell.common.annotations.ExternalThread;
/**
* Interface to engage compat UI.
*/
@ExternalThread
public interface CompatUI {
/**
* Called when the keyguard showing state changes. Removes all compat UIs if the
* keyguard is now showing.
*
* <p>Note that if the keyguard is occluded it will also be considered showing.
*
* @param showing indicates if the keyguard is now showing.
*/
void onKeyguardShowingChanged(boolean showing);
}

View File

@@ -39,9 +39,10 @@ import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListen
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.compatui.CompatUIWindowManager.CompatUIHintsState;
import com.android.wm.shell.compatui.letterboxedu.LetterboxEduWindowManager;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.transition.Transitions;
import java.lang.ref.WeakReference;
@@ -58,7 +59,7 @@ import dagger.Lazy;
* activities are in compatibility mode.
*/
public class CompatUIController implements OnDisplaysChangedListener,
DisplayImeController.ImePositionProcessor {
DisplayImeController.ImePositionProcessor, KeyguardChangeListener {
/** Callback for compat UI interaction. */
public interface CompatUICallback {
@@ -100,13 +101,13 @@ public class CompatUIController implements OnDisplaysChangedListener,
private final SparseArray<WeakReference<Context>> mDisplayContextCache = new SparseArray<>(0);
private final Context mContext;
private final ShellController mShellController;
private final DisplayController mDisplayController;
private final DisplayInsetsController mDisplayInsetsController;
private final DisplayImeController mImeController;
private final SyncTransactionQueue mSyncQueue;
private final ShellExecutor mMainExecutor;
private final Lazy<Transitions> mTransitionsLazy;
private final CompatUIImpl mImpl = new CompatUIImpl();
private CompatUICallback mCallback;
@@ -118,6 +119,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
private boolean mKeyguardShowing;
public CompatUIController(Context context,
ShellController shellController,
DisplayController displayController,
DisplayInsetsController displayInsetsController,
DisplayImeController imeController,
@@ -125,6 +127,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
ShellExecutor mainExecutor,
Lazy<Transitions> transitionsLazy) {
mContext = context;
mShellController = shellController;
mDisplayController = displayController;
mDisplayInsetsController = displayInsetsController;
mImeController = imeController;
@@ -134,11 +137,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
mDisplayController.addDisplayWindowListener(this);
mImeController.addPositionProcessor(this);
mCompatUIHintsState = new CompatUIHintsState();
}
/** Returns implementation of {@link CompatUI}. */
public CompatUI asCompatUI() {
return mImpl;
shellController.addKeyguardChangeListener(this);
}
/** Sets the callback for UI interactions. */
@@ -223,9 +222,10 @@ public class CompatUIController implements OnDisplaysChangedListener,
layout -> layout.updateVisibility(showOnDisplay(displayId)));
}
@VisibleForTesting
void onKeyguardShowingChanged(boolean showing) {
mKeyguardShowing = showing;
@Override
public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
boolean animatingDismiss) {
mKeyguardShowing = visible;
// Hide the compat UIs when keyguard is showing.
forAllLayouts(layout -> layout.updateVisibility(showOnDisplay(layout.getDisplayId())));
}
@@ -373,19 +373,6 @@ public class CompatUIController implements OnDisplaysChangedListener,
}
}
/**
* The interface for calls from outside the Shell, within the host process.
*/
@ExternalThread
private class CompatUIImpl implements CompatUI {
@Override
public void onKeyguardShowingChanged(boolean showing) {
mMainExecutor.execute(() -> {
CompatUIController.this.onKeyguardShowingChanged(showing);
});
}
}
/** An implementation of {@link OnInsetsChangedListener} for a given display id. */
private class PerDisplayOnInsetsChangedListener implements OnInsetsChangedListener {
final int mDisplayId;

View File

@@ -57,15 +57,12 @@ import com.android.wm.shell.common.annotations.ShellAnimationThread;
import com.android.wm.shell.common.annotations.ShellBackgroundThread;
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
import com.android.wm.shell.compatui.CompatUI;
import com.android.wm.shell.compatui.CompatUIController;
import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
import com.android.wm.shell.displayareahelper.DisplayAreaHelperController;
import com.android.wm.shell.draganddrop.DragAndDrop;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.freeform.FreeformTaskListener;
import com.android.wm.shell.fullscreen.FullscreenTaskListener;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
import com.android.wm.shell.onehanded.OneHanded;
@@ -85,8 +82,6 @@ import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm;
import com.android.wm.shell.startingsurface.phone.PhoneStartingWindowTypeAlgorithm;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInterface;
import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper;
import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelperController;
import com.android.wm.shell.transition.ShellTransitions;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
@@ -171,12 +166,6 @@ public abstract class WMShellBaseModule {
iconProvider, mainExecutor);
}
@WMSingleton
@Provides
static Optional<DragAndDrop> provideDragAndDrop(DragAndDropController dragAndDropController) {
return Optional.of(dragAndDropController.asDragAndDrop());
}
@WMSingleton
@Provides
static ShellTaskOrganizer provideShellTaskOrganizer(@ShellMainThread ShellExecutor mainExecutor,
@@ -206,19 +195,15 @@ public abstract class WMShellBaseModule {
recentTasksOptional);
}
@WMSingleton
@Provides static Optional<CompatUI> provideCompatUI(CompatUIController compatUIController) {
return Optional.of(compatUIController.asCompatUI());
}
@WMSingleton
@Provides
static CompatUIController provideCompatUIController(Context context,
ShellController shellController,
DisplayController displayController, DisplayInsetsController displayInsetsController,
DisplayImeController imeController, SyncTransactionQueue syncQueue,
@ShellMainThread ShellExecutor mainExecutor, Lazy<Transitions> transitionsLazy) {
return new CompatUIController(context, displayController, displayInsetsController,
imeController, syncQueue, mainExecutor, transitionsLazy);
return new CompatUIController(context, shellController, displayController,
displayInsetsController, imeController, syncQueue, mainExecutor, transitionsLazy);
}
@WMSingleton
@@ -373,13 +358,6 @@ public abstract class WMShellBaseModule {
// Hide display cutout
//
@WMSingleton
@Provides
static Optional<HideDisplayCutout> provideHideDisplayCutout(
Optional<HideDisplayCutoutController> hideDisplayCutoutController) {
return hideDisplayCutoutController.map((controller) -> controller.asHideDisplayCutout());
}
@WMSingleton
@Provides
static Optional<HideDisplayCutoutController> provideHideDisplayCutoutController(Context context,
@@ -415,23 +393,6 @@ public abstract class WMShellBaseModule {
return Optional.empty();
}
//
// Task to Surface communication
//
@WMSingleton
@Provides
static Optional<TaskSurfaceHelper> provideTaskSurfaceHelper(
Optional<TaskSurfaceHelperController> taskSurfaceController) {
return taskSurfaceController.map((controller) -> controller.asTaskSurfaceHelper());
}
@Provides
static Optional<TaskSurfaceHelperController> provideTaskSurfaceHelperController(
ShellTaskOrganizer taskOrganizer, @ShellMainThread ShellExecutor mainExecutor) {
return Optional.ofNullable(new TaskSurfaceHelperController(taskOrganizer, mainExecutor));
}
//
// Pip (optional feature)
//

View File

@@ -225,6 +225,7 @@ public abstract class WMShellModule {
@Provides
@DynamicOverride
static SplitScreenController provideSplitScreenController(
ShellController shellController,
ShellTaskOrganizer shellTaskOrganizer,
SyncTransactionQueue syncQueue, Context context,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
@@ -234,7 +235,7 @@ public abstract class WMShellModule {
DisplayInsetsController displayInsetsController, Transitions transitions,
TransactionPool transactionPool, IconProvider iconProvider,
Optional<RecentTasksController> recentTasks) {
return new SplitScreenController(shellTaskOrganizer, syncQueue, context,
return new SplitScreenController(shellController, shellTaskOrganizer, syncQueue, context,
rootTaskDisplayAreaOrganizer, mainExecutor, displayController, displayImeController,
displayInsetsController, transitions, transactionPool, iconProvider,
recentTasks);

View File

@@ -1,26 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wm.shell.draganddrop;
import com.android.wm.shell.common.annotations.ExternalThread;
/**
* Interface for telling DragAndDrop stuff.
*/
@ExternalThread
public interface DragAndDrop {
}

View File

@@ -81,11 +81,9 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
private final IconProvider mIconProvider;
private SplitScreenController mSplitScreen;
private ShellExecutor mMainExecutor;
private DragAndDropImpl mImpl;
private ArrayList<DragAndDropListener> mListeners = new ArrayList<>();
private final SparseArray<PerDisplay> mDisplayDropTargets = new SparseArray<>();
private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
/**
* Listener called during drag events, currently just onDragStarted.
@@ -107,11 +105,6 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
mLogger = new DragAndDropEventLogger(uiEventLogger);
mIconProvider = iconProvider;
mMainExecutor = mainExecutor;
mImpl = new DragAndDropImpl();
}
public DragAndDrop asDragAndDrop() {
return mImpl;
}
public void initialize(Optional<SplitScreenController> splitscreen) {
@@ -353,8 +346,4 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
dragLayout = dl;
}
}
private class DragAndDropImpl implements DragAndDrop {
// TODO: To be removed
}
}

View File

@@ -1,26 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wm.shell.hidedisplaycutout;
import com.android.wm.shell.common.annotations.ExternalThread;
/**
* Interface to engage hide display cutout feature.
*/
@ExternalThread
public interface HideDisplayCutout {
}

View File

@@ -40,8 +40,6 @@ public class HideDisplayCutoutController implements ConfigurationChangeListener
private final Context mContext;
private final ShellController mShellController;
private final HideDisplayCutoutOrganizer mOrganizer;
private final ShellExecutor mMainExecutor;
private final HideDisplayCutoutImpl mImpl = new HideDisplayCutoutImpl();
@VisibleForTesting
boolean mEnabled;
@@ -62,23 +60,18 @@ public class HideDisplayCutoutController implements ConfigurationChangeListener
HideDisplayCutoutOrganizer organizer =
new HideDisplayCutoutOrganizer(context, displayController, mainExecutor);
return new HideDisplayCutoutController(context, shellController, organizer, mainExecutor);
return new HideDisplayCutoutController(context, shellController, organizer);
}
HideDisplayCutoutController(Context context, ShellController shellController,
HideDisplayCutoutOrganizer organizer, ShellExecutor mainExecutor) {
HideDisplayCutoutOrganizer organizer) {
mContext = context;
mShellController = shellController;
mOrganizer = organizer;
mMainExecutor = mainExecutor;
updateStatus();
mShellController.addConfigurationChangeListener(this);
}
public HideDisplayCutout asHideDisplayCutout() {
return mImpl;
}
@VisibleForTesting
void updateStatus() {
// The config value is used for controlling enabling/disabling status of the feature and is
@@ -112,8 +105,4 @@ public class HideDisplayCutoutController implements ConfigurationChangeListener
pw.println(mEnabled);
mOrganizer.dump(pw);
}
private class HideDisplayCutoutImpl implements HideDisplayCutout {
// TODO: To be removed
}
}

View File

@@ -85,9 +85,4 @@ public interface OneHanded {
* Notifies when user switch complete
*/
void onUserSwitch(int userId);
/**
* Notifies when keyguard visibility changed
*/
void onKeyguardVisibilityChanged(boolean showing);
}

View File

@@ -55,6 +55,7 @@ import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.sysui.ConfigurationChangeListener;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellController;
import java.io.PrintWriter;
@@ -63,7 +64,8 @@ import java.io.PrintWriter;
* Manages and manipulates the one handed states, transitions, and gesture for phones.
*/
public class OneHandedController implements RemoteCallable<OneHandedController>,
DisplayChangeController.OnDisplayChangingListener, ConfigurationChangeListener {
DisplayChangeController.OnDisplayChangingListener, ConfigurationChangeListener,
KeyguardChangeListener {
private static final String TAG = "OneHandedController";
private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE =
@@ -279,6 +281,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
mState.addSListeners(mTutorialHandler);
mShellController.addConfigurationChangeListener(this);
mShellController.addKeyguardChangeListener(this);
}
public OneHanded asOneHanded() {
@@ -605,8 +608,11 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
mTutorialHandler.onConfigurationChanged();
}
private void onKeyguardVisibilityChanged(boolean showing) {
mKeyguardShowing = showing;
@Override
public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
boolean animatingDismiss) {
mKeyguardShowing = visible;
stopOneHanded();
}
private void onUserSwitch(int newUserId) {
@@ -756,13 +762,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
OneHandedController.this.onUserSwitch(userId);
});
}
@Override
public void onKeyguardVisibilityChanged(boolean showing) {
mMainExecutor.execute(() -> {
OneHandedController.this.onKeyguardVisibilityChanged(showing);
});
}
}
/**

View File

@@ -100,23 +100,6 @@ public interface Pip {
*/
default void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) { }
/**
* Called when the visibility of keyguard is changed.
* @param showing {@code true} if keyguard is now showing, {@code false} otherwise.
* @param animating {@code true} if system is animating between keyguard and surface behind,
* this only makes sense when showing is {@code false}.
*/
default void onKeyguardVisibilityChanged(boolean showing, boolean animating) { }
/**
* Called when the dismissing animation keyguard and surfaces behind is finished.
* See also {@link #onKeyguardVisibilityChanged(boolean, boolean)}.
*
* TODO(b/206741900) deprecate this path once we're able to animate the PiP window as part of
* keyguard dismiss animation.
*/
default void onKeyguardDismissAnimationFinished() { }
/**
* Dump the current state and information if need.
*

View File

@@ -88,6 +88,7 @@ import com.android.wm.shell.pip.PipTransitionState;
import com.android.wm.shell.pip.PipUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.sysui.ConfigurationChangeListener;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.transition.Transitions;
@@ -102,7 +103,7 @@ import java.util.function.Consumer;
* Manages the picture-in-picture (PIP) UI and states for Phones.
*/
public class PipController implements PipTransitionController.PipTransitionCallback,
RemoteCallable<PipController>, ConfigurationChangeListener {
RemoteCallable<PipController>, ConfigurationChangeListener, KeyguardChangeListener {
private static final String TAG = "PipController";
private Context mContext;
@@ -527,6 +528,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
});
mShellController.addConfigurationChangeListener(this);
mShellController.addKeyguardChangeListener(this);
}
@Override
@@ -661,21 +663,24 @@ public class PipController implements PipTransitionController.PipTransitionCallb
* finished first to reset the visibility of PiP window.
* See also {@link #onKeyguardDismissAnimationFinished()}
*/
private void onKeyguardVisibilityChanged(boolean keyguardShowing, boolean animating) {
@Override
public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
boolean animatingDismiss) {
if (!mPipTaskOrganizer.isInPip()) {
return;
}
if (keyguardShowing) {
if (visible) {
mIsKeyguardShowingOrAnimating = true;
hidePipMenu(null /* onStartCallback */, null /* onEndCallback */);
mPipTaskOrganizer.setPipVisibility(false);
} else if (!animating) {
} else if (!animatingDismiss) {
mIsKeyguardShowingOrAnimating = false;
mPipTaskOrganizer.setPipVisibility(true);
}
}
private void onKeyguardDismissAnimationFinished() {
@Override
public void onKeyguardDismissAnimationFinished() {
if (mPipTaskOrganizer.isInPip()) {
mIsKeyguardShowingOrAnimating = false;
mPipTaskOrganizer.setPipVisibility(true);
@@ -995,18 +1000,6 @@ public class PipController implements PipTransitionController.PipTransitionCallb
});
}
@Override
public void onKeyguardVisibilityChanged(boolean showing, boolean animating) {
mMainExecutor.execute(() -> {
PipController.this.onKeyguardVisibilityChanged(showing, animating);
});
}
@Override
public void onKeyguardDismissAnimationFinished() {
mMainExecutor.execute(PipController.this::onKeyguardDismissAnimationFinished);
}
@Override
public void dump(PrintWriter pw) {
try {

View File

@@ -77,12 +77,6 @@ public interface SplitScreen {
return null;
}
/**
* Called when the visibility of the keyguard changes.
* @param showing Indicates if the keyguard is now visible.
*/
void onKeyguardVisibilityChanged(boolean showing);
/** Called when device waking up finished. */
void onFinishedWakingUp();

View File

@@ -80,6 +80,8 @@ import com.android.wm.shell.draganddrop.DragAndDropPolicy;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.transition.LegacyTransitions;
import com.android.wm.shell.transition.Transitions;
@@ -99,7 +101,7 @@ import java.util.concurrent.Executor;
*/
// TODO(b/198577848): Implement split screen flicker test to consolidate CUJ of split screen.
public class SplitScreenController implements DragAndDropPolicy.Starter,
RemoteCallable<SplitScreenController> {
RemoteCallable<SplitScreenController>, KeyguardChangeListener {
private static final String TAG = SplitScreenController.class.getSimpleName();
public static final int EXIT_REASON_UNKNOWN = 0;
@@ -127,6 +129,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
@Retention(RetentionPolicy.SOURCE)
@interface ExitReason{}
private final ShellController mShellController;
private final ShellTaskOrganizer mTaskOrganizer;
private final SyncTransactionQueue mSyncQueue;
private final Context mContext;
@@ -147,7 +150,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
// outside the bounds of the roots by being reparented into a higher level fullscreen container
private SurfaceControl mSplitTasksContainerLayer;
public SplitScreenController(ShellTaskOrganizer shellTaskOrganizer,
public SplitScreenController(ShellController shellController,
ShellTaskOrganizer shellTaskOrganizer,
SyncTransactionQueue syncQueue, Context context,
RootTaskDisplayAreaOrganizer rootTDAOrganizer,
ShellExecutor mainExecutor, DisplayController displayController,
@@ -155,6 +159,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
DisplayInsetsController displayInsetsController,
Transitions transitions, TransactionPool transactionPool, IconProvider iconProvider,
Optional<RecentTasksController> recentTasks) {
mShellController = shellController;
mTaskOrganizer = shellTaskOrganizer;
mSyncQueue = syncQueue;
mContext = context;
@@ -185,6 +190,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
public void onOrganizerRegistered() {
mShellController.addKeyguardChangeListener(this);
if (mStageCoordinator == null) {
// TODO: Multi-display
mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
@@ -283,8 +289,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
mStageCoordinator.exitSplitScreen(toTopTaskId, exitReason);
}
public void onKeyguardVisibilityChanged(boolean showing) {
mStageCoordinator.onKeyguardVisibilityChanged(showing);
@Override
public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
boolean animatingDismiss) {
mStageCoordinator.onKeyguardVisibilityChanged(visible);
}
public void onFinishedWakingUp() {
@@ -657,13 +665,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
});
}
@Override
public void onKeyguardVisibilityChanged(boolean showing) {
mMainExecutor.execute(() -> {
SplitScreenController.this.onKeyguardVisibilityChanged(showing);
});
}
@Override
public void onFinishedWakingUp() {
mMainExecutor.execute(() -> {

View File

@@ -0,0 +1,36 @@
/*
* 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;
/**
* Callbacks for when the keyguard changes.
*/
public interface KeyguardChangeListener {
/**
* Notifies the Shell that the keyguard is showing (and if so, whether it is occluded).
*/
default void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
boolean animatingDismiss) {}
/**
* Notifies the Shell when the keyguard dismiss animation has finished.
*
* TODO(b/206741900) deprecate this path once we're able to animate the PiP window as part of
* keyguard dismiss animation.
*/
default void onKeyguardDismissAnimationFinished() {}
}

View File

@@ -47,7 +47,9 @@ public class ShellController {
private final ShellExecutor mMainExecutor;
private final ShellInterfaceImpl mImpl = new ShellInterfaceImpl();
private final CopyOnWriteArrayList<ConfigurationChangeListener> mListeners =
private final CopyOnWriteArrayList<ConfigurationChangeListener> mConfigChangeListeners =
new CopyOnWriteArrayList<>();
private final CopyOnWriteArrayList<KeyguardChangeListener> mKeyguardChangeListeners =
new CopyOnWriteArrayList<>();
private Configuration mLastConfiguration;
@@ -68,15 +70,31 @@ public class ShellController {
* particular order.
*/
public void addConfigurationChangeListener(ConfigurationChangeListener listener) {
mListeners.remove(listener);
mListeners.add(listener);
mConfigChangeListeners.remove(listener);
mConfigChangeListeners.add(listener);
}
/**
* Removes an existing configuration listener.
*/
public void removeConfigurationChangeListener(ConfigurationChangeListener listener) {
mListeners.remove(listener);
mConfigChangeListeners.remove(listener);
}
/**
* Adds a new Keyguard listener. The Keyguard change callbacks are not made in any
* particular order.
*/
public void addKeyguardChangeListener(KeyguardChangeListener listener) {
mKeyguardChangeListeners.remove(listener);
mKeyguardChangeListeners.add(listener);
}
/**
* Removes an existing Keyguard listener.
*/
public void removeKeyguardChangeListener(KeyguardChangeListener listener) {
mKeyguardChangeListeners.remove(listener);
}
@VisibleForTesting
@@ -102,7 +120,7 @@ public class ShellController {
// Update the last configuration and call listeners
mLastConfiguration.updateFrom(newConfig);
for (ConfigurationChangeListener listener : mListeners) {
for (ConfigurationChangeListener listener : mConfigChangeListeners) {
listener.onConfigurationChanged(newConfig);
if (densityFontScaleChanged) {
listener.onDensityOrFontScaleChanged();
@@ -119,11 +137,26 @@ public class ShellController {
}
}
@VisibleForTesting
void onKeyguardVisibilityChanged(boolean visible, boolean occluded, boolean animatingDismiss) {
for (KeyguardChangeListener listener : mKeyguardChangeListeners) {
listener.onKeyguardVisibilityChanged(visible, occluded, animatingDismiss);
}
}
@VisibleForTesting
void onKeyguardDismissAnimationFinished() {
for (KeyguardChangeListener listener : mKeyguardChangeListeners) {
listener.onKeyguardDismissAnimationFinished();
}
}
public void dump(@NonNull PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.println(prefix + TAG);
pw.println(innerPrefix + "mListeners=" + mListeners.size());
pw.println(innerPrefix + "mConfigChangeListeners=" + mConfigChangeListeners.size());
pw.println(innerPrefix + "mLastConfiguration=" + mLastConfiguration);
pw.println(innerPrefix + "mKeyguardChangeListeners=" + mKeyguardChangeListeners.size());
}
/**
@@ -136,5 +169,19 @@ public class ShellController {
mMainExecutor.execute(() ->
ShellController.this.onConfigurationChanged(newConfiguration));
}
@Override
public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
boolean animatingDismiss) {
mMainExecutor.execute(() ->
ShellController.this.onKeyguardVisibilityChanged(visible, occluded,
animatingDismiss));
}
@Override
public void onKeyguardDismissAnimationFinished() {
mMainExecutor.execute(() ->
ShellController.this.onKeyguardDismissAnimationFinished());
}
}
}

View File

@@ -30,4 +30,16 @@ public interface ShellInterface {
* Notifies the Shell that the configuration has changed.
*/
default void onConfigurationChanged(Configuration newConfiguration) {}
/**
* Notifies the Shell that the keyguard is showing (and if so, whether it is occluded) or not
* showing, and whether it is animating a dismiss.
*/
default void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
boolean animatingDismiss) {}
/**
* Notifies the Shell when the keyguard dismiss animation has finished.
*/
default void onKeyguardDismissAnimationFinished() {}
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright (C) 2021 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.tasksurfacehelper;
import android.app.ActivityManager.RunningTaskInfo;
import android.graphics.Rect;
import android.view.SurfaceControl;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
* Interface to communicate with a Task's SurfaceControl.
*/
public interface TaskSurfaceHelper {
/** Sets the METADATA_GAME_MODE for the layer corresponding to the task **/
default void setGameModeForTask(int taskId, int gameMode) {}
/** Takes a screenshot for a task **/
default void screenshotTask(RunningTaskInfo taskInfo, Rect crop, Executor executor,
Consumer<SurfaceControl.ScreenshotHardwareBuffer> consumer) {}
}

View File

@@ -1,82 +0,0 @@
/*
* Copyright (C) 2021 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.tasksurfacehelper;
import android.app.ActivityManager.RunningTaskInfo;
import android.graphics.Rect;
import android.view.SurfaceControl;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.ShellExecutor;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
* Intermediary controller that communicates with {@link ShellTaskOrganizer} to send commands
* to SurfaceControl.
*/
public class TaskSurfaceHelperController {
private final ShellTaskOrganizer mTaskOrganizer;
private final ShellExecutor mMainExecutor;
private final TaskSurfaceHelperImpl mImpl = new TaskSurfaceHelperImpl();
public TaskSurfaceHelperController(ShellTaskOrganizer taskOrganizer,
ShellExecutor mainExecutor) {
mTaskOrganizer = taskOrganizer;
mMainExecutor = mainExecutor;
}
public TaskSurfaceHelper asTaskSurfaceHelper() {
return mImpl;
}
/**
* Sends a Transaction to set the game mode metadata on the
* corresponding SurfaceControl
*/
public void setGameModeForTask(int taskId, int gameMode) {
mTaskOrganizer.setSurfaceMetadata(taskId, SurfaceControl.METADATA_GAME_MODE, gameMode);
}
/**
* Take screenshot of the specified task.
*/
public void screenshotTask(RunningTaskInfo taskInfo, Rect crop,
Consumer<SurfaceControl.ScreenshotHardwareBuffer> consumer) {
mTaskOrganizer.screenshotTask(taskInfo, crop, consumer);
}
private class TaskSurfaceHelperImpl implements TaskSurfaceHelper {
@Override
public void setGameModeForTask(int taskId, int gameMode) {
mMainExecutor.execute(() -> {
TaskSurfaceHelperController.this.setGameModeForTask(taskId, gameMode);
});
}
@Override
public void screenshotTask(RunningTaskInfo taskInfo, Rect crop, Executor executor,
Consumer<SurfaceControl.ScreenshotHardwareBuffer> consumer) {
mMainExecutor.execute(() -> {
TaskSurfaceHelperController.this.screenshotTask(taskInfo, crop,
(t) -> executor.execute(() -> consumer.accept(t)));
});
}
}
}

View File

@@ -53,6 +53,7 @@ import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.letterboxedu.LetterboxEduWindowManager;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.transition.Transitions;
import org.junit.Before;
@@ -78,6 +79,7 @@ public class CompatUIControllerTest extends ShellTestCase {
private static final int TASK_ID = 12;
private CompatUIController mController;
private @Mock ShellController mMockShellController;
private @Mock DisplayController mMockDisplayController;
private @Mock DisplayInsetsController mMockDisplayInsetsController;
private @Mock DisplayLayout mMockDisplayLayout;
@@ -105,7 +107,7 @@ public class CompatUIControllerTest extends ShellTestCase {
doReturn(TASK_ID).when(mMockLetterboxEduLayout).getTaskId();
doReturn(true).when(mMockLetterboxEduLayout).createLayout(anyBoolean());
doReturn(true).when(mMockLetterboxEduLayout).updateCompatInfo(any(), any(), anyBoolean());
mController = new CompatUIController(mContext, mMockDisplayController,
mController = new CompatUIController(mContext, mMockShellController, mMockDisplayController,
mMockDisplayInsetsController, mMockImeController, mMockSyncQueue, mMockExecutor,
mMockTransitionsLazy) {
@Override
@@ -123,6 +125,11 @@ public class CompatUIControllerTest extends ShellTestCase {
spyOn(mController);
}
@Test
public void instantiateController_registerKeyguardChangeListener() {
verify(mMockShellController, times(1)).addKeyguardChangeListener(any());
}
@Test
public void testListenerRegistered() {
verify(mMockDisplayController).addDisplayWindowListener(mController);
@@ -324,7 +331,7 @@ public class CompatUIControllerTest extends ShellTestCase {
/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
// Verify that the restart button is hidden after keyguard becomes showing.
mController.onKeyguardShowingChanged(true);
mController.onKeyguardVisibilityChanged(true, false, false);
verify(mMockCompatLayout).updateVisibility(false);
verify(mMockLetterboxEduLayout).updateVisibility(false);
@@ -340,7 +347,7 @@ public class CompatUIControllerTest extends ShellTestCase {
false);
// Verify button is shown after keyguard becomes not showing.
mController.onKeyguardShowingChanged(false);
mController.onKeyguardVisibilityChanged(false, false, false);
verify(mMockCompatLayout).updateVisibility(true);
verify(mMockLetterboxEduLayout).updateVisibility(true);
@@ -352,7 +359,7 @@ public class CompatUIControllerTest extends ShellTestCase {
/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
mController.onKeyguardShowingChanged(true);
mController.onKeyguardVisibilityChanged(true, false, false);
verify(mMockCompatLayout, times(2)).updateVisibility(false);
verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);
@@ -360,7 +367,7 @@ public class CompatUIControllerTest extends ShellTestCase {
clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout);
// Verify button remains hidden after keyguard becomes not showing since IME is showing.
mController.onKeyguardShowingChanged(false);
mController.onKeyguardVisibilityChanged(false, false, false);
verify(mMockCompatLayout).updateVisibility(false);
verify(mMockLetterboxEduLayout).updateVisibility(false);
@@ -378,7 +385,7 @@ public class CompatUIControllerTest extends ShellTestCase {
/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
mController.onKeyguardShowingChanged(true);
mController.onKeyguardVisibilityChanged(true, false, false);
verify(mMockCompatLayout, times(2)).updateVisibility(false);
verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);
@@ -392,7 +399,7 @@ public class CompatUIControllerTest extends ShellTestCase {
verify(mMockLetterboxEduLayout).updateVisibility(false);
// Verify button is shown after keyguard becomes not showing.
mController.onKeyguardShowingChanged(false);
mController.onKeyguardVisibilityChanged(false, false, false);
verify(mMockCompatLayout).updateVisibility(true);
verify(mMockLetterboxEduLayout).updateVisibility(true);

View File

@@ -29,7 +29,6 @@ import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.sysui.ShellController;
import org.junit.Before;
@@ -49,8 +48,6 @@ public class HideDisplayCutoutControllerTest extends ShellTestCase {
private ShellController mShellController;
@Mock
private HideDisplayCutoutOrganizer mMockDisplayAreaOrganizer;
@Mock
private ShellExecutor mMockMainExecutor;
private HideDisplayCutoutController mHideDisplayCutoutController;
@@ -58,7 +55,7 @@ public class HideDisplayCutoutControllerTest extends ShellTestCase {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mHideDisplayCutoutController = new HideDisplayCutoutController(
mContext, mShellController, mMockDisplayAreaOrganizer, mMockMainExecutor);
mContext, mShellController, mMockDisplayAreaOrganizer);
}
@Test

View File

@@ -148,6 +148,11 @@ public class OneHandedControllerTest extends OneHandedTestCase {
verify(mMockShellController, times(1)).addConfigurationChangeListener(any());
}
@Test
public void testControllerRegistersKeyguardChangeListener() {
verify(mMockShellController, times(1)).addKeyguardChangeListener(any());
}
@Test
public void testDefaultShouldNotInOneHanded() {
// Assert default transition state is STATE_NONE

View File

@@ -122,6 +122,11 @@ public class PipControllerTest extends ShellTestCase {
verify(mMockShellController, times(1)).addConfigurationChangeListener(any());
}
@Test
public void instantiatePipController_registerKeyguardChangeListener() {
verify(mMockShellController, times(1)).addKeyguardChangeListener(any());
}
@Test
public void instantiatePipController_registersPipTransitionCallback() {
verify(mMockPipTransitionController).registerPipTransitionCallback(any());

View File

@@ -28,6 +28,9 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.content.ComponentName;
@@ -44,10 +47,12 @@ import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.transition.Transitions;
import org.junit.Before;
@@ -65,6 +70,7 @@ import java.util.Optional;
@RunWith(AndroidJUnit4.class)
public class SplitScreenControllerTests extends ShellTestCase {
@Mock ShellController mShellController;
@Mock ShellTaskOrganizer mTaskOrganizer;
@Mock SyncTransactionQueue mSyncQueue;
@Mock RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
@@ -82,10 +88,17 @@ public class SplitScreenControllerTests extends ShellTestCase {
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mSplitScreenController = spy(new SplitScreenController(mTaskOrganizer, mSyncQueue, mContext,
mRootTDAOrganizer, mMainExecutor, mDisplayController, mDisplayImeController,
mDisplayInsetsController, mTransitions, mTransactionPool, mIconProvider,
mRecentTasks));
mSplitScreenController = spy(new SplitScreenController(mShellController, mTaskOrganizer,
mSyncQueue, mContext, mRootTDAOrganizer, mMainExecutor, mDisplayController,
mDisplayImeController, mDisplayInsetsController, mTransitions, mTransactionPool,
mIconProvider, mRecentTasks));
}
@Test
public void testControllerRegistersKeyguardChangeListener() {
when(mDisplayController.getDisplayLayout(anyInt())).thenReturn(new DisplayLayout());
mSplitScreenController.onOrganizerRegistered();
verify(mShellController, times(1)).addKeyguardChangeListener(any());
}
@Test

View File

@@ -46,12 +46,14 @@ public class ShellControllerTest extends ShellTestCase {
private ShellExecutor mExecutor;
private ShellController mController;
private TestConfigurationChangeListener mListener;
private TestConfigurationChangeListener mConfigChangeListener;
private TestKeyguardChangeListener mKeyguardChangeListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mListener = new TestConfigurationChangeListener();
mKeyguardChangeListener = new TestKeyguardChangeListener();
mConfigChangeListener = new TestConfigurationChangeListener();
mController = new ShellController(mExecutor);
mController.onConfigurationChanged(getConfigurationCopy());
}
@@ -61,48 +63,98 @@ public class ShellControllerTest extends ShellTestCase {
// Do nothing
}
@Test
public void testAddKeyguardChangeListener_ensureCallback() {
mController.addKeyguardChangeListener(mKeyguardChangeListener);
mController.onKeyguardVisibilityChanged(true, false, false);
assertTrue(mKeyguardChangeListener.visibilityChanged == 1);
assertTrue(mKeyguardChangeListener.dismissAnimationFinished == 0);
}
@Test
public void testDoubleAddKeyguardChangeListener_ensureSingleCallback() {
mController.addKeyguardChangeListener(mKeyguardChangeListener);
mController.addKeyguardChangeListener(mKeyguardChangeListener);
mController.onKeyguardVisibilityChanged(true, false, false);
assertTrue(mKeyguardChangeListener.visibilityChanged == 1);
assertTrue(mKeyguardChangeListener.dismissAnimationFinished == 0);
}
@Test
public void testAddRemoveKeyguardChangeListener_ensureNoCallback() {
mController.addKeyguardChangeListener(mKeyguardChangeListener);
mController.removeKeyguardChangeListener(mKeyguardChangeListener);
mController.onKeyguardVisibilityChanged(true, false, false);
assertTrue(mKeyguardChangeListener.visibilityChanged == 0);
assertTrue(mKeyguardChangeListener.dismissAnimationFinished == 0);
}
@Test
public void testKeyguardVisibilityChanged() {
mController.addKeyguardChangeListener(mKeyguardChangeListener);
mController.onKeyguardVisibilityChanged(true, true, true);
assertTrue(mKeyguardChangeListener.visibilityChanged == 1);
assertTrue(mKeyguardChangeListener.lastAnimatingDismiss);
assertTrue(mKeyguardChangeListener.lastOccluded);
assertTrue(mKeyguardChangeListener.lastAnimatingDismiss);
assertTrue(mKeyguardChangeListener.dismissAnimationFinished == 0);
}
@Test
public void testKeyguardDismissAnimationFinished() {
mController.addKeyguardChangeListener(mKeyguardChangeListener);
mController.onKeyguardDismissAnimationFinished();
assertTrue(mKeyguardChangeListener.visibilityChanged == 0);
assertTrue(mKeyguardChangeListener.dismissAnimationFinished == 1);
}
@Test
public void testAddConfigurationChangeListener_ensureCallback() {
mController.addConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
Configuration newConfig = getConfigurationCopy();
newConfig.densityDpi = 200;
mController.onConfigurationChanged(newConfig);
assertTrue(mListener.configChanges == 1);
assertTrue(mConfigChangeListener.configChanges == 1);
}
@Test
public void testDoubleAddConfigurationChangeListener_ensureSingleCallback() {
mController.addConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
Configuration newConfig = getConfigurationCopy();
newConfig.densityDpi = 200;
mController.onConfigurationChanged(newConfig);
assertTrue(mListener.configChanges == 1);
assertTrue(mConfigChangeListener.configChanges == 1);
}
@Test
public void testAddRemoveConfigurationChangeListener_ensureNoCallback() {
mController.addConfigurationChangeListener(mListener);
mController.removeConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
mController.removeConfigurationChangeListener(mConfigChangeListener);
Configuration newConfig = getConfigurationCopy();
newConfig.densityDpi = 200;
mController.onConfigurationChanged(newConfig);
assertTrue(mListener.configChanges == 0);
assertTrue(mConfigChangeListener.configChanges == 0);
}
@Test
public void testMultipleConfigurationChangeListeners() {
TestConfigurationChangeListener listener2 = new TestConfigurationChangeListener();
mController.addConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
mController.addConfigurationChangeListener(listener2);
Configuration newConfig = getConfigurationCopy();
newConfig.densityDpi = 200;
mController.onConfigurationChanged(newConfig);
assertTrue(mListener.configChanges == 1);
assertTrue(mConfigChangeListener.configChanges == 1);
assertTrue(listener2.configChanges == 1);
}
@@ -115,7 +167,7 @@ public class ShellControllerTest extends ShellTestCase {
}
};
mController.addConfigurationChangeListener(badListener);
mController.addConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
// Ensure we don't fail just because a listener was removed mid-callback
Configuration newConfig = getConfigurationCopy();
@@ -125,77 +177,77 @@ public class ShellControllerTest extends ShellTestCase {
@Test
public void testDensityChangeCallback() {
mController.addConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
Configuration newConfig = getConfigurationCopy();
newConfig.densityDpi = 200;
mController.onConfigurationChanged(newConfig);
assertTrue(mListener.configChanges == 1);
assertTrue(mListener.densityChanges == 1);
assertTrue(mListener.smallestWidthChanges == 0);
assertTrue(mListener.themeChanges == 0);
assertTrue(mListener.localeChanges == 0);
assertTrue(mConfigChangeListener.configChanges == 1);
assertTrue(mConfigChangeListener.densityChanges == 1);
assertTrue(mConfigChangeListener.smallestWidthChanges == 0);
assertTrue(mConfigChangeListener.themeChanges == 0);
assertTrue(mConfigChangeListener.localeChanges == 0);
}
@Test
public void testFontScaleChangeCallback() {
mController.addConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
Configuration newConfig = getConfigurationCopy();
newConfig.fontScale = 2;
mController.onConfigurationChanged(newConfig);
assertTrue(mListener.configChanges == 1);
assertTrue(mListener.densityChanges == 1);
assertTrue(mListener.smallestWidthChanges == 0);
assertTrue(mListener.themeChanges == 0);
assertTrue(mListener.localeChanges == 0);
assertTrue(mConfigChangeListener.configChanges == 1);
assertTrue(mConfigChangeListener.densityChanges == 1);
assertTrue(mConfigChangeListener.smallestWidthChanges == 0);
assertTrue(mConfigChangeListener.themeChanges == 0);
assertTrue(mConfigChangeListener.localeChanges == 0);
}
@Test
public void testSmallestWidthChangeCallback() {
mController.addConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
Configuration newConfig = getConfigurationCopy();
newConfig.smallestScreenWidthDp = 100;
mController.onConfigurationChanged(newConfig);
assertTrue(mListener.configChanges == 1);
assertTrue(mListener.densityChanges == 0);
assertTrue(mListener.smallestWidthChanges == 1);
assertTrue(mListener.themeChanges == 0);
assertTrue(mListener.localeChanges == 0);
assertTrue(mConfigChangeListener.configChanges == 1);
assertTrue(mConfigChangeListener.densityChanges == 0);
assertTrue(mConfigChangeListener.smallestWidthChanges == 1);
assertTrue(mConfigChangeListener.themeChanges == 0);
assertTrue(mConfigChangeListener.localeChanges == 0);
}
@Test
public void testThemeChangeCallback() {
mController.addConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
Configuration newConfig = getConfigurationCopy();
newConfig.assetsSeq++;
mController.onConfigurationChanged(newConfig);
assertTrue(mListener.configChanges == 1);
assertTrue(mListener.densityChanges == 0);
assertTrue(mListener.smallestWidthChanges == 0);
assertTrue(mListener.themeChanges == 1);
assertTrue(mListener.localeChanges == 0);
assertTrue(mConfigChangeListener.configChanges == 1);
assertTrue(mConfigChangeListener.densityChanges == 0);
assertTrue(mConfigChangeListener.smallestWidthChanges == 0);
assertTrue(mConfigChangeListener.themeChanges == 1);
assertTrue(mConfigChangeListener.localeChanges == 0);
}
@Test
public void testNightModeChangeCallback() {
mController.addConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
Configuration newConfig = getConfigurationCopy();
newConfig.uiMode = Configuration.UI_MODE_NIGHT_YES;
mController.onConfigurationChanged(newConfig);
assertTrue(mListener.configChanges == 1);
assertTrue(mListener.densityChanges == 0);
assertTrue(mListener.smallestWidthChanges == 0);
assertTrue(mListener.themeChanges == 1);
assertTrue(mListener.localeChanges == 0);
assertTrue(mConfigChangeListener.configChanges == 1);
assertTrue(mConfigChangeListener.densityChanges == 0);
assertTrue(mConfigChangeListener.smallestWidthChanges == 0);
assertTrue(mConfigChangeListener.themeChanges == 1);
assertTrue(mConfigChangeListener.localeChanges == 0);
}
@Test
public void testLocaleChangeCallback() {
mController.addConfigurationChangeListener(mListener);
mController.addConfigurationChangeListener(mConfigChangeListener);
Configuration newConfig = getConfigurationCopy();
// Just change the locales to be different
@@ -205,11 +257,11 @@ public class ShellControllerTest extends ShellTestCase {
newConfig.locale = Locale.CANADA;
}
mController.onConfigurationChanged(newConfig);
assertTrue(mListener.configChanges == 1);
assertTrue(mListener.densityChanges == 0);
assertTrue(mListener.smallestWidthChanges == 0);
assertTrue(mListener.themeChanges == 0);
assertTrue(mListener.localeChanges == 1);
assertTrue(mConfigChangeListener.configChanges == 1);
assertTrue(mConfigChangeListener.densityChanges == 0);
assertTrue(mConfigChangeListener.smallestWidthChanges == 0);
assertTrue(mConfigChangeListener.themeChanges == 0);
assertTrue(mConfigChangeListener.localeChanges == 1);
}
private Configuration getConfigurationCopy() {
@@ -253,4 +305,27 @@ public class ShellControllerTest extends ShellTestCase {
localeChanges++;
}
}
private class TestKeyguardChangeListener implements KeyguardChangeListener {
// Counts of number of times each of the callbacks are called
public int visibilityChanged;
public boolean lastVisibility;
public boolean lastOccluded;
public boolean lastAnimatingDismiss;
public int dismissAnimationFinished;
@Override
public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
boolean animatingDismiss) {
lastVisibility = visible;
lastOccluded = occluded;
lastAnimatingDismiss = animatingDismiss;
visibilityChanged++;
}
@Override
public void onKeyguardDismissAnimationFinished() {
dismissAnimationFinished++;
}
}
}

View File

@@ -1,57 +0,0 @@
/*
* Copyright (C) 2021 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.tasksurfacehelper;
import static org.mockito.Mockito.verify;
import android.testing.AndroidTestingRunner;
import android.view.SurfaceControl;
import androidx.test.filters.SmallTest;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.ShellExecutor;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@RunWith(AndroidTestingRunner.class)
@SmallTest
public class TaskSurfaceHelperControllerTest extends ShellTestCase {
private TaskSurfaceHelperController mTaskSurfaceHelperController;
@Mock
private ShellTaskOrganizer mMockTaskOrganizer;
@Mock
private ShellExecutor mMockShellExecutor;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mTaskSurfaceHelperController = new TaskSurfaceHelperController(
mMockTaskOrganizer, mMockShellExecutor);
}
@Test
public void testSetGameModeForTask() {
mTaskSurfaceHelperController.setGameModeForTask(/*taskId*/1, /*gameMode*/3);
verify(mMockTaskOrganizer).setSurfaceMetadata(1, SurfaceControl.METADATA_GAME_MODE, 3);
}
}

View File

@@ -96,16 +96,12 @@ public abstract class SystemUIInitializer {
.setSplitScreen(mWMComponent.getSplitScreen())
.setOneHanded(mWMComponent.getOneHanded())
.setBubbles(mWMComponent.getBubbles())
.setHideDisplayCutout(mWMComponent.getHideDisplayCutout())
.setShellCommandHandler(mWMComponent.getShellCommandHandler())
.setTaskViewFactory(mWMComponent.getTaskViewFactory())
.setTransitions(mWMComponent.getTransitions())
.setStartingSurface(mWMComponent.getStartingSurface())
.setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper())
.setTaskSurfaceHelper(mWMComponent.getTaskSurfaceHelper())
.setRecentTasks(mWMComponent.getRecentTasks())
.setCompatUI(mWMComponent.getCompatUI())
.setDragAndDrop(mWMComponent.getDragAndDrop())
.setBackAnimation(mWMComponent.getBackAnimation());
} else {
// TODO: Call on prepareSysUIComponentBuilder but not with real components. Other option
@@ -116,16 +112,12 @@ public abstract class SystemUIInitializer {
.setSplitScreen(Optional.ofNullable(null))
.setOneHanded(Optional.ofNullable(null))
.setBubbles(Optional.ofNullable(null))
.setHideDisplayCutout(Optional.ofNullable(null))
.setShellCommandHandler(Optional.ofNullable(null))
.setTaskViewFactory(Optional.ofNullable(null))
.setTransitions(new ShellTransitions() {})
.setDisplayAreaHelper(Optional.ofNullable(null))
.setStartingSurface(Optional.ofNullable(null))
.setTaskSurfaceHelper(Optional.ofNullable(null))
.setRecentTasks(Optional.ofNullable(null))
.setCompatUI(Optional.ofNullable(null))
.setDragAndDrop(Optional.ofNullable(null))
.setBackAnimation(Optional.ofNullable(null));
}
mSysUIComponent = builder.build();

View File

@@ -41,17 +41,13 @@ import com.android.wm.shell.ShellCommandHandler;
import com.android.wm.shell.TaskViewFactory;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.compatui.CompatUI;
import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
import com.android.wm.shell.draganddrop.DragAndDrop;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
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.sysui.ShellInterface;
import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper;
import com.android.wm.shell.transition.ShellTransitions;
import java.util.Map;
@@ -99,9 +95,6 @@ public interface SysUIComponent {
@BindsInstance
Builder setTaskViewFactory(Optional<TaskViewFactory> t);
@BindsInstance
Builder setHideDisplayCutout(Optional<HideDisplayCutout> h);
@BindsInstance
Builder setShellCommandHandler(Optional<ShellCommandHandler> shellDump);
@@ -114,18 +107,9 @@ public interface SysUIComponent {
@BindsInstance
Builder setDisplayAreaHelper(Optional<DisplayAreaHelper> h);
@BindsInstance
Builder setTaskSurfaceHelper(Optional<TaskSurfaceHelper> t);
@BindsInstance
Builder setRecentTasks(Optional<RecentTasks> r);
@BindsInstance
Builder setCompatUI(Optional<CompatUI> s);
@BindsInstance
Builder setDragAndDrop(Optional<DragAndDrop> d);
@BindsInstance
Builder setBackAnimation(Optional<BackAnimation> b);

View File

@@ -29,20 +29,16 @@ import com.android.wm.shell.TaskViewFactory;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.compatui.CompatUI;
import com.android.wm.shell.dagger.TvWMShellModule;
import com.android.wm.shell.dagger.WMShellModule;
import com.android.wm.shell.dagger.WMSingleton;
import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
import com.android.wm.shell.draganddrop.DragAndDrop;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
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.sysui.ShellInterface;
import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper;
import com.android.wm.shell.transition.ShellTransitions;
import java.util.Optional;
@@ -103,9 +99,6 @@ public interface WMComponent {
@WMSingleton
Optional<Bubbles> getBubbles();
@WMSingleton
Optional<HideDisplayCutout> getHideDisplayCutout();
@WMSingleton
Optional<TaskViewFactory> getTaskViewFactory();
@@ -118,18 +111,9 @@ public interface WMComponent {
@WMSingleton
Optional<DisplayAreaHelper> getDisplayAreaHelper();
@WMSingleton
Optional<TaskSurfaceHelper> getTaskSurfaceHelper();
@WMSingleton
Optional<RecentTasks> getRecentTasks();
@WMSingleton
Optional<CompatUI> getCompatUI();
@WMSingleton
Optional<DragAndDrop> getDragAndDrop();
@WMSingleton
Optional<BackAnimation> getBackAnimation();
}

View File

@@ -34,7 +34,6 @@ import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;

View File

@@ -55,9 +55,6 @@ import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.tracing.ProtoTracer;
import com.android.systemui.tracing.nano.SystemUiTraceProto;
import com.android.wm.shell.ShellCommandHandler;
import com.android.wm.shell.compatui.CompatUI;
import com.android.wm.shell.draganddrop.DragAndDrop;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.nano.WmShellTraceProto;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.onehanded.OneHandedEventCallback;
@@ -110,10 +107,7 @@ public final class WMShell extends CoreStartable
private final Optional<Pip> mPipOptional;
private final Optional<SplitScreen> mSplitScreenOptional;
private final Optional<OneHanded> mOneHandedOptional;
private final Optional<HideDisplayCutout> mHideDisplayCutoutOptional;
private final Optional<ShellCommandHandler> mShellCommandHandler;
private final Optional<CompatUI> mCompatUIOptional;
private final Optional<DragAndDrop> mDragAndDropOptional;
private final CommandQueue mCommandQueue;
private final ConfigurationController mConfigurationController;
@@ -127,10 +121,7 @@ public final class WMShell extends CoreStartable
private final Executor mSysUiMainExecutor;
private boolean mIsSysUiStateValid;
private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback;
private KeyguardUpdateMonitorCallback mPipKeyguardCallback;
private KeyguardUpdateMonitorCallback mOneHandedKeyguardCallback;
private KeyguardStateController.Callback mCompatUIKeyguardCallback;
private WakefulnessLifecycle.Observer mWakefulnessObserver;
@Inject
@@ -139,10 +130,7 @@ public final class WMShell extends CoreStartable
Optional<Pip> pipOptional,
Optional<SplitScreen> splitScreenOptional,
Optional<OneHanded> oneHandedOptional,
Optional<HideDisplayCutout> hideDisplayCutoutOptional,
Optional<ShellCommandHandler> shellCommandHandler,
Optional<CompatUI> sizeCompatUIOptional,
Optional<DragAndDrop> dragAndDropOptional,
CommandQueue commandQueue,
ConfigurationController configurationController,
KeyguardStateController keyguardStateController,
@@ -164,12 +152,9 @@ public final class WMShell extends CoreStartable
mPipOptional = pipOptional;
mSplitScreenOptional = splitScreenOptional;
mOneHandedOptional = oneHandedOptional;
mHideDisplayCutoutOptional = hideDisplayCutoutOptional;
mWakefulnessLifecycle = wakefulnessLifecycle;
mProtoTracer = protoTracer;
mShellCommandHandler = shellCommandHandler;
mCompatUIOptional = sizeCompatUIOptional;
mDragAndDropOptional = dragAndDropOptional;
mUserInfoController = userInfoController;
mSysUiMainExecutor = sysUiMainExecutor;
}
@@ -185,6 +170,22 @@ public final class WMShell extends CoreStartable
}
});
// Subscribe to keyguard changes
mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
@Override
public void onKeyguardShowingChanged() {
mShell.onKeyguardVisibilityChanged(mKeyguardStateController.isShowing(),
mKeyguardStateController.isOccluded(),
mKeyguardStateController.isAnimatingBetweenKeyguardAndSurfaceBehind());
}
});
mKeyguardUpdateMonitor.registerCallback(new KeyguardUpdateMonitorCallback() {
@Override
public void onKeyguardDismissAnimationFinished() {
mShell.onKeyguardDismissAnimationFinished();
}
});
// TODO: Consider piping config change and other common calls to a shell component to
// delegate internally
mProtoTracer.add(this);
@@ -192,7 +193,6 @@ public final class WMShell extends CoreStartable
mPipOptional.ifPresent(this::initPip);
mSplitScreenOptional.ifPresent(this::initSplitScreen);
mOneHandedOptional.ifPresent(this::initOneHanded);
mCompatUIOptional.ifPresent(this::initCompatUi);
}
@VisibleForTesting
@@ -204,20 +204,6 @@ public final class WMShell extends CoreStartable
}
});
mPipKeyguardCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onKeyguardVisibilityChanged(boolean showing) {
pip.onKeyguardVisibilityChanged(showing,
mKeyguardStateController.isAnimatingBetweenKeyguardAndSurfaceBehind());
}
@Override
public void onKeyguardDismissAnimationFinished() {
pip.onKeyguardDismissAnimationFinished();
}
};
mKeyguardUpdateMonitor.registerCallback(mPipKeyguardCallback);
mSysUiState.addCallback(sysUiStateFlag -> {
mIsSysUiStateValid = (sysUiStateFlag & INVALID_SYSUI_STATE_MASK) == 0;
pip.onSystemUiStateChanged(mIsSysUiStateValid, sysUiStateFlag);
@@ -230,14 +216,6 @@ public final class WMShell extends CoreStartable
@VisibleForTesting
void initSplitScreen(SplitScreen splitScreen) {
mSplitScreenKeyguardCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onKeyguardVisibilityChanged(boolean showing) {
splitScreen.onKeyguardVisibilityChanged(showing);
}
};
mKeyguardUpdateMonitor.registerCallback(mSplitScreenKeyguardCallback);
mWakefulnessLifecycle.addObserver(new WakefulnessLifecycle.Observer() {
@Override
public void onFinishedWakingUp() {
@@ -283,13 +261,8 @@ public final class WMShell extends CoreStartable
}
});
// TODO: Either move into ShellInterface or register a receiver on the Shell side directly
mOneHandedKeyguardCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onKeyguardVisibilityChanged(boolean showing) {
oneHanded.onKeyguardVisibilityChanged(showing);
oneHanded.stopOneHanded();
}
@Override
public void onUserSwitchComplete(int userId) {
oneHanded.onUserSwitch(userId);
@@ -340,17 +313,6 @@ public final class WMShell extends CoreStartable
});
}
@VisibleForTesting
void initCompatUi(CompatUI sizeCompatUI) {
mCompatUIKeyguardCallback = new KeyguardStateController.Callback() {
@Override
public void onKeyguardShowingChanged() {
sizeCompatUI.onKeyguardShowingChanged(mKeyguardStateController.isShowing());
}
};
mKeyguardStateController.addCallback(mCompatUIKeyguardCallback);
}
@Override
public void writeToProto(SystemUiTraceProto proto) {
if (proto.wmShell == null) {

View File

@@ -24,12 +24,10 @@ import android.test.suitebuilder.annotation.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -37,9 +35,6 @@ import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.tracing.ProtoTracer;
import com.android.wm.shell.ShellCommandHandler;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.compatui.CompatUI;
import com.android.wm.shell.draganddrop.DragAndDrop;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.onehanded.OneHandedEventCallback;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
@@ -71,31 +66,25 @@ public class WMShellTest extends SysuiTestCase {
@Mock ConfigurationController mConfigurationController;
@Mock KeyguardStateController mKeyguardStateController;
@Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock NavigationModeController mNavigationModeController;
@Mock ScreenLifecycle mScreenLifecycle;
@Mock SysUiState mSysUiState;
@Mock Pip mPip;
@Mock SplitScreen mSplitScreen;
@Mock OneHanded mOneHanded;
@Mock HideDisplayCutout mHideDisplayCutout;
@Mock WakefulnessLifecycle mWakefulnessLifecycle;
@Mock ProtoTracer mProtoTracer;
@Mock ShellCommandHandler mShellCommandHandler;
@Mock CompatUI mCompatUI;
@Mock UserInfoController mUserInfoController;
@Mock ShellExecutor mSysUiMainExecutor;
@Mock DragAndDrop mDragAndDrop;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mWMShell = new WMShell(mContext, mShellInterface, Optional.of(mPip),
Optional.of(mSplitScreen), Optional.of(mOneHanded), Optional.of(mHideDisplayCutout),
Optional.of(mShellCommandHandler), Optional.of(mCompatUI),
Optional.of(mDragAndDrop),
mCommandQueue, mConfigurationController, mKeyguardStateController,
mKeyguardUpdateMonitor, mScreenLifecycle, mSysUiState,
Optional.of(mSplitScreen), Optional.of(mOneHanded),
Optional.of(mShellCommandHandler), mCommandQueue, mConfigurationController,
mKeyguardStateController, mKeyguardUpdateMonitor, mScreenLifecycle, mSysUiState,
mProtoTracer, mWakefulnessLifecycle, mUserInfoController, mSysUiMainExecutor);
}
@@ -106,28 +95,13 @@ public class WMShellTest extends SysuiTestCase {
verify(mCommandQueue).addCallback(any(CommandQueue.Callbacks.class));
}
@Test
public void initSplitScreen_registersCallbacks() {
mWMShell.initSplitScreen(mSplitScreen);
verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class));
}
@Test
public void initOneHanded_registersCallbacks() {
mWMShell.initOneHanded(mOneHanded);
verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class));
verify(mCommandQueue).addCallback(any(CommandQueue.Callbacks.class));
verify(mScreenLifecycle).addObserver(any(ScreenLifecycle.Observer.class));
verify(mOneHanded).registerTransitionCallback(any(OneHandedTransitionCallback.class));
verify(mOneHanded).registerEventCallback(any(OneHandedEventCallback.class));
}
@Test
public void initCompatUI_registersCallbacks() {
mWMShell.initCompatUi(mCompatUI);
verify(mKeyguardStateController).addCallback(any(KeyguardStateController.Callback.class));
}
}