From 54c677a83c2488d577a047199234d4a152a73acf Mon Sep 17 00:00:00 2001 From: Chloris Kuo Date: Tue, 16 Aug 2022 15:08:29 -0700 Subject: [PATCH] Support ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS in Enhanced Notifications Show detail settings page from the default NAS app if it implements the new intent ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS. Test: Robotest, manually test on device Bug: 231492005 Change-Id: I6566cd9d615331a56728613583295637982bcd3f Merged-In: I6566cd9d615331a56728613583295637982bcd3f --- res/xml/configure_notification_settings.xml | 2 +- ...ficationAssistantPreferenceController.java | 56 +++++++++++++- ...tionAssistantPreferenceControllerTest.java | 74 ++++++++++++++++++- 3 files changed, 125 insertions(+), 7 deletions(-) diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml index 4e58e66887d..96a3f85a46a 100644 --- a/res/xml/configure_notification_settings.xml +++ b/res/xml/configure_notification_settings.xml @@ -156,7 +156,7 @@ android:title="@string/notification_pulse_title" settings:controller="com.android.settings.notification.PulseNotificationPreferenceController"/> - resolved = mPackageManager.queryIntentActivities(mNASSettingIntent, + PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_ALL)); + return (resolved != null && !resolved.isEmpty()); + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + if (isNASSettingActivityAvailable()) { + preference.setIntent(mNASSettingIntent); + } else { + // Cannot find settings activity from the default NAS app + preference.setIntent(null); + preference.setOnPreferenceClickListener( + preference1 -> { + onPreferenceChange(preference1, !isChecked()); + ((PrimarySwitchPreference) preference1).setChecked(isChecked()); + return true; + } + ); + } + } } diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java index d1307114e65..b5946673815 100644 --- a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java @@ -16,7 +16,12 @@ package com.android.settings.notification; +import static android.service.notification.NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -29,16 +34,24 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.Application; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.os.UserManager; import android.provider.Settings; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; +import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; import com.android.settings.testutils.shadow.ShadowSecureSettings; +import com.android.settingslib.PrimarySwitchPreference; import org.junit.Before; import org.junit.Test; @@ -47,9 +60,13 @@ import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; +import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; +import java.util.ArrayList; +import java.util.List; + @RunWith(RobolectricTestRunner.class) public class NotificationAssistantPreferenceControllerTest { @@ -67,23 +84,48 @@ public class NotificationAssistantPreferenceControllerTest { private NotificationBackend mBackend; @Mock private UserManager mUserManager; + @Mock + private PackageManager mPackageManager; private NotificationAssistantPreferenceController mPreferenceController; - ComponentName mNASComponent = new ComponentName("a", "b"); + ComponentName mNASComponent = new ComponentName("pkgname", "clsname"); + private PrimarySwitchPreference mPreference; + private ShadowApplication mShadowApplication; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(ApplicationProvider.getApplicationContext()); - ShadowApplication.getInstance().setSystemService(Context.USER_SERVICE, mUserManager); + mPreference = spy(new PrimarySwitchPreference(mContext)); + mShadowApplication = ShadowApplication.getInstance(); + mShadowApplication.setSystemService(Context.USER_SERVICE, mUserManager); doReturn(mContext).when(mFragment).getContext(); when(mFragment.getFragmentManager()).thenReturn(mFragmentManager); when(mFragmentManager.beginTransaction()).thenReturn(mFragmentTransaction); when(mBackend.getDefaultNotificationAssistant()).thenReturn(mNASComponent); + when(mContext.getPackageManager()).thenReturn(mPackageManager); mPreferenceController = new NotificationAssistantPreferenceController(mContext); mPreferenceController.setBackend(mBackend); mPreferenceController.setFragment(mFragment); + mPreferenceController.getDefaultNASIntent(); + + final PreferenceManager preferenceManager = new PreferenceManager(mContext); + final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext); + mPreference.setKey(NotificationAssistantPreferenceController.KEY_NAS); + screen.addPreference(mPreference); + mPreferenceController.displayPreference(screen); + when(mUserManager.getProfileIds(eq(0), anyBoolean())).thenReturn(new int[] {0, 10}); when(mUserManager.getProfileIds(eq(20), anyBoolean())).thenReturn(new int[] {20}); + + ActivityInfo activityInfo1 = new ActivityInfo(); + activityInfo1.packageName = "pkgname"; + activityInfo1.name = "name"; + ResolveInfo resolveInfo1 = new ResolveInfo(); + resolveInfo1.activityInfo = activityInfo1; + List resolvers1 = new ArrayList<>(); + resolvers1.add(resolveInfo1); + when(mPackageManager.queryIntentActivities(any(Intent.class), any())) + .thenReturn(resolvers1); } @Test @@ -108,6 +150,34 @@ public class NotificationAssistantPreferenceControllerTest { verify(mBackend, times(1)).setNotificationAssistantGranted(null); } + @Test + public void testUpdateState_SettingActivityAvailable() throws Exception { + mPreferenceController.updateState(mPreference); + assertNotNull(mPreference.getIntent()); + + mPreference.performClick(); + Intent nextIntent = Shadows.shadowOf( + (Application) ApplicationProvider.getApplicationContext()).getNextStartedActivity(); + assertEquals(nextIntent.getAction(), ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS); + } + + @Test + public void testUpdateState_SettingActivityUnavailable() throws Exception { + when(mPackageManager.queryIntentActivities(any(Intent.class), any())) + .thenReturn(null); + mPreferenceController.updateState(mPreference); + assertNull(mPreference.getIntent()); + + mPreference.performClick(); + Intent nextIntent = Shadows.shadowOf( + (Application) ApplicationProvider.getApplicationContext()).getNextStartedActivity(); + assertNull(nextIntent); + // Verify a dialog is shown + verify(mFragmentTransaction).add( + any(NotificationAssistantDialogFragment.class), anyString()); + verify(mBackend, times(0)).setNotificationAssistantGranted(any()); + } + @Test @Config(shadows = ShadowSecureSettings.class) public void testMigrationFromSetting_userEnable_multiProfile() throws Exception {