Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fba2d809 authored by Caitlin Cassidy's avatar Caitlin Cassidy
Browse files

[Status Bar Refactor] Inject NotificationPanelViewController into

CollapsedStatusBarFragment.

Because NotificationPanelViewController is not @Singleton but
@StatusBarScope, we need to update the fragment creation classes to
know how to get references to @StatusBarScope classes and that's the
bulk of this CL.

Bug: 205609837
Bug: 204792508
Test: atest FragmentServiceTest
Test: atest SystemUITests
Test: manual
Change-Id: I84ef8c7621944d6924775c1fe54178af296a3485
Merged-In: I84ef8c7621944d6924775c1fe54178af296a3485
parent 6fafaf44
Loading
Loading
Loading
Loading
+9 −10
Original line number Diff line number Diff line
@@ -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);
                }
+35 −16
Original line number Diff line number Diff line
@@ -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;
        }
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -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 {
+21 −35
Original line number Diff line number Diff line
@@ -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,25 +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();

@@ -1558,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);
    }
+14 −1
Original line number Diff line number Diff line
@@ -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();
}
Loading