Merge "[Dagger] Move StatusBarIconController and FeatureFlags from KeyguardStatusBarView to its controller." into sc-v2-dev am: 8c67d4c735 am: ef19e9d4f3

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15327939

Change-Id: Ic3383d5ab9241216fd2982894e282088db94e531
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 72a3a12..222ed63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -43,17 +43,12 @@
 
 import com.android.settingslib.Utils;
 import com.android.systemui.BatteryMeterView;
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
-import com.android.systemui.statusbar.FeatureFlags;
-import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * The header group on Keyguard.
@@ -80,15 +75,11 @@
     private int mSystemIconsSwitcherHiddenExpandedMargin;
     private int mSystemIconsBaseMargin;
     private View mSystemIconsContainer;
-    private TintedIconManager mIconManager;
-    private List<String> mBlockedIcons = new ArrayList<>();
 
     private View mCutoutSpace;
     private ViewGroup mStatusIconArea;
     private int mLayoutState = LAYOUT_NONE;
 
-    private FeatureFlags mFeatureFlags;
-
     /**
      * Draw this many pixels into the left/right side of the cutout to optimally use the space
      */
@@ -122,8 +113,6 @@
         mStatusIconContainer = findViewById(R.id.statusIcons);
 
         loadDimens();
-        loadBlockList();
-        mFeatureFlags = Dependency.get(FeatureFlags.class);
     }
 
     @Override
@@ -183,14 +172,6 @@
                 R.dimen.rounded_corner_content_padding);
     }
 
-    // Set hidden status bar items
-    private void loadBlockList() {
-        Resources r = getResources();
-        mBlockedIcons.add(r.getString(com.android.internal.R.string.status_bar_volume));
-        mBlockedIcons.add(r.getString(com.android.internal.R.string.status_bar_alarm_clock));
-        mBlockedIcons.add(r.getString(com.android.internal.R.string.status_bar_call_strength));
-    }
-
     private void updateVisibilities() {
         if (mMultiUserAvatar.getParent() != mStatusIconArea
                 && !mKeyguardUserSwitcherEnabled) {
@@ -327,20 +308,6 @@
         return true;
     }
 
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mIconManager = new TintedIconManager(findViewById(R.id.statusIcons), mFeatureFlags);
-        mIconManager.setBlockList(mBlockedIcons);
-        Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        Dependency.get(StatusBarIconController.class).removeIconGroup(mIconManager);
-    }
-
     /** Should only be called from {@link KeyguardStatusBarViewController}. */
     void onUserInfoChanged(Drawable picture) {
         mMultiUserAvatar.setImageDrawable(picture);
@@ -421,9 +388,9 @@
     }
 
     /** Should only be called from {@link KeyguardStatusBarViewController}. */
-    void onThemeChanged() {
+    void onThemeChanged(StatusBarIconController.TintedIconManager iconManager) {
         mBatteryView.setColorsFromContext(mContext);
-        updateIconsAndTextColors();
+        updateIconsAndTextColors(iconManager);
     }
 
     /** Should only be called from {@link KeyguardStatusBarViewController}. */
@@ -433,7 +400,7 @@
         mBatteryView.updatePercentView();
     }
 
-    private void updateIconsAndTextColors() {
+    private void updateIconsAndTextColors(StatusBarIconController.TintedIconManager iconManager) {
         @ColorInt int textColor = Utils.getColorAttrDefaultColor(mContext,
                 R.attr.wallpaperTextColor);
         @ColorInt int iconColor = Utils.getColorStateListDefaultColor(mContext,
@@ -441,8 +408,8 @@
                 R.color.light_mode_icon_color_single_tone);
         float intensity = textColor == Color.WHITE ? 0 : 1;
         mCarrierLabel.setTextColor(iconColor);
-        if (mIconManager != null) {
-            mIconManager.setTint(iconColor);
+        if (iconManager != null) {
+            iconManager.setTint(iconColor);
         }
 
         applyDarkness(R.id.battery, mEmptyRect, intensity, iconColor);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index 4d17cbc..5d8d36e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -20,10 +20,12 @@
 import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_OUT;
 
 import android.animation.ValueAnimator;
+import android.content.res.Resources;
 
 import androidx.annotation.NonNull;
 
 import com.android.keyguard.CarrierTextController;
+import com.android.systemui.R;
 import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -33,6 +35,9 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 import javax.inject.Inject;
 
@@ -43,6 +48,8 @@
     private final SystemStatusAnimationScheduler mAnimationScheduler;
     private final BatteryController mBatteryController;
     private final UserInfoController mUserInfoController;
+    private final StatusBarIconController mStatusBarIconController;
+    private final StatusBarIconController.TintedIconManager.Factory mTintedIconManagerFactory;
 
     private final ConfigurationController.ConfigurationListener mConfigurationListener =
             new ConfigurationController.ConfigurationListener() {
@@ -94,7 +101,10 @@
     private final UserInfoController.OnUserInfoChangedListener mOnUserInfoChangedListener =
             (name, picture, userAccount) -> mView.onUserInfoChanged(picture);
 
+    private final List<String> mBlockedIcons;
+
     private boolean mBatteryListening;
+    private StatusBarIconController.TintedIconManager mTintedIconManager;
 
     @Inject
     public KeyguardStatusBarViewController(
@@ -103,13 +113,23 @@
             ConfigurationController configurationController,
             SystemStatusAnimationScheduler animationScheduler,
             BatteryController batteryController,
-            UserInfoController userInfoController) {
+            UserInfoController userInfoController,
+            StatusBarIconController statusBarIconController,
+            StatusBarIconController.TintedIconManager.Factory tintedIconManagerFactory) {
         super(view);
         mCarrierTextController = carrierTextController;
         mConfigurationController = configurationController;
         mAnimationScheduler = animationScheduler;
         mBatteryController = batteryController;
         mUserInfoController = userInfoController;
+        mStatusBarIconController = statusBarIconController;
+        mTintedIconManagerFactory = tintedIconManagerFactory;
+
+        Resources r = getResources();
+        mBlockedIcons = Collections.unmodifiableList(Arrays.asList(
+                r.getString(com.android.internal.R.string.status_bar_volume),
+                r.getString(com.android.internal.R.string.status_bar_alarm_clock),
+                r.getString(com.android.internal.R.string.status_bar_call_strength)));
     }
 
     @Override
@@ -123,19 +143,33 @@
         mConfigurationController.addCallback(mConfigurationListener);
         mAnimationScheduler.addCallback(mAnimationCallback);
         mUserInfoController.addCallback(mOnUserInfoChangedListener);
+        if (mTintedIconManager == null) {
+            mTintedIconManager =
+                    mTintedIconManagerFactory.create(mView.findViewById(R.id.statusIcons));
+            mTintedIconManager.setBlockList(mBlockedIcons);
+            mStatusBarIconController.addIconGroup(mTintedIconManager);
+        }
         onThemeChanged();
     }
 
     @Override
     protected void onViewDetached() {
+        // Don't receive future #onViewAttached calls so that we don't accidentally have two
+        // controllers registered for the same view.
+        // TODO(b/194181195): This shouldn't be necessary.
+        destroy();
+
         mConfigurationController.removeCallback(mConfigurationListener);
         mAnimationScheduler.removeCallback(mAnimationCallback);
         mUserInfoController.removeCallback(mOnUserInfoChangedListener);
+        if (mTintedIconManager != null) {
+            mStatusBarIconController.removeIconGroup(mTintedIconManager);
+        }
     }
 
     /** Should be called when the theme changes. */
     public void onThemeChanged() {
-        mView.onThemeChanged();
+        mView.onThemeChanged(mTintedIconManager);
     }
 
     /** Sets whether this controller should listen to battery updates. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 89036cb..481a8ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -1012,6 +1012,10 @@
 
         KeyguardStatusBarViewComponent statusBarViewComponent =
                 mKeyguardStatusBarViewComponentFactory.build(keyguardStatusBarView);
+        if (mKeyguardStatusBarViewController != null) {
+            // TODO(b/194181195): This shouldn't be necessary.
+            mKeyguardStatusBarViewController.onViewDetached();
+        }
         mKeyguardStatusBarViewController =
                 statusBarViewComponent.getKeyguardStatusBarViewController();
         mKeyguardStatusBarViewController.init();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 2c75534..dbe4c1e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -35,6 +35,7 @@
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.demomode.DemoModeCommandReceiver;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
@@ -50,6 +51,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.inject.Inject;
+
 public interface StatusBarIconController {
 
     /**
@@ -213,6 +216,20 @@
             icons.setColor(mColor);
             return icons;
         }
+
+        @SysUISingleton
+        public static class Factory {
+            private final FeatureFlags mFeatureFlags;
+
+            @Inject
+            public Factory(FeatureFlags featureFlags) {
+                mFeatureFlags = featureFlags;
+            }
+
+            public TintedIconManager create(ViewGroup group) {
+                return new TintedIconManager(group, mFeatureFlags);
+            }
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index 75900a2..9d1c1e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -23,6 +23,7 @@
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.Log;
 import android.view.ViewGroup;
 
 import com.android.internal.statusbar.StatusBarIcon;
@@ -88,6 +89,13 @@
     /** */
     @Override
     public void addIconGroup(IconManager group) {
+        for (IconManager existingIconManager : mIconGroups) {
+            if (existingIconManager.mGroup == group.mGroup) {
+                Log.e(TAG, "Adding new IconManager for the same ViewGroup. This could cause "
+                        + "unexpected results.");
+            }
+        }
+
         mIconGroups.add(group);
         List<Slot> allSlots = getSlots();
         for (int i = 0; i < allSlots.size(); i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/util/ViewController.java b/packages/SystemUI/src/com/android/systemui/util/ViewController.java
index 0dd5788..32bbe1c 100644
--- a/packages/SystemUI/src/com/android/systemui/util/ViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/ViewController.java
@@ -110,6 +110,16 @@
     }
 
     /**
+     * Destroys this controller so that it never receives view attach and detach events again.
+     * Does nothing if the view is null.
+     */
+    public void destroy() {
+        if (mView != null) {
+            mView.removeOnAttachStateChangeListener(mOnAttachStateListener);
+        }
+    }
+
+    /**
      * Called when the view is attached and a call to {@link #init()} has been made in either order.
      */
     protected abstract void onViewAttached();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index c792a4d..217a77d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
@@ -19,11 +19,16 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.view.ViewGroup;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.CarrierTextController;
+import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -39,6 +44,8 @@
     @Mock
     private KeyguardStatusBarView mKeyguardStatusBarView;
     @Mock
+    private ViewGroup mViewGroup;
+    @Mock
     private CarrierTextController mCarrierTextController;
     @Mock
     private ConfigurationController mConfigurationController;
@@ -48,6 +55,10 @@
     private BatteryController mBatteryController;
     @Mock
     private UserInfoController mUserInfoController;
+    @Mock
+    private StatusBarIconController mStatusBarIconController;
+    @Mock
+    private FeatureFlags mFeatureFlags;
 
     private KeyguardStatusBarViewController mController;
 
@@ -55,13 +66,19 @@
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
 
+        when(mKeyguardStatusBarView.getResources()).thenReturn(mContext.getResources());
+        when(mKeyguardStatusBarView.findViewById(R.id.statusIcons)).thenReturn(mViewGroup);
+        when(mViewGroup.getContext()).thenReturn(mContext);
+
         mController = new KeyguardStatusBarViewController(
                 mKeyguardStatusBarView,
                 mCarrierTextController,
                 mConfigurationController,
                 mAnimationScheduler,
                 mBatteryController,
-                mUserInfoController
+                mUserInfoController,
+                mStatusBarIconController,
+                new StatusBarIconController.TintedIconManager.Factory(mFeatureFlags)
         );
     }
 
@@ -72,15 +89,20 @@
         verify(mConfigurationController).addCallback(any());
         verify(mAnimationScheduler).addCallback(any());
         verify(mUserInfoController).addCallback(any());
+        verify(mStatusBarIconController).addIconGroup(any());
     }
 
     @Test
     public void onViewDetached_callbacksUnregistered() {
+        // Set everything up first.
+        mController.onViewAttached();
+
         mController.onViewDetached();
 
         verify(mConfigurationController).removeCallback(any());
         verify(mAnimationScheduler).removeCallback(any());
         verify(mUserInfoController).removeCallback(any());
+        verify(mStatusBarIconController).removeIconGroup(any());
     }
 
     @Test