/* * Copyright (C) 2017 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; import android.annotation.Nullable; import android.app.AlarmManager; import android.app.INotificationManager; import android.app.IWallpaperManager; import android.hardware.SensorPrivacyManager; import android.hardware.display.NightDisplayListener; import android.os.Handler; import android.os.Looper; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.view.IWindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.Preconditions; import com.android.keyguard.KeyguardSecurityModel; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.clock.ClockManager; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.systemui.accessibility.AccessibilityButtonModeObserver; import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver; import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController; import com.android.systemui.appops.AppOpsController; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dock.DockManager; import com.android.systemui.dump.DumpManager; import com.android.systemui.fragments.FragmentService; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.media.dialog.MediaOutputDialogFactory; import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.NavigationBarController; import com.android.systemui.navigationbar.NavigationBarOverlayController; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.PluginDependencyProvider; import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.power.PowerUI; import com.android.systemui.privacy.PrivacyItemController; import com.android.systemui.qs.ReduceBrightColorsController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.DevicePolicyManagerWrapper; import com.android.systemui.shared.system.PackageManagerWrapper; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.NotificationViewHierarchyManager; import com.android.systemui.statusbar.SmartReplyController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.events.PrivacyDotViewController; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment; import com.android.systemui.statusbar.notification.NotificationFilter; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardDismissUtil; import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.phone.LockscreenGestureLogger; import com.android.systemui.statusbar.phone.ManagedProfileController; import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarWindowController; import com.android.systemui.statusbar.policy.AccessibilityController; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BluetoothController; import com.android.systemui.statusbar.policy.CastController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DataSaverController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.ExtensionController; import com.android.systemui.statusbar.policy.FlashlightController; import com.android.systemui.statusbar.policy.HotspotController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.LocationController; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.policy.SecurityController; import com.android.systemui.statusbar.policy.SensorPrivacyController; import com.android.systemui.statusbar.policy.SmartReplyConstants; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.telephony.TelephonyListenerManager; 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 java.util.concurrent.Executor; import java.util.function.Consumer; import javax.inject.Inject; import javax.inject.Named; import dagger.Lazy; /** * Class to handle ugly dependencies throughout sysui until we determine the * long-term dependency injection solution. * * Classes added here should be things that are expected to live the lifetime of sysui, * and are generally applicable to many parts of sysui. They will be lazily * initialized to ensure they aren't created on form factors that don't need them * (e.g. HotspotController on TV). Despite being lazily initialized, it is expected * that all dependencies will be gotten during sysui startup, and not during runtime * to avoid jank. * * All classes used here are expected to manage their own lifecycle, meaning if * they have no clients they should not have any registered resources like bound * services, registered receivers, etc. */ @SysUISingleton public class Dependency { /** * Key for getting a the main looper. */ private static final String MAIN_LOOPER_NAME = "main_looper"; /** * Key for getting a background Looper for background work. */ private static final String BG_LOOPER_NAME = "background_looper"; /** * Key for getting a Handler for receiving time tick broadcasts on. */ public static final String TIME_TICK_HANDLER_NAME = "time_tick_handler"; /** * Generic handler on the main thread. */ private static final String MAIN_HANDLER_NAME = "main_handler"; /** * Generic executor on the main thread. */ private static final String MAIN_EXECUTOR_NAME = "main_executor"; /** * Generic executor on a background thread. */ private static final String BACKGROUND_EXECUTOR_NAME = "background_executor"; /** * An email address to send memory leak reports to by default. */ public static final String LEAK_REPORT_EMAIL_NAME = "leak_report_email"; /** * Whether this platform supports long-pressing notifications to show notification channel * settings. */ public static final String ALLOW_NOTIFICATION_LONG_PRESS_NAME = "allow_notif_longpress"; /** * Key for getting a background Looper for background work. */ public static final DependencyKey BG_LOOPER = new DependencyKey<>(BG_LOOPER_NAME); /** * Key for getting a mainer Looper. */ public static final DependencyKey MAIN_LOOPER = new DependencyKey<>(MAIN_LOOPER_NAME); /** * Key for getting a Handler for receiving time tick broadcasts on. */ public static final DependencyKey TIME_TICK_HANDLER = new DependencyKey<>(TIME_TICK_HANDLER_NAME); /** * Generic handler on the main thread. */ public static final DependencyKey MAIN_HANDLER = new DependencyKey<>(MAIN_HANDLER_NAME); /** * Generic executor on the main thread. */ public static final DependencyKey MAIN_EXECUTOR = new DependencyKey<>(MAIN_EXECUTOR_NAME); /** * Generic executor on a background thread. */ public static final DependencyKey BACKGROUND_EXECUTOR = new DependencyKey<>(BACKGROUND_EXECUTOR_NAME); /** * An email address to send memory leak reports to by default. */ public static final DependencyKey LEAK_REPORT_EMAIL = new DependencyKey<>(LEAK_REPORT_EMAIL_NAME); private final ArrayMap mDependencies = new ArrayMap<>(); private final ArrayMap mProviders = new ArrayMap<>(); @Inject DumpManager mDumpManager; @Inject Lazy mActivityStarter; @Inject Lazy mBroadcastDispatcher; @Inject Lazy mAsyncSensorManager; @Inject Lazy mBluetoothController; @Inject Lazy mLocationController; @Inject Lazy mRotationLockController; @Inject Lazy mNetworkController; @Inject Lazy mZenModeController; @Inject Lazy mHotspotController; @Inject Lazy mCastController; @Inject Lazy mFlashlightController; @Inject Lazy mUserSwitcherController; @Inject Lazy mUserInfoController; @Inject Lazy mKeyguardMonitor; @Inject Lazy mKeyguardUpdateMonitor; @Inject Lazy mBatteryController; @Inject Lazy mNightDisplayListener; @Inject Lazy mReduceBrightColorsController; @Inject Lazy mManagedProfileController; @Inject Lazy mNextAlarmController; @Inject Lazy mDataSaverController; @Inject Lazy mAccessibilityController; @Inject Lazy mDeviceProvisionedController; @Inject Lazy mPluginManager; @Inject Lazy mAssistManager; @Inject Lazy mSecurityController; @Inject Lazy mLeakDetector; @Inject Lazy mLeakReporter; @Inject Lazy mGarbageMonitor; @Inject Lazy mTunerService; @Inject Lazy mNotificationShadeWindowController; @Inject Lazy mTempStatusBarWindowController; @Inject Lazy mDarkIconDispatcher; @Inject Lazy mConfigurationController; @Inject Lazy mStatusBarIconController; @Inject Lazy mScreenLifecycle; @Inject Lazy mWakefulnessLifecycle; @Inject Lazy mFragmentService; @Inject Lazy mExtensionController; @Inject Lazy mPluginDependencyProvider; @Nullable @Inject Lazy mLocalBluetoothManager; @Inject Lazy mVolumeDialogController; @Inject Lazy mMetricsLogger; @Inject Lazy mAccessibilityManagerWrapper; @Inject Lazy mSysuiColorExtractor; @Inject Lazy mTunablePaddingService; @Inject Lazy mForegroundServiceController; @Inject Lazy mUiOffloadThread; @Inject Lazy mWarningsUI; @Inject Lazy mLightBarController; @Inject Lazy mIWindowManager; @Inject Lazy mOverviewProxyService; @Inject Lazy mNavBarModeController; @Inject Lazy mAccessibilityButtonModeObserver; @Inject Lazy mAccessibilityButtonListController; @Inject Lazy mEnhancedEstimates; @Inject Lazy mVibratorHelper; @Inject Lazy mIStatusBarService; @Inject Lazy mDisplayMetrics; @Inject Lazy mLockscreenGestureLogger; @Inject Lazy mKeyguardEnvironment; @Inject Lazy mShadeController; @Inject Lazy mNotificationRemoteInputManagerCallback; @Inject Lazy mAppOpsController; @Inject Lazy mNavigationBarController; @Inject Lazy mAccessibilityFloatingMenuController; @Inject Lazy mStatusBarStateController; @Inject Lazy mNotificationLockscreenUserManager; @Inject Lazy mNotificationGroupAlertTransferHelper; @Inject Lazy mNotificationGroupManager; @Inject Lazy mVisualStabilityManager; @Inject Lazy mNotificationGutsManager; @Inject Lazy mNotificationMediaManager; @Inject Lazy mNotificationRemoteInputManager; @Inject Lazy mSmartReplyConstants; @Inject Lazy mNotificationListener; @Inject Lazy mNotificationLogger; @Inject Lazy mNotificationViewHierarchyManager; @Inject Lazy mNotificationFilter; @Inject Lazy mKeyguardDismissUtil; @Inject Lazy mSmartReplyController; @Inject Lazy mRemoteInputQuickSettingsDisabler; @Inject Lazy mNotificationEntryManager; @Inject Lazy mSensorPrivacyManager; @Inject Lazy mAutoHideController; @Inject Lazy mForegroundServiceNotificationListener; @Inject Lazy mPrivacyItemController; @Inject @Background Lazy mBgLooper; @Inject @Background Lazy mBgHandler; @Inject @Main Lazy mMainLooper; @Inject @Main Lazy mMainHandler; @Inject @Named(TIME_TICK_HANDLER_NAME) Lazy mTimeTickHandler; @Nullable @Inject @Named(LEAK_REPORT_EMAIL_NAME) Lazy mLeakReportEmail; @Inject @Main Lazy mMainExecutor; @Inject @Background Lazy mBackgroundExecutor; @Inject Lazy mClockManager; @Inject Lazy mActivityManagerWrapper; @Inject Lazy mDevicePolicyManagerWrapper; @Inject Lazy mPackageManagerWrapper; @Inject Lazy mSensorPrivacyController; @Inject Lazy mDockManager; @Inject Lazy mINotificationManager; @Inject Lazy mSysUiStateFlagsContainer; @Inject Lazy mAlarmManager; @Inject Lazy mKeyguardSecurityModel; @Inject Lazy mDozeParameters; @Inject Lazy mWallpaperManager; @Inject Lazy mCommandQueue; @Inject Lazy mRecents; @Inject Lazy mStatusBar; @Inject Lazy mRecordingController; @Inject Lazy mProtoTracer; @Inject Lazy mMediaOutputDialogFactory; @Inject Lazy mDeviceConfigProxy; @Inject Lazy mNavbarButtonsControllerLazy; @Inject Lazy mTelephonyListenerManager; @Inject Lazy mSystemStatusAnimationSchedulerLazy; @Inject Lazy mPrivacyDotViewControllerLazy; @Inject Lazy mEdgeBackGestureHandlerFactoryLazy; @Inject Lazy mUiEventLogger; @Inject Lazy mFeatureFlagsLazy; @Inject Lazy mContentInsetsProviderLazy; @Inject public Dependency() { } /** * Initialize Depenency. */ protected void start() { // TODO: Think about ways to push these creation rules out of Dependency to cut down // on imports. mProviders.put(TIME_TICK_HANDLER, mTimeTickHandler::get); mProviders.put(BG_LOOPER, mBgLooper::get); mProviders.put(MAIN_LOOPER, mMainLooper::get); mProviders.put(MAIN_HANDLER, mMainHandler::get); mProviders.put(MAIN_EXECUTOR, mMainExecutor::get); mProviders.put(BACKGROUND_EXECUTOR, mBackgroundExecutor::get); mProviders.put(ActivityStarter.class, mActivityStarter::get); mProviders.put(BroadcastDispatcher.class, mBroadcastDispatcher::get); mProviders.put(AsyncSensorManager.class, mAsyncSensorManager::get); mProviders.put(BluetoothController.class, mBluetoothController::get); mProviders.put(SensorPrivacyManager.class, mSensorPrivacyManager::get); mProviders.put(LocationController.class, mLocationController::get); mProviders.put(RotationLockController.class, mRotationLockController::get); mProviders.put(NetworkController.class, mNetworkController::get); mProviders.put(ZenModeController.class, mZenModeController::get); mProviders.put(HotspotController.class, mHotspotController::get); mProviders.put(CastController.class, mCastController::get); mProviders.put(FlashlightController.class, mFlashlightController::get); mProviders.put(KeyguardStateController.class, mKeyguardMonitor::get); mProviders.put(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor::get); mProviders.put(UserSwitcherController.class, mUserSwitcherController::get); mProviders.put(UserInfoController.class, mUserInfoController::get); mProviders.put(BatteryController.class, mBatteryController::get); mProviders.put(NightDisplayListener.class, mNightDisplayListener::get); mProviders.put(ReduceBrightColorsController.class, mReduceBrightColorsController::get); mProviders.put(ManagedProfileController.class, mManagedProfileController::get); mProviders.put(NextAlarmController.class, mNextAlarmController::get); mProviders.put(DataSaverController.class, mDataSaverController::get); mProviders.put(AccessibilityController.class, mAccessibilityController::get); mProviders.put(DeviceProvisionedController.class, mDeviceProvisionedController::get); mProviders.put(PluginManager.class, mPluginManager::get); mProviders.put(AssistManager.class, mAssistManager::get); mProviders.put(SecurityController.class, mSecurityController::get); mProviders.put(LeakDetector.class, mLeakDetector::get); mProviders.put(LEAK_REPORT_EMAIL, mLeakReportEmail::get); mProviders.put(LeakReporter.class, mLeakReporter::get); mProviders.put(GarbageMonitor.class, mGarbageMonitor::get); mProviders.put(TunerService.class, mTunerService::get); mProviders.put(NotificationShadeWindowController.class, mNotificationShadeWindowController::get); mProviders.put(StatusBarWindowController.class, mTempStatusBarWindowController::get); mProviders.put(DarkIconDispatcher.class, mDarkIconDispatcher::get); mProviders.put(ConfigurationController.class, mConfigurationController::get); mProviders.put(StatusBarIconController.class, mStatusBarIconController::get); mProviders.put(ScreenLifecycle.class, mScreenLifecycle::get); mProviders.put(WakefulnessLifecycle.class, mWakefulnessLifecycle::get); mProviders.put(FragmentService.class, mFragmentService::get); mProviders.put(ExtensionController.class, mExtensionController::get); mProviders.put(PluginDependencyProvider.class, mPluginDependencyProvider::get); mProviders.put(LocalBluetoothManager.class, mLocalBluetoothManager::get); mProviders.put(VolumeDialogController.class, mVolumeDialogController::get); mProviders.put(MetricsLogger.class, mMetricsLogger::get); mProviders.put(AccessibilityManagerWrapper.class, mAccessibilityManagerWrapper::get); mProviders.put(SysuiColorExtractor.class, mSysuiColorExtractor::get); mProviders.put(TunablePaddingService.class, mTunablePaddingService::get); mProviders.put(ForegroundServiceController.class, mForegroundServiceController::get); mProviders.put(UiOffloadThread.class, mUiOffloadThread::get); mProviders.put(PowerUI.WarningsUI.class, mWarningsUI::get); mProviders.put(LightBarController.class, mLightBarController::get); mProviders.put(IWindowManager.class, mIWindowManager::get); mProviders.put(OverviewProxyService.class, mOverviewProxyService::get); mProviders.put(NavigationModeController.class, mNavBarModeController::get); mProviders.put(AccessibilityButtonModeObserver.class, mAccessibilityButtonModeObserver::get); mProviders.put(AccessibilityButtonTargetsObserver.class, mAccessibilityButtonListController::get); mProviders.put(EnhancedEstimates.class, mEnhancedEstimates::get); mProviders.put(VibratorHelper.class, mVibratorHelper::get); mProviders.put(IStatusBarService.class, mIStatusBarService::get); mProviders.put(DisplayMetrics.class, mDisplayMetrics::get); mProviders.put(LockscreenGestureLogger.class, mLockscreenGestureLogger::get); mProviders.put(KeyguardEnvironment.class, mKeyguardEnvironment::get); mProviders.put(ShadeController.class, mShadeController::get); mProviders.put(NotificationRemoteInputManager.Callback.class, mNotificationRemoteInputManagerCallback::get); mProviders.put(AppOpsController.class, mAppOpsController::get); mProviders.put(NavigationBarController.class, mNavigationBarController::get); mProviders.put(AccessibilityFloatingMenuController.class, mAccessibilityFloatingMenuController::get); mProviders.put(StatusBarStateController.class, mStatusBarStateController::get); mProviders.put(NotificationLockscreenUserManager.class, mNotificationLockscreenUserManager::get); mProviders.put(VisualStabilityManager.class, mVisualStabilityManager::get); mProviders.put(NotificationGroupManagerLegacy.class, mNotificationGroupManager::get); mProviders.put(NotificationGroupAlertTransferHelper.class, mNotificationGroupAlertTransferHelper::get); mProviders.put(NotificationMediaManager.class, mNotificationMediaManager::get); mProviders.put(NotificationGutsManager.class, mNotificationGutsManager::get); mProviders.put(NotificationRemoteInputManager.class, mNotificationRemoteInputManager::get); mProviders.put(SmartReplyConstants.class, mSmartReplyConstants::get); mProviders.put(NotificationListener.class, mNotificationListener::get); mProviders.put(NotificationLogger.class, mNotificationLogger::get); mProviders.put(NotificationViewHierarchyManager.class, mNotificationViewHierarchyManager::get); mProviders.put(NotificationFilter.class, mNotificationFilter::get); mProviders.put(KeyguardDismissUtil.class, mKeyguardDismissUtil::get); mProviders.put(SmartReplyController.class, mSmartReplyController::get); mProviders.put(RemoteInputQuickSettingsDisabler.class, mRemoteInputQuickSettingsDisabler::get); mProviders.put(NotificationEntryManager.class, mNotificationEntryManager::get); mProviders.put(ForegroundServiceNotificationListener.class, mForegroundServiceNotificationListener::get); mProviders.put(ClockManager.class, mClockManager::get); mProviders.put(PrivacyItemController.class, mPrivacyItemController::get); mProviders.put(ActivityManagerWrapper.class, mActivityManagerWrapper::get); mProviders.put(DevicePolicyManagerWrapper.class, mDevicePolicyManagerWrapper::get); mProviders.put(PackageManagerWrapper.class, mPackageManagerWrapper::get); mProviders.put(SensorPrivacyController.class, mSensorPrivacyController::get); mProviders.put(DockManager.class, mDockManager::get); mProviders.put(INotificationManager.class, mINotificationManager::get); mProviders.put(SysUiState.class, mSysUiStateFlagsContainer::get); mProviders.put(AlarmManager.class, mAlarmManager::get); mProviders.put(KeyguardSecurityModel.class, mKeyguardSecurityModel::get); mProviders.put(DozeParameters.class, mDozeParameters::get); mProviders.put(IWallpaperManager.class, mWallpaperManager::get); mProviders.put(CommandQueue.class, mCommandQueue::get); mProviders.put(Recents.class, mRecents::get); mProviders.put(StatusBar.class, mStatusBar::get); mProviders.put(ProtoTracer.class, mProtoTracer::get); mProviders.put(DeviceConfigProxy.class, mDeviceConfigProxy::get); mProviders.put(TelephonyListenerManager.class, mTelephonyListenerManager::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 // a new class maybe named DisplayDependency to solve per-display // Dependency problem. mProviders.put(AutoHideController.class, mAutoHideController::get); mProviders.put(RecordingController.class, mRecordingController::get); mProviders.put(MediaOutputDialogFactory.class, mMediaOutputDialogFactory::get); mProviders.put(NavigationBarOverlayController.class, mNavbarButtonsControllerLazy::get); mProviders.put(SystemStatusAnimationScheduler.class, mSystemStatusAnimationSchedulerLazy::get); mProviders.put(PrivacyDotViewController.class, mPrivacyDotViewControllerLazy::get); mProviders.put(EdgeBackGestureHandler.Factory.class, mEdgeBackGestureHandlerFactoryLazy::get); mProviders.put(UiEventLogger.class, mUiEventLogger::get); mProviders.put(FeatureFlags.class, mFeatureFlagsLazy::get); mProviders.put(StatusBarContentInsetsProvider.class, mContentInsetsProviderLazy::get); Dependency.setInstance(this); } @VisibleForTesting public static void setInstance(Dependency dependency) { sDependency = dependency; } protected final T getDependency(Class cls) { return getDependencyInner(cls); } protected final T getDependency(DependencyKey key) { return getDependencyInner(key); } private synchronized T getDependencyInner(Object key) { @SuppressWarnings("unchecked") T obj = (T) mDependencies.get(key); if (obj == null) { obj = createDependency(key); mDependencies.put(key, obj); // TODO: Get dependencies to register themselves instead if (autoRegisterModulesForDump() && obj instanceof Dumpable) { mDumpManager.registerDumpable(obj.getClass().getName(), (Dumpable) obj); } } return obj; } @VisibleForTesting public T createDependency(Object cls) { Preconditions.checkArgument(cls instanceof DependencyKey || cls instanceof Class); @SuppressWarnings("unchecked") LazyDependencyCreator provider = mProviders.get(cls); if (provider == null) { throw new IllegalArgumentException("Unsupported dependency " + cls + ". " + mProviders.size() + " providers known."); } return provider.createDependency(); } // Currently, there are situations in tests where we might create more than one instance of a // thing that should be a singleton: the "real" one (created by Dagger, usually as a result of // inflating a view), and a mocked one (injected into Dependency). If we register the mocked // one, the DumpManager will throw an exception complaining (rightly) that we have too many // things registered with that name. So in tests, we disable the auto-registration until the // root cause is fixed, i.e. inflated views in tests with Dagger dependencies. @VisibleForTesting protected boolean autoRegisterModulesForDump() { return true; } private static Dependency sDependency; /** * Interface for a class that can create a dependency. Used to implement laziness * @param The type of the dependency being created */ private interface LazyDependencyCreator { T createDependency(); } private void destroyDependency(Class cls, Consumer destroy) { T dep = (T) mDependencies.remove(cls); if (dep instanceof Dumpable) { mDumpManager.unregisterDumpable(dep.getClass().getName()); } if (dep != null && destroy != null) { destroy.accept(dep); } } /** * Used in separate process teardown to ensure the context isn't leaked. * * TODO: Remove once PreferenceFragment doesn't reference getActivity() * anymore and these context hacks are no longer needed. */ public static void clearDependencies() { sDependency = null; } /** * Checks to see if a dependency is instantiated, if it is it removes it from * the cache and calls the destroy callback. */ public static void destroy(Class cls, Consumer destroy) { sDependency.destroyDependency(cls, destroy); } /** * @deprecated see docs/dagger.md */ @Deprecated public static T get(Class cls) { return sDependency.getDependency(cls); } /** * @deprecated see docs/dagger.md */ @Deprecated public static T get(DependencyKey cls) { return sDependency.getDependency(cls); } public static final class DependencyKey { private final String mDisplayName; public DependencyKey(String displayName) { mDisplayName = displayName; } @Override public String toString() { return mDisplayName; } } }