Merge "Inform libcore of time format pref. changes."
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 3258585..ce2d806 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -71,6 +71,7 @@
 import android.os.UserHandle;
 import android.transition.Scene;
 import android.transition.TransitionManager;
+import android.provider.Settings;
 import android.util.AndroidRuntimeException;
 import android.util.ArrayMap;
 import android.util.DisplayMetrics;
@@ -110,6 +111,7 @@
 import java.lang.ref.WeakReference;
 import java.net.InetAddress;
 import java.security.Security;
+import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -1103,6 +1105,11 @@
         public void scheduleInstallProvider(ProviderInfo provider) {
             sendMessage(H.INSTALL_PROVIDER, provider);
         }
+
+        @Override
+        public final void updateTimePrefs(boolean is24Hour) {
+            DateFormat.set24HourTimePref(is24Hour);
+        }
     }
 
     private class H extends Handler {
@@ -1152,6 +1159,7 @@
         public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
         public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
         public static final int INSTALL_PROVIDER        = 145;
+
         String codeToString(int code) {
             if (DEBUG_MESSAGES) {
                 switch (code) {
@@ -4215,6 +4223,11 @@
                 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
             }
         }
+
+
+        final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
+        DateFormat.set24HourTimePref(is24Hr);
+
         /**
          * For system applications on userdebug/eng builds, log stack
          * traces of disk and network access to dropbox for analysis.
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 20198f9..f1c632e 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -630,6 +630,15 @@
             reply.writeNoException();
             return true;
         }
+
+        case UPDATE_TIME_PREFS_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            byte is24Hour = data.readByte();
+            updateTimePrefs(is24Hour == (byte) 1);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -1273,4 +1282,13 @@
         mRemote.transact(SCHEDULE_INSTALL_PROVIDER_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
         data.recycle();
     }
+
+    @Override
+    public void updateTimePrefs(boolean is24Hour) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeByte(is24Hour ? (byte) 1 : (byte) 0);
+        mRemote.transact(UPDATE_TIME_PREFS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
 }
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 1ea9d87..ac8ac8f 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -139,6 +139,7 @@
             throws RemoteException;
     void setProcessState(int state) throws RemoteException;
     void scheduleInstallProvider(ProviderInfo provider) throws RemoteException;
+    void updateTimePrefs(boolean is24Hour) throws RemoteException;
 
     String descriptor = "android.app.IApplicationThread";
 
@@ -192,4 +193,5 @@
     int SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+48;
     int SET_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+49;
     int SCHEDULE_INSTALL_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+50;
+    int UPDATE_TIME_PREFS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+51;
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 3fdb6e7..f0b7ca8 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3334,6 +3334,15 @@
     public static final String EXTRA_SHUTDOWN_USERSPACE_ONLY
             = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
 
+    /**
+     * Optional boolean extra for {@link #ACTION_TIME_CHANGED} that indicates the
+     * user has set their time format preferences to the 24 hour format.
+     *
+     * @hide for internal use only.
+     */
+    public static final String EXTRA_TIME_PREF_24_HOUR_FORMAT =
+            "android.intent.extra.TIME_PREF_24_HOUR_FORMAT";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Intent flags (see mFlags variable).
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b23ab25..d910861 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1074,6 +1074,7 @@
     static final int PERSIST_URI_GRANTS_MSG = 38;
     static final int REQUEST_ALL_PSS_MSG = 39;
     static final int START_RELATED_USERS_MSG = 40;
+    static final int UPDATE_TIME = 41;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1693,6 +1694,21 @@
                 }
                 break;
             }
+            case UPDATE_TIME: {
+                synchronized (ActivityManagerService.this) {
+                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
+                        ProcessRecord r = mLruProcesses.get(i);
+                        if (r.thread != null) {
+                            try {
+                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
+                            } catch (RemoteException ex) {
+                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
+                            }
+                        }
+                    }
+                }
+                break;
+            }
             }
         }
     };
@@ -13446,11 +13462,20 @@
          * of all currently running processes. This message will get queued up before the broadcast
          * happens.
          */
-        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
+        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
         }
 
-        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
+        /*
+         * If the user set the time, let all running processes know.
+         */
+        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
+            final int is24Hour = intent.getBooleanExtra(
+                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
+            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
+        }
+
+        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
         }
 
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 10ea67c..4c887dd 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -37,11 +37,16 @@
     private static final String LOG_TAG = CoreSettingsObserver.class.getSimpleName();
 
     // mapping form property name to its type
-    private static final Map<String, Class<?>> sCoreSettingToTypeMap = new HashMap<
+    private static final Map<String, Class<?>> sSecureSettingToTypeMap = new HashMap<
+            String, Class<?>>();
+    private static final Map<String, Class<?>> sSystemSettingToTypeMap = new HashMap<
             String, Class<?>>();
     static {
-        sCoreSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
-        // add other core settings here...
+        sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
+        // add other secure settings here...
+
+        sSystemSettingToTypeMap.put(Settings.System.TIME_12_24, String.class);
+        // add other system settings here...
     }
 
     private final Bundle mCoreSettings = new Bundle();
@@ -67,39 +72,62 @@
     }
 
     private void sendCoreSettings() {
-        populateCoreSettings(mCoreSettings);
+        populateSettings(mCoreSettings, sSecureSettingToTypeMap);
+        populateSettings(mCoreSettings, sSystemSettingToTypeMap);
         mActivityManagerService.onCoreSettingsChange(mCoreSettings);
     }
 
     private void beginObserveCoreSettings() {
-        for (String setting : sCoreSettingToTypeMap.keySet()) {
+        for (String setting : sSecureSettingToTypeMap.keySet()) {
             Uri uri = Settings.Secure.getUriFor(setting);
             mActivityManagerService.mContext.getContentResolver().registerContentObserver(
                     uri, false, this);
         }
+
+        for (String setting : sSystemSettingToTypeMap.keySet()) {
+            Uri uri = Settings.System.getUriFor(setting);
+            mActivityManagerService.mContext.getContentResolver().registerContentObserver(
+                    uri, false, this);
+        }
     }
 
-    private void populateCoreSettings(Bundle snapshot) {
+    private void populateSettings(Bundle snapshot, Map<String, Class<?>> map) {
         Context context = mActivityManagerService.mContext;
-        for (Map.Entry<String, Class<?>> entry : sCoreSettingToTypeMap.entrySet()) {
+        for (Map.Entry<String, Class<?>> entry : map.entrySet()) {
             String setting = entry.getKey();
             Class<?> type = entry.getValue();
             try {
                 if (type == String.class) {
-                    String value = Settings.Secure.getString(context.getContentResolver(),
-                            setting);
+                    final String value;
+                    if (map == sSecureSettingToTypeMap) {
+                        value = Settings.Secure.getString(context.getContentResolver(), setting);
+                    } else {
+                        value = Settings.System.getString(context.getContentResolver(), setting);
+                    }
                     snapshot.putString(setting, value);
                 } else if (type == int.class) {
-                    int value = Settings.Secure.getInt(context.getContentResolver(),
-                            setting);
+                    final int value;
+                    if (map == sSecureSettingToTypeMap) {
+                        value = Settings.Secure.getInt(context.getContentResolver(), setting);
+                    } else {
+                        value = Settings.System.getInt(context.getContentResolver(), setting);
+                    }
                     snapshot.putInt(setting, value);
                 } else if (type == float.class) {
-                    float value = Settings.Secure.getFloat(context.getContentResolver(),
-                            setting);
+                    final float value;
+                    if (map == sSecureSettingToTypeMap) {
+                        value = Settings.Secure.getFloat(context.getContentResolver(), setting);
+                    } else {
+                        value = Settings.System.getFloat(context.getContentResolver(), setting);
+                    }
                     snapshot.putFloat(setting, value);
                 } else if (type == long.class) {
-                    long value = Settings.Secure.getLong(context.getContentResolver(),
-                            setting);
+                    final long value;
+                    if (map == sSecureSettingToTypeMap) {
+                        value = Settings.Secure.getLong(context.getContentResolver(), setting);
+                    } else {
+                        value = Settings.System.getLong(context.getContentResolver(), setting);
+                    }
                     snapshot.putLong(setting, value);
                 }
             } catch (SettingNotFoundException snfe) {