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
This commit is contained in:
@@ -156,7 +156,7 @@
|
||||
android:title="@string/notification_pulse_title"
|
||||
settings:controller="com.android.settings.notification.PulseNotificationPreferenceController"/>
|
||||
|
||||
<SwitchPreference
|
||||
<com.android.settingslib.PrimarySwitchPreference
|
||||
android:key="notification_assistant"
|
||||
android:order="23"
|
||||
android:title="@string/notification_assistant_title"
|
||||
|
@@ -18,35 +18,49 @@ package com.android.settings.notification;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.NotificationAssistantService;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settingslib.PrimarySwitchPreference;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NotificationAssistantPreferenceController extends TogglePreferenceController {
|
||||
private static final String TAG = "NASPreferenceController";
|
||||
private static final String KEY_NAS = "notification_assistant";
|
||||
static final String KEY_NAS = "notification_assistant";
|
||||
|
||||
private static final int AVAILABLE = 1;
|
||||
private final UserManager mUserManager;
|
||||
private final PackageManager mPackageManager;
|
||||
private Fragment mFragment;
|
||||
private int mUserId = UserHandle.myUserId();
|
||||
|
||||
@VisibleForTesting
|
||||
protected NotificationBackend mNotificationBackend;
|
||||
private ComponentName mDefaultNASComponent;
|
||||
private Intent mNASSettingIntent;
|
||||
|
||||
public NotificationAssistantPreferenceController(Context context) {
|
||||
super(context, KEY_NAS);
|
||||
mUserManager = UserManager.get(context);
|
||||
mNotificationBackend = new NotificationBackend();
|
||||
mPackageManager = context.getPackageManager();
|
||||
getDefaultNASIntent();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
@@ -55,14 +69,13 @@ public class NotificationAssistantPreferenceController extends TogglePreferenceC
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
ComponentName acn = mNotificationBackend.getAllowedNotificationAssistant();
|
||||
ComponentName dcn = mNotificationBackend.getDefaultNotificationAssistant();
|
||||
return (acn != null && acn.equals(dcn));
|
||||
return (acn != null && acn.equals(mDefaultNASComponent));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
ComponentName cn = isChecked
|
||||
? mNotificationBackend.getDefaultNotificationAssistant() : null;
|
||||
? mDefaultNASComponent : null;
|
||||
if (isChecked) {
|
||||
if (mFragment == null) {
|
||||
throw new IllegalStateException("No fragment to start activity");
|
||||
@@ -103,8 +116,43 @@ public class NotificationAssistantPreferenceController extends TogglePreferenceC
|
||||
mNotificationBackend = backend;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void getDefaultNASIntent() {
|
||||
mDefaultNASComponent = mNotificationBackend.getDefaultNotificationAssistant();
|
||||
if (mDefaultNASComponent != null) {
|
||||
mNASSettingIntent = new Intent(
|
||||
NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS);
|
||||
mNASSettingIntent.setPackage(mDefaultNASComponent.getPackageName());
|
||||
mNASSettingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSliceable() {
|
||||
return (mFragment != null && mFragment instanceof ConfigureNotificationSettings);
|
||||
}
|
||||
|
||||
private boolean isNASSettingActivityAvailable() {
|
||||
final List<ResolveInfo> 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;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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<ResolveInfo> 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 {
|
||||
|
Reference in New Issue
Block a user