Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53065f93 authored by Chloris Kuo's avatar Chloris Kuo Committed by Android (Google) Code Review
Browse files

Merge "Enable default NAS for users who haven't done NAS migration" into sc-v2-dev

parents 1ba4fcf0 8c606ab1
Loading
Loading
Loading
Loading
+14 −137
Original line number Diff line number Diff line
@@ -266,7 +266,6 @@ import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
@@ -615,12 +614,6 @@ public class NotificationManagerService extends SystemService {
    private NotificationRecordLogger mNotificationRecordLogger;
    private InstanceIdSequence mNotificationInstanceIdSequence;
    private Set<String> mMsgPkgsAllowedAsConvos = new HashSet();
    protected static final String ACTION_ENABLE_NAS =
            "android.server.notification.action.ENABLE_NAS";
    protected static final String ACTION_DISABLE_NAS =
            "android.server.notification.action.DISABLE_NAS";
    protected static final String ACTION_LEARNMORE_NAS =
            "android.server.notification.action.LEARNMORE_NAS";

    static class Archive {
        final SparseArray<Boolean> mEnabled;
@@ -755,95 +748,25 @@ public class NotificationManagerService extends SystemService {
        setDefaultAssistantForUser(userId);
    }

    protected void migrateDefaultNASShowNotificationIfNecessary() {
    protected void migrateDefaultNAS() {
        final List<UserInfo> activeUsers = mUm.getUsers();
        for (UserInfo userInfo : activeUsers) {
            int userId = userInfo.getUserHandle().getIdentifier();
            if (isNASMigrationDone(userId) || mUm.isManagedProfile(userId)) {
                continue;
            }
            if (mAssistants.hasUserSet(userId)) {
                ComponentName defaultFromConfig = mAssistants.getDefaultFromConfig();
            List<ComponentName> allowedComponents = mAssistants.getAllowedComponents(userId);
                if (allowedComponents.size() == 0) {
            if (allowedComponents.size() == 0) { // user set to none
                Slog.d(TAG, "NAS Migration: user set to none, disable new NAS setting");
                setNASMigrationDone(userId);
                mAssistants.clearDefaults();
                    continue;
                } else if (allowedComponents.contains(defaultFromConfig)) {
                    setNASMigrationDone(userId);
                    mAssistants.resetDefaultFromConfig();
                    continue;
                }
                // TODO(b/192450820): re-enable when "user set" isn't over triggering
                //User selected different NAS, need onboarding
                /*enqueueNotificationInternal(getContext().getPackageName(),
                        getContext().getOpPackageName(), Binder.getCallingUid(),
                        Binder.getCallingPid(), TAG,
                        SystemMessageProto.SystemMessage.NOTE_NAS_UPGRADE,
                        createNASUpgradeNotification(userId), userId);*/
            }
            } else {
                Slog.d(TAG, "Reset NAS setting and migrate to new default");
                resetAssistantUserSet(userId);
                // migrate to new default and set migration done
                mAssistants.resetDefaultAssistantsIfNecessary();
            }
        }

    protected Notification createNASUpgradeNotification(int userId) {
        final Bundle extras = new Bundle();
        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
                getContext().getResources().getString(R.string.global_action_settings));
        int title = R.string.nas_upgrade_notification_title;
        int content = R.string.nas_upgrade_notification_content;

        Intent onboardingIntent = new Intent(Settings.ACTION_NOTIFICATION_ASSISTANT_SETTINGS);
        onboardingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

        Intent enableIntent = new Intent(ACTION_ENABLE_NAS);
        enableIntent.putExtra(Intent.EXTRA_USER_ID, userId);
        PendingIntent enableNASPendingIntent = PendingIntent.getBroadcast(getContext(),
                0, enableIntent, PendingIntent.FLAG_IMMUTABLE);

        Intent disableIntent = new Intent(ACTION_DISABLE_NAS);
        disableIntent.putExtra(Intent.EXTRA_USER_ID, userId);
        PendingIntent disableNASPendingIntent = PendingIntent.getBroadcast(getContext(),
                0, disableIntent, PendingIntent.FLAG_IMMUTABLE);

        Intent learnMoreIntent = new Intent(ACTION_LEARNMORE_NAS);
        learnMoreIntent.putExtra(Intent.EXTRA_USER_ID, userId);
        PendingIntent learnNASPendingIntent = PendingIntent.getBroadcast(getContext(),
                0, learnMoreIntent, PendingIntent.FLAG_IMMUTABLE);

        Notification.Action enableNASAction = new Notification.Action.Builder(
                0,
                getContext().getResources().getString(
                        R.string.nas_upgrade_notification_enable_action),
                enableNASPendingIntent).build();

        Notification.Action disableNASAction = new Notification.Action.Builder(
                0,
                getContext().getResources().getString(
                        R.string.nas_upgrade_notification_disable_action),
                disableNASPendingIntent).build();

        Notification.Action learnMoreNASAction = new Notification.Action.Builder(
                0,
                getContext().getResources().getString(
                        R.string.nas_upgrade_notification_learn_more_action),
                learnNASPendingIntent).build();


        return new Notification.Builder(getContext(), SystemNotificationChannels.SYSTEM_CHANGES)
                .setAutoCancel(false)
                .setOngoing(true)
                .setTicker(getContext().getResources().getString(title))
                .setSmallIcon(R.drawable.ic_settings_24dp)
                .setContentTitle(getContext().getResources().getString(title))
                .setContentText(getContext().getResources().getString(content))
                .setContentIntent(PendingIntent.getActivity(getContext(), 0, onboardingIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
                .setLocalOnly(true)
                .setStyle(new Notification.BigTextStyle())
                .addAction(enableNASAction)
                .addAction(disableNASAction)
                .addAction(learnMoreNASAction)
                .build();
    }

    @VisibleForTesting
@@ -1861,41 +1784,6 @@ public class NotificationManagerService extends SystemService {
        }
    };

    private final BroadcastReceiver mNASIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, -1);
            if (ACTION_ENABLE_NAS.equals(action)) {
                mAssistants.resetDefaultFromConfig();
                setNotificationAssistantAccessGrantedForUserInternal(
                        CollectionUtils.firstOrNull(mAssistants.getDefaultComponents()),
                        userId, true, true);
                setNASMigrationDone(userId);
                cancelNotificationInternal(getContext().getPackageName(),
                        getContext().getOpPackageName(), Binder.getCallingUid(),
                        Binder.getCallingPid(), TAG,
                        SystemMessageProto.SystemMessage.NOTE_NAS_UPGRADE, userId);
            } else if (ACTION_DISABLE_NAS.equals(action)) {
                //Set default NAS to be null if user selected none during migration
                mAssistants.clearDefaults();
                setNotificationAssistantAccessGrantedForUserInternal(
                        null, userId, true, true);
                setNASMigrationDone(userId);
                cancelNotificationInternal(getContext().getPackageName(),
                        getContext().getOpPackageName(), Binder.getCallingUid(),
                        Binder.getCallingPid(), TAG,
                        SystemMessageProto.SystemMessage.NOTE_NAS_UPGRADE, userId);
            } else if (ACTION_LEARNMORE_NAS.equals(action)) {
                Intent i = new Intent(getContext(), NASLearnMoreActivity.class);
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                getContext().sendBroadcastAsUser(
                        new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), UserHandle.of(userId));
                getContext().startActivity(i);
            }
        }
    };

    private final class SettingsObserver extends ContentObserver {
        private final Uri NOTIFICATION_BADGING_URI
                = Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BADGING);
@@ -2407,12 +2295,6 @@ public class NotificationManagerService extends SystemService {

        IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
        getContext().registerReceiver(mLocaleChangeReceiver, localeChangedFilter);

        IntentFilter nasFilter = new IntentFilter();
        nasFilter.addAction(ACTION_ENABLE_NAS);
        nasFilter.addAction(ACTION_DISABLE_NAS);
        nasFilter.addAction(ACTION_LEARNMORE_NAS);
        getContext().registerReceiver(mNASIntentReceiver, nasFilter);
    }

    /**
@@ -2424,7 +2306,6 @@ public class NotificationManagerService extends SystemService {
        getContext().unregisterReceiver(mNotificationTimeoutReceiver);
        getContext().unregisterReceiver(mRestoreReceiver);
        getContext().unregisterReceiver(mLocaleChangeReceiver);
        getContext().unregisterReceiver(mNASIntentReceiver);

        if (mDeviceConfigChangedListener != null) {
            DeviceConfig.removeOnPropertiesChangedListener(mDeviceConfigChangedListener);
@@ -2691,7 +2572,7 @@ public class NotificationManagerService extends SystemService {
            mConditionProviders.onBootPhaseAppsCanStart();
            mHistoryManager.onBootPhaseAppsCanStart();
            registerDeviceConfigChange();
            migrateDefaultNASShowNotificationIfNecessary();
            migrateDefaultNAS();
        } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
            mSnoozeHelper.scheduleRepostsForPersistedNotifications(System.currentTimeMillis());
        }
@@ -5229,10 +5110,6 @@ public class NotificationManagerService extends SystemService {
        public void setNASMigrationDoneAndResetDefault(int userId, boolean loadFromConfig) {
            checkCallerIsSystem();
            setNASMigrationDone(userId);
            cancelNotificationInternal(getContext().getPackageName(),
                    getContext().getOpPackageName(), Binder.getCallingUid(),
                    Binder.getCallingPid(), TAG,
                    SystemMessageProto.SystemMessage.NOTE_NAS_UPGRADE, userId);
            if (loadFromConfig) {
                mAssistants.resetDefaultFromConfig();
            } else {
+22 −157
Original line number Diff line number Diff line
@@ -61,10 +61,6 @@ import static android.service.notification.NotificationListenerService.FLAG_FILT
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;

import static com.android.server.notification.NotificationManagerService.ACTION_DISABLE_NAS;
import static com.android.server.notification.NotificationManagerService.ACTION_ENABLE_NAS;
import static com.android.server.notification.NotificationManagerService.ACTION_LEARNMORE_NAS;

import static com.google.common.truth.Truth.assertThat;

import static junit.framework.Assert.assertEquals;
@@ -325,7 +321,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    @Mock
    MultiRateLimiter mToastRateLimiter;
    BroadcastReceiver mPackageIntentReceiver;
    BroadcastReceiver mNASIntentReceiver;
    NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
    private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
            1 << 30);
@@ -553,14 +548,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                    && filter.hasAction(Intent.ACTION_PACKAGES_UNSUSPENDED)
                    && filter.hasAction(Intent.ACTION_PACKAGES_SUSPENDED)) {
                mPackageIntentReceiver = broadcastReceivers.get(i);
            } else if (filter.hasAction(ACTION_ENABLE_NAS)
                    && filter.hasAction(ACTION_DISABLE_NAS)
                    && filter.hasAction(ACTION_LEARNMORE_NAS)) {
                mNASIntentReceiver = broadcastReceivers.get(i);
            }
        }
        assertNotNull("package intent receiver should exist", mPackageIntentReceiver);
        assertNotNull("nas intent receiver should exist", mNASIntentReceiver);

        // Pretend the shortcut exists
        List<ShortcutInfo> shortcutInfos = new ArrayList<>();
@@ -655,16 +645,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        mPackageIntentReceiver.onReceive(getContext(), intent);
    }

    private void simulateNASUpgradeBroadcast(String action, int uid) {
        final Bundle extras = new Bundle();
        extras.putInt(Intent.EXTRA_USER_ID, uid);

        final Intent intent = new Intent(action);
        intent.putExtras(extras);

        mNASIntentReceiver.onReceive(getContext(), intent);
    }

    private ArrayMap<Boolean, ArrayList<ComponentName>> generateResetComponentValues() {
        ArrayMap<Boolean, ArrayList<ComponentName>> changed = new ArrayMap<>();
        changed.put(true, new ArrayList<>());
@@ -6042,7 +6022,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    }

    @Test
    public void testNASSettingUpgrade_userSetNull_noOnBoarding() throws RemoteException {
    public void testNASSettingUpgrade_userSetNull() throws RemoteException {
        ComponentName newDefaultComponent = ComponentName.unflattenFromString("package/Component1");
        TestableNotificationManagerService service = spy(mService);
        int userId = 11;
@@ -6055,14 +6035,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                .thenReturn(new ArrayList<>());
        when(mAssistants.hasUserSet(userId)).thenReturn(true);

        service.migrateDefaultNASShowNotificationIfNecessary();
        service.migrateDefaultNAS();
        assertTrue(service.isNASMigrationDone(userId));
        verify(service, times(0)).createNASUpgradeNotification(eq(userId));
        verify(mAssistants, times(1)).clearDefaults();
    }

    @Test
    public void testNASSettingUpgrade_userSetSameDefault_noOnBoarding() throws RemoteException {
    public void testNASSettingUpgrade_userSet() throws RemoteException {
        ComponentName defaultComponent = ComponentName.unflattenFromString("package/Component1");
        TestableNotificationManagerService service = spy(mService);
        int userId = 11;
@@ -6075,55 +6054,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                .thenReturn(new ArrayList(Arrays.asList(defaultComponent)));
        when(mAssistants.hasUserSet(userId)).thenReturn(true);

        service.migrateDefaultNASShowNotificationIfNecessary();
        assertTrue(service.isNASMigrationDone(userId));
        verify(service, times(0)).createNASUpgradeNotification(eq(userId));
        verify(mAssistants, times(1)).resetDefaultFromConfig();
    }

    @Test
    public void testNASSettingUpgrade_userSetDifferentDefault_showOnboarding()
            throws RemoteException {
        ComponentName oldDefaultComponent = ComponentName.unflattenFromString("package/Component1");
        ComponentName newDefaultComponent = ComponentName.unflattenFromString("package/Component2");
        TestableNotificationManagerService service = spy(mService);
        int userId = 11;
        setUsers(new int[]{userId});
        setNASMigrationDone(false, userId);
        when(mAssistants.getDefaultComponents())
                .thenReturn(new ArraySet<>(Arrays.asList(oldDefaultComponent)));
        when(mAssistants.getDefaultFromConfig())
                .thenReturn(newDefaultComponent);
        when(mAssistants.getAllowedComponents(anyInt()))
                .thenReturn(Arrays.asList(oldDefaultComponent));
        when(mAssistants.hasUserSet(userId)).thenReturn(true);

        service.migrateDefaultNASShowNotificationIfNecessary();
        assertFalse(service.isNASMigrationDone(userId));
        //TODO(b/192450820)
        //verify(service, times(1)).createNASUpgradeNotification(eq(userId));
        verify(mAssistants, times(0)).resetDefaultFromConfig();

        //Test user clear data before enable/disable from onboarding notification
        ArrayMap<Boolean, ArrayList<ComponentName>> changedListeners =
                generateResetComponentValues();
        when(mListeners.resetComponents(anyString(), anyInt())).thenReturn(changedListeners);
        ArrayMap<Boolean, ArrayList<ComponentName>> changes = new ArrayMap<>();
        changes.put(true, new ArrayList(Arrays.asList(newDefaultComponent)));
        changes.put(false, new ArrayList());
        when(mAssistants.resetComponents(anyString(), anyInt())).thenReturn(changes);

        //Clear data
        service.getBinderService().clearData("package", userId, false);
        //Test migrate flow again
        service.migrateDefaultNASShowNotificationIfNecessary();

        //The notification should be still there
        assertFalse(service.isNASMigrationDone(userId));
        //TODO(b/192450820)
        //verify(service, times(2)).createNASUpgradeNotification(eq(userId));
        verify(mAssistants, times(0)).resetDefaultFromConfig();
        assertEquals(oldDefaultComponent, service.getApprovedAssistant(userId));
        service.migrateDefaultNAS();
        verify(mAssistants, times(1)).setUserSet(userId, false);
        //resetDefaultAssistantsIfNecessary should invoke from readPolicyXml() and migration
        verify(mAssistants, times(2)).resetDefaultAssistantsIfNecessary();
    }

    @Test
@@ -6143,24 +6077,22 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                .thenReturn(new ArraySet<>(Arrays.asList(oldDefaultComponent)));
        when(mAssistants.getDefaultFromConfig())
                .thenReturn(newDefaultComponent);
        //User1: need onboarding
        //User1: set different NAS
        when(mAssistants.getAllowedComponents(userId1))
                .thenReturn(Arrays.asList(oldDefaultComponent));
        //User2: no onboarding
        //User2: set to none
        when(mAssistants.getAllowedComponents(userId2))
                .thenReturn(Arrays.asList(newDefaultComponent));
                .thenReturn(new ArrayList<>());

        when(mAssistants.hasUserSet(userId1)).thenReturn(true);
        when(mAssistants.hasUserSet(userId2)).thenReturn(true);

        service.migrateDefaultNASShowNotificationIfNecessary();
        assertFalse(service.isNASMigrationDone(userId1));
        service.migrateDefaultNAS();
        // user1's setting get reset
        verify(mAssistants, times(1)).setUserSet(userId1, false);
        verify(mAssistants, times(0)).setUserSet(eq(userId2), anyBoolean());
        assertTrue(service.isNASMigrationDone(userId2));

        //TODO(b/192450820)
        //verify(service, times(1)).createNASUpgradeNotification(any(Integer.class));
        // only user2's default get updated
        verify(mAssistants, times(1)).resetDefaultFromConfig();
    }

    @Test
@@ -6180,7 +6112,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                .thenReturn(new ArraySet<>(Arrays.asList(oldDefaultComponent)));
        when(mAssistants.getDefaultFromConfig())
                .thenReturn(newDefaultComponent);
        //Both profiles: need onboarding
        //Both profiles: set different NAS
        when(mAssistants.getAllowedComponents(userId1))
                .thenReturn(Arrays.asList(oldDefaultComponent));
        when(mAssistants.getAllowedComponents(userId2))
@@ -6189,13 +6121,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        when(mAssistants.hasUserSet(userId1)).thenReturn(true);
        when(mAssistants.hasUserSet(userId2)).thenReturn(true);

        service.migrateDefaultNASShowNotificationIfNecessary();
        service.migrateDefaultNAS();
        assertFalse(service.isNASMigrationDone(userId1));
        assertFalse(service.isNASMigrationDone(userId2));

        // TODO(b/192450820): only user1 get notification
        //verify(service, times(1)).createNASUpgradeNotification(eq(userId1));
        //verify(service, times(0)).createNASUpgradeNotification(eq(userId2));
    }


@@ -6223,79 +6151,16 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        //Clear data
        service.getBinderService().clearData("package", userId, false);
        //Test migrate flow again
        service.migrateDefaultNASShowNotificationIfNecessary();

        //TODO(b/192450820): The notification should not appear again
        //verify(service, times(0)).createNASUpgradeNotification(eq(userId));
        verify(mAssistants, times(0)).resetDefaultFromConfig();
    }

    @Test
    public void testNASUpgradeNotificationDisableBroadcast_multiProfile() {
        int userId1 = 11;
        int userId2 = 12;
        setUsers(new int[]{userId1, userId2});
        when(mUm.isManagedProfile(userId2)).thenReturn(true);
        when(mUm.getProfileIds(userId1, false)).thenReturn(new int[]{userId1, userId2});

        TestableNotificationManagerService service = spy(mService);
        setNASMigrationDone(false, userId1);
        setNASMigrationDone(false, userId2);
        service.migrateDefaultNAS();

        simulateNASUpgradeBroadcast(ACTION_DISABLE_NAS, userId1);

        assertTrue(service.isNASMigrationDone(userId1));
        assertTrue(service.isNASMigrationDone(userId2));
        // User disabled the NAS from notification, the default stored in xml should be null
        // rather than the new default
        verify(mAssistants, times(1)).clearDefaults();
        verify(mAssistants, times(0)).resetDefaultFromConfig();
        //Migration should not happen again
        verify(mAssistants, times(0)).setUserSet(userId, false);
        verify(mAssistants, times(0)).clearDefaults();
        //resetDefaultAssistantsIfNecessary should only invoke once from readPolicyXml()
        verify(mAssistants, times(1)).resetDefaultAssistantsIfNecessary();

        //TODO(b/192450820):No more notification after disabled
        //service.migrateDefaultNASShowNotificationIfNecessary();
        //verify(service, times(0)).createNASUpgradeNotification(anyInt());
    }

    @Test
    public void testNASUpgradeNotificationEnableBroadcast_multiUser() {
        int userId1 = 11;
        int userId2 = 12;
        setUsers(new int[]{userId1, userId2});
        when(mUm.getProfileIds(userId1, false)).thenReturn(new int[]{userId1});

        TestableNotificationManagerService service = spy(mService);
        setNASMigrationDone(false, userId1);
        setNASMigrationDone(false, userId2);

        simulateNASUpgradeBroadcast(ACTION_ENABLE_NAS, userId1);

        assertTrue(service.isNASMigrationDone(userId1));
        assertFalse(service.isNASMigrationDone(userId2));
        verify(mAssistants, times(1)).resetDefaultFromConfig();

        //TODO(b/192450820)
        //service.migrateDefaultNASShowNotificationIfNecessary();
        //verify(service, times(0)).createNASUpgradeNotification(eq(userId1));
    }

    @Test
    public void testNASUpgradeNotificationLearnMoreBroadcast() {
        int userId = 11;
        setUsers(new int[]{userId});
        TestableNotificationManagerService service = spy(mService);
        setNASMigrationDone(false, userId);
        doNothing().when(mContext).startActivity(any());

        simulateNASUpgradeBroadcast(ACTION_LEARNMORE_NAS, userId);

        verify(mContext, times(1)).startActivity(any(Intent.class));
        assertFalse(service.isNASMigrationDone(userId));
        //TODO(b/192450820)
        //verify(service, times(0)).createNASUpgradeNotification(eq(userId));
        verify(mAssistants, times(0)).resetDefaultFromConfig();
    }


    private void setNASMigrationDone(boolean done, int userId) {
        Settings.Secure.putIntForUser(mContext.getContentResolver(),
                Settings.Secure.NAS_SETTINGS_UPDATED, done ? 1 : 0, userId);