Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt +19 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.graphics.drawable.Drawable import android.graphics.drawable.ColorDrawable import android.util.Log import android.view.Gravity import android.view.View import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.Window Loading Loading @@ -86,13 +87,17 @@ class ChannelEditorDialogController @Inject constructor( internal val groupNameLookup = hashMapOf<String, CharSequence>() private val channelGroupList = mutableListOf<NotificationChannelGroup>() /** * Give the controller all of the information it needs to present the dialog * for a given app. Does a bunch of querying of NoMan, but won't present anything yet */ fun prepareDialogForApp( appName: String, packageName: String, uid: Int, channels: Set<NotificationChannel>, appIcon: Drawable, onSettingsClickListener: NotificationInfo.OnSettingsClickListener onSettingsClickListener: NotificationInfo.OnSettingsClickListener? ) { this.appName = appName this.packageName = packageName Loading Loading @@ -156,6 +161,13 @@ class ChannelEditorDialogController @Inject constructor( dialog.show() } /** * Close the dialog without saving. For external callers */ fun close() { done() } private fun done() { resetState() dialog.dismiss() Loading Loading @@ -235,6 +247,11 @@ class ChannelEditorDialogController @Inject constructor( } } @VisibleForTesting fun launchSettings(sender: View) { onSettingsClickListener?.onClick(sender, null, appUid!!) } private fun initDialog() { dialog = Dialog(context) Loading @@ -257,7 +274,7 @@ class ChannelEditorDialogController @Inject constructor( } findViewById<TextView>(R.id.see_more_button)?.setOnClickListener { onSettingsClickListener?.onClick(it, null, appUid!!) launchSettings(it) done() } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +33 −0 Original line number Diff line number Diff line Loading @@ -41,12 +41,14 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarStateControllerImpl; import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; Loading Loading @@ -97,6 +99,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx @VisibleForTesting protected String mKeyToRemoveOnGutsClosed; private StatusBar mStatusBar; @Inject public NotificationGutsManager( Context context, Loading @@ -114,6 +118,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx mListContainer = listContainer; mCheckSaveListener = checkSave; mOnSettingsClickListener = onSettingsClick; mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class); } public void setNotificationActivityStarter( Loading Loading @@ -376,6 +381,34 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx int x, int y, NotificationMenuRowPlugin.MenuItem menuItem) { if (menuItem.getGutsView() instanceof NotificationInfo) { if (mStatusBarStateController instanceof StatusBarStateControllerImpl) { ((StatusBarStateControllerImpl) mStatusBarStateController) .setLeaveOpenOnKeyguardHide(true); } Runnable r = () -> Dependency.get(Dependency.MAIN_HANDLER).post( () -> openGutsInternal(view, x, y, menuItem)); mStatusBar.executeRunnableDismissingKeyguard( r, null /* cancelAction */, false /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */); return true; } return openGutsInternal(view, x, y, menuItem); } @VisibleForTesting boolean openGutsInternal( View view, int x, int y, NotificationMenuRowPlugin.MenuItem menuItem) { if (!(view instanceof ExpandableNotificationRow)) { return false; } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java +15 −3 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G private int mStartingChannelImportance; private boolean mWasShownHighPriority; private boolean mPressedApply; private boolean mPresentingChannelEditorDialog = false; /** * The last importance level chosen by the user. Null if the user has not chosen an importance Loading Loading @@ -447,11 +448,15 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G private OnClickListener getTurnOffNotificationsClickListener() { return ((View view) -> { if (mChannelEditorDialogController != null) { if (!mPresentingChannelEditorDialog && mChannelEditorDialogController != null) { mPresentingChannelEditorDialog = true; mChannelEditorDialogController.prepareDialogForApp(mAppName, mPackageName, mAppUid, mUniqueChannelsInRow, mPkgIcon, mOnSettingsClickListener); mChannelEditorDialogController.setOnFinishListener( () -> closeControls(this, false)); mChannelEditorDialogController.setOnFinishListener(() -> { mPresentingChannelEditorDialog = false; closeControls(this, false); }); mChannelEditorDialogController.show(); } }); Loading Loading @@ -772,6 +777,13 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G @Override public boolean handleCloseControls(boolean save, boolean force) { if (mPresentingChannelEditorDialog && mChannelEditorDialogController != null) { mPresentingChannelEditorDialog = false; // No need for the finish listener because we're closing mChannelEditorDialogController.setOnFinishListener(null); mChannelEditorDialogController.close(); } // Save regardless of the importance so we can lock the importance field if the user wants // to keep getting notifications if (save) { Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt +11 −1 Original line number Diff line number Diff line Loading @@ -109,7 +109,7 @@ class ChannelEditorDialogControllerTest : SysuiTestCase() { } @Test fun testPrepareDialogForApp_retrievesUpto4Channels() { fun testPrepareDialogForApp_retrievesUpTo4Channels() { val channel3 = NotificationChannel("test_channel_3", "Test channel 3", IMPORTANCE_DEFAULT) val channel4 = NotificationChannel("test_channel_4", "Test channel 4", IMPORTANCE_DEFAULT) Loading Loading @@ -169,6 +169,16 @@ class ChannelEditorDialogControllerTest : SysuiTestCase() { eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(true)) } @Test fun testSettingsClickListenerNull_noCrash() { group.channels = listOf(channel1, channel2) controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID, setOf(channel1, channel2), appIcon, null) // Pass in any old view, it should never actually be used controller.launchSettings(View(context)) } private val clickListener = object : NotificationInfo.OnSettingsClickListener { override fun onClick(v: View, c: NotificationChannel, appUid: Int) { } Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java +5 −3 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.util.Assert; Loading Loading @@ -105,6 +106,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { @Mock private NotificationInfo.CheckSaveListener mCheckSaveListener; @Mock private OnSettingsClickListener mOnSettingsClickListener; @Mock private DeviceProvisionedController mDeviceProvisionedController; @Mock private StatusBar mStatusBar; @Before public void setUp() { Loading @@ -115,7 +117,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager); mHandler = Handler.createAsync(mTestableLooper.getLooper()); mContext.putComponent(StatusBar.class, mStatusBar); mHelper = new NotificationTestHelper(mContext); mGutsManager = new NotificationGutsManager(mContext, mVisualStabilityManager); Loading Loading @@ -150,7 +152,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { when(row.getWindowToken()).thenReturn(new Binder()); when(row.getGuts()).thenReturn(guts); assertTrue(mGutsManager.openGuts(row, 0, 0, menuItem)); assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem)); assertEquals(View.INVISIBLE, guts.getVisibility()); mTestableLooper.processAllMessages(); verify(guts).openControls( Loading Loading @@ -198,7 +200,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { when(entry.getRow()).thenReturn(row); when(entry.getGuts()).thenReturn(guts); assertTrue(mGutsManager.openGuts(row, 0, 0, menuItem)); assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem)); mTestableLooper.processAllMessages(); verify(guts).openControls( eq(true), Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt +19 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.graphics.drawable.Drawable import android.graphics.drawable.ColorDrawable import android.util.Log import android.view.Gravity import android.view.View import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.Window Loading Loading @@ -86,13 +87,17 @@ class ChannelEditorDialogController @Inject constructor( internal val groupNameLookup = hashMapOf<String, CharSequence>() private val channelGroupList = mutableListOf<NotificationChannelGroup>() /** * Give the controller all of the information it needs to present the dialog * for a given app. Does a bunch of querying of NoMan, but won't present anything yet */ fun prepareDialogForApp( appName: String, packageName: String, uid: Int, channels: Set<NotificationChannel>, appIcon: Drawable, onSettingsClickListener: NotificationInfo.OnSettingsClickListener onSettingsClickListener: NotificationInfo.OnSettingsClickListener? ) { this.appName = appName this.packageName = packageName Loading Loading @@ -156,6 +161,13 @@ class ChannelEditorDialogController @Inject constructor( dialog.show() } /** * Close the dialog without saving. For external callers */ fun close() { done() } private fun done() { resetState() dialog.dismiss() Loading Loading @@ -235,6 +247,11 @@ class ChannelEditorDialogController @Inject constructor( } } @VisibleForTesting fun launchSettings(sender: View) { onSettingsClickListener?.onClick(sender, null, appUid!!) } private fun initDialog() { dialog = Dialog(context) Loading @@ -257,7 +274,7 @@ class ChannelEditorDialogController @Inject constructor( } findViewById<TextView>(R.id.see_more_button)?.setOnClickListener { onSettingsClickListener?.onClick(it, null, appUid!!) launchSettings(it) done() } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +33 −0 Original line number Diff line number Diff line Loading @@ -41,12 +41,14 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarStateControllerImpl; import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; Loading Loading @@ -97,6 +99,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx @VisibleForTesting protected String mKeyToRemoveOnGutsClosed; private StatusBar mStatusBar; @Inject public NotificationGutsManager( Context context, Loading @@ -114,6 +118,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx mListContainer = listContainer; mCheckSaveListener = checkSave; mOnSettingsClickListener = onSettingsClick; mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class); } public void setNotificationActivityStarter( Loading Loading @@ -376,6 +381,34 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx int x, int y, NotificationMenuRowPlugin.MenuItem menuItem) { if (menuItem.getGutsView() instanceof NotificationInfo) { if (mStatusBarStateController instanceof StatusBarStateControllerImpl) { ((StatusBarStateControllerImpl) mStatusBarStateController) .setLeaveOpenOnKeyguardHide(true); } Runnable r = () -> Dependency.get(Dependency.MAIN_HANDLER).post( () -> openGutsInternal(view, x, y, menuItem)); mStatusBar.executeRunnableDismissingKeyguard( r, null /* cancelAction */, false /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */); return true; } return openGutsInternal(view, x, y, menuItem); } @VisibleForTesting boolean openGutsInternal( View view, int x, int y, NotificationMenuRowPlugin.MenuItem menuItem) { if (!(view instanceof ExpandableNotificationRow)) { return false; } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java +15 −3 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G private int mStartingChannelImportance; private boolean mWasShownHighPriority; private boolean mPressedApply; private boolean mPresentingChannelEditorDialog = false; /** * The last importance level chosen by the user. Null if the user has not chosen an importance Loading Loading @@ -447,11 +448,15 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G private OnClickListener getTurnOffNotificationsClickListener() { return ((View view) -> { if (mChannelEditorDialogController != null) { if (!mPresentingChannelEditorDialog && mChannelEditorDialogController != null) { mPresentingChannelEditorDialog = true; mChannelEditorDialogController.prepareDialogForApp(mAppName, mPackageName, mAppUid, mUniqueChannelsInRow, mPkgIcon, mOnSettingsClickListener); mChannelEditorDialogController.setOnFinishListener( () -> closeControls(this, false)); mChannelEditorDialogController.setOnFinishListener(() -> { mPresentingChannelEditorDialog = false; closeControls(this, false); }); mChannelEditorDialogController.show(); } }); Loading Loading @@ -772,6 +777,13 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G @Override public boolean handleCloseControls(boolean save, boolean force) { if (mPresentingChannelEditorDialog && mChannelEditorDialogController != null) { mPresentingChannelEditorDialog = false; // No need for the finish listener because we're closing mChannelEditorDialogController.setOnFinishListener(null); mChannelEditorDialogController.close(); } // Save regardless of the importance so we can lock the importance field if the user wants // to keep getting notifications if (save) { Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt +11 −1 Original line number Diff line number Diff line Loading @@ -109,7 +109,7 @@ class ChannelEditorDialogControllerTest : SysuiTestCase() { } @Test fun testPrepareDialogForApp_retrievesUpto4Channels() { fun testPrepareDialogForApp_retrievesUpTo4Channels() { val channel3 = NotificationChannel("test_channel_3", "Test channel 3", IMPORTANCE_DEFAULT) val channel4 = NotificationChannel("test_channel_4", "Test channel 4", IMPORTANCE_DEFAULT) Loading Loading @@ -169,6 +169,16 @@ class ChannelEditorDialogControllerTest : SysuiTestCase() { eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(true)) } @Test fun testSettingsClickListenerNull_noCrash() { group.channels = listOf(channel1, channel2) controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID, setOf(channel1, channel2), appIcon, null) // Pass in any old view, it should never actually be used controller.launchSettings(View(context)) } private val clickListener = object : NotificationInfo.OnSettingsClickListener { override fun onClick(v: View, c: NotificationChannel, appUid: Int) { } Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java +5 −3 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.util.Assert; Loading Loading @@ -105,6 +106,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { @Mock private NotificationInfo.CheckSaveListener mCheckSaveListener; @Mock private OnSettingsClickListener mOnSettingsClickListener; @Mock private DeviceProvisionedController mDeviceProvisionedController; @Mock private StatusBar mStatusBar; @Before public void setUp() { Loading @@ -115,7 +117,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager); mHandler = Handler.createAsync(mTestableLooper.getLooper()); mContext.putComponent(StatusBar.class, mStatusBar); mHelper = new NotificationTestHelper(mContext); mGutsManager = new NotificationGutsManager(mContext, mVisualStabilityManager); Loading Loading @@ -150,7 +152,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { when(row.getWindowToken()).thenReturn(new Binder()); when(row.getGuts()).thenReturn(guts); assertTrue(mGutsManager.openGuts(row, 0, 0, menuItem)); assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem)); assertEquals(View.INVISIBLE, guts.getVisibility()); mTestableLooper.processAllMessages(); verify(guts).openControls( Loading Loading @@ -198,7 +200,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { when(entry.getRow()).thenReturn(row); when(entry.getGuts()).thenReturn(guts); assertTrue(mGutsManager.openGuts(row, 0, 0, menuItem)); assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem)); mTestableLooper.processAllMessages(); verify(guts).openControls( eq(true), Loading