Merge "Add a scrubber to keyguard; layout tweaks" into klp-dev
diff --git a/api/current.txt b/api/current.txt
index d050c18..689cdff 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3178,7 +3178,7 @@
     method public int noteOpNoThrow(java.lang.String, int, java.lang.String);
     method public int startOp(java.lang.String, int, java.lang.String);
     method public int startOpNoThrow(java.lang.String, int, java.lang.String);
-    method public void startWatchingMode(int, java.lang.String, android.app.AppOpsManager.OnOpChangedListener);
+    method public void startWatchingMode(java.lang.String, java.lang.String, android.app.AppOpsManager.OnOpChangedListener);
     method public void stopWatchingMode(android.app.AppOpsManager.OnOpChangedListener);
     field public static final int MODE_ALLOWED = 0; // 0x0
     field public static final int MODE_ERRORED = 2; // 0x2
@@ -17850,7 +17850,7 @@
     field public static final int JELLY_BEAN = 16; // 0x10
     field public static final int JELLY_BEAN_MR1 = 17; // 0x11
     field public static final int JELLY_BEAN_MR2 = 18; // 0x12
-    field public static final int KITKAT = 10000; // 0x2710
+    field public static final int KITKAT = 19; // 0x13
   }
 
   public final class Bundle implements java.lang.Cloneable android.os.Parcelable {
@@ -28338,6 +28338,7 @@
     field public static final int HAPTIC_FEEDBACK_ENABLED = 268435456; // 0x10000000
     field public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0; // 0x0
     field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 2; // 0x2
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 4; // 0x4
     field public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 1; // 0x1
     field public static final int INVISIBLE = 4; // 0x4
     field public static final int KEEP_SCREEN_ON = 67108864; // 0x4000000
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 059945f..bdc4fdde 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -178,12 +178,13 @@
      * If this flag is set the system will regard views that are not important
      * for accessibility in addition to the ones that are important for accessibility.
      * That is, views that are marked as not important for accessibility via
-     * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO} and views that are marked as
-     * potentially important for accessibility via
+     * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO} or
+     * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS} and views that are
+     * marked as potentially important for accessibility via
      * {@link View#IMPORTANT_FOR_ACCESSIBILITY_AUTO} for which the system has determined
-     * that are not important for accessibility, are both reported while querying the
-     * window content and also the accessibility service will receive accessibility events
-     * from them.
+     * that are not important for accessibility, are reported while querying the window
+     * content and also the accessibility service will receive accessibility events from
+     * them.
      * <p>
      * <strong>Note:</strong> For accessibility services targeting API version
      * {@link Build.VERSION_CODES#JELLY_BEAN} or higher this flag has to be explicitly
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 02faeac..b364af7 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -533,8 +533,10 @@
     private native void dumpGraphicsInfo(FileDescriptor fd);
 
     private class ApplicationThread extends ApplicationThreadNative {
-        private static final String HEAP_FULL_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
-        private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s";
+        private static final String HEAP_FULL_COLUMN
+                = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
+        private static final String HEAP_COLUMN
+                = "%13s %8s %8s %8s %8s %8s %8s %8s";
         private static final String ONE_COUNT_COLUMN = "%21s %8d";
         private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
         private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";
@@ -1039,34 +1041,36 @@
             // otherwise, show human-readable format
             if (dumpFullInfo) {
                 printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
-                        "Shared", "Private", "Heap", "Heap", "Heap");
+                        "Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
                 printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
-                        "Clean", "Clean", "Size", "Alloc", "Free");
+                        "Clean", "Clean", "Dirty", "Size", "Alloc", "Free");
                 printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
-                        "------", "------", "------", "------", "------");
+                        "------", "------", "------", "------", "------", "------");
                 printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss,
                         memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
                         memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
-                        memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree);
+                        memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
+                        nativeMax, nativeAllocated, nativeFree);
                 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
                         memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
                         memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
-                        memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree);
+                        memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
+                        dalvikMax, dalvikAllocated, dalvikFree);
             } else {
-                printRow(pw, HEAP_COLUMN, "", "Pss", "Pss", "Private",
-                        "Private", "Heap", "Heap", "Heap");
-                printRow(pw, HEAP_COLUMN, "", "Total", "Clean", "Dirty",
-                        "Clean", "Size", "Alloc", "Free");
+                printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
+                        "Private", "Swapped", "Heap", "Heap", "Heap");
+                printRow(pw, HEAP_COLUMN, "", "Total", "Dirty",
+                        "Clean", "Dirty", "Size", "Alloc", "Free");
                 printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
-                        "------", "------", "------", "------");
+                        "------", "------", "------", "------", "------");
                 printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
-                        memInfo.nativeSwappablePss,
                         memInfo.nativePrivateDirty,
-                        memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree);
+                        memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
+                        nativeMax, nativeAllocated, nativeFree);
                 printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
-                        memInfo.dalvikSwappablePss,
                         memInfo.dalvikPrivateDirty,
-                        memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree);
+                        memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
+                        dalvikMax, dalvikAllocated, dalvikFree);
             }
 
             int otherPss = memInfo.otherPss;
@@ -1075,6 +1079,7 @@
             int otherPrivateDirty = memInfo.otherPrivateDirty;
             int otherSharedClean = memInfo.otherSharedClean;
             int otherPrivateClean = memInfo.otherPrivateClean;
+            int otherSwappedOut = memInfo.otherSwappedOut;
 
             for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
                 final int myPss = memInfo.getOtherPss(i);
@@ -1083,16 +1088,17 @@
                 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
                 final int mySharedClean = memInfo.getOtherSharedClean(i);
                 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
+                final int mySwappedOut = memInfo.getOtherSwappedOut(i);
                 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
-                        || mySharedClean != 0 || myPrivateClean != 0) {
+                        || mySharedClean != 0 || myPrivateClean != 0 || mySwappedOut != 0) {
                     if (dumpFullInfo) {
                         printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
                                 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
-                                mySharedClean, myPrivateClean, "", "", "");
+                                mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
                     } else {
                         printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
-                                myPss, mySwappablePss, myPrivateDirty,
-                                myPrivateClean, "", "", "");
+                                myPss, myPrivateDirty,
+                                myPrivateClean, mySwappedOut, "", "", "");
                     }
                     otherPss -= myPss;
                     otherSwappablePss -= mySwappablePss;
@@ -1100,27 +1106,28 @@
                     otherPrivateDirty -= myPrivateDirty;
                     otherSharedClean -= mySharedClean;
                     otherPrivateClean -= myPrivateClean;
+                    otherSwappedOut -= mySwappedOut;
                 }
             }
 
             if (dumpFullInfo) {
                 printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
                         otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
-                        "", "", "");
+                        otherSwappedOut, "", "", "");
                 printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(),
                         memInfo.getTotalSwappablePss(),
                         memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
                         memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
-                        nativeMax+dalvikMax,
+                        memInfo.getTotalSwappedOut(), nativeMax+dalvikMax,
                         nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
             } else {
-                printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSwappablePss,
-                        otherPrivateDirty, otherPrivateClean,
+                printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
+                        otherPrivateDirty, otherPrivateClean, otherSwappedOut,
                         "", "", "");
                 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
-                        memInfo.getTotalSwappablePss(),
                         memInfo.getTotalPrivateDirty(),
                         memInfo.getTotalPrivateClean(),
+                        memInfo.getTotalSwappedOut(),
                         nativeMax+dalvikMax,
                         nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
             }
@@ -1137,16 +1144,17 @@
                     final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
                     final int mySharedClean = memInfo.getOtherSharedClean(i);
                     final int myPrivateClean = memInfo.getOtherPrivateClean(i);
+                    final int mySwappedOut = memInfo.getOtherSwappedOut(i);
                     if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
                             || mySharedClean != 0 || myPrivateClean != 0) {
                         if (dumpFullInfo) {
                             printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
                                     myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
-                                    mySharedClean, myPrivateClean, "", "", "");
+                                    mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
                         } else {
                             printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
-                                    myPss, mySwappablePss, myPrivateDirty,
-                                    myPrivateClean, "", "", "");
+                                    myPss, myPrivateDirty,
+                                    myPrivateClean, mySwappedOut, "", "", "");
                         }
                     }
                 }
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index dce8cab..183927b 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -790,9 +790,21 @@
 
     /**
      * Monitor for changes to the operating mode for the given op in the given app package.
+     * @param op The operation to monitor, one of OPSTR_*.
+     * @param packageName The name of the application to monitor.
+     * @param callback Where to report changes.
+     */
+    public void startWatchingMode(String op, String packageName,
+            final OnOpChangedListener callback) {
+        startWatchingMode(strOpToOp(op), packageName, callback);
+    }
+
+    /**
+     * Monitor for changes to the operating mode for the given op in the given app package.
      * @param op The operation to monitor, one of OP_*.
      * @param packageName The name of the application to monitor.
      * @param callback Where to report changes.
+     * @hide
      */
     public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
         synchronized (mModeWatchers) {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 7183179..190ddb4 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1461,29 +1461,39 @@
         }
     }
 
+    private void validateServiceIntent(Intent service) {
+        if (service.getComponent() == null && service.getPackage() == null) {
+            if (true || getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
+                Log.w(TAG, "Implicit intents with startService are not safe: " + service
+                        + " " + Debug.getCallers(2, 3));
+                //IllegalArgumentException ex = new IllegalArgumentException(
+                //        "Service Intent must be explicit: " + service);
+                //Log.e(TAG, "This will become an error", ex);
+                //throw ex;
+            }
+        }
+    }
+
     @Override
     public ComponentName startService(Intent service) {
         warnIfCallingFromSystemProcess();
-        return startServiceAsUser(service, mUser);
+        return startServiceCommon(service, mUser);
     }
 
     @Override
     public boolean stopService(Intent service) {
         warnIfCallingFromSystemProcess();
-        return stopServiceAsUser(service, mUser);
+        return stopServiceCommon(service, mUser);
     }
 
     @Override
     public ComponentName startServiceAsUser(Intent service, UserHandle user) {
+        return startServiceCommon(service, user);
+    }
+
+    private ComponentName startServiceCommon(Intent service, UserHandle user) {
         try {
-            if (service.getComponent() == null && service.getPackage() == null) {
-                if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
-                    IllegalArgumentException ex = new IllegalArgumentException(
-                            "Service Intent must be explicit: " + service);
-                    Log.e(TAG, "This will become an error", ex);
-                    //throw ex;
-                }
-            }
+            validateServiceIntent(service);
             service.prepareToLeaveProcess();
             ComponentName cn = ActivityManagerNative.getDefault().startService(
                 mMainThread.getApplicationThread(), service,
@@ -1507,15 +1517,12 @@
 
     @Override
     public boolean stopServiceAsUser(Intent service, UserHandle user) {
+        return stopServiceCommon(service, user);
+    }
+
+    private boolean stopServiceCommon(Intent service, UserHandle user) {
         try {
-            if (service.getComponent() == null && service.getPackage() == null) {
-                if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
-                    IllegalArgumentException ex = new IllegalArgumentException(
-                            "Service Intent must be explicit: " + service);
-                    Log.e(TAG, "This will become an error", ex);
-                    //throw ex;
-                }
-            }
+            validateServiceIntent(service);
             service.prepareToLeaveProcess();
             int res = ActivityManagerNative.getDefault().stopService(
                 mMainThread.getApplicationThread(), service,
@@ -1534,13 +1541,18 @@
     public boolean bindService(Intent service, ServiceConnection conn,
             int flags) {
         warnIfCallingFromSystemProcess();
-        return bindServiceAsUser(service, conn, flags, Process.myUserHandle());
+        return bindServiceCommon(service, conn, flags, Process.myUserHandle());
     }
 
     /** @hide */
     @Override
     public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
             UserHandle user) {
+        return bindServiceCommon(service, conn, flags, user);
+    }
+
+    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
+            UserHandle user) {
         IServiceConnection sd;
         if (conn == null) {
             throw new IllegalArgumentException("connection is null");
@@ -1551,14 +1563,7 @@
         } else {
             throw new RuntimeException("Not supported in system context");
         }
-        if (service.getComponent() == null && service.getPackage() == null) {
-            if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
-                IllegalArgumentException ex = new IllegalArgumentException(
-                        "Service Intent must be explicit: " + service);
-                Log.e(TAG, "This will become an error", ex);
-                //throw ex;
-            }
-        }
+        validateServiceIntent(service);
         try {
             IBinder token = getActivityToken();
             if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 02ccaa5..50401bd 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1657,9 +1657,8 @@
      * Request that a given application service be started.  The Intent
      * should contain either contain the complete class name of a specific service
      * implementation to start or a specific package name to target.  If the
-     * Intent is less specified, it will either throw an {@link IllegalArgumentException}
-     * (if the caller targets {@link android.os.Build.VERSION_CODES#KITKAT} or later),
-     * or which of multiple matching services it finds and uses will be undefined.  If this service
+     * Intent is less specified, it log a warning about this and which of the
+     * multiple matching services it finds and uses will be undefined.  If this service
      * is not already running, it will be instantiated and started (creating a
      * process for it if needed); if it is running then it remains running.
      *
diff --git a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
index 4054a92..02a73d66 100644
--- a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
+++ b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
@@ -25,6 +25,8 @@
      * Keep up-to-date with frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h
      */
 
-    oneway void notifyCallback(int msgType, int ext1, int ext2);
-    oneway void onResultReceived(int frameId, in CameraMetadataNative result);
+    oneway void onCameraError(int errorCode);
+    oneway void onCameraIdle();
+    oneway void onCaptureStarted(int requestId, long timestamp);
+    oneway void onResultReceived(int requestId, in CameraMetadataNative result);
 }
diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java
index 70a6f44..463063c 100644
--- a/core/java/android/hardware/camera2/impl/CameraDevice.java
+++ b/core/java/android/hardware/camera2/impl/CameraDevice.java
@@ -183,13 +183,8 @@
 
         // Need a valid handler, or current thread needs to have a looper, if
         // listener is valid
-        if (handler == null && listener != null) {
-            Looper looper = Looper.myLooper();
-            if (looper == null) {
-                throw new IllegalArgumentException(
-                        "No handler given, and current thread has no looper!");
-            }
-            handler = new Handler(looper);
+        if (listener != null) {
+            handler = checkHandler(handler);
         }
 
         synchronized (mLock) {
@@ -271,12 +266,16 @@
                 // impossible
                 return;
             }
-      }
+        }
     }
 
     @Override
     public void setDeviceListener(StateListener listener, Handler handler) {
         synchronized (mLock) {
+            if (listener != null) {
+                handler = checkHandler(handler);
+            }
+
             mDeviceListener = listener;
             mDeviceHandler = handler;
         }
@@ -365,21 +364,113 @@
 
     }
 
-    // TODO: unit tests
     public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
 
+        //
+        // Constants below need to be kept up-to-date with
+        // frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h
+        //
+
+        //
+        // Error codes for onCameraError
+        //
+
+        /**
+         * Camera has been disconnected
+         */
+        static final int ERROR_CAMERA_DISCONNECTED = 0;
+
+        /**
+         * Camera has encountered a device-level error
+         * Matches CameraDevice.StateListener#ERROR_CAMERA_DEVICE
+         */
+        static final int ERROR_CAMERA_DEVICE = 1;
+
+        /**
+         * Camera has encountered a service-level error
+         * Matches CameraDevice.StateListener#ERROR_CAMERA_SERVICE
+         */
+        static final int ERROR_CAMERA_SERVICE = 2;
+
         @Override
         public IBinder asBinder() {
             return this;
         }
 
-        // TODO: consider rename to onMessageReceived
         @Override
-        public void notifyCallback(int msgType, int ext1, int ext2) throws RemoteException {
-            if (DEBUG) {
-                Log.d(TAG, "Got message " + msgType + " ext1: " + ext1 + " , ext2: " + ext2);
+        public void onCameraError(final int errorCode) {
+            synchronized (mLock) {
+                if (CameraDevice.this.mDeviceListener == null) return;
+                final StateListener listener = CameraDevice.this.mDeviceListener;
+                Runnable r = null;
+                switch (errorCode) {
+                    case ERROR_CAMERA_DISCONNECTED:
+                        r = new Runnable() {
+                            public void run() {
+                                listener.onDisconnected(CameraDevice.this);
+                            }
+                        };
+                        break;
+                    case ERROR_CAMERA_DEVICE:
+                    case ERROR_CAMERA_SERVICE:
+                        r = new Runnable() {
+                            public void run() {
+                                listener.onError(CameraDevice.this, errorCode);
+                            }
+                        };
+                        break;
+                    default:
+                        Log.e(TAG, "Unknown error from camera device: " + errorCode);
+                }
+                if (r != null) {
+                    CameraDevice.this.mDeviceHandler.post(r);
+                }
             }
-            // TODO implement rest
+        }
+
+        @Override
+        public void onCameraIdle() {
+            if (DEBUG) {
+                Log.d(TAG, "Camera now idle");
+            }
+            synchronized (mLock) {
+                if (CameraDevice.this.mDeviceListener == null) return;
+                final StateListener listener = CameraDevice.this.mDeviceListener;
+                Runnable r = new Runnable() {
+                    public void run() {
+                        listener.onIdle(CameraDevice.this);
+                    }
+                };
+                CameraDevice.this.mDeviceHandler.post(r);
+            }
+        }
+
+        @Override
+        public void onCaptureStarted(int requestId, final long timestamp) {
+            if (DEBUG) {
+                Log.d(TAG, "Capture started for id " + requestId);
+            }
+            final CaptureListenerHolder holder;
+
+            // Get the listener for this frame ID, if there is one
+            synchronized (mLock) {
+                holder = CameraDevice.this.mCaptureListenerMap.get(requestId);
+            }
+
+            if (holder == null) {
+                return;
+            }
+
+            // Dispatch capture start notice
+            holder.getHandler().post(
+                new Runnable() {
+                    public void run() {
+                        holder.getListener().onCaptureStarted(
+                            CameraDevice.this,
+                            holder.getRequest(),
+                            timestamp);
+                    }
+                });
         }
 
         @Override
@@ -429,6 +520,22 @@
 
     }
 
+    /**
+     * Default handler management. If handler is null, get the current thread's
+     * Looper to create a Handler with. If no looper exists, throw exception.
+     */
+    private Handler checkHandler(Handler handler) {
+        if (handler == null) {
+            Looper looper = Looper.myLooper();
+            if (looper == null) {
+                throw new IllegalArgumentException(
+                    "No handler given, and current thread has no looper!");
+            }
+            handler = new Handler(looper);
+        }
+        return handler;
+    }
+
     private void checkIfCameraClosed() {
         if (mRemoteDevice == null) {
             throw new IllegalStateException("CameraDevice was already closed");
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 6d7b03e..6d04bf8 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -652,7 +652,6 @@
      * We use a class initializer to allow the native code to cache some field offsets
      */
     static {
-        System.loadLibrary("media_jni");
         nativeClassInit();
 
         Log.v(TAG, "Shall register metadata marshalers");
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 88eb280..114a1ea 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -438,17 +438,28 @@
         public static final int JELLY_BEAN_MR2 = 18;
 
         /**
-         * Android X.X: KitKat, another tasty treat.
+         * Android 4.4: KitKat, another tasty treat.
          *
          * <p>Applications targeting this or a later release will get these
          * new changes in behavior:</p>
          * <ul>
-         * <li>It is no longer allowed to use implicit intents with
-         * {@link android.content.Context#startService} or
-         * {@link android.content.Context#bindService}.
+         * <li> The default result of {android.preference.PreferenceActivity#isValidFragment
+         * PreferenceActivity.isValueFragment} becomes false instead of true.</li>
+         * <li> In {@link android.webkit.WebView}, apps targeting earlier versions will have
+         * JS URLs evaluated directly and any result of the evaluation will not replace
+         * the current page content.  Apps targetting KITKAT or later that load a JS URL will
+         * have the result of that URL replace the content of the current page</li>
+         * <li> {@link android.app.AlarmManager#set AlarmManager.set} becomes interpreted as
+         * an inexact value, to give the system more flexibility in scheduling alarms.</li>
+         * <li> {@link android.content.Context#getSharedPreferences(String, int)
+         * Context.getSharedPreferences} no longer allows a null name.</li>
+         * <li> {@link android.widget.RelativeLayout} changes to compute wrapped content
+         * margins correctly.</li>
+         * <li> {@link android.app.ActionBar}'s window content overlay is allowed to be
+         * drawn.</li>
          * </ul>
          */
-        public static final int KITKAT = CUR_DEVELOPMENT;
+        public static final int KITKAT = 19;
     }
     
     /** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index f47ac4e..5a919fb 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -30,7 +30,8 @@
  *
  */
 public final class Bundle implements Parcelable, Cloneable {
-    private static final String LOG_TAG = "Bundle";
+    private static final String TAG = "Bundle";
+    static final boolean DEBUG = false;
     public static final Bundle EMPTY;
 
     static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
@@ -157,7 +158,7 @@
         unparcel();
         int size = mMap.size();
         if (size > 1) {
-            Log.w(LOG_TAG, "getPairValue() used on Bundle with multiple pairs.");
+            Log.w(TAG, "getPairValue() used on Bundle with multiple pairs.");
         }
         if (size == 0) {
             return null;
@@ -210,10 +211,14 @@
      */
     /* package */ synchronized void unparcel() {
         if (mParcelledData == null) {
+            if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+                    + ": no parcelled data");
             return;
         }
 
         int N = mParcelledData.readInt();
+        if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+                + ": reading " + N + " maps");
         if (N < 0) {
             return;
         }
@@ -226,6 +231,8 @@
         mParcelledData.readArrayMapInternal(mMap, N, mClassLoader);
         mParcelledData.recycle();
         mParcelledData = null;
+        if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+                + " final map: " + mMap);
     }
 
     /**
@@ -794,6 +801,8 @@
      */
     public boolean getBoolean(String key) {
         unparcel();
+        if (DEBUG) Log.d(TAG, "Getting boolean in "
+                + Integer.toHexString(System.identityHashCode(this)));
         return getBoolean(key, false);
     }
 
@@ -810,8 +819,8 @@
         sb.append(".  The default value ");
         sb.append(defaultValue);
         sb.append(" was returned.");
-        Log.w(LOG_TAG, sb.toString());
-        Log.w(LOG_TAG, "Attempt to cast generated internal exception:", e);
+        Log.w(TAG, sb.toString());
+        Log.w(TAG, "Attempt to cast generated internal exception:", e);
     }
 
     private void typeWarning(String key, Object value, String className,
@@ -1648,18 +1657,19 @@
                 parcel.writeInt(BUNDLE_MAGIC);
                 parcel.appendFrom(mParcelledData, 0, length);
             } else {
+                int lengthPos = parcel.dataPosition();
                 parcel.writeInt(-1); // dummy, will hold length
                 parcel.writeInt(BUNDLE_MAGIC);
     
-                int oldPos = parcel.dataPosition();
+                int startPos = parcel.dataPosition();
                 parcel.writeArrayMapInternal(mMap);
-                int newPos = parcel.dataPosition();
+                int endPos = parcel.dataPosition();
     
                 // Backpatch length
-                parcel.setDataPosition(oldPos - 8);
-                int length = newPos - oldPos;
+                parcel.setDataPosition(lengthPos);
+                int length = endPos - startPos;
                 parcel.writeInt(length);
-                parcel.setDataPosition(newPos);
+                parcel.setDataPosition(endPos);
             }
         } finally {
             parcel.restoreAllowFds(oldAllowFds);
@@ -1694,24 +1704,13 @@
         Parcel p = Parcel.obtain();
         p.setDataPosition(0);
         p.appendFrom(parcel, offset, length);
+        if (DEBUG) Log.d(TAG, "Retrieving "  + Integer.toHexString(System.identityHashCode(this))
+                + ": " + length + " bundle bytes starting at " + offset);
         p.setDataPosition(0);
 
-        if (mMap != null) {
-            // It is not allowed to have a Bundle with both a map and a parcel, so if we
-            // already have a map then we need to immediately unparcel into it.  This also
-            // lets us know we need to go through the slow path of unparceling, since the
-            // map may already contains some data so the two need to be merged.
-            if (mFdsKnown) {
-                mHasFds |= p.hasFileDescriptors();
-            }
-            int N = p.readInt();
-            p.readArrayMapSafelyInternal(mMap, N, mClassLoader);
-            p.recycle();
-        } else {
-            mParcelledData = p;
-            mHasFds = p.hasFileDescriptors();
-            mFdsKnown = true;
-        }
+        mParcelledData = p;
+        mHasFds = p.hasFileDescriptors();
+        mFdsKnown = true;
     }
 
     @Override
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index ea9fd06..974bf8d 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -124,6 +124,9 @@
         /** The shared clean pages used by dalvik heap. */
         /** @hide We may want to expose this, eventually. */
         public int dalvikSharedClean;
+        /** The dirty dalvik pages that have been swapped out. */
+        /** @hide We may want to expose this, eventually. */
+        public int dalvikSwappedOut;
 
         /** The proportional set size for the native heap. */
         public int nativePss;
@@ -140,6 +143,9 @@
         /** The shared clean pages used by the native heap. */
         /** @hide We may want to expose this, eventually. */
         public int nativeSharedClean;
+        /** The dirty native pages that have been swapped out. */
+        /** @hide We may want to expose this, eventually. */
+        public int nativeSwappedOut;
 
         /** The proportional set size for everything else. */
         public int otherPss;
@@ -156,6 +162,9 @@
         /** The shared clean pages used by everything else. */
         /** @hide We may want to expose this, eventually. */
         public int otherSharedClean;
+        /** The dirty pages used by anyting else that have been swapped out. */
+        /** @hide We may want to expose this, eventually. */
+        public int otherSwappedOut;
 
         /** @hide */
         public static final int NUM_OTHER_STATS = 16;
@@ -164,7 +173,7 @@
         public static final int NUM_DVK_STATS = 5;
 
         /** @hide */
-        public static final int NUM_CATEGORIES = 6;
+        public static final int NUM_CATEGORIES = 7;
 
         /** @hide */
         public static final int offsetPss = 0;
@@ -178,7 +187,8 @@
         public static final int offsetPrivateClean = 4;
         /** @hide */
         public static final int offsetSharedClean = 5;
-
+        /** @hide */
+        public static final int offsetSwappedOut = 6;
 
         private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES];
 
@@ -236,6 +246,14 @@
             return dalvikSharedClean + nativeSharedClean + otherSharedClean;
         }
 
+        /**
+         * Return total swapped out memory in kB.
+         * @hide
+         */
+        public int getTotalSwappedOut() {
+            return dalvikSwappedOut + nativeSwappedOut + otherSwappedOut;
+        }
+
         /** @hide */
         public int getOtherPss(int which) {
             return otherStats[which*NUM_CATEGORIES + offsetPss];
@@ -263,13 +281,17 @@
             return otherStats[which*NUM_CATEGORIES + offsetPrivateClean];
         }
 
-
         /** @hide */
         public int getOtherSharedClean(int which) {
             return otherStats[which*NUM_CATEGORIES + offsetSharedClean];
         }
 
         /** @hide */
+        public int getOtherSwappedOut(int which) {
+            return otherStats[which*NUM_CATEGORIES + offsetSwappedOut];
+        }
+
+        /** @hide */
         public static String getOtherLabel(int which) {
             switch (which) {
                 case 0: return "Dalvik Other";
@@ -287,7 +309,7 @@
                 case 12: return "Other mmap";
                 case 13: return "Graphics";
                 case 14: return "GL";
-                case 15: return "Other memtrack";
+                case 15: return "Memtrack";
                 case 16: return ".Heap";
                 case 17: return ".LOS";
                 case 18: return ".LinearAlloc";
@@ -308,18 +330,21 @@
             dest.writeInt(dalvikSharedDirty);
             dest.writeInt(dalvikPrivateClean);
             dest.writeInt(dalvikSharedClean);
+            dest.writeInt(dalvikSwappedOut);
             dest.writeInt(nativePss);
             dest.writeInt(nativeSwappablePss);
             dest.writeInt(nativePrivateDirty);
             dest.writeInt(nativeSharedDirty);
             dest.writeInt(nativePrivateClean);
             dest.writeInt(nativeSharedClean);
+            dest.writeInt(nativeSwappedOut);
             dest.writeInt(otherPss);
             dest.writeInt(otherSwappablePss);
             dest.writeInt(otherPrivateDirty);
             dest.writeInt(otherSharedDirty);
             dest.writeInt(otherPrivateClean);
             dest.writeInt(otherSharedClean);
+            dest.writeInt(otherSwappedOut);
             dest.writeIntArray(otherStats);
         }
 
@@ -330,18 +355,21 @@
             dalvikSharedDirty = source.readInt();
             dalvikPrivateClean = source.readInt();
             dalvikSharedClean = source.readInt();
+            dalvikSwappedOut = source.readInt();
             nativePss = source.readInt();
             nativeSwappablePss = source.readInt();
             nativePrivateDirty = source.readInt();
             nativeSharedDirty = source.readInt();
             nativePrivateClean = source.readInt();
             nativeSharedClean = source.readInt();
+            nativeSwappedOut = source.readInt();
             otherPss = source.readInt();
             otherSwappablePss = source.readInt();
             otherPrivateDirty = source.readInt();
             otherSharedDirty = source.readInt();
             otherPrivateClean = source.readInt();
             otherSharedClean = source.readInt();
+            otherSwappedOut = source.readInt();
             otherStats = source.createIntArray();
         }
 
@@ -1582,6 +1610,22 @@
     }
 
     /**
+     * Return a string consisting of methods and locations at multiple call stack levels.
+     * @param depth the number of levels to return, starting with the immediate caller.
+     * @return a string describing the call stack.
+     * {@hide}
+     */
+    public static String getCallers(final int start, int depth) {
+        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        StringBuffer sb = new StringBuffer();
+        depth += start;
+        for (int i = start; i < depth; i++) {
+            sb.append(getCaller(callStack, i)).append(" ");
+        }
+        return sb.toString();
+    }
+
+    /**
      * Like {@link #getCallers(int)}, but each location is append to the string
      * as a new line with <var>linePrefix</var> in front of it.
      * @param depth the number of levels to return, starting with the immediate caller.
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 5f3a81c..02b1998 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -1610,6 +1610,7 @@
     public final Bundle readBundle(ClassLoader loader) {
         int length = readInt();
         if (length < 0) {
+            if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
             return null;
         }
         
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3769e1e..631a38f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2407,6 +2407,15 @@
         public static final String POINTER_SPEED = "pointer_speed";
 
         /**
+         * I am the lolrus.
+         * <p>
+         * Nonzero values indicate that the user has a bukkit.
+         * Backward-compatible with <code>PrefGetPreference(prefAllowEasterEggs)</code>.
+         * @hide
+         */
+        public static final String EGG_MODE = "egg_mode";
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          *
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index fa534cc..df1d4cd 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -292,6 +292,7 @@
             for (int i=0; i<N; i++) {
                 array[i] = null;
             }
+            mSize = 0;
         }
     }
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 06f00f7..f763d19 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2121,6 +2121,12 @@
     public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002;
 
     /**
+     * The view is not important for accessibility, nor are any of its
+     * descendant views.
+     */
+    public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 0x00000004;
+
+    /**
      * The default whether the view is important for accessibility.
      */
     static final int IMPORTANT_FOR_ACCESSIBILITY_DEFAULT = IMPORTANT_FOR_ACCESSIBILITY_AUTO;
@@ -2130,14 +2136,15 @@
      * whether a view is important for accessibility.
      */
     static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK = (IMPORTANT_FOR_ACCESSIBILITY_AUTO
-        | IMPORTANT_FOR_ACCESSIBILITY_YES | IMPORTANT_FOR_ACCESSIBILITY_NO)
+        | IMPORTANT_FOR_ACCESSIBILITY_YES | IMPORTANT_FOR_ACCESSIBILITY_NO
+        | IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS)
         << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
 
     /**
      * Shift for the bits in {@link #mPrivateFlags2} related to the
      * "accessibilityLiveRegion" attribute.
      */
-    static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT = 22;
+    static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT = 23;
 
     /**
      * Live region mode specifying that accessibility services should not
@@ -6999,12 +7006,15 @@
      *
      * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
+     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
      * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
      */
     @ViewDebug.ExportedProperty(category = "accessibility", mapping = {
             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_AUTO, to = "auto"),
             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_YES, to = "yes"),
-            @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO, to = "no")
+            @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO, to = "no"),
+            @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS,
+                    to = "noHideDescendants")
         })
     public int getImportantForAccessibility() {
         return (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
@@ -7074,6 +7084,7 @@
      *
      * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
+     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
      * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
      */
     public void setImportantForAccessibility(int mode) {
@@ -7101,19 +7112,24 @@
     public boolean isImportantForAccessibility() {
         final int mode = (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
                 >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
-        switch (mode) {
-            case IMPORTANT_FOR_ACCESSIBILITY_YES:
-                return true;
-            case IMPORTANT_FOR_ACCESSIBILITY_NO:
-                return false;
-            case IMPORTANT_FOR_ACCESSIBILITY_AUTO:
-                return isActionableForAccessibility() || hasListenersForAccessibility()
-                        || getAccessibilityNodeProvider() != null
-                        || getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE;
-            default:
-                throw new IllegalArgumentException("Unknow important for accessibility mode: "
-                        + mode);
+        if (mode == IMPORTANT_FOR_ACCESSIBILITY_NO
+                || mode == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
+            return false;
         }
+
+        // Check parent mode to ensure we're not hidden.
+        ViewParent parent = mParent;
+        while (parent instanceof View) {
+            if (((View) parent).getImportantForAccessibility()
+                    == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
+                return false;
+            }
+            parent = parent.getParent();
+        }
+
+        return mode == IMPORTANT_FOR_ACCESSIBILITY_YES || isActionableForAccessibility()
+                || hasListenersForAccessibility() || getAccessibilityNodeProvider() != null
+                || getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE;
     }
 
     /**
diff --git a/core/java/android/webkit/CookieSyncManager.java b/core/java/android/webkit/CookieSyncManager.java
index 276bcae..13aa43f 100644
--- a/core/java/android/webkit/CookieSyncManager.java
+++ b/core/java/android/webkit/CookieSyncManager.java
@@ -59,8 +59,10 @@
 
     private static CookieSyncManager sRef;
 
-    private CookieSyncManager(Context context) {
-        super(context, "CookieSyncManager");
+    private static boolean sGetInstanceAllowed = false;
+
+    private CookieSyncManager() {
+        super("CookieSyncManager");
     }
 
     /**
@@ -71,7 +73,10 @@
      * @return CookieSyncManager
      */
     public static synchronized CookieSyncManager getInstance() {
-        checkInstanceIsCreated();
+        checkInstanceIsAllowed();
+        if (sRef == null) {
+            sRef = new CookieSyncManager();
+        }
         return sRef;
     }
 
@@ -80,16 +85,13 @@
      * @param context
      * @return CookieSyncManager
      */
-    public static synchronized CookieSyncManager createInstance(
-            Context context) {
+    public static synchronized CookieSyncManager createInstance(Context context) {
         if (context == null) {
             throw new IllegalArgumentException("Invalid context argument");
         }
 
-        if (sRef == null) {
-            sRef = new CookieSyncManager(context);
-        }
-        return sRef;
+        setGetInstanceIsAllowed();
+        return getInstance();
     }
 
     protected void syncFromRamToFlash() {
@@ -110,8 +112,15 @@
         }
     }
 
-    private static void checkInstanceIsCreated() {
-        if (sRef == null) {
+    static void setGetInstanceIsAllowed() {
+        sGetInstanceAllowed = true;
+    }
+
+    private static void checkInstanceIsAllowed() {
+        // Prior to Android KK, calling createInstance() or constructing a WebView is
+        // a hard pre-condition for calling getInstance(). We retain that contract to aid
+        // developers targeting a range of SDK levels.
+        if (!sGetInstanceAllowed) {
             throw new IllegalStateException(
                     "CookieSyncManager::createInstance() needs to be called "
                             + "before CookieSyncManager::getInstance()");
diff --git a/core/java/android/webkit/WebSyncManager.java b/core/java/android/webkit/WebSyncManager.java
index d3ec603..c600a7e 100644
--- a/core/java/android/webkit/WebSyncManager.java
+++ b/core/java/android/webkit/WebSyncManager.java
@@ -36,7 +36,7 @@
     private String mThreadName;
     // handler of the sync thread
     protected Handler mHandler;
-    // database for the persistent storage
+    // database for the persistent storage. Always null.
     protected WebViewDatabase mDataBase;
     // Ref count for calls to start/stop sync
     private int mStartSyncRefCount;
@@ -60,16 +60,15 @@
     }
 
     protected WebSyncManager(Context context, String name) {
+        this(name);
+    }
+
+    /** @hide */
+    WebSyncManager(String name) {
         mThreadName = name;
-        if (context != null) {
-            mDataBase = WebViewDatabase.getInstance(context);
-            mSyncThread = new Thread(this);
-            mSyncThread.setName(mThreadName);
-            mSyncThread.start();
-        } else {
-            throw new IllegalStateException(
-                    "WebSyncManager can't be created without context");
-        }
+        mSyncThread = new Thread(this);
+        mSyncThread.setName(mThreadName);
+        mSyncThread.start();
     }
 
     protected Object clone() throws CloneNotSupportedException {
@@ -82,7 +81,7 @@
         mHandler = new SyncHandler();
         onSyncInit();
         // lower the priority after onSyncInit() is done
-       Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
 
         Message msg = mHandler.obtainMessage(SYNC_MESSAGE);
         mHandler.sendMessageDelayed(msg, SYNC_LATER_INTERVAL);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 90cc72e..2cbe0e2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -506,8 +506,8 @@
 
         ensureProviderCreated();
         mProvider.init(javaScriptInterfaces, privateBrowsing);
-        // Post condition of creating a webview is the CookieSyncManager instance exists.
-        CookieSyncManager.createInstance(getContext());
+        // Post condition of creating a webview is the CookieSyncManager.getInstance() is allowed.
+        CookieSyncManager.setGetInstanceIsAllowed();
     }
 
     /**
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 76b8579..43bd735 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Typeface;
+import android.provider.Settings;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
@@ -151,6 +152,13 @@
         logo.setOnLongClickListener(new View.OnLongClickListener() {
             @Override
             public boolean onLongClick(View v) {
+                if (Settings.System.getLong(getContentResolver(), Settings.System.EGG_MODE, 0)
+                        == 0) {
+                    // For posterity: the moment this user unlocked the easter egg
+                    Settings.System.putLong(getContentResolver(),
+                            Settings.System.EGG_MODE,
+                            System.currentTimeMillis());
+                }
                 try {
                     startActivity(new Intent(Intent.ACTION_MAIN)
                         .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -158,7 +166,7 @@
                             | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                         .addCategory("com.android.internal.category.PLATLOGO"));
                 } catch (ActivityNotFoundException ex) {
-                    android.util.Log.e("PlatLogoActivity", "Couldn't find a piece of pie.");
+                    android.util.Log.e("PlatLogoActivity", "Couldn't catch a break.");
                 }
                 finish();
                 return true;
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 62f057f..054ee4f6 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -80,6 +80,7 @@
     jfieldID sharedDirty_field;
     jfieldID privateClean_field;
     jfieldID sharedClean_field;
+    jfieldID swappedOut_field;
 };
 
 struct stat_field_names {
@@ -89,14 +90,18 @@
     const char* sharedDirty_name;
     const char* privateClean_name;
     const char* sharedClean_name;
+    const char* swappedOut_name;
 };
 
 static stat_fields stat_fields[_NUM_CORE_HEAP];
 
 static stat_field_names stat_field_names[_NUM_CORE_HEAP] = {
-    { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", "otherPrivateClean", "otherSharedClean" },
-    { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikPrivateClean", "dalvikSharedClean" },
-    { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", "nativePrivateClean", "nativeSharedClean" }
+    { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty",
+        "otherPrivateClean", "otherSharedClean", "otherSwappedOut" },
+    { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty",
+        "dalvikPrivateClean", "dalvikSharedClean", "dalvikSwappedOut" },
+    { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty",
+        "nativePrivateClean", "nativeSharedClean", "nativeSwappedOut" }
 };
 
 jfieldID otherStats_field;
@@ -110,6 +115,7 @@
     int sharedDirty;
     int privateClean;
     int sharedClean;
+    int swappedOut;
 };
 
 #define BINDER_STATS "/proc/binder/stats"
@@ -219,6 +225,7 @@
     float sharing_proportion = 0.0;
     unsigned shared_clean = 0, shared_dirty = 0;
     unsigned private_clean = 0, private_dirty = 0;
+    unsigned swapped_out = 0;
     bool is_swappable = false;
     unsigned referenced = 0;
     unsigned temp;
@@ -333,28 +340,36 @@
         //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap,
         //    isSqliteHeap, line);
 
+        shared_clean = 0;
+        shared_dirty = 0;
+        private_clean = 0;
+        private_dirty = 0;
+        swapped_out = 0;
+
         while (true) {
             if (fgets(line, 1024, fp) == 0) {
                 done = true;
                 break;
             }
 
-            if (sscanf(line, "Size: %d kB", &temp) == 1) {
+            if (line[0] == 'S' && sscanf(line, "Size: %d kB", &temp) == 1) {
                 size = temp;
-            } else if (sscanf(line, "Rss: %d kB", &temp) == 1) {
+            } else if (line[0] == 'R' && sscanf(line, "Rss: %d kB", &temp) == 1) {
                 resident = temp;
-            } else if (sscanf(line, "Pss: %d kB", &temp) == 1) {
+            } else if (line[0] == 'P' && sscanf(line, "Pss: %d kB", &temp) == 1) {
                 pss = temp;
-            } else if (sscanf(line, "Shared_Clean: %d kB", &temp) == 1) {
+            } else if (line[0] == 'S' && sscanf(line, "Shared_Clean: %d kB", &temp) == 1) {
                 shared_clean = temp;
-            } else if (sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) {
+            } else if (line[0] == 'S' && sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) {
                 shared_dirty = temp;
-            } else if (sscanf(line, "Private_Clean: %d kB", &temp) == 1) {
+            } else if (line[0] == 'P' && sscanf(line, "Private_Clean: %d kB", &temp) == 1) {
                 private_clean = temp;
-            } else if (sscanf(line, "Private_Dirty: %d kB", &temp) == 1) {
+            } else if (line[0] == 'P' && sscanf(line, "Private_Dirty: %d kB", &temp) == 1) {
                 private_dirty = temp;
-            } else if (sscanf(line, "Referenced: %d kB", &temp) == 1) {
+            } else if (line[0] == 'R' && sscanf(line, "Referenced: %d kB", &temp) == 1) {
                 referenced = temp;
+            } else if (line[0] == 'S' && sscanf(line, "Swap: %d kB", &temp) == 1) {
+                swapped_out = temp;
             } else if (strlen(line) > 30 && line[8] == '-' && line[17] == ' ') {
                 // looks like a new mapping
                 // example: "10000000-10001000 ---p 10000000 00:00 0"
@@ -366,7 +381,8 @@
             if (is_swappable && (pss > 0)) {
                 sharing_proportion = 0.0;
                 if ((shared_clean > 0) || (shared_dirty > 0)) {
-                    sharing_proportion = (pss - private_clean - private_dirty)/(shared_clean+shared_dirty);
+                    sharing_proportion = (pss - private_clean
+                            - private_dirty)/(shared_clean+shared_dirty);
                 }
                 swappable_pss = (sharing_proportion*shared_clean) + private_clean;
             } else
@@ -378,6 +394,7 @@
             stats[whichHeap].sharedDirty += shared_dirty;
             stats[whichHeap].privateClean += private_clean;
             stats[whichHeap].sharedClean += shared_clean;
+            stats[whichHeap].swappedOut += swapped_out;
             if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) {
                 stats[subHeap].pss += pss;
                 stats[subHeap].swappablePss += swappable_pss;
@@ -385,6 +402,7 @@
                 stats[subHeap].sharedDirty += shared_dirty;
                 stats[subHeap].privateClean += private_clean;
                 stats[subHeap].sharedClean += shared_clean;
+                stats[subHeap].swappedOut += swapped_out;
             }
         }
     }
@@ -428,6 +446,7 @@
         stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty;
         stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean;
         stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean;
+        stats[HEAP_UNKNOWN].swappedOut += stats[i].swappedOut;
     }
 
     for (int i=0; i<_NUM_CORE_HEAP; i++) {
@@ -437,6 +456,7 @@
         env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty);
         env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean);
         env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean);
+        env->SetIntField(object, stat_fields[i].swappedOut_field, stats[i].swappedOut);
     }
 
 
@@ -455,6 +475,7 @@
         otherArray[j++] = stats[i].sharedDirty;
         otherArray[j++] = stats[i].privateClean;
         otherArray[j++] = stats[i].sharedClean;
+        otherArray[j++] = stats[i].swappedOut;
     }
 
     env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0);
@@ -971,6 +992,8 @@
                 env->GetFieldID(clazz, stat_field_names[i].privateClean_name, "I");
         stat_fields[i].sharedClean_field =
                 env->GetFieldID(clazz, stat_field_names[i].sharedClean_name, "I");
+        stat_fields[i].swappedOut_field =
+                env->GetFieldID(clazz, stat_field_names[i].swappedOut_name, "I");
     }
 
     return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods));
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 275afb8..c3dc4ff 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2182,6 +2182,9 @@
             <enum name="yes" value="1" />
             <!-- The view is not important for accessibility. -->
             <enum name="no" value="2" />
+            <!-- The view is not important for accessibility, nor are any of its descendant
+                 views. -->
+            <enum name="noHideDescendants" value="4" />
         </attr>
 
         <!-- Indicates to accessibility services whether the user should be notified when
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index ef7f2b7..431fe82 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2054,29 +2054,29 @@
   <public type="style" name="Theme.DeviceDefault.Light.NoActionBar.Overscan" id="0x010301e0" />
 
 <!-- ===============================================================
-    Resources added in version 19 of the platform
+    Resources added in version 19 of the platform (KitKat)
     =============================================================== -->
   <eat-comment />
 
-  <public type="attr" name="keySet" />
-  <public type="attr" name="targetId" />
-  <public type="attr" name="fromScene" />
-  <public type="attr" name="toScene" />
-  <public type="attr" name="transition" />
-  <public type="attr" name="transitionOrdering" />
-  <public type="attr" name="fadingMode" />
-  <public type="attr" name="startDelay" />
-  <public type="attr" name="ssp" />
-  <public type="attr" name="sspPrefix" />
-  <public type="attr" name="sspPattern" />
-  <public type="attr" name="addPrintersActivity" />
-  <public type="attr" name="vendor" />
-  <public type="attr" name="category" />
-  <public type="attr" name="isAsciiCapable" />
-  <public type="attr" name="autoMirrored" />
-  <public type="attr" name="supportsSwitchingToNextInputMethod" />
-  <public type="attr" name="requireDeviceUnlock" />
-  <public type="attr" name="apduServiceBanner" />
-  <public type="attr" name="accessibilityLiveRegion" />
+  <public type="attr" name="keySet" id="0x010103db" />
+  <public type="attr" name="targetId" id="0x010103dc" />
+  <public type="attr" name="fromScene" id="0x010103dd" />
+  <public type="attr" name="toScene" id="0x010103de" />
+  <public type="attr" name="transition" id="0x010103df" />
+  <public type="attr" name="transitionOrdering" id="0x010103e0" />
+  <public type="attr" name="fadingMode" id="0x010103e1" />
+  <public type="attr" name="startDelay" id="0x010103e2" />
+  <public type="attr" name="ssp" id="0x010103e3" />
+  <public type="attr" name="sspPrefix" id="0x010103e4" />
+  <public type="attr" name="sspPattern" id="0x010103e5" />
+  <public type="attr" name="addPrintersActivity" id="0x010103e6" />
+  <public type="attr" name="vendor" id="0x010103e7" />
+  <public type="attr" name="category" id="0x010103e8" />
+  <public type="attr" name="isAsciiCapable" id="0x010103e9" />
+  <public type="attr" name="autoMirrored" id="0x010103ea" />
+  <public type="attr" name="supportsSwitchingToNextInputMethod" id="0x010103eb" />
+  <public type="attr" name="requireDeviceUnlock" id="0x010103ec" />
+  <public type="attr" name="apduServiceBanner" id="0x010103ed" />
+  <public type="attr" name="accessibilityLiveRegion" id="0x010103ee" />
 
 </resources>
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index 1b7faec..d157478 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -152,11 +152,20 @@
     static class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
 
         @Override
-        public void notifyCallback(int msgType, int ext1, int ext2) throws RemoteException {
+        public void onCameraError(int errorCode) {
         }
 
         @Override
-        public void onResultReceived(int frameId, CameraMetadataNative result) throws RemoteException {
+        public void onCameraIdle() {
+        }
+
+        @Override
+        public void onCaptureStarted(int requestId, long timestamp) {
+        }
+
+        @Override
+        public void onResultReceived(int frameId, CameraMetadataNative result)
+                throws RemoteException {
         }
     }
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 13ce52e..43ebef4 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -30,6 +30,7 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
@@ -40,6 +41,7 @@
 import com.android.mediaframeworktest.MediaFrameworkIntegrationTestRunner;
 
 import org.mockito.ArgumentMatcher;
+import org.mockito.ArgumentCaptor;
 import static org.mockito.Mockito.*;
 
 public class CameraDeviceBinderTest extends AndroidTestCase {
@@ -48,6 +50,12 @@
     private static int NUM_CALLBACKS_CHECKED = 10;
     // Wait for capture result timeout value: 1500ms
     private final static int WAIT_FOR_COMPLETE_TIMEOUT_MS = 1500;
+    // Wait for flush timeout value: 1000ms
+    private final static int WAIT_FOR_FLUSH_TIMEOUT_MS = 1000;
+    // Wait for idle timeout value: 2000ms
+    private final static int WAIT_FOR_IDLE_TIMEOUT_MS = 2000;
+    // Wait while camera device starts working on requests
+    private final static int WAIT_FOR_WORK_MS = 300;
     // Default size is VGA, which is mandatory camera supported image size by CDD.
     private static final int DEFAULT_IMAGE_WIDTH = 640;
     private static final int DEFAULT_IMAGE_HEIGHT = 480;
@@ -77,11 +85,19 @@
     public class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
 
         @Override
-        public void notifyCallback(int msgType, int ext1, int ext2) throws RemoteException {
+        public void onCameraError(int errorCode) {
         }
 
         @Override
-        public void onResultReceived(int frameId, CameraMetadataNative result) throws RemoteException {
+        public void onCameraIdle() {
+        }
+
+        @Override
+        public void onCaptureStarted(int requestId, long timestamp) {
+        }
+
+        @Override
+        public void onResultReceived(int frameId, CameraMetadataNative result) {
         }
     }
 
@@ -90,7 +106,7 @@
         public boolean matches(Object obj) {
             return !((CameraMetadataNative) obj).isEmpty();
         }
-     }
+    }
 
     private void createDefaultSurface() {
         mImageReader =
@@ -346,6 +362,60 @@
     }
 
     @SmallTest
+    public void testCaptureStartedCallbacks() throws Exception {
+        CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
+
+        ArgumentCaptor<Long> timestamps = ArgumentCaptor.forClass(Long.class);
+
+        // Test both single request and streaming request.
+        int requestId1 = submitCameraRequest(request, /* streaming */false);
+        verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).times(1)).onCaptureStarted(
+                eq(requestId1),
+                anyLong());
+
+        int streamingId = submitCameraRequest(request, /* streaming */true);
+        verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).atLeast(NUM_CALLBACKS_CHECKED))
+                .onCaptureStarted(
+                        eq(streamingId),
+                        timestamps.capture());
+
+        long timestamp = 0; // All timestamps should be larger than 0.
+        for (Long nextTimestamp : timestamps.getAllValues()) {
+            Log.v(TAG, "next t: " + nextTimestamp + " current t: " + timestamp);
+            assertTrue("Captures are out of order", timestamp < nextTimestamp);
+            timestamp = nextTimestamp;
+        }
+    }
+
+    @SmallTest
+    public void testIdleCallback() throws Exception {
+        int status;
+        CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
+
+        // Try streaming
+        int streamingId = submitCameraRequest(request, /* streaming */true);
+
+        // Wait a bit to fill up the queue
+        SystemClock.sleep(WAIT_FOR_WORK_MS);
+
+        // Cancel and make sure we eventually quiesce
+        status = mCameraUser.cancelRequest(streamingId);
+
+        verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(1)).onCameraIdle();
+
+        // Submit a few capture requests
+        int requestId1 = submitCameraRequest(request, /* streaming */false);
+        int requestId2 = submitCameraRequest(request, /* streaming */false);
+        int requestId3 = submitCameraRequest(request, /* streaming */false);
+        int requestId4 = submitCameraRequest(request, /* streaming */false);
+        int requestId5 = submitCameraRequest(request, /* streaming */false);
+
+        // And wait for more idle
+        verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(2)).onCameraIdle();
+
+    }
+
+    @SmallTest
     public void testFlush() throws Exception {
         int status;
 
@@ -367,10 +437,24 @@
         int requestId4 = submitCameraRequest(request, /* streaming */false);
         int requestId5 = submitCameraRequest(request, /* streaming */false);
 
-        // Then flush
+        // Then flush and wait for idle
         status = mCameraUser.flush();
         assertEquals(CameraBinderTestUtils.NO_ERROR, status);
 
+        verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(1)).onCameraIdle();
+
+        // Now a streaming request
+        int streamingId = submitCameraRequest(request, /* streaming */true);
+
+        // Wait a bit to fill up the queue
+        SystemClock.sleep(WAIT_FOR_WORK_MS);
+
+        // Then flush and wait for the idle callback
+        status = mCameraUser.flush();
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+
+        verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(2)).onCameraIdle();
+
         // TODO: When errors are hooked up, count that errors + successful
         // requests equal to 5.
     }
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_alarm_small.png b/packages/Keyguard/res/drawable-hdpi/ic_alarm_small.png
new file mode 100644
index 0000000..3819029
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_alarm_small.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_alarm.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_alarm.png
deleted file mode 100644
index d7a8cfc..0000000
--- a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_alarm.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_alarm_small.png b/packages/Keyguard/res/drawable-mdpi/ic_alarm_small.png
new file mode 100644
index 0000000..2aeedaf
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_alarm_small.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_alarm.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_alarm.png
deleted file mode 100644
index 330ade1..0000000
--- a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_alarm.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_alarm_small.png b/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_alarm_small.png
new file mode 100644
index 0000000..e28b3f6
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_alarm_small.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_alarm_small.png b/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_alarm_small.png
new file mode 100644
index 0000000..f727d01
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_alarm_small.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_alarm_small.png b/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_alarm_small.png
new file mode 100644
index 0000000..d9c0623
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_alarm_small.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-xxhdpi/ic_alarm_small.png b/packages/Keyguard/res/drawable-sw600dp-xxhdpi/ic_alarm_small.png
new file mode 100644
index 0000000..a36bf1f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-xxhdpi/ic_alarm_small.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_alarm_small.png b/packages/Keyguard/res/drawable-xhdpi/ic_alarm_small.png
new file mode 100644
index 0000000..0290bdc
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_alarm_small.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_alarm.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_alarm.png
deleted file mode 100644
index e6cceef..0000000
--- a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_alarm.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/ic_alarm_small.png b/packages/Keyguard/res/drawable-xxhdpi/ic_alarm_small.png
new file mode 100644
index 0000000..66968e8
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/ic_alarm_small.png
Binary files differ
diff --git a/packages/Keyguard/res/layout-land/keyguard_status_area.xml b/packages/Keyguard/res/layout-land/keyguard_status_area.xml
deleted file mode 100644
index d450c5c..0000000
--- a/packages/Keyguard/res/layout-land/keyguard_status_area.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- This is a view that shows general status information in Keyguard. -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_status_area"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_gravity="end"
-    android:layout_marginTop="-16dp"
-    android:orientation="vertical">
-
-    <TextView
-        android:id="@+id/date"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="end"
-        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textSize="@dimen/kg_status_date_font_size"
-        android:textAllCaps="@bool/kg_use_all_caps"
-        />
-
-    <TextView
-        android:id="@+id/alarm_status"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="end"
-        android:layout_marginTop="28dp"
-        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:textAppearance="?android:attr/textAppearance"
-        android:textSize="@dimen/kg_status_line_font_size"
-        android:drawablePadding="4dip"
-        android:textAllCaps="@bool/kg_use_all_caps"
-        />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/Keyguard/res/layout-port/keyguard_status_area.xml b/packages/Keyguard/res/layout-port/keyguard_status_area.xml
deleted file mode 100644
index af0d2e8..0000000
--- a/packages/Keyguard/res/layout-port/keyguard_status_area.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- This is a view that shows general status information in Keyguard. -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_status_area"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_gravity="right"
-    android:orientation="vertical">
-
-    <LinearLayout
-        android:orientation="horizontal"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="0dp"
-        android:layout_gravity="right">
-        <TextView
-            android:id="@+id/date"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="@dimen/kg_status_date_font_size"
-            android:textAllCaps="@bool/kg_use_all_caps"
-            />
-
-        <TextView
-            android:id="@+id/alarm_status"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:textAppearance="?android:attr/textAppearance"
-            android:textSize="@dimen/kg_status_line_font_size"
-            android:drawablePadding="4dip"
-            android:textAllCaps="@bool/kg_use_all_caps"
-            />
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/packages/Keyguard/res/layout/keyguard_status_area.xml b/packages/Keyguard/res/layout/keyguard_status_area.xml
new file mode 100644
index 0000000..d1f3873
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_status_area.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:gravity="center">
+    <TextClock android:id="@+id/date_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textColor="@color/clock_white"
+        android:format12Hour="@string/abbrev_wday_month_day_no_year"
+        android:format24Hour="@string/abbrev_wday_month_day_no_year"
+        style="@style/widget_label"
+        android:gravity="center"
+        />
+    <TextView android:id="@+id/alarm_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:drawablePadding="2dip"
+        android:drawableLeft="@drawable/ic_alarm_small"
+        android:drawableStart="@drawable/ic_alarm_small"
+        android:textColor="@color/clock_gray"
+        style="@style/widget_label"
+        android:layout_marginLeft="8dip"
+        android:layout_marginStart="8dip"
+        android:gravity="center"
+        android:visibility="gone"
+        />
+</LinearLayout>
diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml
index 2304d9f..5857fc2 100644
--- a/packages/Keyguard/res/layout/keyguard_status_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_status_view.xml
@@ -35,34 +35,26 @@
         android:layout_height="match_parent"
         android:gravity="center_horizontal|top"
         android:contentDescription="@string/keyguard_accessibility_status">
-
-        <LinearLayout android:layout_width="match_parent"
-                      android:layout_height="wrap_content"
-                      android:layout_gravity="center_horizontal|top"
-                      android:orientation="vertical"
-                      android:focusable="true">
-            <com.android.keyguard.ClockView
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal|top"
+            android:orientation="vertical"
+            android:focusable="true">
+            <TextClock
                 android:id="@+id/clock_view"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-                android:layout_gravity="right">
-
-                <TextView android:id="@+id/clock_text"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:singleLine="true"
-                          android:ellipsize="none"
-                          android:textSize="@dimen/kg_status_clock_font_size"
-                          android:textAppearance="?android:attr/textAppearanceMedium"
-                          android:textColor="#ffffffff"
-                          android:drawablePadding="2dip"
-                          />
-
-            </com.android.keyguard.ClockView>
+                android:layout_gravity="center_horizontal|top"
+                android:textColor="@color/clock_white"
+                android:singleLine="true"
+                style="@style/widget_big_thin"
+                android:format12Hour="@string/keyguard_widget_12_hours_format"
+                android:format24Hour="@string/keyguard_widget_24_hours_format"
+                android:baselineAligned="true"
+                android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
 
             <include layout="@layout/keyguard_status_area" />
         </LinearLayout>
-
     </com.android.keyguard.KeyguardStatusView>
 </com.android.keyguard.KeyguardWidgetFrame>
diff --git a/packages/Keyguard/res/layout/keyguard_widget_remove_drop_target.xml b/packages/Keyguard/res/layout/keyguard_widget_remove_drop_target.xml
index 294c386..58b5b27 100644
--- a/packages/Keyguard/res/layout/keyguard_widget_remove_drop_target.xml
+++ b/packages/Keyguard/res/layout/keyguard_widget_remove_drop_target.xml
@@ -26,7 +26,7 @@
     android:drawablePadding="4dp"
     android:text="@string/kg_reordering_delete_drop_target_text"
     android:textColor="#FFF"
-    android:textSize="13sp"
+    android:textSize="12dp"
     android:shadowColor="#000"
     android:shadowDy="1.0"
     android:shadowRadius="1.0"
diff --git a/packages/Keyguard/res/values-land/dimens.xml b/packages/Keyguard/res/values-land/dimens.xml
index 64e043c..bf30332 100644
--- a/packages/Keyguard/res/values-land/dimens.xml
+++ b/packages/Keyguard/res/values-land/dimens.xml
@@ -19,17 +19,6 @@
 -->
 
 <resources>
-    <!-- Default height of a key in the password keyboard for alpha -->
-    <dimen name="password_keyboard_key_height_alpha">47dip</dimen>
-    <!-- Default height of a key in the password keyboard for numeric -->
-    <dimen name="password_keyboard_key_height_numeric">50dip</dimen>
-    <!-- Default correction for the space key in the password keyboard -->
-    <dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
-    <dimen name="preference_widget_width">72dp</dimen>
-
-    <!-- Size of clock font in LockScreen on Unsecure unlock screen. -->
-    <dimen name="keyguard_lockscreen_clock_font_size">70sp</dimen>
-
     <!-- Shift emergency button from the left edge by this amount.  Used by landscape layout on
          phones -->
     <dimen name="kg_emergency_button_shift">30dp</dimen>
diff --git a/packages/Keyguard/res/values-large/dimens.xml b/packages/Keyguard/res/values-large/dimens.xml
index 8cd614d..0b5d4ad 100644
--- a/packages/Keyguard/res/values-large/dimens.xml
+++ b/packages/Keyguard/res/values-large/dimens.xml
@@ -17,13 +17,6 @@
 */
 -->
 <resources>
-    <!-- Default height of a key in the password keyboard for alpha -->
-    <dimen name="password_keyboard_key_height_alpha">75dip</dimen>
-    <!-- Default height of a key in the password keyboard for numeric -->
-    <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
-    <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
-    <dimen name="password_keyboard_height">48.0mm</dimen>
-
     <!-- Minimum width of the search view text entry area. -->
     <dimen name="search_view_text_min_width">192dip</dimen>
 
diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml
index c0e3937..f8a1362 100644
--- a/packages/Keyguard/res/values-sw600dp/dimens.xml
+++ b/packages/Keyguard/res/values-sw600dp/dimens.xml
@@ -18,9 +18,6 @@
 */
 -->
 <resources>
-    <!-- Size of clock font in LockScreen. -->
-    <dimen name="keyguard_pattern_unlock_clock_font_size">112sp</dimen>
-
     <!-- Size of lockscreen outerring on unsecure unlock LockScreen -->
     <dimen name="keyguard_lockscreen_outerring_diameter">364dp</dimen>
 
@@ -37,9 +34,6 @@
     <!-- Size of the clock font in keyguard's status view -->
     <dimen name="kg_status_clock_font_size">141dp</dimen>
 
-    <!-- Size of the date font in keyguard's status view  -->
-    <dimen name="kg_status_date_font_size">25.5dp</dimen>
-
     <!-- Size of the generic status lines keyguard's status view  -->
     <dimen name="kg_status_line_font_size">16sp</dimen>
 
@@ -68,4 +62,8 @@
     <!-- Margin around the various security views -->
     <dimen name="keyguard_muliuser_selector_margin">12dp</dimen>
 
+    <!-- Overload default clock widget parameters -->
+    <dimen name="widget_label_font_size">16dp</dimen>
+    <dimen name="widget_big_font_size">141dp</dimen>
+
 </resources>
diff --git a/packages/Keyguard/res/values-sw720dp/dimens.xml b/packages/Keyguard/res/values-sw720dp/dimens.xml
index b29ac22..0790b79 100644
--- a/packages/Keyguard/res/values-sw720dp/dimens.xml
+++ b/packages/Keyguard/res/values-sw720dp/dimens.xml
@@ -21,9 +21,6 @@
     <!-- Size of the clock font in keyguard's status view -->
     <dimen name="kg_status_clock_font_size">188dp</dimen>
 
-    <!-- Size of the date font in keyguard's status view  -->
-    <dimen name="kg_status_date_font_size">34dp</dimen>
-
     <!-- Size of the generic status lines keyguard's status view  -->
     <dimen name="kg_status_line_font_size">19sp</dimen>
 
diff --git a/packages/Keyguard/res/values-xlarge/dimens.xml b/packages/Keyguard/res/values-xlarge/dimens.xml
deleted file mode 100644
index b8cf287..0000000
--- a/packages/Keyguard/res/values-xlarge/dimens.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/dimens.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources>
-    <!-- Default height of a key in the password keyboard for alpha -->
-    <dimen name="password_keyboard_key_height_alpha">75dip</dimen>
-    <!-- Default height of a key in the password keyboard for numeric -->
-    <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
-    <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
-    <dimen name="password_keyboard_height">48.0mm</dimen>
-</resources>
diff --git a/packages/Keyguard/res/values/alias.xml b/packages/Keyguard/res/values/alias.xml
index c964391..b22311e 100644
--- a/packages/Keyguard/res/values/alias.xml
+++ b/packages/Keyguard/res/values/alias.xml
@@ -34,9 +34,6 @@
     <!-- Alias used to reference framework drawable in keyguard. -->
     <item type="drawable" name="ic_contact_picture">@*android:drawable/ic_contact_picture</item>
 
-    <!-- Alias used to reference framework drawable in keyguard. -->
-    <item type="drawable" name="ic_lock_idle_alarm">@*android:drawable/ic_lock_idle_alarm</item>
-
     <!-- Alias used to reference framework "OK" string in keyguard.  -->
     <item type="string" name="ok">@*android:string/ok</item>
 
@@ -52,4 +49,4 @@
     <!-- Alias used to reference framework activity duration.  -->
     <item type="integer" name="config_activityDefaultDur">@*android:integer/config_activityDefaultDur</item>
 
-</resources>
\ No newline at end of file
+</resources>
diff --git a/packages/Keyguard/res/values/colors.xml b/packages/Keyguard/res/values/colors.xml
index 0c56a43..a9e8061 100644
--- a/packages/Keyguard/res/values/colors.xml
+++ b/packages/Keyguard/res/values/colors.xml
@@ -23,4 +23,8 @@
 
     <!-- FaceLock -->
     <color name="facelock_spotlight_mask">#CC000000</color>
+
+    <!-- Clock -->
+    <color name="clock_white">#ffffffff</color>
+    <color name="clock_gray">#80ffffff</color>
 </resources>
diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml
index ce72f43..8039b09 100644
--- a/packages/Keyguard/res/values/dimens.xml
+++ b/packages/Keyguard/res/values/dimens.xml
@@ -18,17 +18,6 @@
 */
 -->
 <resources>
-    <!-- Default height of a key in the password keyboard for alpha (used by keyguard) -->
-    <dimen name="password_keyboard_key_height_alpha">56dip</dimen>
-    <!-- Default height of a key in the password keyboard for numeric (used by keyguard) -->
-    <dimen name="password_keyboard_key_height_numeric">56dip</dimen>
-    <!-- Default correction for the space key in the password keyboard  (used by keyguard) -->
-    <dimen name="password_keyboard_spacebar_vertical_correction">4dip</dimen>
-    <!-- Default horizontal gap between keys in the password keyboard (used by keyguard) -->
-    <dimen name="password_keyboard_horizontalGap">3dip</dimen>
-    <!-- Default vertical gap between keys in the password keyboard (used by keyguard) -->
-    <dimen name="password_keyboard_verticalGap">9dip</dimen>
-
     <!-- Size of lockscreen outerring on unsecure unlock LockScreen -->
     <dimen name="keyguard_lockscreen_outerring_diameter">270dp</dimen>
 
@@ -47,9 +36,6 @@
     <!-- Default distance from each snap target that GlowPadView considers a "hit" -->
     <dimen name="glowpadview_inner_radius">15dip</dimen>
 
-    <!-- Size of clock font in LockScreen on Unsecure unlock screen. -->
-    <dimen name="keyguard_lockscreen_clock_font_size">80dip</dimen>
-
     <!-- Size of status line font on Unsecure unlock LockScreen. -->
     <dimen name="keyguard_lockscreen_status_line_font_size">14dip</dimen>
 
@@ -84,11 +70,8 @@
     <!-- Size of the clock font in keyguard's status view -->
     <dimen name="kg_status_clock_font_size">75dp</dimen>
 
-    <!-- Size of the date font in keyguard's status view  -->
-    <dimen name="kg_status_date_font_size">15dp</dimen>
-
     <!-- Size of the generic status lines keyguard's status view  -->
-    <dimen name="kg_status_line_font_size">13dp</dimen>
+    <dimen name="kg_status_line_font_size">12dp</dimen>
 
     <!-- Size of margin on the right of keyguard's status view -->
     <dimen name="kg_status_line_font_right_margin">16dp</dimen>
@@ -166,5 +149,12 @@
     used on tablets; on phones, this size is determined by the space left by the
     security mode. -->
     <dimen name="kg_small_widget_height">160dp</dimen>
+    
+    <!-- Default clock parameters -->
+    <dimen name="bottom_text_spacing_digital">-8dp</dimen>
+    <dimen name="label_font_size">14dp</dimen>
+    <dimen name="widget_label_font_size">12dp</dimen>
+    <dimen name="widget_big_font_size">80dp</dimen>
+    <dimen name="big_font_size">120dp</dimen>
 
 </resources>
diff --git a/packages/Keyguard/res/values/donottranslate.xml b/packages/Keyguard/res/values/donottranslate.xml
new file mode 100644
index 0000000..71d3ed7
--- /dev/null
+++ b/packages/Keyguard/res/values/donottranslate.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- String matching the lock screen format for displaying the date. -->
+    <string name="abbrev_wday_month_day_no_year">EEE, MMMM d</string>
+    <!-- Format for describing the date, for accessibility. -->
+    <string name="full_wday_month_day_no_year">EEEE, MMMM d</string>
+</resources>
diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml
index 11f2e54..abc4483 100644
--- a/packages/Keyguard/res/values/strings.xml
+++ b/packages/Keyguard/res/values/strings.xml
@@ -94,6 +94,10 @@
          progress dialog in the meantime.  this is the emssage. -->
     <string name="keyguard_sim_unlock_progress_dialog_message">Unlocking SIM card\u2026</string>
 
+    <!-- Time format strings for fall-back clock widget -->
+    <string name="keyguard_widget_12_hours_format" translatable="false">h&#58;mm</string>
+    <!-- Time format strings for fall-back clock widget -->
+    <string name="keyguard_widget_24_hours_format" translatable="false">kk&#58;mm</string>
 
     <!-- Accessibility description sent when user changes the current lock screen widget. [CHAR_LIMIT=none] -->
     <string name="keyguard_accessibility_widget_changed">%1$s. Widget %2$d of %3$d.</string>
diff --git a/packages/Keyguard/res/values/styles.xml b/packages/Keyguard/res/values/styles.xml
index a31f708..44f560f 100644
--- a/packages/Keyguard/res/values/styles.xml
+++ b/packages/Keyguard/res/values/styles.xml
@@ -52,5 +52,20 @@
         <item name="android:windowEnterAnimation">@anim/lock_screen_enter</item>
         <item name="android:windowExitAnimation">@anim/lock_screen_exit</item>
     </style>
+    
+    <!-- Built-in clock widget stuff -->
+    <style name="widget_label">
+        <item name="android:textStyle">bold</item>
+        <item name="android:textAllCaps">true</item>
+        <item name="android:fontFamily">sans-serif-condensed</item>
+        <item name="android:textSize">@dimen/kg_status_line_font_size</item>
+    </style>
+    <style name="big_thin">
+        <item name="android:textSize">@dimen/big_font_size</item>
+        <item name="android:fontFamily">sans-serif-thin</item>
+    </style>
+    <style name="widget_big_thin" parent="big_thin">
+        <item name="android:textSize">@dimen/widget_big_font_size</item>
+    </style>
 
 </resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/ClockView.java b/packages/Keyguard/src/com/android/keyguard/ClockView.java
deleted file mode 100644
index ad85e9a..0000000
--- a/packages/Keyguard/src/com/android/keyguard/ClockView.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.keyguard;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.graphics.Typeface;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.text.format.DateFormat;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import java.lang.ref.WeakReference;
-import java.text.DateFormatSymbols;
-import java.util.Calendar;
-
-/**
- * Displays the time
- */
-public class ClockView extends RelativeLayout {
-    private static final String ANDROID_CLOCK_FONT_FILE = "/system/fonts/AndroidClock.ttf";
-    private final static String M12 = "h:mm";
-    private final static String M24 = "HH:mm";
-
-    private Calendar mCalendar;
-    private String mFormat;
-    private TextView mTimeView;
-    private AmPm mAmPm;
-    private ContentObserver mFormatChangeObserver;
-    private int mAttached = 0; // for debugging - tells us whether attach/detach is unbalanced
-
-    /* called by system on minute ticks */
-    private final Handler mHandler = new Handler();
-    private BroadcastReceiver mIntentReceiver;
-
-    private static class TimeChangedReceiver extends BroadcastReceiver {
-        private WeakReference<ClockView> mClock;
-        private Context mContext;
-
-        public TimeChangedReceiver(ClockView clock) {
-            mClock = new WeakReference<ClockView>(clock);
-            mContext = clock.getContext();
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            // Post a runnable to avoid blocking the broadcast.
-            final boolean timezoneChanged =
-                    intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED);
-            final ClockView clock = mClock.get();
-            if (clock != null) {
-                clock.mHandler.post(new Runnable() {
-                    public void run() {
-                        if (timezoneChanged) {
-                            clock.mCalendar = Calendar.getInstance();
-                        }
-                        clock.updateTime();
-                    }
-                });
-            } else {
-                try {
-                    mContext.unregisterReceiver(this);
-                } catch (RuntimeException e) {
-                    // Shouldn't happen
-                }
-            }
-        }
-    };
-
-    static class AmPm {
-        private TextView mAmPmTextView;
-        private String mAmString, mPmString;
-
-        AmPm(View parent, Typeface tf) {
-            // No longer used, uncomment if we decide to use AM/PM indicator again
-            // mAmPmTextView = (TextView) parent.findViewById(R.id.am_pm);
-            if (mAmPmTextView != null && tf != null) {
-                mAmPmTextView.setTypeface(tf);
-            }
-
-            String[] ampm = new DateFormatSymbols().getAmPmStrings();
-            mAmString = ampm[0];
-            mPmString = ampm[1];
-        }
-
-        void setShowAmPm(boolean show) {
-            if (mAmPmTextView != null) {
-                mAmPmTextView.setVisibility(show ? View.VISIBLE : View.GONE);
-            }
-        }
-
-        void setIsMorning(boolean isMorning) {
-            if (mAmPmTextView != null) {
-                mAmPmTextView.setText(isMorning ? mAmString : mPmString);
-            }
-        }
-    }
-
-    private static class FormatChangeObserver extends ContentObserver {
-        private WeakReference<ClockView> mClock;
-        private Context mContext;
-        public FormatChangeObserver(ClockView clock) {
-            super(new Handler());
-            mClock = new WeakReference<ClockView>(clock);
-            mContext = clock.getContext();
-        }
-        @Override
-        public void onChange(boolean selfChange) {
-            ClockView digitalClock = mClock.get();
-            if (digitalClock != null) {
-                digitalClock.setDateFormat();
-                digitalClock.updateTime();
-            } else {
-                try {
-                    mContext.getContentResolver().unregisterContentObserver(this);
-                } catch (RuntimeException e) {
-                    // Shouldn't happen
-                }
-            }
-        }
-    }
-
-    public ClockView(Context context) {
-        this(context, null);
-    }
-
-    public ClockView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mTimeView = (TextView) findViewById(R.id.clock_text);
-        mTimeView.setTypeface(Typeface.createFromFile(ANDROID_CLOCK_FONT_FILE));
-        mAmPm = new AmPm(this, null);
-        mCalendar = Calendar.getInstance();
-        setDateFormat();
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        mAttached++;
-
-        /* monitor time ticks, time changed, timezone */
-        if (mIntentReceiver == null) {
-            mIntentReceiver = new TimeChangedReceiver(this);
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(Intent.ACTION_TIME_TICK);
-            filter.addAction(Intent.ACTION_TIME_CHANGED);
-            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
-            mContext.registerReceiverAsUser(mIntentReceiver, UserHandle.OWNER, filter, null, null );
-        }
-
-        /* monitor 12/24-hour display preference */
-        if (mFormatChangeObserver == null) {
-            mFormatChangeObserver = new FormatChangeObserver(this);
-            mContext.getContentResolver().registerContentObserver(
-                    Settings.System.CONTENT_URI, true, mFormatChangeObserver);
-        }
-
-        updateTime();
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-
-        mAttached--;
-
-        if (mIntentReceiver != null) {
-            mContext.unregisterReceiver(mIntentReceiver);
-        }
-        if (mFormatChangeObserver != null) {
-            mContext.getContentResolver().unregisterContentObserver(
-                    mFormatChangeObserver);
-        }
-
-        mFormatChangeObserver = null;
-        mIntentReceiver = null;
-    }
-
-    void updateTime(Calendar c) {
-        mCalendar = c;
-        updateTime();
-    }
-
-    public void updateTime() {
-        mCalendar.setTimeInMillis(System.currentTimeMillis());
-
-        CharSequence newTime = DateFormat.format(mFormat, mCalendar);
-        mTimeView.setText(newTime);
-        mAmPm.setIsMorning(mCalendar.get(Calendar.AM_PM) == 0);
-    }
-
-    private void setDateFormat() {
-        mFormat = android.text.format.DateFormat.is24HourFormat(getContext()) ? M24 : M12;
-        mAmPm.setShowAmPm(mFormat.equals(M12));
-    }
-}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index 0289a1f..ffb619b 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -38,17 +38,9 @@
     private static final boolean DEBUG = KeyguardViewMediator.DEBUG;
     private static final String TAG = "KeyguardStatusView";
 
-    public static final int LOCK_ICON = 0; // R.drawable.ic_lock_idle_lock;
-    public static final int ALARM_ICON = R.drawable.ic_lock_idle_alarm;
-    public static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
-    public static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
-
-    private SimpleDateFormat mDateFormat;
     private LockPatternUtils mLockPatternUtils;
 
-    private TextView mDateView;
     private TextView mAlarmStatusView;
-    private ClockView mClockView;
 
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
 
@@ -81,21 +73,12 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        Resources res = getContext().getResources();
-        final Locale locale = Locale.getDefault();
-        final String datePattern = res.getString(R.string.system_ui_date_pattern);
-        final String bestFormat = ICU.getBestDateTimePattern(datePattern, locale.toString());
-        mDateFormat = new SimpleDateFormat(bestFormat, locale);
-        mDateView = (TextView) findViewById(R.id.date);
+
         mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);
-        mClockView = (ClockView) findViewById(R.id.clock_view);
         mLockPatternUtils = new LockPatternUtils(getContext());
 
-        // Use custom font in mDateView
-        mDateView.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
-
         // Required to get Marquee to work.
-        final View marqueeViews[] = { mDateView, mAlarmStatusView };
+        final View marqueeViews[] = { mAlarmStatusView };
         for (int i = 0; i < marqueeViews.length; i++) {
             View v = marqueeViews[i];
             if (v == null) {
@@ -107,8 +90,6 @@
     }
 
     protected void refresh() {
-        mClockView.updateTime();
-        refreshDate();
         refreshAlarmStatus(); // might as well
     }
 
@@ -117,17 +98,12 @@
         String nextAlarm = mLockPatternUtils.getNextAlarm();
         if (!TextUtils.isEmpty(nextAlarm)) {
             mAlarmStatusView.setText(nextAlarm);
-            mAlarmStatusView.setCompoundDrawablesWithIntrinsicBounds(ALARM_ICON, 0, 0, 0);
             mAlarmStatusView.setVisibility(View.VISIBLE);
         } else {
             mAlarmStatusView.setVisibility(View.GONE);
         }
     }
 
-    void refreshDate() {
-        mDateView.setText(mDateFormat.format(new Date()));
-    }
-
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 6ab86f5..59ec777 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -2145,6 +2145,10 @@
             return -1;
         }
 
+        if (!appPath.endsWith("/")) {
+            appPath = appPath + "/";
+        }
+
         // Try translating the app path into a vold path, but require that it
         // belong to the calling package.
         String voldPath = maybeTranslatePathForVold(appPath,
@@ -2194,9 +2198,9 @@
         }
 
         for (int i = 0; i < appPaths.length; i++) {
-            final String appPath = appPaths[i].getAbsolutePath();
+            final String appPath = appPaths[i].getAbsolutePath() + "/";
             if (path.startsWith(appPath)) {
-                path = new File(voldPaths[i], path.substring(appPath.length() + 1))
+                path = new File(voldPaths[i], path.substring(appPath.length()))
                         .getAbsolutePath();
                 if (!path.endsWith("/")) {
                     path = path + "/";
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 162add4..6957bac0 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -219,6 +219,8 @@
         WallpaperData mWallpaper;
         IRemoteCallback mReply;
 
+        boolean mDimensionsChanged = false;
+
         public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) {
             mInfo = info;
             mWallpaper = wallpaper;
@@ -262,6 +264,14 @@
         public void attachEngine(IWallpaperEngine engine) {
             synchronized (mLock) {
                 mEngine = engine;
+                if (mDimensionsChanged) {
+                    try {
+                        mEngine.setDesiredSize(mWallpaper.width, mWallpaper.height);
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, "Failed to set wallpaper dimensions", e);
+                    }
+                    mDimensionsChanged = false;
+                }
             }
         }
 
@@ -652,6 +662,11 @@
                         } catch (RemoteException e) {
                         }
                         notifyCallbacksLocked(wallpaper);
+                    } else if (wallpaper.connection.mService != null) {
+                        // We've attached to the service but the engine hasn't attached back to us
+                        // yet. This means it will be created with the previous dimensions, so we
+                        // need to update it to the new dimensions once it attaches.
+                        wallpaper.connection.mDimensionsChanged = true;
                     }
                 }
             }
diff --git a/services/java/com/android/server/wifi/WifiController.java b/services/java/com/android/server/wifi/WifiController.java
index 87b4394..a3d514e 100644
--- a/services/java/com/android/server/wifi/WifiController.java
+++ b/services/java/com/android/server/wifi/WifiController.java
@@ -57,6 +57,7 @@
     private int mStayAwakeConditions;
     private long mIdleMillis;
     private int mSleepPolicy;
+    private boolean mFirstUserSignOnSeen = false;
 
     private AlarmManager mAlarmManager;
     private PendingIntent mIdleIntent;
@@ -113,6 +114,7 @@
     static final int CMD_AIRPLANE_TOGGLED           = BASE + 9;
     static final int CMD_SET_AP                     = BASE + 10;
     static final int CMD_DEFERRED_TOGGLE            = BASE + 11;
+    static final int CMD_USER_PRESENT               = BASE + 12;
 
     private DefaultState mDefaultState = new DefaultState();
     private StaEnabledState mStaEnabledState = new StaEnabledState();
@@ -361,6 +363,9 @@
                 case CMD_AIRPLANE_TOGGLED:
                 case CMD_EMERGENCY_MODE_CHANGED:
                     break;
+                case CMD_USER_PRESENT:
+                    mFirstUserSignOnSeen = true;
+                    break;
                 case CMD_DEFERRED_TOGGLE:
                     log("DEFERRED_TOGGLE ignored due to state change");
                     break;
@@ -639,6 +644,15 @@
             if (msg.what == CMD_DEVICE_IDLE) {
                 checkLocksAndTransitionWhenDeviceIdle();
                 // We let default state handle the rest of work
+            } else if (msg.what == CMD_USER_PRESENT) {
+                // TLS networks can't connect until user unlocks keystore. KeyStore
+                // unlocks when the user punches PIN after the reboot. So use this
+                // trigger to get those networks connected.
+                if (mFirstUserSignOnSeen == false) {
+                    mWifiStateMachine.reloadTlsNetworksAndReconnect();
+                }
+                mFirstUserSignOnSeen = true;
+                return HANDLED;
             }
             return NOT_HANDLED;
         }
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index f93a45b..86c68f3 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -83,6 +83,7 @@
 import static com.android.server.wifi.WifiController.CMD_SCREEN_OFF;
 import static com.android.server.wifi.WifiController.CMD_SCREEN_ON;
 import static com.android.server.wifi.WifiController.CMD_SET_AP;
+import static com.android.server.wifi.WifiController.CMD_USER_PRESENT;
 import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED;
 /**
  * WifiService handles remote WiFi operation requests by implementing
@@ -1084,6 +1085,8 @@
             String action = intent.getAction();
             if (action.equals(Intent.ACTION_SCREEN_ON)) {
                 mWifiController.sendMessage(CMD_SCREEN_ON);
+            } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
+                mWifiController.sendMessage(CMD_USER_PRESENT);
             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                 mWifiController.sendMessage(CMD_SCREEN_OFF);
             } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
@@ -1120,6 +1123,7 @@
     private void registerForBroadcasts() {
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_SCREEN_ON);
+        intentFilter.addAction(Intent.ACTION_USER_PRESENT);
         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
         intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
         intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 2e91e03..9bbaf60 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -1232,10 +1232,10 @@
         // the IME above it until it is completely gone so it doesn't drop
         // behind the dialog or its full-screen scrim.
         final WindowState curTarget = mInputMethodTarget;
-        if (curTarget != null && w != null
+        if (curTarget != null
                 && curTarget.isDisplayedLw()
                 && curTarget.isClosing()
-                && (curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
+                && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
             if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, not changing");
             return windows.indexOf(curTarget) + 1;
         }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 6fd5acc..a8b58aa 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -45,6 +45,12 @@
     }
 
     @Override
+    public void acquireWakeLockWithUid(IBinder arg0, int arg1, String arg2, String arg2_5, int arg3)
+            throws RemoteException {
+        // pass for now.
+    }
+
+    @Override
     public void crash(String arg0) throws RemoteException {
         // pass for now.
     }
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index f79a4a6..a6ae215 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -57,6 +57,7 @@
 import java.io.PrintWriter;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.security.PublicKey;
 import java.util.ArrayList;
 import java.util.BitSet;
 import java.util.Collection;
@@ -742,6 +743,26 @@
         markAllNetworksDisabledExcept(INVALID_NETWORK_ID);
     }
 
+    boolean needsUnlockedKeyStore() {
+
+        // Any network using certificates to authenticate access requires
+        // unlocked key store; unless the certificates can be stored with
+        // hardware encryption
+
+        for(WifiConfiguration config : mConfiguredNetworks.values()) {
+
+            if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP)
+                    && config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
+
+                if (config.enterpriseConfig.needsSoftwareBackedKeyStore()) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
     private void writeIpAndProxyConfigurations() {
 
         /* Make a copy */
@@ -1223,7 +1244,6 @@
                      * Keyguard settings may eventually be controlled by device policy.
                      * We check here if keystore is unlocked before installing
                      * credentials.
-                     * TODO: Figure a way to store these credentials for wifi alone
                      * TODO: Do we need a dialog here ?
                      */
                     if (mKeyStore.state() != KeyStore.State.UNLOCKED) {
@@ -1583,6 +1603,7 @@
         }
 
         config.enterpriseConfig.migrateCerts(mKeyStore);
+        config.enterpriseConfig.initializeSoftwareKeystoreFlag(mKeyStore);
     }
 
     private String removeDoubleQuotes(String string) {
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index e357804a..c7ebecb 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -19,8 +19,10 @@
 import android.os.Parcelable;
 import android.os.Process;
 import android.security.Credentials;
+import android.security.KeyChain;
 import android.security.KeyStore;
 import android.text.TextUtils;
+import android.util.Slog;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -43,6 +45,7 @@
  */
 public class WifiEnterpriseConfig implements Parcelable {
     private static final String TAG = "WifiEnterpriseConfig";
+    private static final boolean DBG = false;
     /**
      * In old configurations, the "private_key" field was used. However, newer
      * configurations use the key_id field with the engine_id set to "keystore".
@@ -91,6 +94,7 @@
     private X509Certificate mCaCert;
     private PrivateKey mClientPrivateKey;
     private X509Certificate mClientCertificate;
+    private boolean mNeedsSoftwareKeystore = false;
 
     /** This represents an empty value of an enterprise field.
      * NULL is used at wpa_supplicant to indicate an empty value
@@ -509,6 +513,18 @@
         return true;
     }
 
+    static boolean isHardwareBackedKey(PrivateKey key) {
+        return KeyChain.isBoundKeyAlgorithm(key.getAlgorithm());
+    }
+
+    static boolean hasHardwareBackedKey(Certificate certificate) {
+        return KeyChain.isBoundKeyAlgorithm(certificate.getPublicKey().getAlgorithm());
+    }
+
+    boolean needsSoftwareBackedKeyStore() {
+        return mNeedsSoftwareKeystore;
+    }
+
     boolean installKeys(android.security.KeyStore keyStore, String name) {
         boolean ret = true;
         String privKeyName = Credentials.USER_PRIVATE_KEY + name;
@@ -516,8 +532,23 @@
         String caCertName = Credentials.CA_CERTIFICATE + name;
         if (mClientCertificate != null) {
             byte[] privKeyData = mClientPrivateKey.getEncoded();
-            ret = keyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID,
-                            KeyStore.FLAG_ENCRYPTED);
+            if (isHardwareBackedKey(mClientPrivateKey)) {
+                // Hardware backed key store is secure enough to store keys un-encrypted, this
+                // removes the need for user to punch a PIN to get access to these keys
+                if (DBG) Slog.d(TAG, "importing keys " + name + " in hardware backed " +
+                        "store");
+                ret = keyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID,
+                                KeyStore.FLAG_NONE);
+            } else {
+                // Software backed key store is NOT secure enough to store keys un-encrypted.
+                // Save keys encrypted so they are protected with user's PIN. User will
+                // have to unlock phone before being able to use these keys and connect to
+                // networks.
+                if (DBG) Slog.d(TAG, "importing keys " + name + " in software backed store");
+                ret = keyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID,
+                        KeyStore.FLAG_ENCRYPTED);
+                mNeedsSoftwareKeystore = true;
+            }
             if (ret == false) {
                 return ret;
             }
@@ -561,7 +592,9 @@
             Certificate cert) {
         try {
             byte[] certData = Credentials.convertToPem(cert);
-            return keyStore.put(name, certData, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED);
+            if (DBG) Slog.d(TAG, "putting certificate " + name + " in keystore");
+            return keyStore.put(name, certData, Process.WIFI_UID, KeyStore.FLAG_NONE);
+
         } catch (IOException e1) {
             return false;
         } catch (CertificateException e2) {
@@ -573,6 +606,7 @@
         String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
         // a valid client certificate is configured
         if (!TextUtils.isEmpty(client)) {
+            if (DBG) Slog.d(TAG, "removing client private key and user cert");
             keyStore.delKey(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID);
             keyStore.delete(Credentials.USER_CERTIFICATE + client, Process.WIFI_UID);
         }
@@ -580,6 +614,7 @@
         String ca = getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX);
         // a valid ca certificate is configured
         if (!TextUtils.isEmpty(ca)) {
+            if (DBG) Slog.d(TAG, "removing CA cert");
             keyStore.delete(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID);
         }
     }
@@ -684,6 +719,61 @@
         }
     }
 
+    void initializeSoftwareKeystoreFlag(android.security.KeyStore keyStore) {
+        String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
+        if (!TextUtils.isEmpty(client)) {
+            // a valid client certificate is configured
+
+            // BUGBUG: keyStore.get() never returns certBytes; because it is not
+            // taking WIFI_UID as a parameter. It always looks for certificate
+            // with SYSTEM_UID, and never finds any Wifi certificates. Assuming that
+            // all certificates need software keystore until we get the get() API
+            // fixed.
+
+            mNeedsSoftwareKeystore = true;
+
+            /*
+            try {
+
+                if (DBG) Slog.d(TAG, "Loading client certificate " + Credentials
+                        .USER_CERTIFICATE + client);
+
+                CertificateFactory factory = CertificateFactory.getInstance("X.509");
+                if (factory == null) {
+                    Slog.e(TAG, "Error getting certificate factory");
+                    return;
+                }
+
+                byte[] certBytes = keyStore.get(Credentials.USER_CERTIFICATE + client);
+                if (certBytes != null) {
+                    Certificate cert = (X509Certificate) factory.generateCertificate(
+                            new ByteArrayInputStream(certBytes));
+
+                    if (cert != null) {
+                        mNeedsSoftwareKeystore = hasHardwareBackedKey(cert);
+
+                        if (DBG) Slog.d(TAG, "Loaded client certificate " + Credentials
+                                .USER_CERTIFICATE + client);
+                        if (DBG) Slog.d(TAG, "It " + (mNeedsSoftwareKeystore ? "needs" :
+                                "does not need" ) + " software key store");
+                    } else {
+                        Slog.d(TAG, "could not generate certificate");
+                    }
+                } else {
+                    Slog.e(TAG, "Could not load client certificate " + Credentials
+                            .USER_CERTIFICATE + client);
+                    mNeedsSoftwareKeystore = true;
+                }
+
+            } catch(CertificateException e) {
+                Slog.e(TAG, "Could not read certificates");
+                mCaCert = null;
+                mClientCertificate = null;
+            }
+            */
+        }
+    }
+
     private String removeDoubleQuotes(String string) {
         if (TextUtils.isEmpty(string)) return "";
         int length = string.length();
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 798bc2e..cf09836 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -426,6 +426,8 @@
     static final int CMD_IP_ADDRESS_UPDATED               = BASE + 140;
     /* An IP address was removed from our interface */
     static final int CMD_IP_ADDRESS_REMOVED               = BASE + 141;
+    /* Reload all networks and reconnect */
+    static final int CMD_RELOAD_TLS_AND_RECONNECT         = BASE + 142;
 
     /* Wifi state machine modes of operation */
     /* CONNECT_MODE - connect to any 'known' AP when it becomes available */
@@ -1320,6 +1322,14 @@
     }
 
     /**
+     * Reload networks and then reconnect; helps load correct data for TLS networks
+     */
+
+    public void reloadTlsNetworksAndReconnect() {
+        sendMessage(CMD_RELOAD_TLS_AND_RECONNECT);
+    }
+
+    /**
      * Add a network synchronously
      *
      * @return network id of the new network
@@ -2445,6 +2455,7 @@
                 case CMD_DISCONNECT:
                 case CMD_RECONNECT:
                 case CMD_REASSOCIATE:
+                case CMD_RELOAD_TLS_AND_RECONNECT:
                 case WifiMonitor.SUP_CONNECTION_EVENT:
                 case WifiMonitor.SUP_DISCONNECTION_EVENT:
                 case WifiMonitor.NETWORK_CONNECTION_EVENT:
@@ -3395,6 +3406,13 @@
                 case CMD_REASSOCIATE:
                     mWifiNative.reassociate();
                     break;
+                case CMD_RELOAD_TLS_AND_RECONNECT:
+                    if (mWifiConfigStore.needsUnlockedKeyStore()) {
+                        logd("Reconnecting to give a chance to un-connected TLS networks");
+                        mWifiNative.disconnect();
+                        mWifiNative.reconnect();
+                    }
+                    break;
                 case WifiManager.CONNECT_NETWORK:
                     /* The connect message can contain a network id passed as arg1 on message or
                      * or a config passed as obj on message.