Merge "Always unfreeze display."
diff --git a/Android.mk b/Android.mk
index be8c25b..c8b2555 100644
--- a/Android.mk
+++ b/Android.mk
@@ -400,6 +400,8 @@
 		            resources/samples/AccessibilityService "Accessibility Service" \
 		-samplecode $(sample_dir)/AccelerometerPlay \
 		            resources/samples/AccelerometerPlay "Accelerometer Play" \
+                -samplecode $(sample_dir)/AndroidBeam \
+		            resources/samples/AndroidBeam "Android Beam" \
 		-samplecode $(sample_dir)/ApiDemos \
 		            resources/samples/ApiDemos "API Demos" \
 		-samplecode $(sample_dir)/Support4Demos \
diff --git a/api/14.txt b/api/14.txt
index 9f2a6df..e26311f 100644
--- a/api/14.txt
+++ b/api/14.txt
@@ -16583,10 +16583,6 @@
     field public static final java.lang.String PHOTO_FILE_ID = "data14";
   }
 
-  public static final class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
-  }
-
   protected static abstract interface ContactsContract.ContactsColumns {
     field public static final java.lang.String DISPLAY_NAME = "display_name";
     field public static final java.lang.String HAS_PHONE_NUMBER = "has_phone_number";
@@ -16844,10 +16840,6 @@
     field public static final java.lang.String DATA_ID = "data_id";
   }
 
-  public static final class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
-  }
-
   protected static abstract interface ContactsContract.RawContactsColumns {
     field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
     field public static final java.lang.String CONTACT_ID = "contact_id";
@@ -16911,56 +16903,6 @@
     field public static final android.net.Uri PROFILE_CONTENT_URI;
   }
 
-  public static final class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String PHOTO = "photo";
-  }
-
-  protected static abstract interface ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id";
-    field public static final java.lang.String PHOTO_URI = "photo_uri";
-    field public static final java.lang.String SORT_INDEX = "sort_index";
-    field public static final java.lang.String STREAM_ITEM_ID = "stream_item_id";
-    field public static final java.lang.String SYNC1 = "stream_item_photo_sync1";
-    field public static final java.lang.String SYNC2 = "stream_item_photo_sync2";
-    field public static final java.lang.String SYNC3 = "stream_item_photo_sync3";
-    field public static final java.lang.String SYNC4 = "stream_item_photo_sync4";
-  }
-
-  public static final class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
-    field public static final android.net.Uri CONTENT_LIMIT_URI;
-    field public static final android.net.Uri CONTENT_PHOTO_URI;
-    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
-    field public static final android.net.Uri CONTENT_URI;
-    field public static final java.lang.String MAX_ITEMS = "max_items";
-  }
-
-  public static final class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "photo";
-    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
-    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
-  }
-
-  protected static abstract interface ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String ACCOUNT_NAME = "account_name";
-    field public static final java.lang.String ACCOUNT_TYPE = "account_type";
-    field public static final java.lang.String COMMENTS = "comments";
-    field public static final java.lang.String CONTACT_ID = "contact_id";
-    field public static final java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
-    field public static final java.lang.String DATA_SET = "data_set";
-    field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
-    field public static final java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
-    field public static final java.lang.String RES_ICON = "icon";
-    field public static final java.lang.String RES_LABEL = "label";
-    field public static final java.lang.String RES_PACKAGE = "res_package";
-    field public static final java.lang.String SYNC1 = "stream_item_sync1";
-    field public static final java.lang.String SYNC2 = "stream_item_sync2";
-    field public static final java.lang.String SYNC3 = "stream_item_sync3";
-    field public static final java.lang.String SYNC4 = "stream_item_sync4";
-    field public static final java.lang.String TEXT = "text";
-    field public static final java.lang.String TIMESTAMP = "timestamp";
-  }
-
   protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns {
     field public static final java.lang.String ACCOUNT_NAME = "account_name";
     field public static final java.lang.String ACCOUNT_TYPE = "account_type";
diff --git a/api/current.txt b/api/current.txt
index 9f2a6df..e26311f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16583,10 +16583,6 @@
     field public static final java.lang.String PHOTO_FILE_ID = "data14";
   }
 
-  public static final class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
-  }
-
   protected static abstract interface ContactsContract.ContactsColumns {
     field public static final java.lang.String DISPLAY_NAME = "display_name";
     field public static final java.lang.String HAS_PHONE_NUMBER = "has_phone_number";
@@ -16844,10 +16840,6 @@
     field public static final java.lang.String DATA_ID = "data_id";
   }
 
-  public static final class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
-  }
-
   protected static abstract interface ContactsContract.RawContactsColumns {
     field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
     field public static final java.lang.String CONTACT_ID = "contact_id";
@@ -16911,56 +16903,6 @@
     field public static final android.net.Uri PROFILE_CONTENT_URI;
   }
 
-  public static final class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String PHOTO = "photo";
-  }
-
-  protected static abstract interface ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id";
-    field public static final java.lang.String PHOTO_URI = "photo_uri";
-    field public static final java.lang.String SORT_INDEX = "sort_index";
-    field public static final java.lang.String STREAM_ITEM_ID = "stream_item_id";
-    field public static final java.lang.String SYNC1 = "stream_item_photo_sync1";
-    field public static final java.lang.String SYNC2 = "stream_item_photo_sync2";
-    field public static final java.lang.String SYNC3 = "stream_item_photo_sync3";
-    field public static final java.lang.String SYNC4 = "stream_item_photo_sync4";
-  }
-
-  public static final class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
-    field public static final android.net.Uri CONTENT_LIMIT_URI;
-    field public static final android.net.Uri CONTENT_PHOTO_URI;
-    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
-    field public static final android.net.Uri CONTENT_URI;
-    field public static final java.lang.String MAX_ITEMS = "max_items";
-  }
-
-  public static final class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "photo";
-    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
-    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
-  }
-
-  protected static abstract interface ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String ACCOUNT_NAME = "account_name";
-    field public static final java.lang.String ACCOUNT_TYPE = "account_type";
-    field public static final java.lang.String COMMENTS = "comments";
-    field public static final java.lang.String CONTACT_ID = "contact_id";
-    field public static final java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
-    field public static final java.lang.String DATA_SET = "data_set";
-    field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
-    field public static final java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
-    field public static final java.lang.String RES_ICON = "icon";
-    field public static final java.lang.String RES_LABEL = "label";
-    field public static final java.lang.String RES_PACKAGE = "res_package";
-    field public static final java.lang.String SYNC1 = "stream_item_sync1";
-    field public static final java.lang.String SYNC2 = "stream_item_sync2";
-    field public static final java.lang.String SYNC3 = "stream_item_sync3";
-    field public static final java.lang.String SYNC4 = "stream_item_sync4";
-    field public static final java.lang.String TEXT = "text";
-    field public static final java.lang.String TIMESTAMP = "timestamp";
-  }
-
   protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns {
     field public static final java.lang.String ACCOUNT_NAME = "account_name";
     field public static final java.lang.String ACCOUNT_TYPE = "account_type";
diff --git a/cmds/bu/src/com/android/commands/bu/Backup.java b/cmds/bu/src/com/android/commands/bu/Backup.java
index 4c4bf98..046ccca 100644
--- a/cmds/bu/src/com/android/commands/bu/Backup.java
+++ b/cmds/bu/src/com/android/commands/bu/Backup.java
@@ -66,6 +66,7 @@
         boolean saveApks = false;
         boolean saveShared = false;
         boolean doEverything = false;
+        boolean allIncludesSystem = true;
 
         String arg;
         while ((arg = nextArg()) != null) {
@@ -78,6 +79,10 @@
                     saveShared = true;
                 } else if ("-noshared".equals(arg)) {
                     saveShared = false;
+                } else if ("-system".equals(arg)) {
+                    allIncludesSystem = true;
+                } else if ("-nosystem".equals(arg)) {
+                    allIncludesSystem = false;
                 } else if ("-all".equals(arg)) {
                     doEverything = true;
                 } else {
@@ -102,7 +107,7 @@
         try {
             ParcelFileDescriptor fd = ParcelFileDescriptor.adoptFd(socketFd);
             String[] packArray = new String[packages.size()];
-            mBackupManager.fullBackup(fd, saveApks, saveShared, doEverything,
+            mBackupManager.fullBackup(fd, saveApks, saveShared, doEverything, allIncludesSystem,
                     packages.toArray(packArray));
         } catch (RemoteException e) {
             Log.e(TAG, "Unable to invoke backup manager for backup");
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 99aae37..d2facdc 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1478,7 +1478,7 @@
         }
 
         //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
-        DisplayMetrics metrics = getDisplayMetricsLocked(compInfo, false);
+        DisplayMetrics metrics = getDisplayMetricsLocked(null, false);
         r = new Resources(assets, metrics, getConfiguration(), compInfo);
         if (false) {
             Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
@@ -3476,7 +3476,7 @@
             return false;
         }
         int changes = mResConfiguration.updateFrom(config);
-        DisplayMetrics dm = getDisplayMetricsLocked(compat, true);
+        DisplayMetrics dm = getDisplayMetricsLocked(null, true);
 
         if (compat != null && (mResCompatibilityInfo == null ||
                 !mResCompatibilityInfo.equals(compat))) {
@@ -3517,7 +3517,20 @@
         
         return changes != 0;
     }
-    
+
+    final Configuration applyCompatConfiguration() {
+        Configuration config = mConfiguration;
+        if (mCompatConfiguration == null) {
+            mCompatConfiguration = new Configuration();
+        }
+        mCompatConfiguration.setTo(mConfiguration);
+        if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
+            mResCompatibilityInfo.applyToConfiguration(mCompatConfiguration);
+            config = mCompatConfiguration;
+        }
+        return config;
+    }
+
     final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
 
         ArrayList<ComponentCallbacks2> callbacks = null;
@@ -3546,14 +3559,7 @@
                 return;
             }
             mConfiguration.updateFrom(config);
-            if (mCompatConfiguration == null) {
-                mCompatConfiguration = new Configuration();
-            }
-            mCompatConfiguration.setTo(mConfiguration);
-            if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
-                mResCompatibilityInfo.applyToConfiguration(mCompatConfiguration);
-                config = mCompatConfiguration;
-            }
+            config = applyCompatConfiguration();
             callbacks = collectComponentCallbacksLocked(false, config);
         }
         
@@ -3752,6 +3758,7 @@
          * in AppBindData can be safely assumed to be up to date
          */
         applyConfigurationToResourcesLocked(data.config, data.compatInfo);
+        applyCompatConfiguration();
 
         data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
 
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index c154296..acdd0b5 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -157,11 +157,15 @@
      * @param allApps If <code>true</code>, the resulting tar stream will include all
      *     installed applications' data, not just those named in the <code>packageNames</code>
      *     parameter.
+     * @param allIncludesSystem If {@code true}, then {@code allApps} will be interpreted
+     *     as including packages pre-installed as part of the system. If {@code false},
+     *     then setting {@code allApps} to {@code true} will mean only that all 3rd-party
+     *     applications will be included in the dataset.
      * @param packageNames The package names of the apps whose data (and optionally .apk files)
      *     are to be backed up.  The <code>allApps</code> parameter supersedes this.
      */
     void fullBackup(in ParcelFileDescriptor fd, boolean includeApks, boolean includeShared,
-            boolean allApps, in String[] packageNames);
+            boolean allApps, boolean allIncludesSystem, in String[] packageNames);
 
     /**
      * Restore device content from the data stream passed through the given socket.  The
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index e40de26..c3a14ca 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -201,7 +201,7 @@
         public static final int CAMERA_FACING_FRONT = 1;
 
         /**
-         * The direction that the camera faces to. It should be
+         * The direction that the camera faces. It should be
          * CAMERA_FACING_BACK or CAMERA_FACING_FRONT.
          */
         public int facing;
@@ -1055,9 +1055,9 @@
         /**
          * Notify the listener of the detected faces in the preview frame.
          *
-         * @param faces the detected faces. The list is sorted by the score.
-         *              The highest score is the first element.
-         * @param camera  the Camera service object
+         * @param faces The detected faces in a list sorted by the confidence score.
+         *              The highest scored face is the first element.
+         * @param camera  The {@link Camera} service object
          */
         void onFaceDetection(Face[] faces, Camera camera);
     }
@@ -1105,7 +1105,7 @@
     /**
      * Stops the face detection.
      *
-     * @see #startFaceDetection(int)
+     * @see #startFaceDetection()
      */
     public final void stopFaceDetection() {
         _stopFaceDetection();
@@ -1116,8 +1116,12 @@
     private native final void _stopFaceDetection();
 
     /**
-     * The information of a face from camera face detection.
+     * Information about a face identified through camera face detection.
+     * 
+     * <p>When face detection is used with a camera, the {@link FaceDetectionListener} returns a
+     * list of face objects for use in focusing and metering.</p>
      *
+     * @see FaceDetectionListener
      */
     public static class Face {
         /**
@@ -1138,15 +1142,15 @@
          * the sensor sees. The direction is not affected by the rotation or
          * mirroring of {@link #setDisplayOrientation(int)}.</p>
          *
-         * @see #startFaceDetection(int)
+         * @see #startFaceDetection()
          */
         public Rect rect;
 
         /**
-         * The confidence level of the face. The range is 1 to 100. 100 is the
+         * The confidence level for the detection of the face. The range is 1 to 100. 100 is the
          * highest confidence.
          *
-         * @see #startFaceDetection(int)
+         * @see #startFaceDetection()
          */
         public int score;
 
@@ -3144,7 +3148,7 @@
          * supported.
          *
          * @return the maximum number of detected face supported by the camera.
-         * @see #startFaceDetection(int)
+         * @see #startFaceDetection()
          */
         public int getMaxNumDetectedFaces() {
             return getInt(KEY_MAX_NUM_DETECTED_FACES_HW, 0);
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 1119c1e..5343e2a 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -248,6 +248,8 @@
     private AccessibilityManager mAccessibilityManager;
     /** The audio manager for accessibility support */
     private AudioManager mAudioManager;
+    /** Whether the requirement of a headset to hear passwords if accessibility is enabled is announced. */
+    private boolean mHeadsetRequiredToHearPasswordsAnnounced;
 
     Handler mHandler = new Handler() {
         @Override
@@ -852,13 +854,15 @@
                 Key oldKey = keys[oldKeyIndex];
                 oldKey.onReleased(mCurrentKeyIndex == NOT_A_KEY);
                 invalidateKey(oldKeyIndex);
-                sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT, oldKey.codes[0]);
+                sendAccessibilityEventForUnicodeCharacter(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT,
+                        oldKey.codes[0]);
             }
             if (mCurrentKeyIndex != NOT_A_KEY && keys.length > mCurrentKeyIndex) {
                 Key newKey = keys[mCurrentKeyIndex];
                 newKey.onPressed();
                 invalidateKey(mCurrentKeyIndex);
-                sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER, newKey.codes[0]);
+                sendAccessibilityEventForUnicodeCharacter(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
+                        newKey.codes[0]);
             }
         }
         // If key changed and preview is on ...
@@ -958,13 +962,13 @@
         mPreviewText.setVisibility(VISIBLE);
     }
 
-    private void sendAccessibilityEvent(int eventType, int code) {
+    private void sendAccessibilityEventForUnicodeCharacter(int eventType, int code) {
         if (mAccessibilityManager.isEnabled()) {
             AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
             onInitializeAccessibilityEvent(event);
+            String text = null;
             // Add text only if headset is used to avoid leaking passwords.
             if (mAudioManager.isBluetoothA2dpOn() || mAudioManager.isWiredHeadsetOn()) {
-                String text = null;
                 switch (code) {
                     case Keyboard.KEYCODE_ALT:
                         text = mContext.getString(R.string.keyboardview_keycode_alt);
@@ -990,11 +994,17 @@
                     default:
                         text = String.valueOf((char) code);
                 }
-                event.getText().add(text);
+            } else if (!mHeadsetRequiredToHearPasswordsAnnounced) {
+                // We want the waring for required head set to be send with both the
+                // hover enter and hover exit event, so set the flag after the exit.
+                if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
+                    mHeadsetRequiredToHearPasswordsAnnounced = true;
+                }
+                text = mContext.getString(R.string.keyboard_headset_required_to_hear_password);
             } else {
-                event.getText().add(mContext.getString(
-                R.string.keyboard_headset_required_to_hear_password));
+                text = mContext.getString(R.string.keyboard_password_character_no_headset);
             }
+            event.getText().add(text);
             mAccessibilityManager.sendAccessibilityEvent(event);
         }
     }
@@ -1134,15 +1144,13 @@
     }
 
     @Override
-    protected boolean dispatchHoverEvent(MotionEvent event) {
+    public boolean onHoverEvent(MotionEvent event) {
         // If touch exploring is enabled we ignore touch events and transform
         // the stream of hover events as touch events. This allows one consistent
         // event stream to drive the keyboard since during touch exploring the
         // first touch generates only hover events and tapping on the same
         // location generates hover and touch events.
-        if (mAccessibilityManager.isEnabled()
-                && mAccessibilityManager.isTouchExplorationEnabled()
-                && event.getPointerCount() == 1) {
+        if (mAccessibilityManager.isTouchExplorationEnabled() && event.getPointerCount() == 1) {
             final int action = event.getAction();
             switch (action) {
                 case MotionEvent.ACTION_HOVER_ENTER:
@@ -1156,9 +1164,9 @@
                     break;
             }
             onTouchEventInternal(event);
-            return true;
+            event.setAction(action);
         }
-        return super.dispatchHoverEvent(event);
+        return super.onHoverEvent(event);
     }
 
     @Override
@@ -1168,8 +1176,7 @@
         // event stream to drive the keyboard since during touch exploring the
         // first touch generates only hover events and tapping on the same
         // location generates hover and touch events.
-        if (mAccessibilityManager.isEnabled()
-                && mAccessibilityManager.isTouchExplorationEnabled()) {
+        if (mAccessibilityManager.isTouchExplorationEnabled()) {
             return true;
         }
         return onTouchEventInternal(event);
diff --git a/core/java/android/net/http/SslError.java b/core/java/android/net/http/SslError.java
index 08c6692..5998f5f 100644
--- a/core/java/android/net/http/SslError.java
+++ b/core/java/android/net/http/SslError.java
@@ -19,7 +19,8 @@
 import java.security.cert.X509Certificate;
 
 /**
- * One or more individual SSL errors and the associated SSL certificate
+ * This class represents a set of one or more SSL errors and the associated SSL
+ * certificate.
  */
 public class SslError {
 
@@ -48,16 +49,17 @@
      */
     public static final int SSL_DATE_INVALID = 4;
     /**
-     * The certificate is invalid
+     * A generic error occurred
      */
     public static final int SSL_INVALID = 5;
 
 
     /**
-     * The number of different SSL errors (update if you add a new SSL error!!!)
+     * The number of different SSL errors.
      * @deprecated This constant is not necessary for using the SslError API and
      *             can change from release to release.
      */
+    // Update if you add a new SSL error!!!
     @Deprecated
     public static final int SSL_MAX_ERROR = 6;
 
@@ -78,56 +80,56 @@
     final String mUrl;
 
     /**
-     * Creates a new SSL error set object
+     * Creates a new SslError object using the supplied error and certificate.
+     * The URL will be set to the empty string.
      * @param error The SSL error
      * @param certificate The associated SSL certificate
      * @deprecated Use {@link #SslError(int, SslCertificate, String)}
      */
     @Deprecated
     public SslError(int error, SslCertificate certificate) {
-        addError(error);
-        if (certificate == null) {
-            throw new NullPointerException("certificate is null.");
-        }
-        mCertificate = certificate;
-        mUrl = "";
+        this(error, certificate, "");
     }
 
     /**
-     * Creates a new SSL error set object
+     * Creates a new SslError object using the supplied error and certificate.
+     * The URL will be set to the empty string.
      * @param error The SSL error
      * @param certificate The associated SSL certificate
      * @deprecated Use {@link #SslError(int, X509Certificate, String)}
      */
     @Deprecated
     public SslError(int error, X509Certificate certificate) {
-        addError(error);
-        if (certificate == null) {
-            throw new NullPointerException("certificate is null.");
-        }
-        mCertificate = new SslCertificate(certificate);
-        mUrl = "";
+        this(error, certificate, "");
     }
 
     /**
-     * Creates a new SSL error set object
+     * Creates a new SslError object using the supplied error, certificate and
+     * URL.
      * @param error The SSL error
      * @param certificate The associated SSL certificate
-     * @param url The associated URL.
+     * @param url The associated URL
      */
     public SslError(int error, SslCertificate certificate, String url) {
+        assert certificate != null;
+        assert url != null;
         addError(error);
-        if (certificate == null) {
-            throw new NullPointerException("certificate is null.");
-        }
         mCertificate = certificate;
-        if (url == null) {
-            throw new NullPointerException("url is null.");
-        }
         mUrl = url;
     }
 
     /**
+     * Creates a new SslError object using the supplied error, certificate and
+     * URL.
+     * @param error The SSL error
+     * @param certificate The associated SSL certificate
+     * @param url The associated URL
+     */
+    public SslError(int error, X509Certificate certificate, String url) {
+        this(error, new SslCertificate(certificate), url);
+    }
+
+    /**
      * Creates an SslError object from a chromium error code.
      * @param error The chromium error code
      * @param certificate The associated SSL certificate
@@ -138,56 +140,38 @@
             int error, SslCertificate cert, String url) {
         // The chromium error codes are in:
         // external/chromium/net/base/net_error_list.h
-        if (error > -200 || error < -299) {
-            throw new NullPointerException("Not a valid chromium SSL error code.");
-        }
+        assert (error >= -299 && error <= -200);
         if (error == -200)
             return new SslError(SSL_IDMISMATCH, cert, url);
         if (error == -201)
             return new SslError(SSL_DATE_INVALID, cert, url);
         if (error == -202)
             return new SslError(SSL_UNTRUSTED, cert, url);
-        // Map all other errors to SSL_INVALID
+        // Map all other codes to SSL_INVALID.
         return new SslError(SSL_INVALID, cert, url);
     }
 
     /**
-     * Creates a new SSL error set object
-     * @param error The SSL error
-     * @param certificate The associated SSL certificate
-     * @param url The associated URL.
-     */
-    public SslError(int error, X509Certificate certificate, String url) {
-        addError(error);
-        if (certificate == null) {
-            throw new NullPointerException("certificate is null.");
-        }
-        mCertificate = new SslCertificate(certificate);
-        if (url == null) {
-            throw new NullPointerException("url is null.");
-        }
-        mUrl = url;
-    }
-
-    /**
-     * @return The SSL certificate associated with the error set, non-null.
+     * Gets the SSL certificate associated with this object.
+     * @return The SSL certificate, non-null.
      */
     public SslCertificate getCertificate() {
         return mCertificate;
     }
 
     /**
-     * @return The URL associated with the error set, non-null.
-     * "" if one of the deprecated constructors is used.
+     * Gets the URL associated with this object.
+     * @return The URL, non-null.
      */
     public String getUrl() {
         return mUrl;
     }
 
     /**
-     * Adds the SSL error to the error set
+     * Adds the supplied SSL error to the set.
      * @param error The SSL error to add
-     * @return True iff the error being added is a known SSL error
+     * @return True if the error being added is a known SSL error, otherwise
+     *         false.
      */
     public boolean addError(int error) {
         boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
@@ -199,8 +183,9 @@
     }
 
     /**
-     * @param error The SSL error to check
-     * @return True iff the set includes the error
+     * Determines whether this object includes the supplied error.
+     * @param error The SSL error to check for
+     * @return True if this object includes the error, otherwise false.
      */
     public boolean hasError(int error) {
         boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
@@ -212,7 +197,8 @@
     }
 
     /**
-     * @return The primary, most severe, SSL error in the set
+     * Gets the most severe SSL error in this object's set of errors.
+     * @return The most severe SSL error.
      */
     public int getPrimaryError() {
         if (mErrors != 0) {
@@ -228,12 +214,12 @@
     }
 
     /**
-     * @return A String representation of this SSL error object
-     * (used mostly for debugging).
+     * Returns a string representation of this object.
+     * @return A String representation of this object.
      */
     public String toString() {
         return "primary error: " + getPrimaryError() +
-            " certificate: " + getCertificate() +
-            "  on URL: " + getUrl();
+                " certificate: " + getCertificate() +
+                " on URL: " + getUrl();
     }
 }
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 1d8ea12..5faab36 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -282,6 +282,10 @@
          * <p>Applications targeting this or a later release will get these
          * new changes in behavior:</p>
          * <ul>
+         * <li> For devices without a dedicated menu key, the software compatibility
+         * menu key will not be shown even on phones.  By targeting Ice Cream Sandwich
+         * or later, your UI must always have its own menu UI affordance if needed,
+         * on both tablets and phones.  The ActionBar will take care of this for you.
          * <li> 2d drawing hardware acceleration is now turned on by default.
          * You can use
          * {@link android.R.attr#hardwareAccelerated android:hardwareAccelerated}
@@ -296,6 +300,12 @@
          *      will not change character within the same platform version. Applications
          *      that wish to blend in with the device should use a theme from the
          *      {@link android.R.style#Theme_DeviceDefault} family.
+         * <li> Managed cursors can now throw an exception if you directly close
+         * the cursor yourself without stopping the management of it; previously failures
+         * would be silently ignored.
+         * <li> The fadingEdge attribute on views will be ignored (fading edges is no
+         * longer a standard part of the UI).  A new requiresFadingEdge attribute allows
+         * applications to still force fading edges on for special cases.
          * </ul>
          */
         public static final int ICE_CREAM_SANDWICH = 14;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index fb119b3..8483b4f 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1611,9 +1611,16 @@
         }
 
         /**
+         * <p>
          * A sub-directory of a single contact that contains all of the constituent raw contact
          * {@link ContactsContract.StreamItems} rows.  This directory can be used either
          * with a {@link #CONTENT_URI} or {@link #CONTENT_LOOKUP_URI}.
+         * </p>
+         * <p>
+         * Querying for social stream data requires android.permission.READ_SOCIAL_STREAM
+         * permission.
+         * </p>
+         * @hide
          */
         public static final class StreamItems implements StreamItemsColumns {
             /**
@@ -2669,6 +2676,14 @@
          * {@link ContactsContract.StreamItems} for a stand-alone table containing the
          * same data.
          * </p>
+         * <p>
+         * Access to the social stream through this sub-directory requires additional permissions
+         * beyond the read/write contact permissions required by the provider.  Querying for
+         * social stream data requires android.permission.READ_SOCIAL_STREAM permission, and
+         * inserting or updating social stream items requires android.permission.WRITE_SOCIAL_STREAM
+         * permission.
+         * </p>
+         * @hide
          */
         public static final class StreamItems implements BaseColumns, StreamItemsColumns {
             /**
@@ -2963,6 +2978,12 @@
      * transaction correspondingly.  Insertion of more items beyond the limit will
      * automatically lead to deletion of the oldest items, by {@link StreamItems#TIMESTAMP}.
      * </p>
+     * <p>
+     * Access to the social stream through these URIs requires additional permissions beyond the
+     * read/write contact permissions required by the provider.  Querying for social stream data
+     * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating social
+     * stream items requires android.permission.WRITE_SOCIAL_STREAM permission.
+     * </p>
      * <h3>Operations</h3>
      * <dl>
      * <dt><b>Insert</b></dt>
@@ -3075,6 +3096,7 @@
      * </pre>
      * </dd>
      * </dl>
+     * @hide
      */
     public static final class StreamItems implements BaseColumns, StreamItemsColumns {
         /**
@@ -3135,6 +3157,12 @@
          * directory append {@link StreamItems.StreamItemPhotos#CONTENT_DIRECTORY} to
          * an individual stream item URI.
          * </p>
+         * <p>
+         * Access to social stream photos requires additional permissions beyond the read/write
+         * contact permissions required by the provider.  Querying for social stream photos
+         * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating
+         * social stream photos requires android.permission.WRITE_SOCIAL_STREAM permission.
+         * </p>
          */
         public static final class StreamItemPhotos
                 implements BaseColumns, StreamItemPhotosColumns {
@@ -3166,6 +3194,7 @@
      * Columns in the StreamItems table.
      *
      * @see ContactsContract.StreamItems
+     * @hide
      */
     protected interface StreamItemsColumns {
         /**
@@ -3312,6 +3341,12 @@
      * Constants for the stream_item_photos table, which contains photos associated with
      * social stream updates.
      * </p>
+     * <p>
+     * Access to social stream photos requires additional permissions beyond the read/write
+     * contact permissions required by the provider.  Querying for social stream photos
+     * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating
+     * social stream photos requires android.permission.WRITE_SOCIAL_STREAM permission.
+     * </p>
      * <h3>Operations</h3>
      * <dl>
      * <dt><b>Insert</b></dt>
@@ -3450,6 +3485,7 @@
      * <pre>
      * </dd>
      * </dl>
+     * @hide
      */
     public static final class StreamItemPhotos implements BaseColumns, StreamItemPhotosColumns {
         /**
@@ -3477,6 +3513,7 @@
      * Columns in the StreamItemPhotos table.
      *
      * @see ContactsContract.StreamItemPhotos
+     * @hide
      */
     protected interface StreamItemPhotosColumns {
         /**
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 5126e48..98ab310 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -440,6 +440,9 @@
     private final Context mContext;
     private Connection mServiceConnection;
     private OnInitListener mInitListener;
+    // Written from an unspecified application thread, read from
+    // a binder thread.
+    private volatile OnUtteranceCompletedListener mUtteranceCompletedListener;
     private final Object mStartLock = new Object();
 
     private String mRequestedEngine;
@@ -1071,20 +1074,8 @@
      * @return {@link #ERROR} or {@link #SUCCESS}.
      */
     public int setOnUtteranceCompletedListener(final OnUtteranceCompletedListener listener) {
-        return runAction(new Action<Integer>() {
-            @Override
-            public Integer run(ITextToSpeechService service) throws RemoteException {
-                ITextToSpeechCallback.Stub callback = new ITextToSpeechCallback.Stub() {
-                    public void utteranceCompleted(String utteranceId) {
-                        if (listener != null) {
-                            listener.onUtteranceCompleted(utteranceId);
-                        }
-                    }
-                };
-                service.setCallback(getPackageName(), callback);
-                return SUCCESS;
-            }
-        }, ERROR, "setOnUtteranceCompletedListener");
+        mUtteranceCompletedListener = listener;
+        return TextToSpeech.SUCCESS;
     }
 
     /**
@@ -1137,6 +1128,15 @@
 
     private class Connection implements ServiceConnection {
         private ITextToSpeechService mService;
+        private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() {
+            @Override
+            public void utteranceCompleted(String utteranceId) {
+                OnUtteranceCompletedListener listener = mUtteranceCompletedListener;
+                if (listener != null) {
+                    listener.onUtteranceCompleted(utteranceId);
+                }
+            }
+        };
 
         public void onServiceConnected(ComponentName name, IBinder service) {
             Log.i(TAG, "Connected to " + name);
@@ -1147,7 +1147,13 @@
                 }
                 mServiceConnection = this;
                 mService = ITextToSpeechService.Stub.asInterface(service);
-                dispatchOnInit(SUCCESS);
+                try {
+                    mService.setCallback(getPackageName(), mCallback);
+                    dispatchOnInit(SUCCESS);
+                } catch (RemoteException re) {
+                    Log.e(TAG, "Error connecting to service, setCallback() failed");
+                    dispatchOnInit(ERROR);
+                }
             }
         }
 
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index c3a2308..f82c9c4 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -76,7 +76,7 @@
                          boolean includepad,
                          TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
         this(base, display, paint, width, align, TextDirectionHeuristics.FIRSTSTRONG_LTR,
-                spacingmult, spacingadd, includepad, ellipsize, ellipsizedWidth, Integer.MAX_VALUE);
+                spacingmult, spacingadd, includepad, ellipsize, ellipsizedWidth);
     }
 
     /**
@@ -93,7 +93,7 @@
                          int width, Alignment align, TextDirectionHeuristic textDir,
                          float spacingmult, float spacingadd,
                          boolean includepad,
-                         TextUtils.TruncateAt ellipsize, int ellipsizedWidth, int maxLines) {
+                         TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
         super((ellipsize == null)
                 ? display
                 : (display instanceof Spanned)
@@ -135,8 +135,6 @@
             mEllipsize = true;
         }
 
-        mMaxLines = maxLines;
-
         // Initial state is a single line with 0 characters (0 to 0),
         // with top at 0 and bottom at whatever is natural, and
         // undefined ellipsis.
@@ -285,7 +283,7 @@
         reflowed.generate(text, where, where + after,
                 getPaint(), getWidth(), getAlignment(), getTextDirectionHeuristic(),
                 getSpacingMultiplier(), getSpacingAdd(),
-                false, true, mEllipsizedWidth, mEllipsizeAt, mMaxLines);
+                false, true, mEllipsizedWidth, mEllipsizeAt);
         int n = reflowed.getLineCount();
 
         // If the new layout has a blank line at the end, but it is not
@@ -490,8 +488,6 @@
 
     private int mTopPadding, mBottomPadding;
 
-    private int mMaxLines;
-
     private static StaticLayout sStaticLayout = new StaticLayout(null);
 
     private static final Object[] sLock = new Object[0];
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 7c27396..583cbe6 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -139,7 +139,7 @@
 
         generate(source, bufstart, bufend, paint, outerwidth, align, textDir,
                  spacingmult, spacingadd, includepad, includepad,
-                 ellipsizedWidth, ellipsize, mMaximumVisibleLineCount);
+                 ellipsizedWidth, ellipsize);
 
         mMeasured = MeasuredText.recycle(mMeasured);
         mFontMetricsInt = null;
@@ -160,7 +160,7 @@
                         Alignment align, TextDirectionHeuristic textDir,
                         float spacingmult, float spacingadd,
                         boolean includepad, boolean trackpad,
-                        float ellipsizedWidth, TextUtils.TruncateAt ellipsize, int maxLines) {
+                        float ellipsizedWidth, TextUtils.TruncateAt ellipsize) {
         mLineCount = 0;
 
         int v = 0;
@@ -477,13 +477,13 @@
                             width = restWidth;
                         }
                     }
-                    if (mLineCount >= maxLines) {
+                    if (mLineCount >= mMaximumVisibleLineCount) {
                         break;
                     }
                 }
             }
 
-            if (paraEnd != here && mLineCount < maxLines) {
+            if (paraEnd != here && mLineCount < mMaximumVisibleLineCount) {
                 if ((fitTop | fitBottom | fitDescent | fitAscent) == 0) {
                     paint.getFontMetricsInt(fm);
 
@@ -514,7 +514,7 @@
         }
 
         if ((bufEnd == bufStart || source.charAt(bufEnd - 1) == CHAR_NEW_LINE) &&
-                mLineCount < maxLines) {
+                mLineCount < mMaximumVisibleLineCount) {
             // Log.e("text", "output last " + bufEnd);
 
             paint.getFontMetricsInt(fm);
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 3bd0f76..7945441 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -30,7 +30,7 @@
  */
 public class Display {
     static final String TAG = "Display";
-    static final boolean DEBUG_DISPLAY_SIZE = false;
+    static final boolean DEBUG_DISPLAY_SIZE = true;
 
     /**
      * The default Display id.
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 28f54aa..8c22da0 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -43,7 +43,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.ref.WeakReference;
-import java.net.URL;
 import java.net.URLEncoder;
 import java.nio.charset.Charsets;
 import java.security.PrivateKey;
@@ -472,8 +471,6 @@
 
     /**
      * We have received an SSL certificate for the main top-level page.
-     *
-     * !!!Called from the network thread!!!
      */
     void certificate(SslCertificate certificate) {
         if (mIsMainFrame) {
@@ -1171,12 +1168,7 @@
         try {
             X509Certificate cert = new X509CertImpl(certDER);
             SslCertificate sslCert = new SslCertificate(cert);
-            if (JniUtil.useChromiumHttpStack()) {
-                sslError = SslError.SslErrorFromChromiumErrorCode(certError, sslCert,
-                        new URL(url).getHost());
-            } else {
-                sslError = new SslError(certError, cert, url);
-            }
+            sslError = SslError.SslErrorFromChromiumErrorCode(certError, sslCert, url);
         } catch (IOException e) {
             // Can't get the certificate, not much to do.
             Log.e(LOGTAG, "Can't get the certificate from WebKit, canceling");
@@ -1192,12 +1184,11 @@
         SslErrorHandler handler = new SslErrorHandler() {
             @Override
             public void proceed() {
-                SslCertLookupTable.getInstance().setIsAllowed(sslError, true);
+                SslCertLookupTable.getInstance().setIsAllowed(sslError);
                 nativeSslCertErrorProceed(handle);
             }
             @Override
             public void cancel() {
-                SslCertLookupTable.getInstance().setIsAllowed(sslError, false);
                 nativeSslCertErrorCancel(handle, certError);
             }
         };
diff --git a/core/java/android/webkit/SslCertLookupTable.java b/core/java/android/webkit/SslCertLookupTable.java
index 052244f..a06836c 100644
--- a/core/java/android/webkit/SslCertLookupTable.java
+++ b/core/java/android/webkit/SslCertLookupTable.java
@@ -19,10 +19,14 @@
 import android.os.Bundle;
 import android.net.http.SslError;
 
+import java.net.MalformedURLException;
+import java.net.URL;
+
 /**
  * Stores the user's decision of whether to allow or deny an invalid certificate.
  *
- * This class is not threadsafe. It is used only on the WebCore thread.
+ * This class is not threadsafe. It is used only on the WebCore thread. Also, it
+ * is used only by the Chromium HTTP stack.
  */
 final class SslCertLookupTable {
     private static SslCertLookupTable sTable;
@@ -39,15 +43,33 @@
         table = new Bundle();
     }
 
-    public void setIsAllowed(SslError sslError, boolean allow) {
-        table.putBoolean(sslError.toString(), allow);
+    public void setIsAllowed(SslError sslError) {
+        // TODO: We should key on just the host. See http://b/5409251.
+        String errorString = sslErrorToString(sslError);
+        if (errorString != null) {
+            table.putBoolean(errorString, true);
+        }
     }
 
     public boolean isAllowed(SslError sslError) {
-        return table.getBoolean(sslError.toString());
+        // TODO: We should key on just the host. See http://b/5409251.
+        String errorString = sslErrorToString(sslError);
+        return errorString == null ? false : table.getBoolean(errorString);
     }
 
     public void clear() {
         table.clear();
     }
+
+    private static String sslErrorToString(SslError error) {
+        String host;
+        try {
+            host = new URL(error.getUrl()).getHost();
+        } catch(MalformedURLException e) {
+            return null;
+        }
+        return "primary error: " + error.getPrimaryError() +
+                " certificate: " + error.getCertificate() +
+                " on host: " + host;
+    }
 }
diff --git a/core/java/android/webkit/SslErrorHandlerImpl.java b/core/java/android/webkit/SslErrorHandlerImpl.java
index e029e37..82cd3e8 100644
--- a/core/java/android/webkit/SslErrorHandlerImpl.java
+++ b/core/java/android/webkit/SslErrorHandlerImpl.java
@@ -16,8 +16,6 @@
 
 package android.webkit;
 
-import junit.framework.Assert;
-
 import android.net.http.SslError;
 import android.os.Bundle;
 import android.os.Handler;
@@ -54,7 +52,7 @@
     private final SslErrorHandler mOriginHandler;
     private final LoadListener mLoadListener;
 
-    // Message id for handling the response
+    // Message id for handling the response from the client.
     private static final int HANDLE_RESPONSE = 100;
 
     @Override
@@ -130,7 +128,9 @@
     }
 
     /**
-     * Handles SSL error(s) on the way up to the user.
+     * Handles requests from the network stack about whether to proceed with a
+     * load given an SSL error(s). We may ask the client what to do, or use a
+     * cached response.
      */
     /* package */ synchronized void handleSslErrorRequest(LoadListener loader) {
         if (DebugFlags.SSL_ERROR_HANDLER) {
@@ -147,8 +147,10 @@
     }
 
     /**
-     * Check the preference table for a ssl error that has already been shown
-     * to the user.
+     * Check the preference table to see if we already have a 'proceed' decision
+     * from the client for this host and for an error of equal or greater
+     * severity than the supplied error. If so, instruct the loader to proceed
+     * and return true. Otherwise return false.
      */
     /* package */ synchronized boolean checkSslPrefTable(LoadListener loader,
             SslError error) {
@@ -156,21 +158,22 @@
         final int primary = error.getPrimaryError();
 
         if (DebugFlags.SSL_ERROR_HANDLER) {
-            Assert.assertTrue(host != null && primary != 0);
+            assert host != null;
+            assert primary != 0;
         }
 
-        if (mSslPrefTable.containsKey(host)) {
-            if (primary <= mSslPrefTable.getInt(host)) {
-                handleSslErrorResponse(loader, error, true);
-                return true;
+        if (mSslPrefTable.containsKey(host) && primary <= mSslPrefTable.getInt(host)) {
+            if (!loader.cancelled()) {
+                loader.handleSslErrorResponse(true);
             }
+            return true;
         }
         return false;
     }
 
     /**
      * Processes queued SSL-error confirmation requests in
-     * a tight loop while there is no need to ask the user.
+     * a tight loop while there is no need to ask the client.
      */
     /* package */void fastProcessQueuedSslErrors() {
         while (processNextLoader());
@@ -195,19 +198,18 @@
             SslError error = loader.sslError();
 
             if (DebugFlags.SSL_ERROR_HANDLER) {
-                Assert.assertNotNull(error);
+                assert error != null;
             }
 
-            // checkSslPrefTable will handle the ssl error response if the
-            // answer is available. It does not remove the loader from the
-            // queue.
+            // checkSslPrefTable() will instruct the loader to proceed if we
+            // have a cached 'proceed' decision. It does not remove the loader
+            // from the queue.
             if (checkSslPrefTable(loader, error)) {
                 mLoaderQueue.remove(loader);
                 return true;
             }
 
-            // if we do not have information on record, ask
-            // the user (display a dialog)
+            // If we can not proceed based on a cached decision, ask the client.
             CallbackProxy proxy = loader.getFrame().getCallbackProxy();
             proxy.onReceivedSslError(new SslErrorHandlerImpl(this, loader), error);
         }
@@ -217,32 +219,31 @@
     }
 
     /**
-     * Proceed with the SSL certificate.
+     * Proceed with this load.
      */
     public void proceed() {
-        mOriginHandler.sendMessage(
-                mOriginHandler.obtainMessage(
-                        HANDLE_RESPONSE, 1, 0, mLoadListener));
+        mOriginHandler.sendMessage(mOriginHandler.obtainMessage(
+                HANDLE_RESPONSE, 1, 0, mLoadListener));
     }
 
     /**
-     * Cancel this request and all pending requests for the WebView that had
-     * the error.
+     * Cancel this load and all pending loads for the WebView that had the
+     * error.
      */
     public void cancel() {
-        mOriginHandler.sendMessage(
-                mOriginHandler.obtainMessage(
-                        HANDLE_RESPONSE, 0, 0, mLoadListener));
+        mOriginHandler.sendMessage(mOriginHandler.obtainMessage(
+                HANDLE_RESPONSE, 0, 0, mLoadListener));
     }
 
     /**
-     * Handles SSL error(s) on the way down from the user.
+     * Handles the response from the client about whether to proceed with this
+     * load. We save the response to be re-used in the future.
      */
     /* package */ synchronized void handleSslErrorResponse(LoadListener loader,
             SslError error, boolean proceed) {
         if (DebugFlags.SSL_ERROR_HANDLER) {
-            Assert.assertNotNull(loader);
-            Assert.assertNotNull(error);
+            assert loader != null;
+            assert error != null;
         }
 
         if (DebugFlags.SSL_ERROR_HANDLER) {
@@ -253,16 +254,16 @@
 
         if (!loader.cancelled()) {
             if (proceed) {
-                // update the user's SSL error preference table
+                // Update the SSL error preference table
                 int primary = error.getPrimaryError();
                 String host = loader.host();
 
                 if (DebugFlags.SSL_ERROR_HANDLER) {
-                    Assert.assertTrue(host != null && primary != 0);
+                    assert host != null;
+                    assert primary != 0;
                 }
                 boolean hasKey = mSslPrefTable.containsKey(host);
-                if (!hasKey ||
-                    primary > mSslPrefTable.getInt(host)) {
+                if (!hasKey || primary > mSslPrefTable.getInt(host)) {
                     mSslPrefTable.putInt(host, primary);
                 }
             }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 17f0e05..f7a9dc1 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6262,7 +6262,7 @@
             result = new DynamicLayout(mText, mTransformed, mTextPaint, w,
                     alignment, mTextDir, mSpacingMult,
                     mSpacingAdd, mIncludePad, mInput == null ? effectiveEllipsize : null,
-                            ellipsisWidth, mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
+                            ellipsisWidth);
         } else {
             if (boring == UNKNOWN_BORING) {
                 boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, mBoring);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 2694aa2..d5450e4 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -119,6 +119,8 @@
     private final static String LOCKSCREEN_OPTIONS = "lockscreen.options";
     public final static String LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK
             = "lockscreen.biometric_weak_fallback";
+    public final static String BIOMETRIC_WEAK_EVER_CHOSEN_KEY
+            = "lockscreen.biometricweakeverchosen";
 
     private final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
 
@@ -341,6 +343,16 @@
     }
 
     /**
+     * Return true if the user has ever chosen biometric weak.  This is true even if biometric
+     * weak is not current set.
+     *
+     * @return True if the user has ever chosen biometric weak.
+     */
+    public boolean isBiometricWeakEverChosen() {
+        return getBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY);
+    }
+
+    /**
      * Used by device policy manager to validate the current password
      * information it has.
      */
@@ -489,6 +501,7 @@
                     setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
                     setLong(PASSWORD_TYPE_ALTERNATE_KEY,
                             DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+                    setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
                     moveTempGallery();
                 }
                 dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern
@@ -606,6 +619,7 @@
                 } else {
                     setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
                     setLong(PASSWORD_TYPE_ALTERNATE_KEY, Math.max(quality, computedQuality));
+                    setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
                     moveTempGallery();
                 }
                 if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9755f22..18194ee 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -263,6 +263,23 @@
         android:label="@string/permlab_writeProfile"
         android:description="@string/permdesc_writeProfile" />
 
+    <!-- Allows an application to read from the user's social stream.
+         @hide -->
+    <permission android:name="android.permission.READ_SOCIAL_STREAM"
+        android:permissionGroup="android.permission-group.PERSONAL_INFO"
+        android:protectionLevel="dangerous"
+        android:label="@string/permlab_readSocialStream"
+        android:description="@string/permdesc_readSocialStream" />
+
+    <!-- Allows an application to write (but not read) the user's
+         social stream data.
+         @hide -->
+    <permission android:name="android.permission.WRITE_SOCIAL_STREAM"
+        android:permissionGroup="android.permission-group.PERSONAL_INFO"
+        android:protectionLevel="dangerous"
+        android:label="@string/permlab_writeSocialStream"
+        android:description="@string/permdesc_writeSocialStream" />
+
     <!-- Allows an application to read the user's calendar data. -->
     <permission android:name="android.permission.READ_CALENDAR"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1e0151a..b1dc252 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -941,6 +941,19 @@
         information.  This means other applications can identify you and send your profile
         information to others.</string>
 
+    <!-- Title of the read social stream permission, listed so the user can decide whether to allow the application to read information from the user's social stream. [CHAR LIMIT=30] -->
+    <string name="permlab_readSocialStream" product="default">read your social stream</string>
+    <string name="permdesc_readSocialStream" product="default">Allows the application to access
+        and sync social updates from you and your friends. Malicious apps can use this to read
+        private communications between you and your friends on social networks.</string>
+
+    <!-- Title of the write social stream permission, listed so the user can decide whether to allow the application to write information to the user's social stream. [CHAR LIMIT=30] -->
+    <string name="permlab_writeSocialStream" product="default">write to your social stream</string>
+    <string name="permdesc_writeSocialStream" product="default">Allows the application to display
+        social updates from your friends. Malicious apps can use this to pretend to be a friend
+        and trick you into revealing passwords or other confidential information.</string>
+
+    
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_readCalendar">read calendar events plus confidential information</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -3216,8 +3229,9 @@
     <string name="description_target_soundon">Sound on</string>
 
     <!-- Announce that a headset is required to hear keyboard keys while typing a password. [CHAR LIMIT=NONE] -->
-    <string name="keyboard_headset_required_to_hear_password">Key. Headset required to hear
-    keys while typing a password.</string>
+    <string name="keyboard_headset_required_to_hear_password">Plug in a headset to hear password keys spoken aloud.</string>
+    <!-- The value of a keyboard key announced when accessibility is enabled and no headsed is used. [CHAR LIMIT=NONE] -->
+    <string name="keyboard_password_character_no_headset">Dot.</string>
 
     <!-- Content description for the action bar "home" affordance. [CHAR LIMIT=NONE] -->
     <string name="action_bar_home_description">Navigate home</string>
@@ -3316,4 +3330,4 @@
     <!-- Delimeter used between each item in a textual list; for example "Alpha, Beta". [CHAR LIMIT=3] -->
     <string name="list_delimeter">", "</string>
 
-</resources>
\ No newline at end of file
+</resources>
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
deleted file mode 100644
index 1fd7bba..0000000
--- a/data/fonts/fonts.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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 only used by the layoutlib to display
-	layouts in ADT.
--->
-<fonts>
-    <font ttf="DroidSans">
-        <name>sans-serif</name>
-        <name>arial</name>
-        <name>helvetica</name>
-        <name>tahoma</name>
-        <name>verdana</name>
-    </font>
-   <font ttf="DroidSerif">
-        <name>serif</name>
-        <name>times</name>
-        <name>times new roman</name>
-        <name>palatino</name>
-        <name>georgia</name>
-        <name>baskerville</name>
-        <name>goudy</name>
-        <name>fantasy</name>
-        <name>cursive</name>
-        <name>ITC Stone Serif</name>
-    </font>
-    <font ttf="DroidSansMono">
-        <name>monospace</name>
-        <name>courier</name>
-        <name>courier new</name>
-        <name>monaco</name>
-    </font>
-    <fallback ttf="DroidSansFallback" />
-    <fallback ttf="MTLmr3m" />
-</fonts>
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 6c5d882..d7700ee 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -408,6 +408,16 @@
     }
   },
   {
+    tags: ['sample', 'new'],
+    path: 'samples/AndroidBeam/index.html',
+    title: {
+      en: 'Android Beam'
+    },
+    description: {
+      en: 'An example of how to use the Android Beam feature to send messages between two Android-powered devices (API level 14 or later) that support NFC.'
+    }
+  },
+  {
     tags: ['sample', 'layout', 'ui'],
     path: 'samples/ApiDemos/index.html',
     title: {
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 21b8c74..0d5a726 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -319,6 +319,8 @@
     void initOutputFormat(const sp<MetaData> &inputFormat);
     status_t initNativeWindow();
 
+    void initNativeWindowCrop();
+
     void dumpPortStatus(OMX_U32 portIndex);
 
     status_t configureCodec(const sp<MetaData> &meta);
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index bd70319..d51154d 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -70,13 +70,6 @@
             clipRect = s->clipRect;
         }
 
-        if ((s->flags & Snapshot::kFlagClipSet) &&
-                !(s->flags & Snapshot::kFlagDirtyLocalClip)) {
-            mLocalClip.set(s->mLocalClip);
-        } else {
-            flags |= Snapshot::kFlagDirtyLocalClip;
-        }
-
         if (s->flags & Snapshot::kFlagFboTarget) {
             flags |= Snapshot::kFlagFboTarget;
             region = s->region;
@@ -106,18 +99,14 @@
          */
         kFlagIsFboLayer = 0x4,
         /**
-         * Indicates that the local clip should be recomputed.
-         */
-        kFlagDirtyLocalClip = 0x8,
-        /**
          * Indicates that this snapshot has changed the ortho matrix.
          */
-        kFlagDirtyOrtho = 0x10,
+        kFlagDirtyOrtho = 0x8,
         /**
          * Indicates that this snapshot or an ancestor snapshot is
          * an FBO layer.
          */
-        kFlagFboTarget = 0x20
+        kFlagFboTarget = 0x10
     };
 
     /**
@@ -169,7 +158,7 @@
         }
 
         if (clipped) {
-            flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
+            flags |= Snapshot::kFlagClipSet;
         }
 
         return clipped;
@@ -180,19 +169,16 @@
      */
     void setClip(float left, float top, float right, float bottom) {
         clipRect->set(left, top, right, bottom);
-        flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
+        flags |= Snapshot::kFlagClipSet;
     }
 
     const Rect& getLocalClip() {
-        if (flags & Snapshot::kFlagDirtyLocalClip) {
-            mat4 inverse;
-            inverse.loadInverse(*transform);
+        mat4 inverse;
+        inverse.loadInverse(*transform);
 
-            mLocalClip.set(*clipRect);
-            inverse.mapRect(mLocalClip);
+        mLocalClip.set(*clipRect);
+        inverse.mapRect(mLocalClip);
 
-            flags &= ~Snapshot::kFlagDirtyLocalClip;
-        }
         return mLocalClip;
     }
 
@@ -204,7 +190,7 @@
     void resetClip(float left, float top, float right, float bottom) {
         clipRect = &mClipRectRoot;
         clipRect->set(left, top, right, bottom);
-        flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
+        flags |= Snapshot::kFlagClipSet;
     }
 
     bool isIgnored() const {
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 0755fb7..5fd5c35 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -302,7 +302,10 @@
     DrvScript *drv = (DrvScript *)s->mHal.drv;
     // We only support slot 0 (root) at this point in time.
     rsAssert(slot == 0);
-    mtls.sig = drv->mExportForEachSignatureList[slot];
+    mtls.sig = 0x1f;  // temp fix for old apps, full table in slang_rs_export_foreach.cpp
+    if (drv->mExportForEachSignatureList) {
+        mtls.sig = drv->mExportForEachSignatureList[slot];
+    }
     if (ain) {
         mtls.dimX = ain->getType()->getDimX();
         mtls.dimY = ain->getType()->getDimY();
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index ccc8a18..7c34257 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2351,22 +2351,6 @@
                     formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) {
                     mOutputPortSettingsHaveChanged = true;
 
-                    if (mNativeWindow != NULL) {
-                        int32_t left, top, right, bottom;
-                        CHECK(mOutputFormat->findRect(
-                                    kKeyCropRect,
-                                    &left, &top, &right, &bottom));
-
-                        android_native_rect_t crop;
-                        crop.left = left;
-                        crop.top = top;
-                        crop.right = right + 1;
-                        crop.bottom = bottom + 1;
-
-                        // We'll ignore any errors here, if the surface is
-                        // already invalid, we'll know soon enough.
-                        native_window_set_crop(mNativeWindow.get(), &crop);
-                    }
                 } else if (data2 == OMX_IndexConfigCommonScale) {
                     OMX_CONFIG_SCALEFACTORTYPE scale;
                     InitOMXParams(&scale);
@@ -4183,6 +4167,24 @@
     return OK;
 }
 
+void OMXCodec::initNativeWindowCrop() {
+    int32_t left, top, right, bottom;
+
+    CHECK(mOutputFormat->findRect(
+                        kKeyCropRect,
+                        &left, &top, &right, &bottom));
+
+    android_native_rect_t crop;
+    crop.left = left;
+    crop.top = top;
+    crop.right = right + 1;
+    crop.bottom = bottom + 1;
+
+    // We'll ignore any errors here, if the surface is
+    // already invalid, we'll know soon enough.
+    native_window_set_crop(mNativeWindow.get(), &crop);
+}
+
 void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
     mOutputFormat = new MetaData;
     mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
@@ -4366,6 +4368,10 @@
                             video_def->nFrameWidth - 1,
                             video_def->nFrameHeight - 1);
                 }
+
+                if (mNativeWindow != NULL) {
+                     initNativeWindowCrop();
+                }
             }
             break;
         }
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index ca5d274..899a761 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -231,6 +231,8 @@
         }
     };
 
+    private TransportControlView mTransportControlView;
+
     /**
      * @return Whether we are stuck on the lock screen because the sim is
      *   missing.
@@ -516,7 +518,10 @@
 
         // When screen is turned on, need to bind to FaceLock service if we are using FaceLock
         // But only if not dealing with a call
-        if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE) {
+        final boolean transportInvisible = mTransportControlView == null ? true :
+                mTransportControlView.getVisibility() != View.VISIBLE;
+        if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
+                && transportInvisible) {
             bindToFaceLock();
         } else {
             mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
@@ -805,14 +810,13 @@
     }
 
     private void initializeTransportControlView(View view) {
-        com.android.internal.widget.TransportControlView tcv =
-                (TransportControlView) view.findViewById(R.id.transport);
-        if (tcv == null) {
+        mTransportControlView = (TransportControlView) view.findViewById(R.id.transport);
+        if (mTransportControlView == null) {
             if (DEBUG) Log.w(TAG, "Couldn't find transport control widget");
         } else {
             mUpdateMonitor.reportClockVisible(true);
-            tcv.setVisibility(View.GONE); // hide tcv until we get the callback below to show it.
-            tcv.setCallback(mWidgetCallback);
+            mTransportControlView.setVisibility(View.GONE); // hide until it requests being shown.
+            mTransportControlView.setCallback(mWidgetCallback);
         }
     }
 
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index fe49cd2..7b8657a 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -325,14 +325,16 @@
         public boolean includeApks;
         public boolean includeShared;
         public boolean allApps;
+        public boolean includeSystem;
         public String[] packages;
 
         FullBackupParams(ParcelFileDescriptor output, boolean saveApks, boolean saveShared,
-                boolean doAllApps, String[] pkgList) {
+                boolean doAllApps, boolean doSystem, String[] pkgList) {
             fd = output;
             includeApks = saveApks;
             includeShared = saveShared;
             allApps = doAllApps;
+            includeSystem = doSystem;
             packages = pkgList;
         }
     }
@@ -504,7 +506,7 @@
                 PerformFullBackupTask task = new PerformFullBackupTask(params.fd,
                         params.observer, params.includeApks,
                         params.includeShared, params.curPassword, params.encryptPassword,
-                        params.allApps, params.packages, params.latch);
+                        params.allApps, params.includeSystem, params.packages, params.latch);
                 (new Thread(task)).start();
                 break;
             }
@@ -2161,6 +2163,7 @@
         boolean mIncludeApks;
         boolean mIncludeShared;
         boolean mAllApps;
+        final boolean mIncludeSystem;
         String[] mPackages;
         String mCurrentPassword;
         String mEncryptPassword;
@@ -2219,13 +2222,14 @@
 
         PerformFullBackupTask(ParcelFileDescriptor fd, IFullBackupRestoreObserver observer, 
                 boolean includeApks, boolean includeShared, String curPassword,
-                String encryptPassword, boolean doAllApps, String[] packages,
+                String encryptPassword, boolean doAllApps, boolean doSystem, String[] packages,
                 AtomicBoolean latch) {
             mOutputFile = fd;
             mObserver = observer;
             mIncludeApks = includeApks;
             mIncludeShared = includeShared;
             mAllApps = doAllApps;
+            mIncludeSystem = doSystem;
             mPackages = packages;
             mCurrentPassword = curPassword;
             // when backing up, if there is a current backup password, we require that
@@ -2245,7 +2249,7 @@
 
         @Override
         public void run() {
-            final List<PackageInfo> packagesToBackup;
+            List<PackageInfo> packagesToBackup = new ArrayList<PackageInfo>();
 
             Slog.i(TAG, "--- Performing full-dataset backup ---");
             sendStartBackup();
@@ -2254,8 +2258,23 @@
             if (mAllApps) {
                 packagesToBackup = mPackageManager.getInstalledPackages(
                         PackageManager.GET_SIGNATURES);
-            } else {
-                packagesToBackup = new ArrayList<PackageInfo>();
+                // Exclude system apps if we've been asked to do so
+                if (mIncludeSystem == false) {
+                    for (int i = 0; i < packagesToBackup.size(); ) {
+                        PackageInfo pkg = packagesToBackup.get(i);
+                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                            packagesToBackup.remove(i);
+                        } else {
+                            i++;
+                        }
+                    }
+                }
+            }
+
+            // Now process the command line argument packages, if any. Note that explicitly-
+            // named system-partition packages will be included even if includeSystem was
+            // set to false.
+            if (mPackages != null) {
                 for (String pkgName : mPackages) {
                     try {
                         packagesToBackup.add(mPackageManager.getPackageInfo(pkgName,
@@ -2268,8 +2287,8 @@
 
             // Cull any packages that have indicated that backups are not permitted.
             for (int i = 0; i < packagesToBackup.size(); ) {
-                PackageInfo info = packagesToBackup.get(i);
-                if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
+                PackageInfo pkg = packagesToBackup.get(i);
+                if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
                     packagesToBackup.remove(i);
                 } else {
                     i++;
@@ -4781,7 +4800,7 @@
     // to the supplied file descriptor.  This method is synchronous and does not return
     // to the caller until the backup has been completed.
     public void fullBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeShared,
-            boolean doAllApps, String[] pkgList) {
+            boolean doAllApps, boolean includeSystem, String[] pkgList) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullBackup");
 
         // Validate
@@ -4811,7 +4830,7 @@
             Slog.i(TAG, "Beginning full backup...");
 
             FullBackupParams params = new FullBackupParams(fd, includeApks, includeShared,
-                    doAllApps, pkgList);
+                    doAllApps, includeSystem, pkgList);
             final int token = generateToken();
             synchronized (mFullConfirmations) {
                 mFullConfirmations.put(token, params);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index bddda0a..8e98ec4 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5704,6 +5704,7 @@
 
     Configuration computeNewConfigurationLocked() {
         Configuration config = new Configuration();
+        config.fontScale = 0;
         if (!computeNewConfigurationLocked(config)) {
             return null;
         }
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index e60a61c..1523823 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -1166,7 +1166,7 @@
                 if (mTextScaleX != 1.0 || mTextSkewX != 0) {
                     // TODO: support skew
                     info.mFont = info.mFont.deriveFont(new AffineTransform(
-                            mTextScaleX, mTextSkewX, 0, 0, 1, 0));
+                            mTextScaleX, mTextSkewX, 0, 1, 0, 0));
                 }
                 info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index 0f084f7..2414d70 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -25,8 +25,8 @@
 import android.content.res.AssetManager;
 
 import java.awt.Font;
+import java.io.File;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -44,13 +44,14 @@
  */
 public final class Typeface_Delegate {
 
+    private static final String SYSTEM_FONTS = "/system/fonts/";
+
     // ---- delegate manager ----
     private static final DelegateManager<Typeface_Delegate> sManager =
             new DelegateManager<Typeface_Delegate>(Typeface_Delegate.class);
 
     // ---- delegate helper data ----
     private static final String DEFAULT_FAMILY = "sans-serif";
-    private static final int[] STYLE_BUFFER = new int[1];
 
     private static FontLoader sFontLoader;
     private static final List<Typeface_Delegate> sPostInitDelegate =
@@ -145,9 +146,31 @@
 
     @LayoutlibDelegate
     /*package*/ static synchronized int nativeCreateFromFile(String path) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Typeface.createFromFile() is not supported.", null /*throwable*/, null /*data*/);
-        return 0;
+        if (path.startsWith(SYSTEM_FONTS) ) {
+            String relativePath = path.substring(SYSTEM_FONTS.length());
+            File f = new File(sFontLoader.getOsFontsLocation(), relativePath);
+
+            try {
+                Font font = Font.createFont(Font.TRUETYPE_FONT, f);
+                if (font != null) {
+                    Typeface_Delegate newDelegate = new Typeface_Delegate(font);
+                    return sManager.addNewDelegate(newDelegate);
+                }
+            } catch (Exception e) {
+                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
+                        String.format("Unable to load font %1$s", relativePath),
+                            null /*throwable*/, null /*data*/);
+            }
+        } else {
+            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                    "Typeface.createFromFile() can only work with platform fonts located in " +
+                        SYSTEM_FONTS,
+                    null /*throwable*/, null /*data*/);
+        }
+
+
+        // return a copy of the base font
+        return nativeCreate(null, 0);
     }
 
     @LayoutlibDelegate
@@ -177,15 +200,17 @@
         mStyle = style;
     }
 
+    private Typeface_Delegate(Font font) {
+        mFamily = font.getFamily();
+        mStyle = Typeface.NORMAL;
+
+        mFonts = sFontLoader.getFallbackFonts(mStyle);
+
+        // insert the font glyph first.
+        mFonts.add(0, font);
+    }
+
     private void init() {
-        STYLE_BUFFER[0] = mStyle;
-        Font font = sFontLoader.getFont(mFamily, STYLE_BUFFER);
-        if (font != null) {
-            List<Font> list = new ArrayList<Font>();
-            list.add(font);
-            list.addAll(sFontLoader.getFallBackFonts());
-            mFonts = Collections.unmodifiableList(list);
-            mStyle = STYLE_BUFFER[0];
-        }
+        mFonts = sFontLoader.getFont(mFamily, mStyle);
     }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
index f62fad2..081ce67 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
@@ -23,17 +23,13 @@
 import android.graphics.Typeface;
 
 import java.awt.Font;
-import java.awt.FontFormatException;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import javax.xml.parsers.ParserConfigurationException;
@@ -47,49 +43,55 @@
  * fonts.xml file located alongside the ttf files.
  */
 public final class FontLoader {
-    private static final String FONTS_DEFINITIONS = "fonts.xml";
+    private static final String FONTS_SYSTEM = "system_fonts.xml";
+    private static final String FONTS_VENDOR = "vendor_fonts.xml";
+    private static final String FONTS_FALLBACK = "fallback_fonts.xml";
 
-    private static final String NODE_FONTS = "fonts";
-    private static final String NODE_FONT = "font";
+    private static final String NODE_FAMILYSET = "familyset";
+    private static final String NODE_FAMILY = "family";
     private static final String NODE_NAME = "name";
-    private static final String NODE_FALLBACK = "fallback";
+    private static final String NODE_FILE = "file";
 
-    private static final String ATTR_TTF = "ttf";
+    private static final String FONT_SUFFIX_NONE = ".ttf";
+    private static final String FONT_SUFFIX_REGULAR = "-Regular.ttf";
+    private static final String FONT_SUFFIX_BOLD = "-Bold.ttf";
+    private static final String FONT_SUFFIX_ITALIC = "-Italic.ttf";
+    private static final String FONT_SUFFIX_BOLDITALIC = "-BoldItalic.ttf";
 
-    private static final String FONT_EXT = ".ttf";
-
-    private static final String[] FONT_STYLE_DEFAULT = { "", "-Regular" };
-    private static final String[] FONT_STYLE_BOLD = { "-Bold" };
-    private static final String[] FONT_STYLE_ITALIC = { "-Italic" };
-    private static final String[] FONT_STYLE_BOLDITALIC = { "-BoldItalic" };
-
-    // list of font style, in the order matching the Typeface Font style
-    private static final String[][] FONT_STYLES = {
-        FONT_STYLE_DEFAULT,
-        FONT_STYLE_BOLD,
-        FONT_STYLE_ITALIC,
-        FONT_STYLE_BOLDITALIC
+    // This must match the values of Typeface styles so that we can use them for indices in this
+    // array.
+    private static final int[] AWT_STYLES = new int[] {
+        Font.PLAIN,
+        Font.BOLD,
+        Font.ITALIC,
+        Font.BOLD | Font.ITALIC
     };
+    private static int[] DERIVE_BOLD_ITALIC = new int[] {
+        Typeface.ITALIC, Typeface.BOLD, Typeface.NORMAL
+    };
+    private static int[] DERIVE_ITALIC = new int[] { Typeface.NORMAL };
+    private static int[] DERIVE_BOLD = new int[] { Typeface.NORMAL };
 
-    private final Map<String, String> mFamilyToTtf = new HashMap<String, String>();
-    private final Map<String, Map<Integer, Font>> mTtfToFontMap =
-        new HashMap<String, Map<Integer, Font>>();
+    private static final List<FontInfo> mMainFonts = new ArrayList<FontInfo>();
+    private static final List<FontInfo> mFallbackFonts = new ArrayList<FontInfo>();
 
-    private List<Font> mFallBackFonts = null;
+    private final String mOsFontsLocation;
 
     public static FontLoader create(String fontOsLocation) {
         try {
             SAXParserFactory parserFactory = SAXParserFactory.newInstance();
                 parserFactory.setNamespaceAware(true);
 
-            SAXParser parser = parserFactory.newSAXParser();
-            File f = new File(fontOsLocation + File.separator + FONTS_DEFINITIONS);
+            // parse the system fonts
+            FontHandler handler = parseFontFile(parserFactory, fontOsLocation, FONTS_SYSTEM);
+            List<FontInfo> systemFonts = handler.getFontList();
 
-            FontDefinitionParser definitionParser = new FontDefinitionParser(
-                    fontOsLocation + File.separator);
-            parser.parse(new FileInputStream(f), definitionParser);
 
-            return definitionParser.getFontLoader();
+            // parse the fallback fonts
+            handler = parseFontFile(parserFactory, fontOsLocation, FONTS_FALLBACK);
+            List<FontInfo> fallbackFonts = handler.getFontList();
+
+            return new FontLoader(fontOsLocation, systemFonts, fallbackFonts);
         } catch (ParserConfigurationException e) {
             // return null below
         } catch (SAXException e) {
@@ -103,35 +105,29 @@
         return null;
     }
 
-    private FontLoader(List<FontInfo> fontList, List<String> fallBackList) {
-        for (FontInfo info : fontList) {
-            for (String family : info.families) {
-                mFamilyToTtf.put(family, info.ttf);
-            }
-        }
+    private static FontHandler parseFontFile(SAXParserFactory parserFactory,
+            String fontOsLocation, String fontFileName)
+            throws ParserConfigurationException, SAXException, IOException, FileNotFoundException {
 
-        ArrayList<Font> list = new ArrayList<Font>();
-        for (String path : fallBackList) {
-            File f = new File(path + FONT_EXT);
-            if (f.isFile()) {
-                try {
-                    Font font = Font.createFont(Font.TRUETYPE_FONT, f);
-                    if (font != null) {
-                        list.add(font);
-                    }
-                } catch (FontFormatException e) {
-                    // skip this font name
-                } catch (IOException e) {
-                    // skip this font name
-                }
-            }
-        }
+        SAXParser parser = parserFactory.newSAXParser();
+        File f = new File(fontOsLocation, fontFileName);
 
-        mFallBackFonts = Collections.unmodifiableList(list);
+        FontHandler definitionParser = new FontHandler(
+                fontOsLocation + File.separator);
+        parser.parse(new FileInputStream(f), definitionParser);
+        return definitionParser;
     }
 
-    public List<Font> getFallBackFonts() {
-        return mFallBackFonts;
+    private FontLoader(String fontOsLocation,
+            List<FontInfo> fontList, List<FontInfo> fallBackList) {
+        mOsFontsLocation = fontOsLocation;
+        mMainFonts.addAll(fontList);
+        mFallbackFonts.addAll(fallBackList);
+    }
+
+
+    public String getOsFontsLocation() {
+        return mOsFontsLocation;
     }
 
     /**
@@ -143,96 +139,43 @@
      *              the method returns.
      * @return the font object or null if no match could be found.
      */
-    public synchronized Font getFont(String family, int[] style) {
+    public synchronized List<Font> getFont(String family, int style) {
+        List<Font> result = new ArrayList<Font>();
+
         if (family == null) {
-            return null;
+            return result;
         }
 
-        // get the ttf name from the family
-        String ttf = mFamilyToTtf.get(family);
 
-        if (ttf == null) {
-            return null;
-        }
-
-        // get the font from the ttf
-        Map<Integer, Font> styleMap = mTtfToFontMap.get(ttf);
-
-        if (styleMap == null) {
-            styleMap = new HashMap<Integer, Font>();
-            mTtfToFontMap.put(ttf, styleMap);
-        }
-
-        Font f = styleMap.get(style[0]);
-
-        if (f != null) {
-            return f;
-        }
-
-        // if it doesn't exist, we create it, and we can't, we try with a simpler style
-        switch (style[0]) {
-            case Typeface.NORMAL:
-                f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]);
+        // get the font objects from the main list based on family.
+        for (FontInfo info : mMainFonts) {
+            if (info.families.contains(family)) {
+                result.add(info.font[style]);
                 break;
-            case Typeface.BOLD:
-            case Typeface.ITALIC:
-                f = getFont(ttf, FONT_STYLES[style[0]]);
-                if (f == null) {
-                    f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]);
-                    style[0] = Typeface.NORMAL;
-                }
-                break;
-            case Typeface.BOLD_ITALIC:
-                f = getFont(ttf, FONT_STYLES[style[0]]);
-                if (f == null) {
-                    f = getFont(ttf, FONT_STYLES[Typeface.BOLD]);
-                    if (f != null) {
-                        style[0] = Typeface.BOLD;
-                    } else {
-                        f = getFont(ttf, FONT_STYLES[Typeface.ITALIC]);
-                        if (f != null) {
-                            style[0] = Typeface.ITALIC;
-                        } else {
-                            f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]);
-                            style[0] = Typeface.NORMAL;
-                        }
-                    }
-                }
-                break;
-        }
-
-        if (f != null) {
-            styleMap.put(style[0], f);
-            return f;
-        }
-
-        return null;
-    }
-
-    private Font getFont(String ttf, String[] fontFileSuffix) {
-        for (String suffix : fontFileSuffix) {
-            String name = ttf + suffix + FONT_EXT;
-
-            File f = new File(name);
-            if (f.isFile()) {
-                try {
-                    Font font = Font.createFont(Font.TRUETYPE_FONT, f);
-                    if (font != null) {
-                        return font;
-                    }
-                } catch (FontFormatException e) {
-                    // skip this font name
-                } catch (IOException e) {
-                    // skip this font name
-                }
             }
         }
 
-        return null;
+        // add all the fallback fonts for the given style
+        for (FontInfo info : mFallbackFonts) {
+            result.add(info.font[style]);
+        }
+
+        return result;
     }
 
+
+    public synchronized List<Font> getFallbackFonts(int style) {
+        List<Font> result = new ArrayList<Font>();
+        // add all the fallback fonts
+        for (FontInfo info : mFallbackFonts) {
+            result.add(info.font[style]);
+        }
+        return result;
+    }
+
+
     private final static class FontInfo {
-        String ttf;
+        final Font[] font = new Font[4]; // Matches the 4 type-face styles.
         final Set<String> families;
 
         FontInfo() {
@@ -240,21 +183,20 @@
         }
     }
 
-    private final static class FontDefinitionParser extends DefaultHandler {
+    private final static class FontHandler extends DefaultHandler {
         private final String mOsFontsLocation;
 
         private FontInfo mFontInfo = null;
         private final StringBuilder mBuilder = new StringBuilder();
-        private List<FontInfo> mFontList;
-        private List<String> mFallBackList;
+        private List<FontInfo> mFontList = new ArrayList<FontInfo>();
 
-        private FontDefinitionParser(String osFontsLocation) {
+        private FontHandler(String osFontsLocation) {
             super();
             mOsFontsLocation = osFontsLocation;
         }
 
-        FontLoader getFontLoader() {
-            return new FontLoader(mFontList, mFallBackList);
+        public List<FontInfo> getFontList() {
+            return mFontList;
         }
 
         /* (non-Javadoc)
@@ -263,26 +205,11 @@
         @Override
         public void startElement(String uri, String localName, String name, Attributes attributes)
                 throws SAXException {
-            if (NODE_FONTS.equals(localName)) {
+            if (NODE_FAMILYSET.equals(localName)) {
                 mFontList = new ArrayList<FontInfo>();
-                mFallBackList = new ArrayList<String>();
-            } else if (NODE_FONT.equals(localName)) {
+            } else if (NODE_FAMILY.equals(localName)) {
                 if (mFontList != null) {
-                    String ttf = attributes.getValue(ATTR_TTF);
-                    if (ttf != null) {
-                        mFontInfo = new FontInfo();
-                        mFontInfo.ttf = mOsFontsLocation + ttf;
-                        mFontList.add(mFontInfo);
-                    }
-                }
-            } else if (NODE_NAME.equals(localName)) {
-                // do nothing, we'll handle the name in the endElement
-            } else if (NODE_FALLBACK.equals(localName)) {
-                if (mFallBackList != null) {
-                    String ttf = attributes.getValue(ATTR_TTF);
-                    if (ttf != null) {
-                        mFallBackList.add(mOsFontsLocation + ttf);
-                    }
+                    mFontInfo = new FontInfo();
                 }
             }
 
@@ -304,21 +231,80 @@
          */
         @Override
         public void endElement(String uri, String localName, String name) throws SAXException {
-            if (NODE_FONTS.equals(localName)) {
-                // top level, do nothing
-            } else if (NODE_FONT.equals(localName)) {
-                mFontInfo = null;
+            if (NODE_FAMILY.equals(localName)) {
+                if (mFontInfo != null) {
+                    // if has a normal font file, add to the list
+                    if (mFontInfo.font[Typeface.NORMAL] != null) {
+                        mFontList.add(mFontInfo);
+
+                        // create missing font styles, order is important.
+                        if (mFontInfo.font[Typeface.BOLD_ITALIC] == null) {
+                            computeDerivedFont(Typeface.BOLD_ITALIC, DERIVE_BOLD_ITALIC);
+                        }
+                        if (mFontInfo.font[Typeface.ITALIC] == null) {
+                            computeDerivedFont(Typeface.ITALIC, DERIVE_ITALIC);
+                        }
+                        if (mFontInfo.font[Typeface.BOLD] == null) {
+                            computeDerivedFont(Typeface.BOLD, DERIVE_BOLD);
+                        }
+                    }
+
+                    mFontInfo = null;
+                }
             } else if (NODE_NAME.equals(localName)) {
                 // handle a new name for an existing Font Info
                 if (mFontInfo != null) {
                     String family = trimXmlWhitespaces(mBuilder.toString());
                     mFontInfo.families.add(family);
                 }
-            } else if (NODE_FALLBACK.equals(localName)) {
-                // nothing to do here.
+            } else if (NODE_FILE.equals(localName)) {
+                // handle a new file for an existing Font Info
+                if (mFontInfo != null) {
+                    String fileName = trimXmlWhitespaces(mBuilder.toString());
+                    Font font = getFont(fileName);
+                    if (font != null) {
+                        if (fileName.endsWith(FONT_SUFFIX_REGULAR)) {
+                            mFontInfo.font[Typeface.NORMAL] = font;
+                        } else if (fileName.endsWith(FONT_SUFFIX_BOLD)) {
+                            mFontInfo.font[Typeface.BOLD] = font;
+                        } else if (fileName.endsWith(FONT_SUFFIX_ITALIC)) {
+                            mFontInfo.font[Typeface.ITALIC] = font;
+                        } else if (fileName.endsWith(FONT_SUFFIX_BOLDITALIC)) {
+                            mFontInfo.font[Typeface.BOLD_ITALIC] = font;
+                        } else if (fileName.endsWith(FONT_SUFFIX_NONE)) {
+                            mFontInfo.font[Typeface.NORMAL] = font;
+                        }
+                    }
+                }
             }
         }
 
+        private Font getFont(String fileName) {
+            try {
+                File file = new File(mOsFontsLocation, fileName);
+                if (file.exists()) {
+                    return Font.createFont(Font.TRUETYPE_FONT, file);
+                }
+            } catch (Exception e) {
+
+            }
+
+            return null;
+        }
+
+        private void computeDerivedFont( int toCompute, int[] basedOnList) {
+            for (int basedOn : basedOnList) {
+                if (mFontInfo.font[basedOn] != null) {
+                    mFontInfo.font[toCompute] =
+                        mFontInfo.font[basedOn].deriveFont(AWT_STYLES[toCompute]);
+                    return;
+                }
+            }
+
+            // we really shouldn't stop there. This means we don't have a NORMAL font...
+            assert false;
+        }
+
         private String trimXmlWhitespaces(String value) {
             if (value == null) {
                 return null;
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 5ca7aff..1e45f68 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -2597,6 +2597,15 @@
         public boolean processMessage(Message message) {
             if (DBG) log(getName() + message.toString() + "\n");
             switch (message.what) {
+                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
+                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
+                    SupplicantState state = stateChangeResult.state;
+                    // A WEXT bug means that we can be back to driver started state
+                    // unexpectedly
+                    if (SupplicantState.isDriverActive(state)) {
+                        transitionTo(mDriverStartedState);
+                    }
+                    break;
                 case CMD_START_DRIVER:
                     mWakeLock.acquire();
                     WifiNative.startDriverCommand();
@@ -2667,8 +2676,18 @@
                     sendErrorBroadcast(WifiManager.WPS_OVERLAP_ERROR);
                     break;
                 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    handleSupplicantStateChange(message);
-                   break;
+                    SupplicantState state = handleSupplicantStateChange(message);
+                    // Due to a WEXT bug, during the time of driver start/stop
+                    // we can go into a driver stopped state in an unexpected way.
+                    // The sequence eventually puts interface
+                    // up and we should be back to a connected state
+                    if (!SupplicantState.isDriverActive(state)) {
+                        if (mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
+                            handleNetworkDisconnect();
+                        }
+                        transitionTo(mDriverStoppedState);
+                    }
+                    break;
                     /* Do a redundant disconnect without transition */
                 case CMD_DISCONNECT:
                     WifiNative.disconnectCommand();