Fix issue #4976176: Font size setting does not persist

Change-Id: Id58caf990bdd3aac5ea97aaba45652ffad1f678a
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index fdf4a3a..2a731a3 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1514,6 +1514,14 @@
             return true;
         }
 
+        case UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            Configuration config = Configuration.CREATOR.createFromParcel(data);
+            updatePersistentConfiguration(config);
+            reply.writeNoException();
+            return true;
+        }
+
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -3410,5 +3418,17 @@
         return res;
     }
 
+    public void updatePersistentConfiguration(Configuration values) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        values.writeToParcel(data, 0);
+        mRemote.transact(UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 9e20764..93c821c 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -363,6 +363,8 @@
 
     public boolean isIntentSenderTargetedToPackage(IIntentSender sender) throws RemoteException;
 
+    public void updatePersistentConfiguration(Configuration values) throws RemoteException;
+    
     /*
      * Private non-Binder interfaces
      */
@@ -590,4 +592,5 @@
     int REGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+132;
     int UNREGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+133;
     int IS_INTENT_SENDER_TARGETED_TO_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+134;
+    int UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+135;
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 34699e2..ad32047 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1045,6 +1045,14 @@
         }
 
         /**
+         * @hide Erase the fields in the Configuration that should be applied
+         * by the settings.
+         */
+        public static void clearConfiguration(Configuration inoutConfig) {
+            inoutConfig.fontScale = 0;
+        }
+        
+        /**
          * Convenience function to write a batch of configuration-related
          * settings from a {@link Configuration} object.
          *
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 94af46d..0924b86 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2439,7 +2439,7 @@
                     r.mayFreezeScreenLocked(r.app) ? r : null);
             if (config != null) {
                 r.frozenBeforeDestroy = true;
-                if (!updateConfigurationLocked(config, r)) {
+                if (!updateConfigurationLocked(config, r, false)) {
                     mMainStack.resumeTopActivityLocked(null);
                 }
             }
@@ -12398,6 +12398,22 @@
         return ci;
     }
 
+    public void updatePersistentConfiguration(Configuration values) {
+        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
+                "updateConfiguration()");
+        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
+                "updateConfiguration()");
+        if (values == null) {
+            throw new NullPointerException("Configuration must not be null");
+        }
+
+        synchronized(this) {
+            final long origId = Binder.clearCallingIdentity();
+            updateConfigurationLocked(values, null, true);
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
     public void updateConfiguration(Configuration values) {
         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
                 "updateConfiguration()");
@@ -12409,7 +12425,10 @@
             }
             
             final long origId = Binder.clearCallingIdentity();
-            updateConfigurationLocked(values, null);
+            if (values != null) {
+                Settings.System.clearConfiguration(values);
+            }
+            updateConfigurationLocked(values, null, false);
             Binder.restoreCallingIdentity(origId);
         }
     }
@@ -12420,9 +12439,10 @@
      * configuration.  Returns true if the activity has been left running, or
      * false if <var>starting</var> is being destroyed to match the new
      * configuration.
+     * @param persistent TODO
      */
     public boolean updateConfigurationLocked(Configuration values,
-            ActivityRecord starting) {
+            ActivityRecord starting, boolean persistent) {
         int changes = 0;
         
         boolean kept = true;
@@ -12465,7 +12485,7 @@
                 // code is executed.
                 mSystemThread.applyConfigurationToResources(newConfig);
 
-                if (Settings.System.hasInterestingConfigurationChanges(changes)) {
+                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
                     msg.obj = new Configuration(mConfiguration);
                     mHandler.sendMessage(msg);
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 93d8164..0d89081 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -518,7 +518,7 @@
             Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
                     mService.mConfiguration,
                     r.mayFreezeScreenLocked(app) ? r : null);
-            mService.updateConfigurationLocked(config, r);
+            mService.updateConfigurationLocked(config, r, false);
         }
 
         r.app = app;
@@ -1424,7 +1424,7 @@
                     if (config != null) {
                         next.frozenBeforeDestroy = true;
                     }
-                    updated = mService.updateConfigurationLocked(config, next);
+                    updated = mService.updateConfigurationLocked(config, next, false);
                 }
             }
             if (!updated) {
@@ -2817,7 +2817,7 @@
                 mConfigWillChange = false;
                 if (DEBUG_CONFIGURATION) Slog.v(TAG,
                         "Updating to new configuration after starting activity.");
-                mService.updateConfigurationLocked(config, null);
+                mService.updateConfigurationLocked(config, null, false);
             }
             
             Binder.restoreCallingIdentity(origId);