summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Julia Reynolds <juliacr@google.com> 2023-08-02 20:47:44 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-08-02 20:47:44 +0000
commitdf8581f33155c1615b2eba93a39dd83050e04054 (patch)
tree62e199105997d05f4c8de4fb411904af14875d07
parent20fd792af6c64aba4295c2a5fa15dfda6e93ebb6 (diff)
parent54ebde46f75de147548c715e993e03932f3fcc86 (diff)
Merge "Revert "Do less on the main thread"" into udc-qpr-dev
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSettingsController.java167
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt90
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSettingsControllerTest.kt245
6 files changed, 5 insertions, 544 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 80f5d1939ac0..a4e8c2ece894 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -21,16 +21,12 @@ import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENAB
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.notification.NotificationUtils.logKey;
-import android.net.Uri;
-import android.os.UserHandle;
-import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
@@ -75,10 +71,6 @@ import javax.inject.Named;
@NotificationRowScope
public class ExpandableNotificationRowController implements NotifViewController {
private static final String TAG = "NotifRowController";
-
- static final Uri BUBBLES_SETTING_URI =
- Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BUBBLES);
- private static final String BUBBLES_SETTING_ENABLED_VALUE = "1";
private final ExpandableNotificationRow mView;
private final NotificationListContainer mListContainer;
private final RemoteInputViewSubcomponent.Factory mRemoteInputViewSubcomponentFactory;
@@ -112,23 +104,6 @@ public class ExpandableNotificationRowController implements NotifViewController
private final ExpandableNotificationRowDragController mDragController;
private final NotificationDismissibilityProvider mDismissibilityProvider;
private final IStatusBarService mStatusBarService;
-
- private final NotificationSettingsController mSettingsController;
-
- @VisibleForTesting
- final NotificationSettingsController.Listener mSettingsListener =
- new NotificationSettingsController.Listener() {
- @Override
- public void onSettingChanged(Uri setting, int userId, String value) {
- if (BUBBLES_SETTING_URI.equals(setting)) {
- final int viewUserId = mView.getEntry().getSbn().getUserId();
- if (viewUserId == UserHandle.USER_ALL || viewUserId == userId) {
- mView.getPrivateLayout().setBubblesEnabledForUser(
- BUBBLES_SETTING_ENABLED_VALUE.equals(value));
- }
- }
- }
- };
private final ExpandableNotificationRow.ExpandableNotificationRowLogger mLoggerCallback =
new ExpandableNotificationRow.ExpandableNotificationRowLogger() {
@Override
@@ -226,7 +201,6 @@ public class ExpandableNotificationRowController implements NotifViewController
FeatureFlags featureFlags,
PeopleNotificationIdentifier peopleNotificationIdentifier,
Optional<BubblesManager> bubblesManagerOptional,
- NotificationSettingsController settingsController,
ExpandableNotificationRowDragController dragController,
NotificationDismissibilityProvider dismissibilityProvider,
IStatusBarService statusBarService) {
@@ -255,7 +229,6 @@ public class ExpandableNotificationRowController implements NotifViewController
mFeatureFlags = featureFlags;
mPeopleNotificationIdentifier = peopleNotificationIdentifier;
mBubblesManagerOptional = bubblesManagerOptional;
- mSettingsController = settingsController;
mDragController = dragController;
mMetricsLogger = metricsLogger;
mChildrenContainerLogger = childrenContainerLogger;
@@ -325,14 +298,12 @@ public class ExpandableNotificationRowController implements NotifViewController
NotificationMenuRowPlugin.class, false /* Allow multiple */);
mView.setOnKeyguard(mStatusBarStateController.getState() == KEYGUARD);
mStatusBarStateController.addCallback(mStatusBarStateListener);
- mSettingsController.addCallback(BUBBLES_SETTING_URI, mSettingsListener);
}
@Override
public void onViewDetachedFromWindow(View v) {
mPluginManager.removePluginListener(mView);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
- mSettingsController.removeCallback(BUBBLES_SETTING_URI, mSettingsListener);
}
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 7b6802f95cda..20f4429f294b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -44,7 +44,6 @@ import android.widget.LinearLayout;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.SmartReplyController;
@@ -66,6 +65,7 @@ import com.android.systemui.statusbar.policy.SmartReplyStateInflaterKt;
import com.android.systemui.statusbar.policy.SmartReplyView;
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
import com.android.systemui.util.Compile;
+import com.android.systemui.wmshell.BubblesManager;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -134,7 +134,6 @@ public class NotificationContentView extends FrameLayout implements Notification
private PeopleNotificationIdentifier mPeopleIdentifier;
private RemoteInputViewSubcomponent.Factory mRemoteInputSubcomponentFactory;
private IStatusBarService mStatusBarService;
- private boolean mBubblesEnabledForUser;
/**
* List of listeners for when content views become inactive (i.e. not the showing view).
@@ -1441,17 +1440,12 @@ public class NotificationContentView extends FrameLayout implements Notification
}
}
- @Background
- public void setBubblesEnabledForUser(boolean enabled) {
- mBubblesEnabledForUser = enabled;
- }
-
@VisibleForTesting
boolean shouldShowBubbleButton(NotificationEntry entry) {
boolean isPersonWithShortcut =
mPeopleIdentifier.getPeopleNotificationType(entry)
>= PeopleNotificationIdentifier.TYPE_FULL_PERSON;
- return mBubblesEnabledForUser
+ return BubblesManager.areBubblesEnabled(mContext, entry.getSbn().getUser())
&& isPersonWithShortcut
&& entry.getBubbleMetadata() != null;
}
@@ -2085,7 +2079,6 @@ public class NotificationContentView extends FrameLayout implements Notification
pw.print("null");
}
pw.println();
- pw.println("mBubblesEnabledForUser: " + mBubblesEnabledForUser);
pw.print("RemoteInputViews { ");
pw.print(" visibleType: " + mVisibleType);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSettingsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSettingsController.java
deleted file mode 100644
index 585ff523b9a0..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSettingsController.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2023 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.notification.row;
-
-import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.util.settings.SecureSettings;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import javax.inject.Inject;
-
-/**
- * Centralized controller for listening to Secure Settings changes and informing in-process
- * listeners, on a background thread.
- */
-@SysUISingleton
-public class NotificationSettingsController implements Dumpable {
-
- private final static String TAG = "NotificationSettingsController";
- private final UserTracker mUserTracker;
- private final UserTracker.Callback mCurrentUserTrackerCallback;
- private final Handler mHandler;
- private final ContentObserver mContentObserver;
- private final SecureSettings mSecureSettings;
- private final HashMap<Uri, ArrayList<Listener>> mListeners = new HashMap<>();
-
- @Inject
- public NotificationSettingsController(UserTracker userTracker,
- @Background Handler handler,
- SecureSettings secureSettings,
- DumpManager dumpManager) {
- mUserTracker = userTracker;
- mHandler = handler;
- mSecureSettings = secureSettings;
- mContentObserver = new ContentObserver(mHandler) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- super.onChange(selfChange, uri);
- synchronized (mListeners) {
- if (mListeners.containsKey(uri)) {
- for (Listener listener : mListeners.get(uri)) {
- notifyListener(listener, uri);
- }
- }
- }
- }
- };
-
- mCurrentUserTrackerCallback = new UserTracker.Callback() {
- @Override
- public void onUserChanged(int newUser, Context userContext) {
- synchronized (mListeners) {
- if (mListeners.size() > 0) {
- mSecureSettings.unregisterContentObserver(mContentObserver);
- for (Uri uri : mListeners.keySet()) {
- mSecureSettings.registerContentObserverForUser(
- uri, false, mContentObserver, newUser);
- }
- }
- }
- }
- };
- mUserTracker.addCallback(mCurrentUserTrackerCallback, new HandlerExecutor(handler));
-
- dumpManager.registerNormalDumpable(TAG, this);
- }
-
- /**
- * Register callback whenever the given secure settings changes.
- *
- * On registration, will call back on the provided handler with the current value of
- * the setting.
- */
- public void addCallback(@NonNull Uri uri, @NonNull Listener listener) {
- if (uri == null || listener == null) {
- return;
- }
- synchronized (mListeners) {
- ArrayList<Listener> currentListeners = mListeners.get(uri);
- if (currentListeners == null) {
- currentListeners = new ArrayList<>();
- }
- if (!currentListeners.contains(listener)) {
- currentListeners.add(listener);
- }
- mListeners.put(uri, currentListeners);
- if (currentListeners.size() == 1) {
- mSecureSettings.registerContentObserverForUser(
- uri, false, mContentObserver, mUserTracker.getUserId());
- }
- }
- mHandler.post(() -> notifyListener(listener, uri));
-
- }
-
- public void removeCallback(Uri uri, Listener listener) {
- synchronized (mListeners) {
- ArrayList<Listener> currentListeners = mListeners.get(uri);
-
- if (currentListeners != null) {
- currentListeners.remove(listener);
- }
- if (currentListeners == null || currentListeners.size() == 0) {
- mListeners.remove(uri);
- }
-
- if (mListeners.size() == 0) {
- mSecureSettings.unregisterContentObserver(mContentObserver);
- }
- }
- }
-
- @Override
- public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
- synchronized (mListeners) {
- pw.println("Settings Uri Listener List:");
- for (Uri uri : mListeners.keySet()) {
- pw.println(" Uri=" + uri);
- for (Listener listener : mListeners.get(uri)) {
- pw.println(" Listener=" + listener.getClass().getName());
- }
- }
- }
- }
-
- private void notifyListener(Listener listener, Uri uri) {
- final String setting = uri == null ? null : uri.getLastPathSegment();
- int userId = mUserTracker.getUserId();
- listener.onSettingChanged(uri, userId, mSecureSettings.getStringForUser(setting, userId));
- }
-
- /**
- * Listener invoked whenever settings are changed.
- */
- public interface Listener {
- void onSettingChanged(@NonNull Uri setting, int userId, @Nullable String value);
- }
-} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
index 4d4d319a3540..2e68cec1fe63 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
@@ -17,10 +17,6 @@
package com.android.systemui.statusbar.notification.row
-import android.app.Notification
-import android.net.Uri
-import android.os.UserHandle
-import android.os.UserHandle.USER_ALL
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
@@ -32,17 +28,13 @@ import com.android.systemui.flags.FeatureFlags
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.PluginManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.statusbar.SbnBuilder
import com.android.systemui.statusbar.SmartReplyController
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider
import com.android.systemui.statusbar.notification.collection.render.FakeNodeController
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager
import com.android.systemui.statusbar.notification.logging.NotificationLogger
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController.BUBBLES_SETTING_URI
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
@@ -53,9 +45,9 @@ import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.withArgCaptor
import com.android.systemui.util.time.SystemClock
import com.android.systemui.wmshell.BubblesManager
+import java.util.Optional
import junit.framework.Assert
import org.junit.After
import org.junit.Before
@@ -63,10 +55,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.mockito.Mockito.anyBoolean
-import org.mockito.Mockito.mock
import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
-import java.util.*
import org.mockito.Mockito.`when` as whenever
@SmallTest
@@ -103,10 +92,10 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() {
private val featureFlags: FeatureFlags = mock()
private val peopleNotificationIdentifier: PeopleNotificationIdentifier = mock()
private val bubblesManager: BubblesManager = mock()
- private val settingsController: NotificationSettingsController = mock()
private val dragController: ExpandableNotificationRowDragController = mock()
private val dismissibilityProvider: NotificationDismissibilityProvider = mock()
private val statusBarService: IStatusBarService = mock()
+
private lateinit var controller: ExpandableNotificationRowController
@Before
@@ -143,16 +132,11 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() {
featureFlags,
peopleNotificationIdentifier,
Optional.of(bubblesManager),
- settingsController,
dragController,
dismissibilityProvider,
statusBarService
)
whenever(view.childrenContainer).thenReturn(childrenContainer)
-
- val notification = Notification.Builder(mContext).build()
- val sbn = SbnBuilder().setNotification(notification).build()
- whenever(view.entry).thenReturn(NotificationEntryBuilder().setSbn(sbn).build())
}
@After
@@ -220,74 +204,4 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() {
Mockito.verify(view).removeChildNotification(eq(childView))
Mockito.verify(listContainer).notifyGroupChildRemoved(eq(childView), eq(childrenContainer))
}
-
- @Test
- fun registerSettingsListener_forBubbles() {
- controller.init(mock(NotificationEntry::class.java))
- val viewStateObserver = withArgCaptor {
- verify(view).addOnAttachStateChangeListener(capture());
- }
- viewStateObserver.onViewAttachedToWindow(view);
- verify(settingsController).addCallback(any(), any());
- }
-
- @Test
- fun unregisterSettingsListener_forBubbles() {
- controller.init(mock(NotificationEntry::class.java))
- val viewStateObserver = withArgCaptor {
- verify(view).addOnAttachStateChangeListener(capture());
- }
- viewStateObserver.onViewDetachedFromWindow(view);
- verify(settingsController).removeCallback(any(), any());
- }
-
- @Test
- fun settingsListener_invalidUri() {
- controller.mSettingsListener.onSettingChanged(Uri.EMPTY, view.entry.sbn.userId, "1")
-
- verify(view, never()).getPrivateLayout()
- }
-
- @Test
- fun settingsListener_invalidUserId() {
- controller.mSettingsListener.onSettingChanged(BUBBLES_SETTING_URI, -1000, "1")
- controller.mSettingsListener.onSettingChanged(BUBBLES_SETTING_URI, -1000, null)
-
- verify(view, never()).getPrivateLayout()
- }
-
- @Test
- fun settingsListener_validUserId() {
- val childView: NotificationContentView = mock()
- whenever(view.privateLayout).thenReturn(childView)
-
- controller.mSettingsListener.onSettingChanged(
- BUBBLES_SETTING_URI, view.entry.sbn.userId, "1")
- verify(childView).setBubblesEnabledForUser(true)
-
- controller.mSettingsListener.onSettingChanged(
- BUBBLES_SETTING_URI, view.entry.sbn.userId, "9")
- verify(childView).setBubblesEnabledForUser(false)
- }
-
- @Test
- fun settingsListener_userAll() {
- val childView: NotificationContentView = mock()
- whenever(view.privateLayout).thenReturn(childView)
-
- val notification = Notification.Builder(mContext).build()
- val sbn = SbnBuilder().setNotification(notification)
- .setUser(UserHandle.of(USER_ALL))
- .build()
- whenever(view.entry).thenReturn(NotificationEntryBuilder()
- .setSbn(sbn)
- .setUser(UserHandle.of(USER_ALL))
- .build())
-
- controller.mSettingsListener.onSettingChanged(BUBBLES_SETTING_URI, 9, "1")
- verify(childView).setBubblesEnabledForUser(true)
-
- controller.mSettingsListener.onSettingChanged(BUBBLES_SETTING_URI, 1, "0")
- verify(childView).setBubblesEnabledForUser(false)
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
index ba6c7fd50bc5..0b90ebec3ec6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
@@ -250,9 +250,6 @@ class NotificationContentViewTest : SysuiTestCase() {
.thenReturn(actionListMarginTarget)
view.setContainingNotification(mockContainingNotification)
- // Given: controller says bubbles are enabled for the user
- view.setBubblesEnabledForUser(true);
-
// When: call NotificationContentView.setExpandedChild() to set the expandedChild
view.expandedChild = mockExpandedChild
@@ -304,9 +301,6 @@ class NotificationContentViewTest : SysuiTestCase() {
view.expandedChild = mockExpandedChild
assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget))
- // Given: controller says bubbles are enabled for the user
- view.setBubblesEnabledForUser(true);
-
// When: call NotificationContentView.onNotificationUpdated() to update the
// NotificationEntry, which should show bubble button
view.onNotificationUpdated(createMockNotificationEntry(true))
@@ -411,6 +405,7 @@ class NotificationContentViewTest : SysuiTestCase() {
val userMock: UserHandle = mock()
whenever(this.sbn).thenReturn(sbnMock)
whenever(sbnMock.user).thenReturn(userMock)
+ doReturn(showButton).whenever(view).shouldShowBubbleButton(this)
}
private fun createLinearLayoutWithBottomMargin(bottomMargin: Int): LinearLayout {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSettingsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSettingsControllerTest.kt
deleted file mode 100644
index 2bccdcafbb6e..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSettingsControllerTest.kt
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 2023 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.notification.row
-
-import android.app.ActivityManager
-import android.database.ContentObserver
-import android.net.Uri
-import android.os.Handler
-import android.provider.Settings.Secure
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.settings.UserTracker
-import com.android.systemui.statusbar.notification.row.NotificationSettingsController.Listener
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.capture
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.settings.SecureSettings
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.anyString
-import org.mockito.Captor
-import org.mockito.Mock
-import org.mockito.Mockito
-import org.mockito.Mockito.anyBoolean
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-@TestableLooper.RunWithLooper
-class NotificationSettingsControllerTest : SysuiTestCase() {
-
- val setting1: String = Secure.NOTIFICATION_BUBBLES
- val setting2: String = Secure.ACCESSIBILITY_ENABLED
- val settingUri1: Uri = Secure.getUriFor(setting1)
- val settingUri2: Uri = Secure.getUriFor(setting2)
-
- @Mock
- private lateinit var userTracker: UserTracker
- private lateinit var handler: Handler
- private lateinit var testableLooper: TestableLooper
- @Mock
- private lateinit var secureSettings: SecureSettings
- @Mock
- private lateinit var dumpManager: DumpManager
-
- @Captor
- private lateinit var userTrackerCallbackCaptor: ArgumentCaptor<UserTracker.Callback>
- @Captor
- private lateinit var settingsObserverCaptor: ArgumentCaptor<ContentObserver>
-
- private lateinit var controller: NotificationSettingsController
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
- testableLooper = TestableLooper.get(this)
- handler = Handler(testableLooper.looper)
- allowTestableLooperAsMainThread()
- controller =
- NotificationSettingsController(
- userTracker,
- handler,
- secureSettings,
- dumpManager
- )
- }
-
- @After
- fun tearDown() {
- disallowTestableLooperAsMainThread()
- }
-
- @Test
- fun creationRegistersCallbacks() {
- verify(userTracker).addCallback(any(), any())
- verify(dumpManager).registerNormalDumpable(anyString(), eq(controller))
- }
- @Test
- fun updateContentObserverRegistration_onUserChange_noSettingsListeners() {
- verify(userTracker).addCallback(capture(userTrackerCallbackCaptor), any())
- val userCallback = userTrackerCallbackCaptor.value
- val userId = 9
-
- // When: User is changed
- userCallback.onUserChanged(userId, context)
-
- // Validate: Nothing to do, since we aren't monitoring settings
- verify(secureSettings, never()).unregisterContentObserver(any())
- verify(secureSettings, never()).registerContentObserverForUser(
- any(Uri::class.java), anyBoolean(), any(), anyInt())
- }
- @Test
- fun updateContentObserverRegistration_onUserChange_withSettingsListeners() {
- // When: someone is listening to a setting
- controller.addCallback(settingUri1,
- Mockito.mock(Listener::class.java))
-
- verify(userTracker).addCallback(capture(userTrackerCallbackCaptor), any())
- val userCallback = userTrackerCallbackCaptor.value
- val userId = 9
-
- // Then: User is changed
- userCallback.onUserChanged(userId, context)
-
- // Validate: The tracker is unregistered and re-registered with the new user
- verify(secureSettings).unregisterContentObserver(any())
- verify(secureSettings).registerContentObserverForUser(
- eq(settingUri1), eq(false), any(), eq(userId))
- }
-
- @Test
- fun addCallback_onlyFirstForUriRegistersObserver() {
- controller.addCallback(settingUri1,
- Mockito.mock(Listener::class.java))
- verify(secureSettings).registerContentObserverForUser(
- eq(settingUri1), eq(false), any(), eq(ActivityManager.getCurrentUser()))
-
- controller.addCallback(settingUri1,
- Mockito.mock(Listener::class.java))
- verify(secureSettings).registerContentObserverForUser(
- any(Uri::class.java), anyBoolean(), any(), anyInt())
- }
-
- @Test
- fun addCallback_secondUriRegistersObserver() {
- controller.addCallback(settingUri1,
- Mockito.mock(Listener::class.java))
- verify(secureSettings).registerContentObserverForUser(
- eq(settingUri1), eq(false), any(), eq(ActivityManager.getCurrentUser()))
-
- controller.addCallback(settingUri2,
- Mockito.mock(Listener::class.java))
- verify(secureSettings).registerContentObserverForUser(
- eq(settingUri2), eq(false), any(), eq(ActivityManager.getCurrentUser()))
- verify(secureSettings).registerContentObserverForUser(
- eq(settingUri1), anyBoolean(), any(), anyInt())
- }
-
- @Test
- fun removeCallback_lastUnregistersObserver() {
- val listenerSetting1 : Listener = mock()
- val listenerSetting2 : Listener = mock()
- controller.addCallback(settingUri1, listenerSetting1)
- verify(secureSettings).registerContentObserverForUser(
- eq(settingUri1), eq(false), any(), eq(ActivityManager.getCurrentUser()))
-
- controller.addCallback(settingUri2, listenerSetting2)
- verify(secureSettings).registerContentObserverForUser(
- eq(settingUri2), anyBoolean(), any(), anyInt())
-
- controller.removeCallback(settingUri2, listenerSetting2)
- verify(secureSettings, never()).unregisterContentObserver(any())
-
- controller.removeCallback(settingUri1, listenerSetting1)
- verify(secureSettings).unregisterContentObserver(any())
- }
-
- @Test
- fun addCallback_updatesCurrentValue() {
- whenever(secureSettings.getStringForUser(
- setting1, ActivityManager.getCurrentUser())).thenReturn("9")
- whenever(secureSettings.getStringForUser(
- setting2, ActivityManager.getCurrentUser())).thenReturn("5")
-
- val listenerSetting1a : Listener = mock()
- val listenerSetting1b : Listener = mock()
- val listenerSetting2 : Listener = mock()
-
- controller.addCallback(settingUri1, listenerSetting1a)
- controller.addCallback(settingUri1, listenerSetting1b)
- controller.addCallback(settingUri2, listenerSetting2)
-
- testableLooper.processAllMessages()
-
- verify(listenerSetting1a).onSettingChanged(
- settingUri1, ActivityManager.getCurrentUser(), "9")
- verify(listenerSetting1b).onSettingChanged(
- settingUri1, ActivityManager.getCurrentUser(), "9")
- verify(listenerSetting2).onSettingChanged(
- settingUri2, ActivityManager.getCurrentUser(), "5")
- }
-
- @Test
- fun removeCallback_noMoreUpdates() {
- whenever(secureSettings.getStringForUser(
- setting1, ActivityManager.getCurrentUser())).thenReturn("9")
-
- val listenerSetting1a : Listener = mock()
- val listenerSetting1b : Listener = mock()
-
- // First, register
- controller.addCallback(settingUri1, listenerSetting1a)
- controller.addCallback(settingUri1, listenerSetting1b)
- testableLooper.processAllMessages()
-
- verify(secureSettings).registerContentObserverForUser(
- any(Uri::class.java), anyBoolean(), capture(settingsObserverCaptor), anyInt())
- verify(listenerSetting1a).onSettingChanged(
- settingUri1, ActivityManager.getCurrentUser(), "9")
- verify(listenerSetting1b).onSettingChanged(
- settingUri1, ActivityManager.getCurrentUser(), "9")
- Mockito.clearInvocations(listenerSetting1b)
- Mockito.clearInvocations(listenerSetting1a)
-
- // Remove one of them
- controller.removeCallback(settingUri1, listenerSetting1a)
-
- // On update, only remaining listener should get the callback
- settingsObserverCaptor.value.onChange(false, settingUri1)
- testableLooper.processAllMessages()
-
- verify(listenerSetting1a, never()).onSettingChanged(
- settingUri1, ActivityManager.getCurrentUser(), "9")
- verify(listenerSetting1b).onSettingChanged(
- settingUri1, ActivityManager.getCurrentUser(), "9")
- }
-
-} \ No newline at end of file