System print service enabled after every system reboot

The system was overriding the user on every boot by turing of all system
print services, i.e. service that are on the system image. Now the system
print service are enabled by default only once per user, the user can later
disable them and the system does not override that. We now have a system
setting with the services we enabled once by default so we never do
default enabling again (unless device is wiped).

bug:10594775

Change-Id: Id3129ccfba95bf57375ea9fec0b5ca0e51bda199
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 31817cc..83e1544 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3708,13 +3708,22 @@
         public static final String LONG_PRESS_TIMEOUT = "long_press_timeout";
 
         /**
-         * List of the enabled print providers.
+         * List of the enabled print services.
          * @hide
          */
         public static final String ENABLED_PRINT_SERVICES =
             "enabled_print_services";
 
         /**
+         * List of the system print services we enabled on first boot. On
+         * first boot we enable all system, i.e. bundled print services,
+         * once, so they work out-of-the-box.
+         * @hide
+         */
+        public static final String ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES =
+            "enabled_on_first_boot_system_print_services";
+
+        /**
          * Setting to always use the default text-to-speech settings regardless
          * of the application settings.
          * 1 = override application settings,
diff --git a/services/java/com/android/server/print/UserState.java b/services/java/com/android/server/print/UserState.java
index 4a1b96b..7d94a42 100644
--- a/services/java/com/android/server/print/UserState.java
+++ b/services/java/com/android/server/print/UserState.java
@@ -19,8 +19,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
@@ -68,11 +66,6 @@
 
     private static final char COMPONENT_NAME_SEPARATOR = ':';
 
-    private static final String SHARED_PREFERENCES_FILE = "shared_prefs";
-
-    private static final String KEY_SYSTEM_PRINT_SERVICES_ENABLED =
-            "KEY_SYSTEM_PRINT_SERVICES_ENABLED";
-
     private final SimpleStringSplitter mStringColonSplitter =
             new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
 
@@ -105,7 +98,9 @@
         mUserId = userId;
         mLock = lock;
         mSpooler = new RemotePrintSpooler(context, userId, this);
-        enableSystemPrintServicesOnce();
+        synchronized (mLock) {
+            enableSystemPrintServicesOnFirstBootLocked();
+        }
     }
 
     @Override
@@ -379,11 +374,23 @@
         return false;
     }
 
+
     private boolean readEnabledPrintServicesLocked() {
         Set<ComponentName> tempEnabledServiceNameSet = new HashSet<ComponentName>();
+        readPrintServicesFromSettingLocked(Settings.Secure.ENABLED_PRINT_SERVICES,
+                tempEnabledServiceNameSet);
+        if (!tempEnabledServiceNameSet.equals(mEnabledServices)) {
+            mEnabledServices.clear();
+            mEnabledServices.addAll(tempEnabledServiceNameSet);
+            return true;
+        }
+        return false;
+    }
 
+    private void readPrintServicesFromSettingLocked(String setting,
+            Set<ComponentName> outServiceNames) {
         String settingValue = Settings.Secure.getStringForUser(mContext.getContentResolver(),
-                Settings.Secure.ENABLED_PRINT_SERVICES, mUserId);
+                setting, mUserId);
         if (!TextUtils.isEmpty(settingValue)) {
             TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
             splitter.setString(settingValue);
@@ -394,48 +401,72 @@
                 }
                 ComponentName componentName = ComponentName.unflattenFromString(string);
                 if (componentName != null) {
-                    tempEnabledServiceNameSet.add(componentName);
+                    outServiceNames.add(componentName);
                 }
             }
         }
-
-        if (!tempEnabledServiceNameSet.equals(mEnabledServices)) {
-            mEnabledServices.clear();
-            mEnabledServices.addAll(tempEnabledServiceNameSet);
-            return true;
-        }
-
-        return false;
     }
 
-    private void enableSystemPrintServicesOnce() {
-        SharedPreferences preferences = mContext.getSharedPreferences(
-                SHARED_PREFERENCES_FILE, Context.MODE_PRIVATE);
-        if (preferences.getInt(KEY_SYSTEM_PRINT_SERVICES_ENABLED, 0) == 0) {
-            Editor editor = preferences.edit();
-            editor.putInt(KEY_SYSTEM_PRINT_SERVICES_ENABLED, 1);
-            editor.commit();
+    private void enableSystemPrintServicesOnFirstBootLocked() {
+        // Load enabled and installed services.
+        readEnabledPrintServicesLocked();
+        readInstalledPrintServicesLocked();
 
-            readInstalledPrintServicesLocked();
+        // Load the system services once enabled on first boot.
+        Set<ComponentName> enabledOnFirstBoot = new HashSet<ComponentName>();
+        readPrintServicesFromSettingLocked(
+                Settings.Secure.ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES,
+                enabledOnFirstBoot);
 
-            StringBuilder builder = new StringBuilder();
+        StringBuilder builder = new StringBuilder();
 
-            final int serviceCount = mInstalledServices.size();
-            for (int i = 0; i < serviceCount; i++) {
-                ServiceInfo serviceInfo = mInstalledServices.get(i).getResolveInfo().serviceInfo;
-                if ((serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-                    ComponentName serviceName = new ComponentName(
-                            serviceInfo.packageName, serviceInfo.name);
+        final int serviceCount = mInstalledServices.size();
+        for (int i = 0; i < serviceCount; i++) {
+            ServiceInfo serviceInfo = mInstalledServices.get(i).getResolveInfo().serviceInfo;
+            // Enable system print services if we never did that and are not enabled.
+            if ((serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                ComponentName serviceName = new ComponentName(
+                        serviceInfo.packageName, serviceInfo.name);
+                if (!mEnabledServices.contains(serviceName)
+                        && !enabledOnFirstBoot.contains(serviceName)) {
                     if (builder.length() > 0) {
                         builder.append(":");
                     }
                     builder.append(serviceName.flattenToString());
                 }
             }
-
-            Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                    Settings.Secure.ENABLED_PRINT_SERVICES, builder.toString(), mUserId);
         }
+
+        // Nothing to be enabled - done.
+        if (builder.length() <= 0) {
+            return;
+        }
+
+        String servicesToEnable = builder.toString();
+
+        // Update the enabled services setting.
+        String enabledServices = Settings.Secure.getStringForUser(
+                mContext.getContentResolver(), Settings.Secure.ENABLED_PRINT_SERVICES, mUserId);
+        if (TextUtils.isEmpty(enabledServices)) {
+            enabledServices = servicesToEnable;
+        } else {
+            enabledServices = enabledServices + ":" + servicesToEnable;
+        }
+        Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                Settings.Secure.ENABLED_PRINT_SERVICES, enabledServices, mUserId);
+
+        // Update the enabled on first boot services setting.
+        String enabledOnFirstBootServices = Settings.Secure.getStringForUser(
+                mContext.getContentResolver(),
+                Settings.Secure.ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES, mUserId);
+        if (TextUtils.isEmpty(enabledOnFirstBootServices)) {
+            enabledOnFirstBootServices = servicesToEnable;
+        } else {
+            enabledOnFirstBootServices = enabledOnFirstBootServices + ":" + enabledServices;
+        }
+        Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                Settings.Secure.ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES,
+                enabledOnFirstBootServices, mUserId);
     }
 
     private void onConfigurationChangedLocked() {