Loading services/core/java/com/android/server/notification/ManagedServices.java +21 −1 Original line number Diff line number Diff line Loading @@ -212,12 +212,25 @@ abstract public class ManagedServices { } } protected void onSettingRestored(String element, String value, int userId) { protected void onSettingRestored(String element, String value, int backupSdkInt, int userId) { if (!mUseXml) { Slog.d(TAG, "Restored managed service setting: " + element); if (mConfig.secureSettingName.equals(element) || (mConfig.secondarySettingName != null && mConfig.secondarySettingName.equals(element))) { if (backupSdkInt < Build.VERSION_CODES.O) { // automatic system grants were added in O, so append the approved apps // rather than wiping out the setting String currentSetting = getApproved(userId, mConfig.secureSettingName.equals(element)); if (!TextUtils.isEmpty(currentSetting)) { if (!TextUtils.isEmpty(value)) { value = value + ENABLED_SERVICES_SEPARATOR + currentSetting; } else { value = currentSetting; } } } Settings.Secure.putStringForUser( mContext.getContentResolver(), element, value, userId); loadAllowedComponentsFromSettings(); Loading Loading @@ -370,6 +383,13 @@ abstract public class ManagedServices { } } protected String getApproved(int userId, boolean primary) { final ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.getOrDefault(userId, new ArrayMap<>()); ArraySet<String> approved = allowedByType.getOrDefault(primary, new ArraySet<>()); return String.join(ENABLED_SERVICES_SEPARATOR, approved); } protected List<ComponentName> getAllowedComponents(int userId) { final List<ComponentName> allowedComponents = new ArrayList<>(); final ArrayMap<Boolean, ArraySet<String>> allowedByType = Loading services/core/java/com/android/server/notification/NotificationManagerService.java +4 −2 Original line number Diff line number Diff line Loading @@ -817,8 +817,10 @@ public class NotificationManagerService extends SystemService { String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE); int restoredFromSdkInt = intent.getIntExtra( Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, 0); mListeners.onSettingRestored(element, newValue, getSendingUserId()); mConditionProviders.onSettingRestored(element, newValue, getSendingUserId()); mListeners.onSettingRestored( element, newValue, restoredFromSdkInt, getSendingUserId()); mConditionProviders.onSettingRestored( element, newValue, restoredFromSdkInt, getSendingUserId()); } catch (Exception e) { Slog.wtf(TAG, "Cannot restore managed services from settings", e); } Loading services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java +76 −11 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.os.Build; import android.os.IBinder; import android.os.IInterface; import android.os.UserHandle; Loading Loading @@ -146,18 +147,85 @@ public class ManagedServicesTest extends NotificationTestCase { service.onSettingRestored( service.getConfig().secureSettingName, mExpectedPrimary.get(approvalLevel).get(userId), userId); Build.VERSION_CODES.O, userId); } verifyExpectedApprovedEntries(service, true); for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) { service.onSettingRestored(service.getConfig().secondarySettingName, mExpectedSecondary.get(approvalLevel).get(userId), userId); mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O, userId); } verifyExpectedApprovedEntries(service); } } @Test public void testBackupAndRestore_migration_preO() throws Exception { ArrayMap backupPrimaryPackages = new ArrayMap<>(); backupPrimaryPackages.put(0, "backup.0:backup:0a"); backupPrimaryPackages.put(10, "10.backup"); backupPrimaryPackages.put(11, "eleven"); backupPrimaryPackages.put(12, ""); ArrayMap backupPrimaryComponentNames = new ArrayMap<>(); backupPrimaryComponentNames.put(0, "backup.first/whatever:a/b"); backupPrimaryComponentNames.put(10, "again/M1"); backupPrimaryComponentNames.put(11, "orange/youglad:itisnot/banana"); backupPrimaryComponentNames.put(12, ""); ArrayMap<Integer, ArrayMap<Integer, String>> backupPrimary = new ArrayMap<>(); backupPrimary.put(APPROVAL_BY_PACKAGE, backupPrimaryPackages); backupPrimary.put(APPROVAL_BY_COMPONENT, backupPrimaryComponentNames); ArrayMap backupSecondaryComponentNames = new ArrayMap<>(); backupSecondaryComponentNames.put(0, "secondary.1/component.Name"); backupSecondaryComponentNames.put(10, "this.is.another.package.backup/with.Component:component.backup/2"); ArrayMap backupSecondaryPackages = new ArrayMap<>(); backupSecondaryPackages.put(0, ""); backupSecondaryPackages.put(10, "this.is.another.package.backup:package.backup"); ArrayMap<Integer, ArrayMap<Integer, String>> backupSecondary = new ArrayMap<>(); backupSecondary.put(APPROVAL_BY_PACKAGE, backupSecondaryPackages); backupSecondary.put(APPROVAL_BY_COMPONENT, backupSecondaryComponentNames); for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm, approvalLevel); // not an expected flow but a way to get data into the settings for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) { service.onSettingRestored( service.getConfig().secureSettingName, mExpectedPrimary.get(approvalLevel).get(userId), Build.VERSION_CODES.O, userId); } for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) { service.onSettingRestored(service.getConfig().secondarySettingName, mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O, userId); } // actual test for (int userId : backupPrimary.get(approvalLevel).keySet()) { service.onSettingRestored( service.getConfig().secureSettingName, backupPrimary.get(approvalLevel).get(userId), Build.VERSION_CODES.N_MR1, userId); } verifyExpectedApprovedEntries(service, true); for (int userId : backupSecondary.get(approvalLevel).keySet()) { service.onSettingRestored(service.getConfig().secondarySettingName, backupSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.N_MR1, userId); } verifyExpectedApprovedEntries(service); verifyExpectedApprovedEntries(service, backupPrimary.get(approvalLevel)); verifyExpectedApprovedEntries(service, backupSecondary.get(approvalLevel)); } } @Test public void testReadXml_migrationFromSettings() throws Exception { for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { Loading Loading @@ -619,6 +687,11 @@ public class ManagedServicesTest extends NotificationTestCase { ArrayMap<Integer, String> verifyMap = primary ? mExpectedPrimary.get(service.mApprovalLevel) : mExpectedSecondary.get(service.mApprovalLevel); verifyExpectedApprovedEntries(service, verifyMap); } private void verifyExpectedApprovedEntries(ManagedServices service, ArrayMap<Integer, String> verifyMap) { for (int userId : verifyMap.keySet()) { for (String verifyValue : verifyMap.get(userId).split(":")) { if (!TextUtils.isEmpty(verifyValue)) { Loading @@ -630,14 +703,6 @@ public class ManagedServicesTest extends NotificationTestCase { } } private boolean isPackage(String packageOrComponent) { final ComponentName component = ComponentName.unflattenFromString(packageOrComponent); if (component != null) { return false; } return true; } private void writeExpectedValuesToSettings(int approvalLevel) { for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) { Settings.Secure.putStringForUser(getContext().getContentResolver(), SETTING, Loading Loading
services/core/java/com/android/server/notification/ManagedServices.java +21 −1 Original line number Diff line number Diff line Loading @@ -212,12 +212,25 @@ abstract public class ManagedServices { } } protected void onSettingRestored(String element, String value, int userId) { protected void onSettingRestored(String element, String value, int backupSdkInt, int userId) { if (!mUseXml) { Slog.d(TAG, "Restored managed service setting: " + element); if (mConfig.secureSettingName.equals(element) || (mConfig.secondarySettingName != null && mConfig.secondarySettingName.equals(element))) { if (backupSdkInt < Build.VERSION_CODES.O) { // automatic system grants were added in O, so append the approved apps // rather than wiping out the setting String currentSetting = getApproved(userId, mConfig.secureSettingName.equals(element)); if (!TextUtils.isEmpty(currentSetting)) { if (!TextUtils.isEmpty(value)) { value = value + ENABLED_SERVICES_SEPARATOR + currentSetting; } else { value = currentSetting; } } } Settings.Secure.putStringForUser( mContext.getContentResolver(), element, value, userId); loadAllowedComponentsFromSettings(); Loading Loading @@ -370,6 +383,13 @@ abstract public class ManagedServices { } } protected String getApproved(int userId, boolean primary) { final ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.getOrDefault(userId, new ArrayMap<>()); ArraySet<String> approved = allowedByType.getOrDefault(primary, new ArraySet<>()); return String.join(ENABLED_SERVICES_SEPARATOR, approved); } protected List<ComponentName> getAllowedComponents(int userId) { final List<ComponentName> allowedComponents = new ArrayList<>(); final ArrayMap<Boolean, ArraySet<String>> allowedByType = Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +4 −2 Original line number Diff line number Diff line Loading @@ -817,8 +817,10 @@ public class NotificationManagerService extends SystemService { String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE); int restoredFromSdkInt = intent.getIntExtra( Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, 0); mListeners.onSettingRestored(element, newValue, getSendingUserId()); mConditionProviders.onSettingRestored(element, newValue, getSendingUserId()); mListeners.onSettingRestored( element, newValue, restoredFromSdkInt, getSendingUserId()); mConditionProviders.onSettingRestored( element, newValue, restoredFromSdkInt, getSendingUserId()); } catch (Exception e) { Slog.wtf(TAG, "Cannot restore managed services from settings", e); } Loading
services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java +76 −11 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.os.Build; import android.os.IBinder; import android.os.IInterface; import android.os.UserHandle; Loading Loading @@ -146,18 +147,85 @@ public class ManagedServicesTest extends NotificationTestCase { service.onSettingRestored( service.getConfig().secureSettingName, mExpectedPrimary.get(approvalLevel).get(userId), userId); Build.VERSION_CODES.O, userId); } verifyExpectedApprovedEntries(service, true); for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) { service.onSettingRestored(service.getConfig().secondarySettingName, mExpectedSecondary.get(approvalLevel).get(userId), userId); mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O, userId); } verifyExpectedApprovedEntries(service); } } @Test public void testBackupAndRestore_migration_preO() throws Exception { ArrayMap backupPrimaryPackages = new ArrayMap<>(); backupPrimaryPackages.put(0, "backup.0:backup:0a"); backupPrimaryPackages.put(10, "10.backup"); backupPrimaryPackages.put(11, "eleven"); backupPrimaryPackages.put(12, ""); ArrayMap backupPrimaryComponentNames = new ArrayMap<>(); backupPrimaryComponentNames.put(0, "backup.first/whatever:a/b"); backupPrimaryComponentNames.put(10, "again/M1"); backupPrimaryComponentNames.put(11, "orange/youglad:itisnot/banana"); backupPrimaryComponentNames.put(12, ""); ArrayMap<Integer, ArrayMap<Integer, String>> backupPrimary = new ArrayMap<>(); backupPrimary.put(APPROVAL_BY_PACKAGE, backupPrimaryPackages); backupPrimary.put(APPROVAL_BY_COMPONENT, backupPrimaryComponentNames); ArrayMap backupSecondaryComponentNames = new ArrayMap<>(); backupSecondaryComponentNames.put(0, "secondary.1/component.Name"); backupSecondaryComponentNames.put(10, "this.is.another.package.backup/with.Component:component.backup/2"); ArrayMap backupSecondaryPackages = new ArrayMap<>(); backupSecondaryPackages.put(0, ""); backupSecondaryPackages.put(10, "this.is.another.package.backup:package.backup"); ArrayMap<Integer, ArrayMap<Integer, String>> backupSecondary = new ArrayMap<>(); backupSecondary.put(APPROVAL_BY_PACKAGE, backupSecondaryPackages); backupSecondary.put(APPROVAL_BY_COMPONENT, backupSecondaryComponentNames); for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm, approvalLevel); // not an expected flow but a way to get data into the settings for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) { service.onSettingRestored( service.getConfig().secureSettingName, mExpectedPrimary.get(approvalLevel).get(userId), Build.VERSION_CODES.O, userId); } for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) { service.onSettingRestored(service.getConfig().secondarySettingName, mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O, userId); } // actual test for (int userId : backupPrimary.get(approvalLevel).keySet()) { service.onSettingRestored( service.getConfig().secureSettingName, backupPrimary.get(approvalLevel).get(userId), Build.VERSION_CODES.N_MR1, userId); } verifyExpectedApprovedEntries(service, true); for (int userId : backupSecondary.get(approvalLevel).keySet()) { service.onSettingRestored(service.getConfig().secondarySettingName, backupSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.N_MR1, userId); } verifyExpectedApprovedEntries(service); verifyExpectedApprovedEntries(service, backupPrimary.get(approvalLevel)); verifyExpectedApprovedEntries(service, backupSecondary.get(approvalLevel)); } } @Test public void testReadXml_migrationFromSettings() throws Exception { for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { Loading Loading @@ -619,6 +687,11 @@ public class ManagedServicesTest extends NotificationTestCase { ArrayMap<Integer, String> verifyMap = primary ? mExpectedPrimary.get(service.mApprovalLevel) : mExpectedSecondary.get(service.mApprovalLevel); verifyExpectedApprovedEntries(service, verifyMap); } private void verifyExpectedApprovedEntries(ManagedServices service, ArrayMap<Integer, String> verifyMap) { for (int userId : verifyMap.keySet()) { for (String verifyValue : verifyMap.get(userId).split(":")) { if (!TextUtils.isEmpty(verifyValue)) { Loading @@ -630,14 +703,6 @@ public class ManagedServicesTest extends NotificationTestCase { } } private boolean isPackage(String packageOrComponent) { final ComponentName component = ComponentName.unflattenFromString(packageOrComponent); if (component != null) { return false; } return true; } private void writeExpectedValuesToSettings(int approvalLevel) { for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) { Settings.Secure.putStringForUser(getContext().getContentResolver(), SETTING, Loading