OSDN Git Service

Optionally append managed service approvals
authorJulia Reynolds <juliacr@google.com>
Mon, 14 Aug 2017 17:22:23 +0000 (13:22 -0400)
committerJulia Reynolds <juliacr@google.com>
Tue, 15 Aug 2017 18:57:09 +0000 (14:57 -0400)
If the backup comes from a pre O device, don't wipe
preexisting managed service grants (which were introduced
in O).

Test: runtest systemui-notification
Change-Id: Ie569972dc0d076718a3a9c59e1ebd942c5bfa987
Fixes: 64232609

services/core/java/com/android/server/notification/ManagedServices.java
services/core/java/com/android/server/notification/NotificationManagerService.java
services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java

index 8087813..beaddb4 100644 (file)
@@ -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();
@@ -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 =
index 6aa83b3..28acd9a 100644 (file)
@@ -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);
                 }
index bd65f57..8242149 100644 (file)
@@ -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;
@@ -146,15 +147,82 @@ 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));
         }
     }
 
@@ -619,25 +687,22 @@ 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)) {
                     assertTrue("service type " + service.mApprovalLevel + ":"
-                            + verifyValue + " is not allowed for user " + userId,
+                                    + verifyValue + " is not allowed for user " + userId,
                             service.isPackageOrComponentAllowed(verifyValue, userId));
                 }
             }
         }
     }
 
-    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,