summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java51
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java104
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt82
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java1
11 files changed, 278 insertions, 73 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
index b45dc52585ad..10878dcc2474 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
@@ -42,7 +42,6 @@ import com.android.systemui.util.leak.LeakDetector;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
@@ -308,22 +307,22 @@ public class FragmentHostManager {
return instantiateWithInjections(context, className, arguments);
}
- private Fragment instantiateWithInjections(Context context, String className,
- Bundle args) {
- Method method = mManager.getInjectionMap().get(className);
- if (method != null) {
+ private Fragment instantiateWithInjections(
+ Context context, String className, Bundle args) {
+ FragmentService.FragmentInstantiationInfo fragmentInstantiationInfo =
+ mManager.getInjectionMap().get(className);
+ if (fragmentInstantiationInfo != null) {
try {
- Fragment f = (Fragment) method.invoke(mManager.getFragmentCreator());
+ Fragment f = (Fragment) fragmentInstantiationInfo
+ .mMethod
+ .invoke(fragmentInstantiationInfo.mDaggerComponent);
// Setup the args, taken from Fragment#instantiate.
if (args != null) {
args.setClassLoader(f.getClass().getClassLoader());
f.setArguments(args);
}
return f;
- } catch (IllegalAccessException e) {
- throw new Fragment.InstantiationException("Unable to instantiate " + className,
- e);
- } catch (InvocationTargetException e) {
+ } catch (IllegalAccessException | InvocationTargetException e) {
throw new Fragment.InstantiationException("Unable to instantiate " + className,
e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
index 7f57fcc56117..2a5e653dd051 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
@@ -18,13 +18,13 @@ import android.app.Fragment;
import android.content.res.Configuration;
import android.os.Handler;
import android.util.ArrayMap;
+import android.util.Log;
import android.view.View;
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.qs.QSFragment;
-import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.policy.ConfigurationController;
import java.io.FileDescriptor;
@@ -46,9 +46,14 @@ public class FragmentService implements Dumpable {
private static final String TAG = "FragmentService";
private final ArrayMap<View, FragmentHostState> mHosts = new ArrayMap<>();
- private final ArrayMap<String, Method> mInjectionMap = new ArrayMap<>();
+ /**
+ * A map with the means to create fragments via Dagger injection.
+ *
+ * key: the fragment class name.
+ * value: see {@link FragmentInstantiationInfo}.
+ */
+ private final ArrayMap<String, FragmentInstantiationInfo> mInjectionMap = new ArrayMap<>();
private final Handler mHandler = new Handler();
- private final FragmentCreator mFragmentCreator;
private ConfigurationController.ConfigurationListener mConfigurationListener =
new ConfigurationController.ConfigurationListener() {
@@ -65,26 +70,31 @@ public class FragmentService implements Dumpable {
FragmentCreator.Factory fragmentCreatorFactory,
ConfigurationController configurationController,
DumpManager dumpManager) {
- mFragmentCreator = fragmentCreatorFactory.build();
- initInjectionMap();
+ addFragmentInstantiationProvider(fragmentCreatorFactory.build());
configurationController.addCallback(mConfigurationListener);
dumpManager.registerDumpable(getClass().getSimpleName(), this);
}
- ArrayMap<String, Method> getInjectionMap() {
+ ArrayMap<String, FragmentInstantiationInfo> getInjectionMap() {
return mInjectionMap;
}
- FragmentCreator getFragmentCreator() {
- return mFragmentCreator;
- }
-
- private void initInjectionMap() {
- for (Method method : FragmentCreator.class.getDeclaredMethods()) {
+ /**
+ * Adds a new Dagger component object that provides method(s) to create fragments via injection.
+ */
+ public void addFragmentInstantiationProvider(Object daggerComponent) {
+ for (Method method : daggerComponent.getClass().getDeclaredMethods()) {
if (Fragment.class.isAssignableFrom(method.getReturnType())
&& (method.getModifiers() & Modifier.PUBLIC) != 0) {
- mInjectionMap.put(method.getReturnType().getName(), method);
+ String fragmentName = method.getReturnType().getName();
+ if (mInjectionMap.containsKey(fragmentName)) {
+ Log.w(TAG, "Fragment " + fragmentName + " is already provided by different"
+ + " Dagger component; Not adding method");
+ continue;
+ }
+ mInjectionMap.put(
+ fragmentName, new FragmentInstantiationInfo(method, daggerComponent));
}
}
}
@@ -134,9 +144,6 @@ public class FragmentService implements Dumpable {
* Inject a QSFragment.
*/
QSFragment createQSFragment();
-
- /** Inject a CollapsedStatusBarFragment. */
- CollapsedStatusBarFragment createCollapsedStatusBarFragment();
}
private class FragmentHostState {
@@ -161,4 +168,16 @@ public class FragmentService implements Dumpable {
mFragmentHostManager.onConfigurationChanged(newConfig);
}
}
+
+ /** An object containing the information needed to instantiate a fragment. */
+ static class FragmentInstantiationInfo {
+ /** The method that returns a newly-created fragment of the given class. */
+ final Method mMethod;
+ /** The Dagger component that the method should be invoked on. */
+ final Object mDaggerComponent;
+ FragmentInstantiationInfo(Method method, Object daggerComponent) {
+ this.mMethod = method;
+ this.mDaggerComponent = daggerComponent;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt
index c814622ff074..a4feeab48e6e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt
@@ -25,6 +25,7 @@ import com.android.systemui.battery.BatteryMeterViewController
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.qs.carrier.QSCarrierGroupController
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope
+import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.SPLIT_SHADE_BATTERY_CONTROLLER
import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.SPLIT_SHADE_HEADER
import javax.inject.Inject
import javax.inject.Named
@@ -35,7 +36,7 @@ class SplitShadeHeaderController @Inject constructor(
private val statusBarIconController: StatusBarIconController,
qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder,
featureFlags: FeatureFlags,
- batteryMeterViewController: BatteryMeterViewController
+ @Named(SPLIT_SHADE_BATTERY_CONTROLLER) batteryMeterViewController: BatteryMeterViewController
) {
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index e033c4725999..7b6cdbecc640 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -150,6 +150,7 @@ import com.android.systemui.emergency.EmergencyGesture;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.fragments.ExtensionFragmentListener;
import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.KeyguardService;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -489,7 +490,6 @@ public class StatusBar extends SystemUI implements
private final DozeParameters mDozeParameters;
private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
private final StatusBarComponent.Factory mStatusBarComponentFactory;
- private final StatusBarFragmentComponent.Factory mStatusBarFragmentComponentFactory;
private final PluginManager mPluginManager;
private final Optional<LegacySplitScreen> mSplitScreenOptional;
private final StatusBarNotificationActivityStarter.Builder
@@ -538,7 +538,7 @@ public class StatusBar extends SystemUI implements
protected final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
private final BrightnessSliderController.Factory mBrightnessSliderFactory;
private final FeatureFlags mFeatureFlags;
-
+ private final FragmentService mFragmentService;
private final WallpaperController mWallpaperController;
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private final MessageRouter mMessageRouter;
@@ -546,6 +546,8 @@ public class StatusBar extends SystemUI implements
private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private final TunerService mTunerService;
+ private StatusBarComponent mStatusBarComponent;
+
// Flags for disabling the status bar
// Two variables becaseu the first one evidently ran out of room for new flags.
private int mDisabled1 = 0;
@@ -690,6 +692,7 @@ public class StatusBar extends SystemUI implements
public StatusBar(
Context context,
NotificationsController notificationsController,
+ FragmentService fragmentService,
LightBarController lightBarController,
AutoHideController autoHideController,
StatusBarWindowController statusBarWindowController,
@@ -747,7 +750,6 @@ public class StatusBar extends SystemUI implements
CommandQueue commandQueue,
CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
StatusBarComponent.Factory statusBarComponentFactory,
- StatusBarFragmentComponent.Factory statusBarFragmentComponentFactory,
PluginManager pluginManager,
Optional<LegacySplitScreen> splitScreenOptional,
LightsOutNotifController lightsOutNotifController,
@@ -791,6 +793,7 @@ public class StatusBar extends SystemUI implements
ActivityLaunchAnimator activityLaunchAnimator) {
super(context);
mNotificationsController = notificationsController;
+ mFragmentService = fragmentService;
mLightBarController = lightBarController;
mAutoHideController = autoHideController;
mStatusBarWindowController = statusBarWindowController;
@@ -852,7 +855,6 @@ public class StatusBar extends SystemUI implements
mCommandQueue = commandQueue;
mCollapsedStatusBarFragmentLogger = collapsedStatusBarFragmentLogger;
mStatusBarComponentFactory = statusBarComponentFactory;
- mStatusBarFragmentComponentFactory = statusBarFragmentComponentFactory;
mPluginManager = pluginManager;
mSplitScreenOptional = splitScreenOptional;
mStatusBarNotificationActivityStarterBuilder = statusBarNotificationActivityStarterBuilder;
@@ -1184,24 +1186,7 @@ public class StatusBar extends SystemUI implements
}).getFragmentManager()
.beginTransaction()
.replace(R.id.status_bar_container,
- new CollapsedStatusBarFragment(
- mStatusBarFragmentComponentFactory,
- mOngoingCallController,
- mAnimationScheduler,
- mStatusBarLocationPublisher,
- mNotificationIconAreaController,
- mPanelExpansionStateManager,
- mFeatureFlags,
- () -> Optional.of(this),
- mStatusBarIconController,
- mStatusBarHideIconsForBouncerManager,
- mKeyguardStateController,
- mNetworkController,
- mStatusBarStateController,
- mCommandQueue,
- mCollapsedStatusBarFragmentLogger,
- mOperatorNameViewControllerFactory
- ),
+ mStatusBarComponent.createCollapsedStatusBarFragment(),
CollapsedStatusBarFragment.TAG)
.commit();
@@ -1557,32 +1542,34 @@ public class StatusBar extends SystemUI implements
}
private void inflateStatusBarWindow() {
- StatusBarComponent statusBarComponent = mStatusBarComponentFactory.create();
- mNotificationShadeWindowView = statusBarComponent.getNotificationShadeWindowView();
- mNotificationShadeWindowViewController = statusBarComponent
+ mStatusBarComponent = mStatusBarComponentFactory.create();
+ mFragmentService.addFragmentInstantiationProvider(mStatusBarComponent);
+
+ mNotificationShadeWindowView = mStatusBarComponent.getNotificationShadeWindowView();
+ mNotificationShadeWindowViewController = mStatusBarComponent
.getNotificationShadeWindowViewController();
mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
mNotificationShadeWindowViewController.setupExpandedStatusBar();
- mNotificationPanelViewController = statusBarComponent.getNotificationPanelViewController();
- statusBarComponent.getLockIconViewController().init();
- mStackScrollerController = statusBarComponent.getNotificationStackScrollLayoutController();
+ mNotificationPanelViewController = mStatusBarComponent.getNotificationPanelViewController();
+ mStatusBarComponent.getLockIconViewController().init();
+ mStackScrollerController = mStatusBarComponent.getNotificationStackScrollLayoutController();
mStackScroller = mStackScrollerController.getView();
- mNotificationShelfController = statusBarComponent.getNotificationShelfController();
- mAuthRippleController = statusBarComponent.getAuthRippleController();
+ mNotificationShelfController = mStatusBarComponent.getNotificationShelfController();
+ mAuthRippleController = mStatusBarComponent.getAuthRippleController();
mAuthRippleController.init();
- mHeadsUpManager.addListener(statusBarComponent.getStatusBarHeadsUpChangeListener());
+ mHeadsUpManager.addListener(mStatusBarComponent.getStatusBarHeadsUpChangeListener());
- mHeadsUpManager.addListener(statusBarComponent.getStatusBarHeadsUpChangeListener());
+ mHeadsUpManager.addListener(mStatusBarComponent.getStatusBarHeadsUpChangeListener());
// Listen for demo mode changes
- mDemoModeController.addCallback(statusBarComponent.getStatusBarDemoMode());
+ mDemoModeController.addCallback(mStatusBarComponent.getStatusBarDemoMode());
if (mCommandQueueCallbacks != null) {
mCommandQueue.removeCallback(mCommandQueueCallbacks);
}
- mCommandQueueCallbacks = statusBarComponent.getStatusBarCommandQueueCallbacks();
+ mCommandQueueCallbacks = mStatusBarComponent.getStatusBarCommandQueueCallbacks();
// Connect in to the status bar manager service
mCommandQueue.addCallback(mCommandQueueCallbacks);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
index e06605eac46f..375641fdb69d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
@@ -29,6 +29,7 @@ import com.android.systemui.statusbar.phone.SplitShadeHeaderController;
import com.android.systemui.statusbar.phone.StatusBarCommandQueueCallbacks;
import com.android.systemui.statusbar.phone.StatusBarDemoMode;
import com.android.systemui.statusbar.phone.StatusBarHeadsUpChangeListener;
+import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
@@ -38,7 +39,13 @@ import javax.inject.Scope;
import dagger.Subcomponent;
/**
- * Dagger subcomponent tied to the lifecycle of StatusBar views.
+ * Dagger subcomponent for classes (semi-)related to the status bar. The component is created once
+ * inside {@link com.android.systemui.statusbar.phone.StatusBar} and never re-created.
+ *
+ * TODO(b/197137564): This should likely be re-factored a bit. It includes classes that aren't
+ * directly related to status bar functionality, like multiple notification classes. And, the fact
+ * that it has many getter methods indicates that we need to access many of these classes from
+ * outside the component. Should more items be moved *into* this component to avoid so many getters?
*/
@Subcomponent(modules = {StatusBarViewModule.class})
@StatusBarComponent.StatusBarScope
@@ -121,4 +128,10 @@ public interface StatusBarComponent {
*/
@StatusBarScope
SplitShadeHeaderController getSplitShadeHeaderController();
+
+ /**
+ * Creates a new {@link CollapsedStatusBarFragment} each time it's called. See
+ * {@link StatusBarViewModule#createCollapsedStatusBarFragment}.
+ */
+ CollapsedStatusBarFragment createCollapsedStatusBarFragment();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 27ece84859d8..50e6151bd3a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -39,6 +39,7 @@ import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
@@ -100,7 +101,6 @@ import com.android.systemui.statusbar.phone.StatusBarSignalPolicy;
import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger;
-import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -143,6 +143,7 @@ public interface StatusBarPhoneModule {
static StatusBar provideStatusBar(
Context context,
NotificationsController notificationsController,
+ FragmentService fragmentService,
LightBarController lightBarController,
AutoHideController autoHideController,
StatusBarWindowController statusBarWindowController,
@@ -200,7 +201,6 @@ public interface StatusBarPhoneModule {
CommandQueue commandQueue,
CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
StatusBarComponent.Factory statusBarComponentFactory,
- StatusBarFragmentComponent.Factory statusBarFragmentComponentFactory,
PluginManager pluginManager,
Optional<LegacySplitScreen> splitScreenOptional,
LightsOutNotifController lightsOutNotifController,
@@ -245,6 +245,7 @@ public interface StatusBarPhoneModule {
return new StatusBar(
context,
notificationsController,
+ fragmentService,
lightBarController,
autoHideController,
statusBarWindowController,
@@ -302,7 +303,6 @@ public interface StatusBarPhoneModule {
commandQueue,
collapsedStatusBarFragmentLogger,
statusBarComponentFactory,
- statusBarFragmentComponentFactory,
pluginManager,
splitScreenOptional,
lightsOutNotifController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index 2765fe37f846..76176df136b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -17,6 +17,8 @@
package com.android.systemui.statusbar.phone.dagger;
import android.annotation.Nullable;
+import android.content.ContentResolver;
+import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewStub;
@@ -24,19 +26,45 @@ import android.view.ViewStub;
import com.android.keyguard.LockIconView;
import com.android.systemui.R;
import com.android.systemui.battery.BatteryMeterView;
+import com.android.systemui.battery.BatteryMeterViewController;
import com.android.systemui.biometrics.AuthRippleView;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationShelfController;
+import com.android.systemui.statusbar.OperatorNameViewController;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.NotificationPanelView;
+import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
import com.android.systemui.statusbar.phone.TapAgainView;
+import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
+import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger;
+import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
+import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.tuner.TunerService;
+
+import java.util.Optional;
import javax.inject.Named;
+import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
@@ -44,6 +72,8 @@ import dagger.Provides;
public abstract class StatusBarViewModule {
public static final String SPLIT_SHADE_HEADER = "split_shade_header";
+ private static final String SPLIT_SHADE_BATTERY_VIEW = "split_shade_battery_view";
+ public static final String SPLIT_SHADE_BATTERY_CONTROLLER = "split_shade_battery_controller";
/** */
@Provides
@@ -143,10 +173,34 @@ public abstract class StatusBarViewModule {
/** */
@Provides
@StatusBarComponent.StatusBarScope
+ @Named(SPLIT_SHADE_BATTERY_VIEW)
static BatteryMeterView getBatteryMeterView(@Named(SPLIT_SHADE_HEADER) View view) {
return view.findViewById(R.id.batteryRemainingIcon);
}
+ @Provides
+ @StatusBarComponent.StatusBarScope
+ @Named(SPLIT_SHADE_BATTERY_CONTROLLER)
+ static BatteryMeterViewController getBatteryMeterViewController(
+ @Named(SPLIT_SHADE_BATTERY_VIEW) BatteryMeterView batteryMeterView,
+ ConfigurationController configurationController,
+ TunerService tunerService,
+ BroadcastDispatcher broadcastDispatcher,
+ @Main Handler mainHandler,
+ ContentResolver contentResolver,
+ BatteryController batteryController
+ ) {
+ return new BatteryMeterViewController(
+ batteryMeterView,
+ configurationController,
+ tunerService,
+ broadcastDispatcher,
+ mainHandler,
+ contentResolver,
+ batteryController);
+
+ }
+
/** */
@Provides
@StatusBarComponent.StatusBarScope
@@ -161,4 +215,54 @@ public abstract class StatusBarViewModule {
NotificationShadeWindowView notificationShadeWindowView) {
return notificationShadeWindowView.findViewById(R.id.notification_container_parent);
}
+
+ /**
+ * Creates a new {@link CollapsedStatusBarFragment}.
+ *
+ * **IMPORTANT**: This method intentionally does not have
+ * {@link StatusBarComponent.StatusBarScope}, which means a new fragment *will* be created each
+ * time this method is called. This is intentional because we need fragments to re-created in
+ * certain lifecycle scenarios.
+ *
+ * **IMPORTANT**: This method also intentionally does not have a {@link Provides} annotation. If
+ * you need to get access to a {@link CollapsedStatusBarFragment}, go through
+ * {@link StatusBarFragmentComponent} instead.
+ */
+ public static CollapsedStatusBarFragment createCollapsedStatusBarFragment(
+ StatusBarFragmentComponent.Factory statusBarFragmentComponentFactory,
+ OngoingCallController ongoingCallController,
+ SystemStatusAnimationScheduler animationScheduler,
+ StatusBarLocationPublisher locationPublisher,
+ NotificationIconAreaController notificationIconAreaController,
+ PanelExpansionStateManager panelExpansionStateManager,
+ FeatureFlags featureFlags,
+ Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+ StatusBarIconController statusBarIconController,
+ StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
+ KeyguardStateController keyguardStateController,
+ NotificationPanelViewController notificationPanelViewController,
+ NetworkController networkController,
+ StatusBarStateController statusBarStateController,
+ CommandQueue commandQueue,
+ CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
+ OperatorNameViewController.Factory operatorNameViewControllerFactory
+ ) {
+ return new CollapsedStatusBarFragment(statusBarFragmentComponentFactory,
+ ongoingCallController,
+ animationScheduler,
+ locationPublisher,
+ notificationIconAreaController,
+ panelExpansionStateManager,
+ featureFlags,
+ statusBarOptionalLazy,
+ statusBarIconController,
+ statusBarHideIconsForBouncerManager,
+ keyguardStateController,
+ notificationPanelViewController,
+ networkController,
+ statusBarStateController,
+ commandQueue,
+ collapsedStatusBarFragmentLogger,
+ operatorNameViewControllerFactory);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 9bcf4a58ce0b..b32acce51e84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -53,6 +53,7 @@ import com.android.systemui.statusbar.connectivity.SignalCallback;
import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
+import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
@@ -94,6 +95,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
private PhoneStatusBarView mStatusBar;
private final StatusBarStateController mStatusBarStateController;
private final KeyguardStateController mKeyguardStateController;
+ private final NotificationPanelViewController mNotificationPanelViewController;
private final NetworkController mNetworkController;
private LinearLayout mSystemIconArea;
private View mClockView;
@@ -147,6 +149,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
StatusBarIconController statusBarIconController,
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
KeyguardStateController keyguardStateController,
+ NotificationPanelViewController notificationPanelViewController,
NetworkController networkController,
StatusBarStateController statusBarStateController,
CommandQueue commandQueue,
@@ -164,6 +167,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
mStatusBarIconController = statusBarIconController;
mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
mKeyguardStateController = keyguardStateController;
+ mNotificationPanelViewController = notificationPanelViewController;
mNetworkController = networkController;
mStatusBarStateController = statusBarStateController;
mCommandQueue = commandQueue;
@@ -354,8 +358,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
// The shelf will be hidden when dozing with a custom clock, we must show notification
// icons in this occasion.
if (mStatusBarStateController.isDozing()
- && mStatusBarOptionalLazy.get().map(
- sb -> sb.getPanelController().hasCustomClock()).orElse(false)) {
+ && mNotificationPanelViewController.hasCustomClock()) {
state |= DISABLE_CLOCK | DISABLE_SYSTEM_INFO;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt
new file mode 100644
index 000000000000..77c837b803af
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt
@@ -0,0 +1,82 @@
+package com.android.systemui.fragments
+
+import android.app.Fragment
+import android.os.Looper
+import android.test.suitebuilder.annotation.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.qs.QSFragment
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+@SmallTest
+class FragmentServiceTest : SysuiTestCase() {
+ private val fragmentCreator = TestFragmentCreator()
+ private val fragmentCreatorFactory = FragmentService.FragmentCreator.Factory { fragmentCreator }
+
+ private lateinit var fragmentService: FragmentService
+
+ @Before
+ fun setUp() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare()
+ }
+
+ fragmentService = FragmentService(fragmentCreatorFactory, mock(), DumpManager())
+ }
+
+ @Test
+ fun constructor_addsFragmentCreatorMethodsToMap() {
+ val map = fragmentService.injectionMap
+ assertThat(map).hasSize(2)
+ assertThat(map.keys).contains(QSFragment::class.java.name)
+ assertThat(map.keys).contains(TestFragmentInCreator::class.java.name)
+ }
+
+ @Test
+ fun addFragmentInstantiationProvider_objectHasNoFragmentMethods_nothingAdded() {
+ fragmentService.addFragmentInstantiationProvider(Object())
+
+ assertThat(fragmentService.injectionMap).hasSize(2)
+ }
+
+ @Test
+ fun addFragmentInstantiationProvider_objectHasFragmentMethods_methodsAdded() {
+ fragmentService.addFragmentInstantiationProvider(
+ @Suppress("unused")
+ object : Any() {
+ fun createTestFragment2() = TestFragment2()
+ fun createTestFragment3() = TestFragment3()
+ }
+ )
+
+ val map = fragmentService.injectionMap
+ assertThat(map).hasSize(4)
+ assertThat(map.keys).contains(TestFragment2::class.java.name)
+ assertThat(map.keys).contains(TestFragment3::class.java.name)
+ }
+
+ @Test
+ fun addFragmentInstantiationProvider_objectFragmentMethodsAlreadyProvided_nothingAdded() {
+ fragmentService.addFragmentInstantiationProvider(
+ @Suppress("unused")
+ object : Any() {
+ fun createTestFragment() = TestFragmentInCreator()
+ }
+ )
+
+ assertThat(fragmentService.injectionMap).hasSize(2)
+ }
+
+ class TestFragmentCreator : FragmentService.FragmentCreator {
+ override fun createQSFragment(): QSFragment = mock()
+ @Suppress("unused")
+ fun createTestFragment(): TestFragmentInCreator = TestFragmentInCreator()
+ }
+
+ class TestFragmentInCreator : Fragment()
+ class TestFragment2 : Fragment()
+ class TestFragment3 : Fragment()
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 88d36b0e3d44..d58e13cd8a64 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -86,6 +86,7 @@ import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
@@ -132,7 +133,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger;
-import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -244,8 +244,6 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private CollapsedStatusBarFragmentLogger mCollapsedStatusBarFragmentLogger;
@Mock private StatusBarComponent.Factory mStatusBarComponentFactory;
@Mock private StatusBarComponent mStatusBarComponent;
- @Mock private StatusBarFragmentComponent.Factory mStatusBarFragmentComponentFactory;
- @Mock private StatusBarFragmentComponent mStatusBarFragmentComponent;
@Mock private PluginManager mPluginManager;
@Mock private LegacySplitScreen mLegacySplitScreen;
@Mock private LightsOutNotifController mLightsOutNotifController;
@@ -350,8 +348,6 @@ public class StatusBarTest extends SysuiTestCase {
when(mBiometricUnlockControllerLazy.get()).thenReturn(mBiometricUnlockController);
when(mStatusBarComponentFactory.create()).thenReturn(mStatusBarComponent);
- when(mStatusBarFragmentComponentFactory.create(any()))
- .thenReturn(mStatusBarFragmentComponent);
when(mStatusBarComponent.getNotificationShadeWindowViewController()).thenReturn(
mNotificationShadeWindowViewController);
@@ -366,6 +362,7 @@ public class StatusBarTest extends SysuiTestCase {
mStatusBar = new StatusBar(
mContext,
mNotificationsController,
+ mock(FragmentService.class),
mLightBarController,
mAutoHideController,
mStatusBarWindowController,
@@ -422,7 +419,6 @@ public class StatusBarTest extends SysuiTestCase {
mCommandQueue,
mCollapsedStatusBarFragmentLogger,
mStatusBarComponentFactory,
- mStatusBarFragmentComponentFactory,
mPluginManager,
Optional.of(mLegacySplitScreen),
mLightsOutNotifController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index ec35edfdfab2..8b5989ff61a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -295,6 +295,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
new StatusBarHideIconsForBouncerManager(
mCommandQueue, new FakeExecutor(new FakeSystemClock()), new DumpManager()),
mKeyguardStateController,
+ mock(NotificationPanelViewController.class),
mNetworkController,
mStatusBarStateController,
mCommandQueue,