Merge "Add settings observing for vibrate icon to Keyguard" into tm-dev am: 2540293518
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18602315
Change-Id: Ic5d40b4a1e7c77ca3be9175247f87c2006b529bf
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
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 779c6b4..def574c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -23,12 +23,16 @@
import android.animation.ValueAnimator;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.hardware.biometrics.BiometricSourceType;
+import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.Settings;
import android.util.MathUtils;
import android.view.View;
import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
import com.android.keyguard.CarrierTextController;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -36,6 +40,7 @@
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.battery.BatteryMeterViewController;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -45,6 +50,7 @@
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.fragment.StatusBarIconBlocklistKt;
import com.android.systemui.statusbar.phone.fragment.StatusBarSystemEventAnimator;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserInfoTracker;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherController;
@@ -54,10 +60,12 @@
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.util.ViewController;
+import com.android.systemui.util.settings.SecureSettings;
import java.io.PrintWriter;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -98,6 +106,9 @@
private final StatusBarUserSwitcherFeatureController mFeatureController;
private final StatusBarUserSwitcherController mUserSwitcherController;
private final StatusBarUserInfoTracker mStatusBarUserInfoTracker;
+ private final SecureSettings mSecureSettings;
+ private final Executor mMainExecutor;
+ private final Object mLock = new Object();
private final ConfigurationController.ConfigurationListener mConfigurationListener =
new ConfigurationController.ConfigurationListener() {
@@ -206,7 +217,7 @@
}
};
- private final List<String> mBlockedIcons;
+ private final List<String> mBlockedIcons = new ArrayList<>();
private final int mNotificationsHeaderCollideDistance;
private boolean mBatteryListening;
@@ -255,7 +266,9 @@
UserManager userManager,
StatusBarUserSwitcherFeatureController featureController,
StatusBarUserSwitcherController userSwitcherController,
- StatusBarUserInfoTracker statusBarUserInfoTracker
+ StatusBarUserInfoTracker statusBarUserInfoTracker,
+ SecureSettings secureSettings,
+ @Main Executor mainExecutor
) {
super(view);
mCarrierTextController = carrierTextController;
@@ -277,6 +290,8 @@
mFeatureController = featureController;
mUserSwitcherController = userSwitcherController;
mStatusBarUserInfoTracker = statusBarUserInfoTracker;
+ mSecureSettings = secureSettings;
+ mMainExecutor = mainExecutor;
mFirstBypassAttempt = mKeyguardBypassController.getBypassEnabled();
mKeyguardStateController.addCallback(
@@ -292,8 +307,7 @@
);
Resources r = getResources();
- mBlockedIcons = Arrays.asList(r.getStringArray(
- R.array.config_keyguard_statusbar_icon_blocklist));
+ updateBlockedIcons();
mNotificationsHeaderCollideDistance = r.getDimensionPixelSize(
R.dimen.header_notifications_collide_distance);
@@ -321,11 +335,16 @@
if (mTintedIconManager == null) {
mTintedIconManager =
mTintedIconManagerFactory.create(mView.findViewById(R.id.statusIcons));
- mTintedIconManager.setBlockList(mBlockedIcons);
+ mTintedIconManager.setBlockList(getBlockedIcons());
mStatusBarIconController.addIconGroup(mTintedIconManager);
}
mView.setOnApplyWindowInsetsListener(
(view, windowInsets) -> mView.updateWindowInsets(windowInsets, mInsetsProvider));
+ mSecureSettings.registerContentObserverForUser(
+ Settings.Secure.getUriFor(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON),
+ false,
+ mVolumeSettingObserver,
+ UserHandle.USER_ALL);
updateUserSwitcher();
onThemeChanged();
}
@@ -337,6 +356,7 @@
mUserInfoController.removeCallback(mOnUserInfoChangedListener);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
+ mSecureSettings.unregisterContentObserver(mVolumeSettingObserver);
if (mTintedIconManager != null) {
mStatusBarIconController.removeIconGroup(mTintedIconManager);
}
@@ -486,8 +506,32 @@
R.bool.qs_show_user_switcher_for_single_user)));
}
+ @VisibleForTesting
+ void updateBlockedIcons() {
+ List<String> newBlockList = StatusBarIconBlocklistKt
+ .getStatusBarIconBlocklist(getResources(), mSecureSettings);
+
+ synchronized (mLock) {
+ mBlockedIcons.clear();
+ mBlockedIcons.addAll(newBlockList);
+ }
+
+ mMainExecutor.execute(() -> {
+ if (mTintedIconManager != null) {
+ mTintedIconManager.setBlockList(getBlockedIcons());
+ }
+ });
+ }
+
+ @VisibleForTesting
+ List<String> getBlockedIcons() {
+ synchronized (mLock) {
+ return new ArrayList<>(mBlockedIcons);
+ }
+ }
+
/**
- * Update {@link KeyguardStatusBarView}'s visibility based on whether keyguard is showing and
+ Update {@link KeyguardStatusBarView}'s visibility based on whether keyguard is showing and
* whether heads up is visible.
*/
public void updateForHeadsUp() {
@@ -533,4 +577,11 @@
mExplicitAlpha = alpha;
updateViewState();
}
+
+ private final ContentObserver mVolumeSettingObserver = new ContentObserver(null) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateBlockedIcons();
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt
new file mode 100644
index 0000000..b845bad
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 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.statusbar.phone.fragment
+
+import android.content.res.Resources
+import android.os.UserHandle
+import android.provider.Settings
+import com.android.internal.R
+import com.android.systemui.util.settings.SecureSettings
+
+/**
+ * Centralize the logic for the status bar / keyguard status bar icon blocklist. The default is
+ * loaded from the config, and we currently support a system setting for the vibrate icon. It's
+ * pretty likely that we would end up supporting more user-configurable settings in the future, so
+ * breaking this out into its own file for now.
+ *
+ * Note for the future: it might be reasonable to turn this into its own class that can listen to
+ * the system setting and execute a callback when it changes instead of having multiple content
+ * observers.
+ */
+fun getStatusBarIconBlocklist(
+ res: Resources,
+ settings: SecureSettings
+): List<String> {
+ // Load the default blocklist from res
+ val blocklist = res.getStringArray(
+ com.android.systemui.R.array.config_collapsed_statusbar_icon_blocklist).toList()
+
+ val vibrateIconSlot: String = res.getString(R.string.status_bar_volume)
+ val showVibrateIcon = settings.getIntForUser(
+ Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON,
+ 0,
+ UserHandle.USER_CURRENT) == 0
+
+ // Filter out vibrate icon from the blocklist if the setting is on
+ return blocklist.filter { icon ->
+ !icon.equals(vibrateIconSlot) || showVibrateIcon
+ }
+}
\ No newline at end of file
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 39d5a16..4e1a708 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
@@ -22,6 +22,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.clearInvocations;
@@ -29,7 +31,9 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.LayoutInflater;
@@ -55,6 +59,9 @@
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserInfoController;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.settings.SecureSettings;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
@@ -108,10 +115,12 @@
private StatusBarUserSwitcherController mStatusBarUserSwitcherController;
@Mock
private StatusBarUserInfoTracker mStatusBarUserInfoTracker;
+ @Mock private SecureSettings mSecureSettings;
private TestNotificationPanelViewStateProvider mNotificationPanelViewStateProvider;
private KeyguardStatusBarView mKeyguardStatusBarView;
private KeyguardStatusBarViewController mController;
+ private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
@Before
public void setup() throws Exception {
@@ -150,7 +159,9 @@
mUserManager,
mStatusBarUserSwitcherFeatureController,
mStatusBarUserSwitcherController,
- mStatusBarUserInfoTracker
+ mStatusBarUserInfoTracker,
+ mSecureSettings,
+ mFakeExecutor
);
}
@@ -420,6 +431,39 @@
assertThat(mKeyguardStatusBarView.isKeyguardUserAvatarEnabled()).isTrue();
}
+ @Test
+ public void testBlockedIcons_obeysSettingForVibrateIcon_settingOff() {
+ String str = mContext.getString(com.android.internal.R.string.status_bar_volume);
+
+ // GIVEN the setting is off
+ when(mSecureSettings.getInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0))
+ .thenReturn(0);
+
+ // WHEN CollapsedStatusBarFragment builds the blocklist
+ mController.updateBlockedIcons();
+
+ // THEN status_bar_volume SHOULD be present in the list
+ boolean contains = mController.getBlockedIcons().contains(str);
+ assertTrue(contains);
+ }
+
+ @Test
+ public void testBlockedIcons_obeysSettingForVibrateIcon_settingOn() {
+ String str = mContext.getString(com.android.internal.R.string.status_bar_volume);
+
+ // GIVEN the setting is ON
+ when(mSecureSettings.getIntForUser(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0,
+ UserHandle.USER_CURRENT))
+ .thenReturn(1);
+
+ // WHEN CollapsedStatusBarFragment builds the blocklist
+ mController.updateBlockedIcons();
+
+ // THEN status_bar_volume SHOULD NOT be present in the list
+ boolean contains = mController.getBlockedIcons().contains(str);
+ assertFalse(contains);
+ }
+
private void updateStateToNotKeyguard() {
updateStatusBarState(SHADE);
}