Isolate shell dependencies

- Add initializer path for required shell dependencies
- Move shell dependencies into WMComponent scope, and expose shell
  features to SysUIComponent explicitly
- Moved temporary Bubble's specific dependencies to global scope until
  the migration finishes

Bug: 162923491
Test: atest WMShellUnitTestsWMShellUnitTests
Test: make SystemUIGoogle CarSystemUI ArcSystemUI AAECarSystemUI
Test: Verify pip/split/onehanded/bubbles still works

Change-Id: Ibaa8b5a718f32a1fff49d1756a18a009d6ad164f
Signed-off-by: Winson Chung <winsonc@google.com>
This commit is contained in:
Winson Chung
2020-10-06 15:48:46 -07:00
parent fe82ad21fe
commit f56eee702a
28 changed files with 311 additions and 152 deletions

View File

@@ -69,11 +69,6 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
private final SparseArray<PerDisplay> mImePerDisplay = new SparseArray<>();
private final ArrayList<ImePositionProcessor> mPositionProcessors = new ArrayList<>();
@Deprecated
public DisplayImeController(IWindowManager wmService, DisplayController displayController,
Handler mainHandler, TransactionPool transactionPool) {
this(wmService, displayController, mainHandler::post, transactionPool);
}
public DisplayImeController(IWindowManager wmService, DisplayController displayController,
Executor mainExecutor, TransactionPool transactionPool) {

View File

@@ -98,7 +98,7 @@ public interface Pip {
/**
* Hides the PIP menu.
*/
void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback);
default void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {}
/**
* Returns {@code true} if PIP is shown.
@@ -226,7 +226,7 @@ public interface Pip {
/**
* Called when showing Pip menu.
*/
void showPictureInPictureMenu();
default void showPictureInPictureMenu() {}
/**
* Suspends resizing operation on the Pip until {@link #resumePipResizing} is called.

View File

@@ -19,6 +19,7 @@ package com.android.systemui;
import com.android.systemui.dagger.GlobalModule;
import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.WMModule;
import com.android.systemui.wmshell.CarWMComponent;
import javax.inject.Singleton;
@@ -41,6 +42,12 @@ public interface CarGlobalRootComponent extends GlobalRootComponent {
CarGlobalRootComponent build();
}
/**
* Builder for a WMComponent.
*/
@Override
CarWMComponent.Builder getWMComponentBuilder();
@Override
CarSysUIComponent.Builder getSysUIComponent();
}

View File

@@ -64,7 +64,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.volume.VolumeDialogComponent;
import com.android.systemui.wmshell.CarWMShellModule;
import javax.inject.Named;
@@ -74,8 +73,7 @@ import dagger.Provides;
@Module(
includes = {
QSModule.class,
CarWMShellModule.class
QSModule.class
})
abstract class CarSystemUIModule {

View File

@@ -0,0 +1,39 @@
/*
* 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.systemui.wmshell;
import com.android.systemui.dagger.WMComponent;
import com.android.systemui.dagger.WMSingleton;
import dagger.Subcomponent;
/**
* Dagger Subcomponent for WindowManager.
*/
@WMSingleton
@Subcomponent(modules = {CarWMShellModule.class})
public interface CarWMComponent extends WMComponent {
/**
* Builder for a SysUIComponent.
*/
@Subcomponent.Builder
interface Builder extends WMComponent.Builder {
CarWMComponent build();
}
}

View File

@@ -20,7 +20,7 @@ import android.content.Context;
import android.os.Handler;
import android.view.IWindowManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.WMSingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.wm.DisplaySystemBarsController;
import com.android.wm.shell.common.DisplayController;
@@ -35,7 +35,7 @@ import dagger.Provides;
/** Provides dependencies from {@link com.android.wm.shell} for CarSystemUI. */
@Module(includes = WMShellBaseModule.class)
public abstract class CarWMShellModule {
@SysUISingleton
@WMSingleton
@Provides
static DisplayImeController provideDisplayImeController(Context context,
IWindowManager wmService, DisplayController displayController,

View File

@@ -119,13 +119,11 @@ import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tracing.ProtoTracer;
import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.leak.GarbageMonitor;
import com.android.systemui.util.leak.LeakDetector;
import com.android.systemui.util.leak.LeakReporter;
import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.SystemWindows;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -340,12 +338,10 @@ public class Dependency {
@Inject Lazy<CommandQueue> mCommandQueue;
@Inject Lazy<Recents> mRecents;
@Inject Lazy<StatusBar> mStatusBar;
@Inject Lazy<DisplayController> mDisplayController;
@Inject Lazy<SystemWindows> mSystemWindows;
@Inject Lazy<DisplayImeController> mDisplayImeController;
@Inject Lazy<RecordingController> mRecordingController;
@Inject Lazy<ProtoTracer> mProtoTracer;
@Inject Lazy<MediaOutputDialogFactory> mMediaOutputDialogFactory;
@Inject Lazy<DeviceConfigProxy> mDeviceConfigProxy;
@Inject
public Dependency() {
@@ -530,10 +526,8 @@ public class Dependency {
mProviders.put(CommandQueue.class, mCommandQueue::get);
mProviders.put(Recents.class, mRecents::get);
mProviders.put(StatusBar.class, mStatusBar::get);
mProviders.put(DisplayController.class, mDisplayController::get);
mProviders.put(SystemWindows.class, mSystemWindows::get);
mProviders.put(DisplayImeController.class, mDisplayImeController::get);
mProviders.put(ProtoTracer.class, mProtoTracer::get);
mProviders.put(DeviceConfigProxy.class, mDeviceConfigProxy::get);
// TODO(b/118592525): to support multi-display , we start to add something which is
// per-display, while others may be global. I think it's time to add

View File

@@ -30,6 +30,7 @@ import com.android.systemui.dagger.WMComponent;
import com.android.systemui.navigationbar.gestural.BackGestureTfClassifierProvider;
import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
@@ -49,6 +50,11 @@ public class SystemUIFactory {
}
public static void createFromConfig(Context context) {
createFromConfig(context, false);
}
@VisibleForTesting
public static void createFromConfig(Context context, boolean fromTest) {
if (mFactory != null) {
return;
}
@@ -62,7 +68,7 @@ public class SystemUIFactory {
Class<?> cls = null;
cls = context.getClassLoader().loadClass(clsName);
mFactory = (SystemUIFactory) cls.newInstance();
mFactory.init(context);
mFactory.init(context, fromTest);
} catch (Throwable t) {
Log.w(TAG, "Error creating SystemUIFactory component: " + clsName, t);
throw new RuntimeException(t);
@@ -76,16 +82,38 @@ public class SystemUIFactory {
public SystemUIFactory() {}
private void init(Context context) throws ExecutionException, InterruptedException {
@VisibleForTesting
public void init(Context context, boolean fromTest)
throws ExecutionException, InterruptedException {
mRootComponent = buildGlobalRootComponent(context);
// Stand up WMComponent
mWMComponent = mRootComponent.getWMComponentBuilder().build();
if (!fromTest) {
// Only initialize when not starting from tests since this currently initializes some
// components that shouldn't be run in the test environment
mWMComponent.init();
}
// And finally, retrieve whatever SysUI needs from WMShell and build SysUI.
// TODO: StubAPIClass is just a placeholder.
mSysUIComponent = mRootComponent.getSysUIComponent()
.setStubAPIClass(mWMComponent.createStubAPIClass())
SysUIComponent.Builder builder = mRootComponent.getSysUIComponent();
if (!fromTest) {
// Only initialize when not starting from tests since this currently initializes some
// components that shouldn't be run in the test environment
builder = builder.setPip(mWMComponent.getPip())
.setSplitScreen(mWMComponent.getSplitScreen())
.setOneHanded(mWMComponent.getOneHanded());
} else {
builder = builder.setPip(Optional.ofNullable(null))
.setSplitScreen(Optional.ofNullable(null))
.setOneHanded(Optional.ofNullable(null));
}
mSysUIComponent = builder
.setInputConsumerController(mWMComponent.getInputConsumerController())
.setShellTaskOrganizer(mWMComponent.getShellTaskOrganizer())
.build();
if (!fromTest) {
mSysUIComponent.init();
}
// Every other part of our codebase currently relies on Dependency, so we
// really need to ensure the Dependency gets initialized early on.
@@ -93,6 +121,16 @@ public class SystemUIFactory {
dependency.start();
}
/**
* Prepares the SysUIComponent builder before it is built.
* @param sysUIBuilder the builder provided by the root component's getSysUIComponent() method
* @param wm the built WMComponent from the root component's getWMComponent() method
*/
protected SysUIComponent.Builder prepareSysUIComponentBuilder(
SysUIComponent.Builder sysUIBuilder, WMComponent wm) {
return sysUIBuilder;
}
protected GlobalRootComponent buildGlobalRootComponent(Context context) {
return DaggerGlobalRootComponent.builder()
.context(context)

View File

@@ -38,7 +38,6 @@ import android.view.accessibility.AccessibilityManager;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.util.NotificationMessagingUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
@@ -340,13 +339,6 @@ public class DependencyProvider {
return Choreographer.getInstance();
}
/** Provides an instance of {@link com.android.internal.logging.UiEventLogger} */
@Provides
@SysUISingleton
static UiEventLogger provideUiEventLogger() {
return new UiEventLoggerImpl();
}
/** */
@Provides
@SysUISingleton

View File

@@ -16,9 +16,20 @@
package com.android.systemui.dagger;
import android.content.Context;
import android.util.DisplayMetrics;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.systemui.util.concurrency.GlobalConcurrencyModule;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.animation.FlingAnimationUtils;
import com.android.wm.shell.common.FloatingContentCoordinator;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
/**
* Supplies globally scoped instances that should be available in all versions of SystemUI
@@ -39,4 +50,38 @@ import dagger.Module;
FrameworkServicesModule.class,
GlobalConcurrencyModule.class})
public class GlobalModule {
// TODO(b/161980186): Currently only used by Bubbles, can move back to WMShellBaseModule once
// Bubbles has migrated over
@Singleton
@Provides
static FloatingContentCoordinator provideFloatingContentCoordinator() {
return new FloatingContentCoordinator();
}
// TODO(b/161980186): Currently only used by Bubbles, can move back to WMShellBaseModule once
// Bubbles has migrated over
@Singleton
@Provides
static WindowManagerShellWrapper provideWindowManagerShellWrapper() {
return new WindowManagerShellWrapper();
}
// TODO(b/162923491): This should not be a singleton at all, the display metrics can change and
// callers should be creating a new builder on demand
@Singleton
@Provides
static FlingAnimationUtils.Builder provideFlingAnimationUtilsBuilder(
Context context) {
DisplayMetrics displayMetrics = new DisplayMetrics();
context.getDisplay().getMetrics(displayMetrics);
return new FlingAnimationUtils.Builder(displayMetrics);
}
/** Provides an instance of {@link com.android.internal.logging.UiEventLogger} */
@Provides
@Singleton
static UiEventLogger provideUiEventLogger() {
return new UiEventLoggerImpl();
}
}

View File

@@ -52,7 +52,7 @@ public interface GlobalRootComponent {
WMComponent.Builder getWMComponentBuilder();
/**
* Builder for a SysuiComponent.
* Builder for a SysUIComponent.
*/
SysUIComponent.Builder getSysUIComponent();

View File

@@ -22,8 +22,15 @@ import com.android.systemui.InitController;
import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.InjectionInflationController;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.splitscreen.SplitScreen;
import java.util.Optional;
import dagger.BindsInstance;
import dagger.Subcomponent;
@@ -43,14 +50,34 @@ public interface SysUIComponent {
/**
* Builder for a SysUIComponent.
*/
@SysUISingleton
@Subcomponent.Builder
interface Builder {
@BindsInstance
Builder setStubAPIClass(WMComponent.StubAPIClass stubAPIClass);
Builder setPip(Optional<Pip> p);
@BindsInstance
Builder setSplitScreen(Optional<SplitScreen> s);
@BindsInstance
Builder setOneHanded(Optional<OneHanded> o);
@BindsInstance
Builder setInputConsumerController(InputConsumerController i);
@BindsInstance
Builder setShellTaskOrganizer(ShellTaskOrganizer s);
SysUIComponent build();
}
/**
* Initializes all the SysUI components.
*/
default void init() {
// Do nothing
}
/**
* Provides a BootCompleteCache.
*/

View File

@@ -62,7 +62,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.wmshell.WMShellModule;
import javax.inject.Named;
@@ -76,8 +75,7 @@ import dagger.Provides;
*/
@Module(includes = {
MediaModule.class,
QSModule.class,
WMShellModule.class
QSModule.class
})
public abstract class SystemUIDefaultModule {

View File

@@ -21,6 +21,7 @@ import com.android.systemui.BootCompleteCache;
import com.android.systemui.BootCompleteCacheImpl;
import com.android.systemui.appops.dagger.AppOpsModule;
import com.android.systemui.assist.AssistModule;
import com.android.systemui.bubbles.Bubbles;
import com.android.systemui.controls.dagger.ControlsModule;
import com.android.systemui.demomode.dagger.DemoModeModule;
import com.android.systemui.doze.dagger.DozeComponent;
@@ -125,6 +126,9 @@ public abstract class SystemUIModule {
@BindsOptionalOf
abstract StatusBar optionalStatusBar();
@BindsOptionalOf
abstract Bubbles optionalBubbles();
@SysUISingleton
@Binds
abstract SystemClock bindSystemClock(SystemClockImpl systemClock);

View File

@@ -16,7 +16,15 @@
package com.android.systemui.dagger;
import javax.inject.Inject;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.wmshell.WMShellModule;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.splitscreen.SplitScreen;
import java.util.Optional;
import dagger.Subcomponent;
@@ -24,7 +32,7 @@ import dagger.Subcomponent;
* Dagger Subcomponent for WindowManager.
*/
@WMSingleton
@Subcomponent(modules = {})
@Subcomponent(modules = {WMShellModule.class})
public interface WMComponent {
/**
@@ -35,18 +43,36 @@ public interface WMComponent {
WMComponent build();
}
/**
* Example class used for passing an API to SysUI from WMShell.
*
* TODO: Remove this once real WM classes are ready to go.
**/
@WMSingleton
class StubAPIClass {
@Inject
StubAPIClass() {}
* Initializes all the WMShell components before starting any of the SystemUI components.
*/
default void init() {
// This is to prevent circular init problem by separating registration step out of its
// constructor. And make sure the initialization of DisplayImeController won't depend on
// specific feature anymore.
getDisplayImeController().startMonitorDisplays();
getShellTaskOrganizer().registerOrganizer();
}
/** Create a StubAPIClass. */
StubAPIClass createStubAPIClass();
// Required components to be initialized at start up
@WMSingleton
ShellTaskOrganizer getShellTaskOrganizer();
@WMSingleton
DisplayImeController getDisplayImeController();
@WMSingleton
InputConsumerController getInputConsumerController();
// TODO(b/162923491): We currently pass the instances through to SysUI, but that may change
// depending on the threading mechanism we go with
@WMSingleton
Optional<OneHanded> getOneHanded();
@WMSingleton
Optional<Pip> getPip();
@WMSingleton
Optional<SplitScreen> getSplitScreen();
}

View File

@@ -42,6 +42,12 @@ public interface TvGlobalRootComponent extends GlobalRootComponent {
TvGlobalRootComponent build();
}
/**
* Builder for a WMComponent.
*/
@Override
TvWMComponent.Builder getWMComponentBuilder();
@Override
TvSysUIComponent.Builder getSysUIComponent();
}

View File

@@ -19,7 +19,7 @@ package com.android.systemui.tv;
import dagger.Module;
/**
* Dagger module for including the WMComponent.
* Dagger module for including the SysUIComponent.
*/
@Module(subcomponents = {TvSysUIComponent.class})
public abstract class TvSysUIComponentModule {

View File

@@ -22,7 +22,7 @@ import com.android.systemui.wmshell.TvPipModule;
import dagger.Binds;
import dagger.Module;
@Module(includes = TvPipModule.class)
@Module
interface TvSystemUIBinder {
@Binds
GlobalRootComponent bindGlobalRootComponent(TvGlobalRootComponent globalRootComponent);

View File

@@ -62,7 +62,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.wmshell.TvWMShellModule;
import javax.inject.Named;
@@ -75,8 +74,7 @@ import dagger.Provides;
* overridden by the System UI implementation.
*/
@Module(includes = {
QSModule.class,
TvWMShellModule.class,
QSModule.class
},
subcomponents = {
})

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2019 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.systemui.tv;
import com.android.systemui.dagger.WMComponent;
import com.android.systemui.dagger.WMSingleton;
import com.android.systemui.wmshell.TvWMShellModule;
import dagger.Subcomponent;
/**
* Dagger Subcomponent for WindowManager.
*/
@WMSingleton
@Subcomponent(modules = {TvWMShellModule.class})
public interface TvWMComponent extends WMComponent {
/**
* Builder for a SysUIComponent.
*/
@Subcomponent.Builder
interface Builder extends WMComponent.Builder {
TvWMComponent build();
}
}

View File

@@ -23,13 +23,19 @@ import android.content.Context;
import android.provider.DeviceConfig;
import android.provider.Settings;
import com.android.systemui.dagger.SysUISingleton;
import java.util.concurrent.Executor;
import javax.inject.Inject;
/**
* Wrapper around DeviceConfig useful for testing.
*/
@SysUISingleton
public class DeviceConfigProxy {
@Inject
public DeviceConfigProxy() {
}

View File

@@ -20,7 +20,7 @@ import android.content.Context;
import android.os.Handler;
import android.view.LayoutInflater;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.WMSingleton;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.DisplayController;
@@ -46,7 +46,7 @@ import dagger.Provides;
*/
@Module
public abstract class TvPipModule {
@SysUISingleton
@WMSingleton
@Provides
static Optional<Pip> providePip(
Context context,
@@ -61,7 +61,7 @@ public abstract class TvPipModule {
windowManagerShellWrapper));
}
@SysUISingleton
@WMSingleton
@Provides
static PipControlsViewController providePipControlsViewController(
PipControlsView pipControlsView, PipController pipController,
@@ -70,32 +70,32 @@ public abstract class TvPipModule {
handler);
}
@SysUISingleton
@WMSingleton
@Provides
static PipControlsView providePipControlsView(Context context) {
return new PipControlsView(context, null);
}
@SysUISingleton
@WMSingleton
@Provides
static PipNotification providePipNotification(Context context,
PipController pipController) {
return new PipNotification(context, pipController);
}
@SysUISingleton
@WMSingleton
@Provides
static PipBoundsHandler providePipBoundsHandler(Context context) {
return new PipBoundsHandler(context);
}
@SysUISingleton
@WMSingleton
@Provides
static PipBoundsState providePipBoundsState() {
return new PipBoundsState();
}
@SysUISingleton
@WMSingleton
@Provides
static PipTaskOrganizer providePipTaskOrganizer(Context context,
PipBoundsState pipBoundsState,

View File

@@ -20,7 +20,7 @@ import android.content.Context;
import android.os.Handler;
import android.view.IWindowManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.WMSingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
@@ -40,10 +40,9 @@ import dagger.Provides;
* Provides dependencies from {@link com.android.wm.shell} which could be customized among different
* branches of SystemUI.
*/
// TODO(b/162923491): Move most of these dependencies into WMSingleton scope.
@Module(includes = {WMShellBaseModule.class, TvPipModule.class})
public class TvWMShellModule {
@SysUISingleton
@WMSingleton
@Provides
static DisplayImeController provideDisplayImeController(IWindowManager wmService,
DisplayController displayController, @Main Executor mainExecutor,
@@ -52,7 +51,7 @@ public class TvWMShellModule {
transactionPool);
}
@SysUISingleton
@WMSingleton
@Provides
static SplitScreen provideSplitScreen(Context context,
DisplayController displayController, SystemWindows systemWindows,

View File

@@ -64,8 +64,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
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.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.nano.WmShellTraceProto;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.onehanded.OneHandedEvents;
@@ -101,7 +99,6 @@ public final class WMShell extends SystemUI
private final CommandQueue mCommandQueue;
private final ConfigurationController mConfigurationController;
private final DisplayImeController mDisplayImeController;
private final InputConsumerController mInputConsumerController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final TaskStackChangeListeners mTaskStackChangeListeners;
@@ -111,9 +108,6 @@ public final class WMShell extends SystemUI
private final Optional<Pip> mPipOptional;
private final Optional<SplitScreen> mSplitScreenOptional;
private final Optional<OneHanded> mOneHandedOptional;
// Inject the organizer directly in case the optionals aren't loaded to depend on it. There
// are non-optional windowing features like FULLSCREEN.
private final ShellTaskOrganizer mShellTaskOrganizer;
private final ProtoTracer mProtoTracer;
private boolean mIsSysUiStateValid;
private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback;
@@ -126,14 +120,12 @@ public final class WMShell extends SystemUI
InputConsumerController inputConsumerController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
TaskStackChangeListeners taskStackChangeListeners,
DisplayImeController displayImeController,
NavigationModeController navigationModeController,
ScreenLifecycle screenLifecycle,
SysUiState sysUiState,
Optional<Pip> pipOptional,
Optional<SplitScreen> splitScreenOptional,
Optional<OneHanded> oneHandedOptional,
ShellTaskOrganizer shellTaskOrganizer,
ProtoTracer protoTracer) {
super(context);
mCommandQueue = commandQueue;
@@ -141,14 +133,12 @@ public final class WMShell extends SystemUI
mInputConsumerController = inputConsumerController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mTaskStackChangeListeners = taskStackChangeListeners;
mDisplayImeController = displayImeController;
mNavigationModeController = navigationModeController;
mScreenLifecycle = screenLifecycle;
mSysUiState = sysUiState;
mPipOptional = pipOptional;
mSplitScreenOptional = splitScreenOptional;
mOneHandedOptional = oneHandedOptional;
mShellTaskOrganizer = shellTaskOrganizer;
mProtoTracer = protoTracer;
mProtoTracer.add(this);
}
@@ -156,10 +146,6 @@ public final class WMShell extends SystemUI
@Override
public void start() {
mCommandQueue.addCallback(this);
// This is to prevent circular init problem by separating registration step out of its
// constructor. And make sure the initialization of DisplayImeController won't depend on
// specific feature anymore.
mDisplayImeController.startMonitorDisplays();
mPipOptional.ifPresent(this::initPip);
mSplitScreenOptional.ifPresent(this::initSplitScreen);
mOneHandedOptional.ifPresent(this::initOneHanded);
@@ -201,6 +187,7 @@ public final class WMShell extends SystemUI
}
});
// TODO: Move this into the shell
// Handle for system task stack changes.
mTaskStackChangeListeners.registerTaskStackListener(
new TaskStackChangeListener() {
@@ -417,6 +404,8 @@ public final class WMShell extends SystemUI
return;
}
// Dump WMShell stuff here if no commands were handled
mPipOptional.ifPresent(pip -> pip.dump(pw));
mSplitScreenOptional.ifPresent(splitScreen -> splitScreen.dump(pw));
mOneHandedOptional.ifPresent(oneHanded -> oneHanded.dump(pw));
}

View File

@@ -20,21 +20,16 @@ import android.app.IActivityManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.IWindowManager;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.bubbles.Bubbles;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.WMSingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.animation.FlingAnimationUtils;
import com.android.wm.shell.common.AnimationThread;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.HandlerExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.SystemWindows;
@@ -58,41 +53,28 @@ import dagger.Provides;
* Provides basic dependencies from {@link com.android.wm.shell}, the dependencies declared here
* should be shared among different branches of SystemUI.
*/
// TODO(b/162923491): Move most of these dependencies into WMSingleton scope.
@Module
public abstract class WMShellBaseModule {
@SysUISingleton
@WMSingleton
@Provides
static TransactionPool provideTransactionPool() {
return new TransactionPool();
}
@SysUISingleton
@WMSingleton
@Provides
static DisplayController provideDisplayController(Context context, @Main Handler handler,
IWindowManager wmService) {
return new DisplayController(context, handler, wmService);
}
@SysUISingleton
@Provides
static DeviceConfigProxy provideDeviceConfigProxy() {
return new DeviceConfigProxy();
}
@SysUISingleton
@WMSingleton
@Provides
static InputConsumerController provideInputConsumerController() {
return InputConsumerController.getPipInputConsumer();
}
@SysUISingleton
@Provides
static FloatingContentCoordinator provideFloatingContentCoordinator() {
return new FloatingContentCoordinator();
}
@SysUISingleton
@WMSingleton
@Provides
static PipAppOpsListener providePipAppOpsListener(Context context,
IActivityManager activityManager,
@@ -100,61 +82,46 @@ public abstract class WMShellBaseModule {
return new PipAppOpsListener(context, activityManager, pipTouchHandler.getMotionHelper());
}
@SysUISingleton
@WMSingleton
@Provides
static PipMediaController providePipMediaController(Context context,
IActivityManager activityManager) {
return new PipMediaController(context, activityManager);
}
@SysUISingleton
@WMSingleton
@Provides
static PipUiEventLogger providePipUiEventLogger(UiEventLogger uiEventLogger,
PackageManager packageManager) {
return new PipUiEventLogger(uiEventLogger, packageManager);
}
@SysUISingleton
@WMSingleton
@Provides
static PipSurfaceTransactionHelper providePipSurfaceTransactionHelper(Context context) {
return new PipSurfaceTransactionHelper(context);
}
@SysUISingleton
@WMSingleton
@Provides
static SystemWindows provideSystemWindows(DisplayController displayController,
IWindowManager wmService) {
return new SystemWindows(displayController, wmService);
}
@SysUISingleton
@WMSingleton
@Provides
static SyncTransactionQueue provideSyncTransactionQueue(@Main Handler handler,
TransactionPool pool) {
return new SyncTransactionQueue(pool, handler);
}
@SysUISingleton
@WMSingleton
@Provides
static ShellTaskOrganizer provideShellTaskOrganizer(SyncTransactionQueue syncQueue,
@Main Handler handler, TransactionPool transactionPool) {
ShellTaskOrganizer organizer = new ShellTaskOrganizer(syncQueue, transactionPool,
return new ShellTaskOrganizer(syncQueue, transactionPool,
new HandlerExecutor(handler), AnimationThread.instance().getExecutor());
organizer.registerOrganizer();
return organizer;
}
@SysUISingleton
@Provides
static WindowManagerShellWrapper provideWindowManagerShellWrapper() {
return new WindowManagerShellWrapper();
}
@SysUISingleton
@Provides
static FlingAnimationUtils.Builder provideFlingAnimationUtilsBuilder(
DisplayMetrics displayMetrics) {
return new FlingAnimationUtils.Builder(displayMetrics);
}
@BindsOptionalOf
@@ -163,7 +130,7 @@ public abstract class WMShellBaseModule {
@BindsOptionalOf
abstract Bubbles optionalBubbles();
@SysUISingleton
@WMSingleton
@Provides
static Optional<OneHanded> provideOneHandedController(Context context,
DisplayController displayController) {

View File

@@ -20,7 +20,7 @@ import android.content.Context;
import android.os.Handler;
import android.view.IWindowManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.WMSingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.WindowManagerShellWrapper;
@@ -54,10 +54,9 @@ import dagger.Provides;
* Provides dependencies from {@link com.android.wm.shell} which could be customized among different
* branches of SystemUI.
*/
// TODO(b/162923491): Move most of these dependencies into WMSingleton scope.
@Module(includes = WMShellBaseModule.class)
public class WMShellModule {
@SysUISingleton
@WMSingleton
@Provides
static DisplayImeController provideDisplayImeController(IWindowManager wmService,
DisplayController displayController, @Main Executor mainExecutor,
@@ -66,7 +65,7 @@ public class WMShellModule {
transactionPool);
}
@SysUISingleton
@WMSingleton
@Provides
static SplitScreen provideSplitScreen(Context context,
DisplayController displayController, SystemWindows systemWindows,
@@ -77,7 +76,7 @@ public class WMShellModule {
displayImeController, handler, transactionPool, shellTaskOrganizer, syncQueue);
}
@SysUISingleton
@WMSingleton
@Provides
static Optional<Pip> providePip(Context context, DisplayController displayController,
PipAppOpsListener pipAppOpsListener, PipBoundsHandler pipBoundsHandler,
@@ -90,26 +89,26 @@ public class WMShellModule {
windowManagerShellWrapper));
}
@SysUISingleton
@WMSingleton
@Provides
static PipBoundsState providePipBoundsState() {
return new PipBoundsState();
}
@SysUISingleton
@WMSingleton
@Provides
static PipBoundsHandler providePipBoundsHandler(Context context) {
return new PipBoundsHandler(context);
}
@SysUISingleton
@WMSingleton
@Provides
static PipMenuActivityController providePipMenuActivityController(Context context,
PipMediaController pipMediaController, PipTaskOrganizer pipTaskOrganizer) {
return new PipMenuActivityController(context, pipMediaController, pipTaskOrganizer);
}
@SysUISingleton
@WMSingleton
@Provides
static PipTouchHandler providePipTouchHandler(Context context,
PipMenuActivityController menuActivityController, PipBoundsHandler pipBoundsHandler,
@@ -121,7 +120,7 @@ public class WMShellModule {
pipBoundsState, pipTaskOrganizer, floatingContentCoordinator, pipUiEventLogger);
}
@SysUISingleton
@WMSingleton
@Provides
static PipTaskOrganizer providePipTaskOrganizer(Context context,
PipBoundsState pipBoundsState,

View File

@@ -72,7 +72,7 @@ public abstract class SysuiTestCase {
@Before
public void SysuiSetup() throws Exception {
SystemUIFactory.createFromConfig(mContext);
SystemUIFactory.createFromConfig(mContext, true);
mDependency = new TestableDependency(
SystemUIFactory.getInstance().getSysUIComponent().createDependency());
Dependency.setInstance(mDependency);

View File

@@ -27,6 +27,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.model.SysUiState;
@@ -53,6 +54,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -64,7 +66,6 @@ public class WMShellTest extends SysuiTestCase {
@Mock ConfigurationController mConfigurationController;
@Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock TaskStackChangeListeners mTaskStackChangeListeners;
@Mock DisplayImeController mDisplayImeController;
@Mock InputConsumerController mMockInputConsumerController;
@Mock NavigationModeController mNavigationModeController;
@Mock ScreenLifecycle mScreenLifecycle;
@@ -73,7 +74,6 @@ public class WMShellTest extends SysuiTestCase {
@Mock PipTouchHandler mPipTouchHandler;
@Mock SplitScreen mSplitScreen;
@Mock OneHanded mOneHanded;
@Mock ShellTaskOrganizer mTaskOrganizer;
@Mock ProtoTracer mProtoTracer;
@Mock PackageManager mMockPackageManager;
@@ -84,20 +84,12 @@ public class WMShellTest extends SysuiTestCase {
mWMShell = new WMShell(mContext, mCommandQueue, mConfigurationController,
mInputConsumerController, mKeyguardUpdateMonitor, mTaskStackChangeListeners,
mDisplayImeController, mNavigationModeController, mScreenLifecycle, mSysUiState,
Optional.of(mPip), Optional.of(mSplitScreen), Optional.of(mOneHanded),
mTaskOrganizer, mProtoTracer);
mNavigationModeController, mScreenLifecycle, mSysUiState, Optional.of(mPip),
Optional.of(mSplitScreen), Optional.of(mOneHanded), mProtoTracer);
when(mPip.getPipTouchHandler()).thenReturn(mPipTouchHandler);
}
@Test
public void start_startsMonitorDisplays() {
mWMShell.start();
verify(mDisplayImeController).startMonitorDisplays();
}
@Test
public void initPip_registersCommandQueueCallback() {
mWMShell.initPip(mPip);