Merge "Change Activity Scene Transitions to be more automatic."
diff --git a/api/current.txt b/api/current.txt
index 355dc93..4a24522 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -889,6 +889,7 @@
     field public static final int required = 16843406; // 0x101028e
     field public static final int requiredAccountType = 16843734; // 0x10103d6
     field public static final int requiredForAllUsers = 16843728; // 0x10103d0
+    field public static final int requiredForProfile = 16843778; // 0x1010402
     field public static final int requiresFadingEdge = 16843685; // 0x10103a5
     field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
     field public static final int resizeMode = 16843619; // 0x1010363
@@ -3352,17 +3353,6 @@
     method public void update(android.app.ActivityOptions);
   }
 
-  public class ActivityView extends android.view.ViewGroup {
-    ctor public ActivityView(android.content.Context);
-    ctor public ActivityView(android.content.Context, android.util.AttributeSet);
-    ctor public ActivityView(android.content.Context, android.util.AttributeSet, int);
-    method public boolean isAttachedToDisplay();
-    method protected void onLayout(boolean, int, int, int, int);
-    method public void startActivity(android.content.Intent);
-    method public void startActivity(android.content.IntentSender);
-    method public void startActivity(android.app.PendingIntent);
-  }
-
   public class AlarmManager {
     method public void cancel(android.app.PendingIntent);
     method public void set(int, long, android.app.PendingIntent);
@@ -15841,6 +15831,7 @@
     method public static android.nfc.NdefRecord createApplicationRecord(java.lang.String);
     method public static android.nfc.NdefRecord createExternal(java.lang.String, java.lang.String, byte[]);
     method public static android.nfc.NdefRecord createMime(java.lang.String, byte[]);
+    method public static android.nfc.NdefRecord createTextRecord(java.lang.String, java.lang.String);
     method public static android.nfc.NdefRecord createUri(android.net.Uri);
     method public static android.nfc.NdefRecord createUri(java.lang.String);
     method public int describeContents();
@@ -15877,6 +15868,7 @@
     method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
     method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
     method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
+    method public boolean invokeBeam(android.app.Activity);
     method public boolean isEnabled();
     method public boolean isNdefPushEnabled();
     method public void setBeamPushUris(android.net.Uri[], android.app.Activity);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b3c10da..c79a0a5 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1033,7 +1033,7 @@
     /**
      * Called after {@link #onCreate} — or after {@link #onRestart} when  
      * the activity had been stopped, but is now again being displayed to the 
-	 * user.  It will be followed by {@link #onResume}.
+     * user.  It will be followed by {@link #onResume}.
      *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index b40008e..ea0ddc1 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1843,6 +1843,17 @@
             return true;
         }
 
+        case GET_TAG_FOR_INTENT_SENDER_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IIntentSender r = IIntentSender.Stub.asInterface(
+                data.readStrongBinder());
+            String prefix = data.readString();
+            String tag = getTagForIntentSender(r, prefix);
+            reply.writeNoException();
+            reply.writeString(tag);
+            return true;
+        }
+
         case UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             Configuration config = Configuration.CREATOR.createFromParcel(data);
@@ -2038,6 +2049,15 @@
             return true;
         }
 
+        case DELETE_ACTIVITY_CONTAINER_TRANSACTION:  {
+            data.enforceInterface(IActivityManager.descriptor);
+            IActivityContainer activityContainer =
+                    IActivityContainer.Stub.asInterface(data.readStrongBinder());
+            deleteActivityContainer(activityContainer);
+            reply.writeNoException();
+            return true;
+        }
+
         case GET_ACTIVITY_CONTAINER_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder activityToken = data.readStrongBinder();
@@ -4426,6 +4446,21 @@
         return res;
     }
 
+    public String getTagForIntentSender(IIntentSender sender, String prefix)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(sender.asBinder());
+        data.writeString(prefix);
+        mRemote.transact(GET_TAG_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        String res = reply.readString();
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+
     public void updatePersistentConfiguration(Configuration values) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -4697,6 +4732,18 @@
         return res;
     }
 
+    public void deleteActivityContainer(IActivityContainer activityContainer)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(activityContainer.asBinder());
+        mRemote.transact(DELETE_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
             throws RemoteException {
         Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 14f0829..113f123 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -37,6 +37,7 @@
 import android.view.ViewGroup;
 import android.view.WindowManager;
 
+/** @hide */
 public class ActivityView extends ViewGroup {
     private final String TAG = "ActivityView";
     private final boolean DEBUG = false;
@@ -107,6 +108,10 @@
         super.onDetachedFromWindow();
         if (mActivityContainer != null) {
             detach();
+            try {
+                ActivityManagerNative.getDefault().deleteActivityContainer(mActivityContainer);
+            } catch (RemoteException e) {
+            }
             mActivityContainer = null;
         }
     }
@@ -122,7 +127,6 @@
             case  View.INVISIBLE:
                 break;
             case View.GONE:
-                detach();
                 break;
         }
     }
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 6b48130..061e5a5 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1059,7 +1059,7 @@
     }
 
     @Override
-	  public void installPackageWithVerificationAndEncryption(Uri packageURI,
+    public void installPackageWithVerificationAndEncryption(Uri packageURI,
             IPackageInstallObserver observer, int flags, String installerPackageName,
             VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
         try {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index c8f1280..20198f9 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -714,7 +714,7 @@
     }
 
     public final void scheduleSendResult(IBinder token, List<ResultInfo> results)
-    		throws RemoteException {
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
@@ -884,7 +884,7 @@
     }
 
     public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
-	    int flags, Intent args) throws RemoteException {
+            int flags, Intent args) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 873db8e..7efb3f1 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -358,10 +358,11 @@
                             ctx.mMainThread.getHandler());
                 }});
 
-        registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
-                public Object createStaticService() {
+        registerService(CONNECTIVITY_SERVICE, new ServiceFetcher() {
+                public Object createService(ContextImpl ctx) {
                     IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
-                    return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
+                    return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b),
+                        ctx.getPackageName());
                 }});
 
         registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8c7fe10..4412261 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -367,6 +367,8 @@
 
     public Intent getIntentForIntentSender(IIntentSender sender) throws RemoteException;
 
+    public String getTagForIntentSender(IIntentSender sender, String prefix) throws RemoteException;
+
     public void updatePersistentConfiguration(Configuration values) throws RemoteException;
 
     public long[] getProcessPss(int[] pids) throws RemoteException;
@@ -408,9 +410,13 @@
 
     public void performIdleMaintenance() throws RemoteException;
 
+    /** @hide */
     public IActivityContainer createActivityContainer(IBinder parentActivityToken,
             IActivityContainerCallback callback) throws RemoteException;
 
+    /** @hide */
+    public void deleteActivityContainer(IActivityContainer container) throws RemoteException;
+
     public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
             throws RemoteException;
 
@@ -704,4 +710,9 @@
     int APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+182;
     int GET_HOME_ACTIVITY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183;
     int GET_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184;
+    int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
+
+
+    // Start of L transactions
+    int GET_TAG_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+210;
 }
diff --git a/core/java/android/app/OnActivityPausedListener.java b/core/java/android/app/OnActivityPausedListener.java
index 379f133..5003973 100644
--- a/core/java/android/app/OnActivityPausedListener.java
+++ b/core/java/android/app/OnActivityPausedListener.java
@@ -5,7 +5,7 @@
  * 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
+ *        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,
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index d4de112..8efc14f 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -889,6 +889,20 @@
     }
 
     /**
+     * @hide
+     * Return descriptive tag for this PendingIntent.
+     */
+    public String getTag(String prefix) {
+        try {
+            return ActivityManagerNative.getDefault()
+                .getTagForIntentSender(mTarget, prefix);
+        } catch (RemoteException e) {
+            // Should never happen.
+            return null;
+        }
+    }
+
+    /**
      * Comparison operator on two PendingIntent objects, such that true
      * is returned then they both represent the same operation from the
      * same package.  This allows you to use {@link #getActivity},
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 7b8b286..4b33799 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -172,7 +172,7 @@
      * <p>This field corresponds to the <code>android:previewImage</code> attribute in
      * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
      */
-	public int previewImage;
+    public int previewImage;
 
     /**
      * The rules by which a widget can be resized. See {@link #RESIZE_NONE},
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 785f2b4..ef0c4d5 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -209,6 +209,19 @@
      */
     public static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2;
     /**
+     * Flag for {@link #requiredForProfile}
+     * The application will always be installed for a restricted profile.
+     * @hide
+     */
+    public static final int RESTRICTED_PROFILE = 1;
+    /**
+     * Flag for {@link #requiredForProfile}
+     * The application will always be installed for a managed profile.
+     * @hide
+     */
+    public static final int MANAGED_PROFILE = 2;
+
+    /**
      * The install location requested by the activity.  From the
      * {@link android.R.attr#installLocation} attribute, one of
      * {@link #INSTALL_LOCATION_AUTO},
@@ -218,6 +231,12 @@
      */
     public int installLocation = INSTALL_LOCATION_INTERNAL_ONLY;
 
+    /**
+     * Defines which profiles this app is required for.
+     * @hide
+     */
+    public int requiredForProfile;
+
     /** @hide */
     public boolean requiredForAllUsers;
 
@@ -276,6 +295,7 @@
         dest.writeTypedArray(reqFeatures, parcelableFlags);
         dest.writeInt(installLocation);
         dest.writeInt(requiredForAllUsers ? 1 : 0);
+        dest.writeInt(requiredForProfile);
         dest.writeString(restrictedAccountType);
         dest.writeString(requiredAccountType);
         dest.writeString(overlayTarget);
@@ -318,6 +338,7 @@
         reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
         installLocation = source.readInt();
         requiredForAllUsers = source.readInt() != 0;
+        requiredForProfile = source.readInt();
         restrictedAccountType = source.readString();
         requiredAccountType = source.readString();
         overlayTarget = source.readString();
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 7fa9417..c222003 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -304,6 +304,7 @@
         if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0
                 || (pi.applicationInfo.flags&ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
             pi.requiredForAllUsers = p.mRequiredForAllUsers;
+            pi.requiredForProfile = p.mRequiredForProfile;
         }
         pi.restrictedAccountType = p.mRestrictedAccountType;
         pi.requiredAccountType = p.mRequiredAccountType;
@@ -1978,6 +1979,8 @@
                 false)) {
             owner.mRequiredForAllUsers = true;
         }
+        owner.mRequiredForProfile = sa.getInt(
+                com.android.internal.R.styleable.AndroidManifestApplication_requiredForProfile, 0);
 
         String restrictedAccountType = sa.getString(com.android.internal.R.styleable
                 .AndroidManifestApplication_restrictedAccountType);
@@ -3565,6 +3568,9 @@
         /* An app that's required for all users and cannot be uninstalled for a user */
         public boolean mRequiredForAllUsers;
 
+        /* For which types of profile this app is required */
+        public int mRequiredForProfile;
+
         /* The restricted account authenticator type that is used by this application */
         public String mRestrictedAccountType;
 
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index aa4a243..6f1d4f8 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 
 /**
@@ -116,6 +117,14 @@
         return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE;
     }
 
+    /**
+     * @return true if this user can be switched to.
+     **/
+    public boolean supportsSwitchTo() {
+        // TODO remove fw.show_hidden_users when we have finished developing managed profiles.
+        return !isManagedProfile() || SystemProperties.getBoolean("fw.show_hidden_users", false);
+    }
+
     public UserInfo() {
     }
 
diff --git a/core/java/android/hardware/GeomagneticField.java b/core/java/android/hardware/GeomagneticField.java
index 0369825..ef05732 100644
--- a/core/java/android/hardware/GeomagneticField.java
+++ b/core/java/android/hardware/GeomagneticField.java
@@ -361,7 +361,7 @@
             mP[0] = new float[] { 1.0f };
             mPDeriv[0] = new float[] { 0.0f };
             for (int n = 1; n <= maxN; n++) {
-            	mP[n] = new float[n + 1];
+                mP[n] = new float[n + 1];
                 mPDeriv[n] = new float[n + 1];
                 for (int m = 0; m <= n; m++) {
                     if (n == m) {
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index cbd6ec3..ff12d77 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -999,7 +999,7 @@
     /**
      * <p>Use specific scene mode. Enabling this disables
      * control.aeMode, control.awbMode and control.afMode
-     * controls; the HAL must ignore those settings while
+     * controls; the camera device will ignore those settings while
      * USE_SCENE_MODE is active (except for FACE_PRIORITY
      * scene mode). Other control entries are still active.
      * This setting can only be used if availableSceneModes !=
@@ -1468,14 +1468,16 @@
 
     /**
      * <p>AE is off or recently reset. When a camera device is opened, it starts in
-     * this state.</p>
+     * this state. This is a transient state, the camera device may skip reporting
+     * this state in capture result.</p>
      * @see CaptureResult#CONTROL_AE_STATE
      */
     public static final int CONTROL_AE_STATE_INACTIVE = 0;
 
     /**
      * <p>AE doesn't yet have a good set of control values
-     * for the current scene.</p>
+     * for the current scene. This is a transient state, the camera device may skip
+     * reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AE_STATE
      */
     public static final int CONTROL_AE_STATE_SEARCHING = 1;
@@ -1506,7 +1508,8 @@
      * (through the {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} START),
      * and is currently executing it. Once PRECAPTURE
      * completes, AE will transition to CONVERGED or
-     * FLASH_REQUIRED as appropriate.</p>
+     * FLASH_REQUIRED as appropriate. This is a transient state, the
+     * camera device may skip reporting this state in capture result.</p>
      *
      * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
      * @see CaptureResult#CONTROL_AE_STATE
@@ -1520,7 +1523,8 @@
     /**
      * <p>AF off or has not yet tried to scan/been asked
      * to scan.  When a camera device is opened, it starts in
-     * this state.</p>
+     * this state. This is a transient state, the camera device may
+     * skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_INACTIVE = 0;
@@ -1528,7 +1532,8 @@
     /**
      * <p>if CONTINUOUS_* modes are supported. AF is
      * currently doing an AF scan initiated by a continuous
-     * autofocus mode</p>
+     * autofocus mode. This is a transient state, the camera device may
+     * skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_PASSIVE_SCAN = 1;
@@ -1536,15 +1541,17 @@
     /**
      * <p>if CONTINUOUS_* modes are supported. AF currently
      * believes it is in focus, but may restart scanning at
-     * any time.</p>
+     * any time. This is a transient state, the camera device may skip
+     * reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_PASSIVE_FOCUSED = 2;
 
     /**
      * <p>if AUTO or MACRO modes are supported. AF is doing
-     * an AF scan because it was triggered by AF
-     * trigger</p>
+     * an AF scan because it was triggered by AF trigger. This is a
+     * transient state, the camera device may skip reporting
+     * this state in capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_ACTIVE_SCAN = 3;
@@ -1552,7 +1559,7 @@
     /**
      * <p>if any AF mode besides OFF is supported. AF
      * believes it is focused correctly and is
-     * locked</p>
+     * locked.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_FOCUSED_LOCKED = 4;
@@ -1560,7 +1567,7 @@
     /**
      * <p>if any AF mode besides OFF is supported. AF has
      * failed to focus successfully and is
-     * locked</p>
+     * locked.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5;
@@ -1568,7 +1575,8 @@
     /**
      * <p>if CONTINUOUS_* modes are supported. AF finished a
      * passive scan without finding focus, and may restart
-     * scanning at any time.</p>
+     * scanning at any time. This is a transient state, the camera
+     * device may skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_PASSIVE_UNFOCUSED = 6;
@@ -1579,14 +1587,16 @@
 
     /**
      * <p>AWB is not in auto mode.  When a camera device is opened, it
-     * starts in this state.</p>
+     * starts in this state. This is a transient state, the camera device may
+     * skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AWB_STATE
      */
     public static final int CONTROL_AWB_STATE_INACTIVE = 0;
 
     /**
      * <p>AWB doesn't yet have a good set of control
-     * values for the current scene.</p>
+     * values for the current scene. This is a transient state, the camera device
+     * may skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AWB_STATE
      */
     public static final int CONTROL_AWB_STATE_SEARCHING = 1;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index dfde11b..c8668f5 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -390,7 +390,7 @@
 
     /**
      * <p>Gains applying to Bayer raw color channels for
-     * white-balance</p>
+     * white-balance.</p>
      * <p>The 4-channel white-balance gains are defined in
      * the order of <code>[R G_even G_odd B]</code>, where <code>G_even</code> is the gain
      * for green pixels on even rows of the output, and <code>G_odd</code>
@@ -398,11 +398,11 @@
      * does not support a separate gain for even/odd green channels,
      * it should use the <code>G_even</code> value, and write <code>G_odd</code> equal to
      * <code>G_even</code> in the output result metadata.</p>
-     * <p>This array is either set by HAL when the request
+     * <p>This array is either set by the camera device when the request
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is not TRANSFORM_MATRIX, or
      * directly by the application in the request when the
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
-     * <p>The output should be the gains actually applied by the HAL to
+     * <p>The output should be the gains actually applied by the camera device to
      * the current frame.</p>
      *
      * @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -536,9 +536,9 @@
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
      * <p>If all regions have 0 weight, then no specific metering area
-     * needs to be used by the HAL. If the metering region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * needs to be used by the camera device. If the metering region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -579,13 +579,15 @@
     /**
      * <p>Whether AF is currently enabled, and what
      * mode it is set to</p>
-     * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO.</p>
+     * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO and the lens is not fixed focus
+     * (i.e. <code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} &gt; 0</code>).</p>
      * <p>If the lens is controlled by the camera device auto-focus algorithm,
      * the camera device will report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState}
      * in result metadata.</p>
      *
      * @see CaptureResult#CONTROL_AF_STATE
      * @see CaptureRequest#CONTROL_MODE
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
      * @see #CONTROL_AF_MODE_OFF
      * @see #CONTROL_AF_MODE_AUTO
      * @see #CONTROL_AF_MODE_MACRO
@@ -609,9 +611,9 @@
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
      * <p>If all regions have 0 weight, then no specific focus area
-     * needs to be used by the HAL. If the focusing region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * needs to be used by the camera device. If the focusing region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -651,14 +653,14 @@
     /**
      * <p>Whether AWB is currently setting the color
      * transform fields, and what its illumination target
-     * is</p>
+     * is.</p>
      * <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
      * <p>When set to the ON mode, the camera device's auto white balance
      * routine is enabled, overriding the application's selected
      * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
      * <p>When set to the OFF mode, the camera device's auto white balance
-     * routine is disabled. The applicantion manually controls the white
+     * routine is disabled. The application manually controls the white
      * balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
      * and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
      * <p>When set to any other modes, the camera device's auto white balance
@@ -695,10 +697,10 @@
      * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
-     * <p>If all regions have 0 weight, then no specific metering area
-     * needs to be used by the HAL. If the metering region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * <p>If all regions have 0 weight, then no specific auto-white balance (AWB) area
+     * needs to be used by the camera device. If the AWB region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -753,7 +755,7 @@
 
     /**
      * <p>Overall mode of 3A control
-     * routines</p>
+     * routines.</p>
      * <p>High-level 3A control. When set to OFF, all 3A control
      * by the camera device is disabled. The application must set the fields for
      * capture parameters itself.</p>
@@ -830,9 +832,9 @@
 
     /**
      * <p>Operation mode for edge
-     * enhancement</p>
+     * enhancement.</p>
      * <p>Edge/sharpness/detail enhancement. OFF means no
-     * enhancement will be applied by the HAL.</p>
+     * enhancement will be applied by the camera device.</p>
      * <p>FAST/HIGH_QUALITY both mean camera device determined enhancement
      * will be applied. HIGH_QUALITY mode indicates that the
      * camera device will use the highest-quality enhancement algorithms,
@@ -1044,7 +1046,7 @@
      * <p>Mode of operation for the noise reduction
      * algorithm</p>
      * <p>Noise filtering control. OFF means no noise reduction
-     * will be applied by the HAL.</p>
+     * will be applied by the camera device.</p>
      * <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
      * will be applied. HIGH_QUALITY mode indicates that the camera device
      * will use the highest-quality noise filtering algorithms,
@@ -1285,8 +1287,8 @@
             new Key<Integer>("android.statistics.faceDetectMode", int.class);
 
     /**
-     * <p>Whether the HAL needs to output the lens
-     * shading map in output result metadata</p>
+     * <p>Whether the camera device will output the lens
+     * shading map in output result metadata.</p>
      * <p>When set to ON,
      * {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} must be provided in
      * the output result metadata.</p>
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index bd9ba2f..0749edd 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -143,7 +143,7 @@
 
     /**
      * <p>Gains applying to Bayer raw color channels for
-     * white-balance</p>
+     * white-balance.</p>
      * <p>The 4-channel white-balance gains are defined in
      * the order of <code>[R G_even G_odd B]</code>, where <code>G_even</code> is the gain
      * for green pixels on even rows of the output, and <code>G_odd</code>
@@ -151,11 +151,11 @@
      * does not support a separate gain for even/odd green channels,
      * it should use the <code>G_even</code> value, and write <code>G_odd</code> equal to
      * <code>G_even</code> in the output result metadata.</p>
-     * <p>This array is either set by HAL when the request
+     * <p>This array is either set by the camera device when the request
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is not TRANSFORM_MATRIX, or
      * directly by the application in the request when the
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
-     * <p>The output should be the gains actually applied by the HAL to
+     * <p>The output should be the gains actually applied by the camera device to
      * the current frame.</p>
      *
      * @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -225,9 +225,9 @@
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
      * <p>If all regions have 0 weight, then no specific metering area
-     * needs to be used by the HAL. If the metering region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * needs to be used by the camera device. If the metering region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -370,6 +370,54 @@
      * </tr>
      * </tbody>
      * </table>
+     * <p>For the above table, the camera device may skip reporting any state changes that happen
+     * without application intervention (i.e. mode switch, trigger, locking). Any state that
+     * can be skipped in that manner is called a transient state.</p>
+     * <p>For example, for above AE modes (AE_MODE_ON_*), in addition to the state transitions
+     * listed in above table, it is also legal for the camera device to skip one or more
+     * transient states between two results. See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device finished AE scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Values are already good, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is START, sequence done</td>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Converged but too dark w/o flash after a precapture sequence, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is START, sequence done</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Converged after a precapture sequence, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Camera device finished AE scan</td>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Converged but too dark w/o flash after a new scan, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Camera device finished AE scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Converged after a new scan, transient states are skipped by camera device.</td>
+     * </tr>
+     * </tbody>
+     * </table>
      *
      * @see CaptureRequest#CONTROL_AE_LOCK
      * @see CaptureRequest#CONTROL_AE_MODE
@@ -389,13 +437,15 @@
     /**
      * <p>Whether AF is currently enabled, and what
      * mode it is set to</p>
-     * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO.</p>
+     * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO and the lens is not fixed focus
+     * (i.e. <code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} &gt; 0</code>).</p>
      * <p>If the lens is controlled by the camera device auto-focus algorithm,
      * the camera device will report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState}
      * in result metadata.</p>
      *
      * @see CaptureResult#CONTROL_AF_STATE
      * @see CaptureRequest#CONTROL_MODE
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
      * @see #CONTROL_AF_MODE_OFF
      * @see #CONTROL_AF_MODE_AUTO
      * @see #CONTROL_AF_MODE_MACRO
@@ -419,9 +469,9 @@
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
      * <p>If all regions have 0 weight, then no specific focus area
-     * needs to be used by the HAL. If the focusing region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * needs to be used by the camera device. If the focusing region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -431,7 +481,7 @@
             new Key<int[]>("android.control.afRegions", int[].class);
 
     /**
-     * <p>Current state of AF algorithm</p>
+     * <p>Current state of AF algorithm.</p>
      * <p>Switching between or enabling AF modes ({@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}) always
      * resets the AF state to INACTIVE. Similarly, switching between {@link CaptureRequest#CONTROL_MODE android.control.mode},
      * or {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} if <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code> resets all
@@ -529,6 +579,48 @@
      * </tr>
      * </tbody>
      * </table>
+     * <p>For the above table, the camera device may skip reporting any state changes that happen
+     * without application intervention (i.e. mode switch, trigger, locking). Any state that
+     * can be skipped in that manner is called a transient state.</p>
+     * <p>For example, for these AF modes (AF_MODE_AUTO and AF_MODE_MACRO), in addition to the
+     * state transitions listed in above table, it is also legal for the camera device to skip
+     * one or more transient states between two results. See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Focus is already good or good after a scan, lens is now locked.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Focus failed after a scan, lens is now locked.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Focus is already good or good after a scan, lens is now locked.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Focus is good after a scan, lens is not locked.</td>
+     * </tr>
+     * </tbody>
+     * </table>
      * <p>When {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} is AF_MODE_CONTINUOUS_VIDEO:</p>
      * <table>
      * <thead>
@@ -735,6 +827,41 @@
      * </tr>
      * </tbody>
      * </table>
+     * <p>When switch between AF_MODE_CONTINUOUS_* (CAF modes) and AF_MODE_AUTO/AF_MODE_MACRO
+     * (AUTO modes), the initial INACTIVE or PASSIVE_SCAN states may be skipped by the
+     * camera device. When a trigger is included in a mode switch request, the trigger
+     * will be evaluated in the context of the new mode in the request.
+     * See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">any state</td>
+     * <td align="center">CAF--&gt;AUTO mode switch</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Mode switch without trigger, initial state must be INACTIVE</td>
+     * </tr>
+     * <tr>
+     * <td align="center">any state</td>
+     * <td align="center">CAF--&gt;AUTO mode switch with AF_TRIGGER</td>
+     * <td align="center">trigger-reachable states from INACTIVE</td>
+     * <td align="center">Mode switch with trigger, INACTIVE is skipped</td>
+     * </tr>
+     * <tr>
+     * <td align="center">any state</td>
+     * <td align="center">AUTO--&gt;CAF mode switch</td>
+     * <td align="center">passively reachable states from INACTIVE</td>
+     * <td align="center">Mode switch without trigger, passive transient state is skipped</td>
+     * </tr>
+     * </tbody>
+     * </table>
      *
      * @see CaptureRequest#CONTROL_AF_MODE
      * @see CaptureRequest#CONTROL_MODE
@@ -764,14 +891,14 @@
     /**
      * <p>Whether AWB is currently setting the color
      * transform fields, and what its illumination target
-     * is</p>
+     * is.</p>
      * <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
      * <p>When set to the ON mode, the camera device's auto white balance
      * routine is enabled, overriding the application's selected
      * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
      * <p>When set to the OFF mode, the camera device's auto white balance
-     * routine is disabled. The applicantion manually controls the white
+     * routine is disabled. The application manually controls the white
      * balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
      * and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
      * <p>When set to any other modes, the camera device's auto white balance
@@ -808,10 +935,10 @@
      * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
-     * <p>If all regions have 0 weight, then no specific metering area
-     * needs to be used by the HAL. If the metering region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * <p>If all regions have 0 weight, then no specific auto-white balance (AWB) area
+     * needs to be used by the camera device. If the AWB region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -905,11 +1032,35 @@
      * <td align="center">SEARCHING</td>
      * <td align="center">Values not good after unlock</td>
      * </tr>
+     * </tbody>
+     * </table>
+     * <p>For the above table, the camera device may skip reporting any state changes that happen
+     * without application intervention (i.e. mode switch, trigger, locking). Any state that
+     * can be skipped in that manner is called a transient state.</p>
+     * <p>For example, for this AWB mode (AWB_MODE_AUTO), in addition to the state transitions
+     * listed in above table, it is also legal for the camera device to skip one or more
+     * transient states between two results. See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device finished AWB scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Values are already good, transient states are skipped by camera device.</td>
+     * </tr>
      * <tr>
      * <td align="center">LOCKED</td>
      * <td align="center">{@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock} is OFF</td>
      * <td align="center">CONVERGED</td>
-     * <td align="center">Values good after unlock</td>
+     * <td align="center">Values good after unlock, transient states are skipped by camera device.</td>
      * </tr>
      * </tbody>
      * </table>
@@ -928,7 +1079,7 @@
 
     /**
      * <p>Overall mode of 3A control
-     * routines</p>
+     * routines.</p>
      * <p>High-level 3A control. When set to OFF, all 3A control
      * by the camera device is disabled. The application must set the fields for
      * capture parameters itself.</p>
@@ -956,9 +1107,9 @@
 
     /**
      * <p>Operation mode for edge
-     * enhancement</p>
+     * enhancement.</p>
      * <p>Edge/sharpness/detail enhancement. OFF means no
-     * enhancement will be applied by the HAL.</p>
+     * enhancement will be applied by the camera device.</p>
      * <p>FAST/HIGH_QUALITY both mean camera device determined enhancement
      * will be applied. HIGH_QUALITY mode indicates that the
      * camera device will use the highest-quality enhancement algorithms,
@@ -1236,7 +1387,7 @@
      * <p>Mode of operation for the noise reduction
      * algorithm</p>
      * <p>Noise filtering control. OFF means no noise reduction
-     * will be applied by the HAL.</p>
+     * will be applied by the camera device.</p>
      * <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
      * will be applied. HIGH_QUALITY mode indicates that the camera device
      * will use the highest-quality noise filtering algorithms,
@@ -1262,7 +1413,7 @@
      * before the FINAL buffer for frame 4. PARTIAL buffers may be returned
      * in any order relative to other frames, but all PARTIAL buffers for a given
      * capture must arrive before the FINAL buffer for that capture. This entry may
-     * only be used by the HAL if quirks.usePartialResult is set to 1.</p>
+     * only be used by the camera device if quirks.usePartialResult is set to 1.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      * @hide
      */
@@ -1755,7 +1906,7 @@
 
     /**
      * <p>The best-fit color channel gains calculated
-     * by the HAL's statistics units for the current output frame</p>
+     * by the camera device's statistics units for the current output frame.</p>
      * <p>This may be different than the gains used for this frame,
      * since statistics processing on data from a new frame
      * typically completes after the transform has already been
@@ -1774,11 +1925,11 @@
 
     /**
      * <p>The best-fit color transform matrix estimate
-     * calculated by the HAL's statistics units for the current
-     * output frame</p>
-     * <p>The HAL must provide the estimate from its
+     * calculated by the camera device's statistics units for the current
+     * output frame.</p>
+     * <p>The camera device will provide the estimate from its
      * statistics unit on the white balance transforms to use
-     * for the next frame. These are the values the HAL believes
+     * for the next frame. These are the values the camera device believes
      * are the best fit for the current output frame. This may
      * be different than the transform used for this frame, since
      * statistics processing on data from a new frame typically
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3a35cb9..e6b9d4c 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -400,6 +400,8 @@
 
     private final IConnectivityManager mService;
 
+    private final String mPackageName;
+
     /**
      * Tests if a given integer represents a valid network type.
      * @param networkType the type to be tested
@@ -811,7 +813,7 @@
     public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
         byte[] address = hostAddress.getAddress();
         try {
-            return mService.requestRouteToHostAddress(networkType, address);
+            return mService.requestRouteToHostAddress(networkType, address, mPackageName);
         } catch (RemoteException e) {
             return false;
         }
@@ -907,8 +909,9 @@
     /**
      * {@hide}
      */
-    public ConnectivityManager(IConnectivityManager service) {
+    public ConnectivityManager(IConnectivityManager service, String packageName) {
         mService = checkNotNull(service, "missing IConnectivityManager");
+        mPackageName = checkNotNull(packageName, "missing package name");
     }
 
     /** {@hide} */
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b3217eb..381a817 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -71,9 +71,9 @@
 
     int stopUsingNetworkFeature(int networkType, in String feature);
 
-    boolean requestRouteToHost(int networkType, int hostAddress);
+    boolean requestRouteToHost(int networkType, int hostAddress, String packageName);
 
-    boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
+    boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, String packageName);
 
     boolean getMobileDataEnabled();
     void setMobileDataEnabled(boolean enabled);
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index a7aae2a..25514f4 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -44,6 +44,8 @@
     public static final String IFACE_ALL = null;
     /** {@link #uid} value when UID details unavailable. */
     public static final int UID_ALL = -1;
+    /** {@link #tag} value matching any tag. */
+    public static final int TAG_ALL = -1;
     /** {@link #set} value when all sets combined. */
     public static final int SET_ALL = -1;
     /** {@link #set} value where background data is accounted. */
@@ -59,8 +61,9 @@
      * {@link SystemClock#elapsedRealtime()} timestamp when this data was
      * generated.
      */
-    private final long elapsedRealtime;
+    private long elapsedRealtime;
     private int size;
+    private int capacity;
     private String[] iface;
     private int[] uid;
     private int[] set;
@@ -152,20 +155,27 @@
     public NetworkStats(long elapsedRealtime, int initialSize) {
         this.elapsedRealtime = elapsedRealtime;
         this.size = 0;
-        this.iface = new String[initialSize];
-        this.uid = new int[initialSize];
-        this.set = new int[initialSize];
-        this.tag = new int[initialSize];
-        this.rxBytes = new long[initialSize];
-        this.rxPackets = new long[initialSize];
-        this.txBytes = new long[initialSize];
-        this.txPackets = new long[initialSize];
-        this.operations = new long[initialSize];
+        if (initialSize >= 0) {
+            this.capacity = initialSize;
+            this.iface = new String[initialSize];
+            this.uid = new int[initialSize];
+            this.set = new int[initialSize];
+            this.tag = new int[initialSize];
+            this.rxBytes = new long[initialSize];
+            this.rxPackets = new long[initialSize];
+            this.txBytes = new long[initialSize];
+            this.txPackets = new long[initialSize];
+            this.operations = new long[initialSize];
+        } else {
+            // Special case for use by NetworkStatsFactory to start out *really* empty.
+            this.capacity = 0;
+        }
     }
 
     public NetworkStats(Parcel parcel) {
         elapsedRealtime = parcel.readLong();
         size = parcel.readInt();
+        capacity = parcel.readInt();
         iface = parcel.createStringArray();
         uid = parcel.createIntArray();
         set = parcel.createIntArray();
@@ -181,6 +191,7 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeLong(elapsedRealtime);
         dest.writeInt(size);
+        dest.writeInt(capacity);
         dest.writeStringArray(iface);
         dest.writeIntArray(uid);
         dest.writeIntArray(set);
@@ -222,8 +233,8 @@
      * object can be recycled across multiple calls.
      */
     public NetworkStats addValues(Entry entry) {
-        if (size >= this.iface.length) {
-            final int newLength = Math.max(iface.length, 10) * 3 / 2;
+        if (size >= capacity) {
+            final int newLength = Math.max(size, 10) * 3 / 2;
             iface = Arrays.copyOf(iface, newLength);
             uid = Arrays.copyOf(uid, newLength);
             set = Arrays.copyOf(set, newLength);
@@ -233,6 +244,7 @@
             txBytes = Arrays.copyOf(txBytes, newLength);
             txPackets = Arrays.copyOf(txPackets, newLength);
             operations = Arrays.copyOf(operations, newLength);
+            capacity = newLength;
         }
 
         iface[size] = entry.iface;
@@ -270,6 +282,10 @@
         return elapsedRealtime;
     }
 
+    public void setElapsedRealtime(long time) {
+        elapsedRealtime = time;
+    }
+
     /**
      * Return age of this {@link NetworkStats} object with respect to
      * {@link SystemClock#elapsedRealtime()}.
@@ -284,7 +300,7 @@
 
     @VisibleForTesting
     public int internalSize() {
-        return iface.length;
+        return capacity;
     }
 
     @Deprecated
@@ -507,8 +523,25 @@
      * If counters have rolled backwards, they are clamped to {@code 0} and
      * reported to the given {@link NonMonotonicObserver}.
      */
-    public static <C> NetworkStats subtract(
-            NetworkStats left, NetworkStats right, NonMonotonicObserver<C> observer, C cookie) {
+    public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right,
+            NonMonotonicObserver<C> observer, C cookie) {
+        return subtract(left, right, observer, cookie, null);
+    }
+
+    /**
+     * Subtract the two given {@link NetworkStats} objects, returning the delta
+     * between two snapshots in time. Assumes that statistics rows collect over
+     * time, and that none of them have disappeared.
+     * <p>
+     * If counters have rolled backwards, they are clamped to {@code 0} and
+     * reported to the given {@link NonMonotonicObserver}.
+     * <p>
+     * If <var>recycle</var> is supplied, this NetworkStats object will be
+     * reused (and returned) as the result if it is large enough to contain
+     * the data.
+     */
+    public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right,
+            NonMonotonicObserver<C> observer, C cookie, NetworkStats recycle) {
         long deltaRealtime = left.elapsedRealtime - right.elapsedRealtime;
         if (deltaRealtime < 0) {
             if (observer != null) {
@@ -519,7 +552,14 @@
 
         // result will have our rows, and elapsed time between snapshots
         final Entry entry = new Entry();
-        final NetworkStats result = new NetworkStats(deltaRealtime, left.size);
+        final NetworkStats result;
+        if (recycle != null && recycle.capacity >= left.size) {
+            result = recycle;
+            result.size = 0;
+            result.elapsedRealtime = deltaRealtime;
+        } else {
+            result = new NetworkStats(deltaRealtime, left.size);
+        }
         for (int i = 0; i < left.size; i++) {
             entry.iface = left.iface[i];
             entry.uid = left.uid[i];
diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java
index a7d287b..461e8b8 100644
--- a/core/java/android/net/ProxyDataTracker.java
+++ b/core/java/android/net/ProxyDataTracker.java
@@ -16,13 +16,24 @@
 
 package android.net;
 
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -31,27 +42,70 @@
  * {@hide}
  */
 public class ProxyDataTracker extends BaseNetworkStateTracker {
-    private static final String NETWORK_TYPE = "PROXY";
     private static final String TAG = "ProxyDataTracker";
+    private static final String NETWORK_TYPE = "PROXY";
 
     // TODO: investigate how to get these DNS addresses from the system.
     private static final String DNS1 = "8.8.8.8";
     private static final String DNS2 = "8.8.4.4";
     private static final String REASON_ENABLED = "enabled";
+    private static final String REASON_DISABLED = "disabled";
+    private static final String REASON_PROXY_DOWN = "proxy_down";
 
+    private static final int MSG_TEAR_DOWN_REQUEST = 1;
+    private static final int MSG_SETUP_REQUEST = 2;
+
+    private static final String PERMISSION_PROXY_STATUS_SENDER =
+            "android.permission.ACCESS_NETWORK_CONDITIONS";
+    private static final String ACTION_PROXY_STATUS_CHANGE =
+            "com.android.net.PROXY_STATUS_CHANGE";
+    private static final String KEY_IS_PROXY_AVAILABLE = "is_proxy_available";
+    private static final String KEY_REPLY_TO_MESSENGER_BINDER = "reply_to_messenger_binder";
+    private static final String KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE =
+            "reply_to_messenger_binder_bundle";
+
+    private Handler mTarget;
+    private Messenger mProxyStatusService;
+    private AtomicBoolean mReconnectRequested = new AtomicBoolean(false);
+    private AtomicBoolean mIsProxyAvailable = new AtomicBoolean(false);
     private final AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
-    private final AtomicInteger mReconnectGeneration = new AtomicInteger(0);
+
+    private final BroadcastReceiver mProxyStatusServiceListener = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(ACTION_PROXY_STATUS_CHANGE)) {
+                mIsProxyAvailable.set(intent.getBooleanExtra(KEY_IS_PROXY_AVAILABLE, false));
+                if (mIsProxyAvailable.get()) {
+                    Bundle bundle = intent.getBundleExtra(KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE);
+                    if (bundle == null || bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER) == null) {
+                        Log.e(TAG, "no messenger binder in the intent to send future requests");
+                        mIsProxyAvailable.set(false);
+                        return;
+                    }
+                    mProxyStatusService =
+                            new Messenger(bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER));
+                    // If there is a pending reconnect request, do it now.
+                    if (mReconnectRequested.get()) {
+                        reconnect();
+                    }
+                } else {
+                    setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
+                            REASON_PROXY_DOWN, null);
+                }
+            } else {
+                Log.d(TAG, "Unrecognized broadcast intent");
+            }
+        }
+    };
 
     /**
      * Create a new ProxyDataTracker
      */
     public ProxyDataTracker() {
         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_PROXY, 0, NETWORK_TYPE, "");
-        // TODO: update available state according to proxy state.
-        mNetworkInfo.setIsAvailable(true);
         mLinkProperties = new LinkProperties();
         mLinkCapabilities = new LinkCapabilities();
-
+        mNetworkInfo.setIsAvailable(true);
         try {
           mLinkProperties.addDns(InetAddress.getByName(DNS1));
           mLinkProperties.addDns(InetAddress.getByName(DNS2));
@@ -64,11 +118,31 @@
         throw new CloneNotSupportedException();
     }
 
+    @Override
+    public void startMonitoring(Context context, Handler target) {
+        mContext = context;
+        mTarget = target;
+        mContext.registerReceiver(mProxyStatusServiceListener,
+                new IntentFilter(ACTION_PROXY_STATUS_CHANGE),
+                PERMISSION_PROXY_STATUS_SENDER,
+                null);
+    }
+
     /**
      * Disable connectivity to the network.
      */
     public boolean teardown() {
-        // TODO: tell relevant service to tear down proxy.
+        setTeardownRequested(true);
+        mReconnectRequested.set(false);
+        try {
+            if (mIsProxyAvailable.get() && mProxyStatusService != null) {
+                mProxyStatusService.send(Message.obtain(null, MSG_TEAR_DOWN_REQUEST));
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to connect to proxy status service", e);
+            return false;
+        }
+        setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_DISABLED, null);
         return true;
     }
 
@@ -76,16 +150,24 @@
      * Re-enable proxy data connectivity after a {@link #teardown()}.
      */
     public boolean reconnect() {
-        if (!isAvailable()) {
-            Log.w(TAG, "Reconnect requested even though network is disabled. Bailing.");
+        mReconnectRequested.set(true);
+        setTeardownRequested(false);
+        if (!mIsProxyAvailable.get()) {
+            Log.w(TAG, "Reconnect requested even though proxy service is not up. Bailing.");
             return false;
         }
-        setTeardownRequested(false);
-        mReconnectGeneration.incrementAndGet();
-        // TODO: tell relevant service to setup proxy. Set state to connected only if setup
-        // succeeds.
-        setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null);
+        setDetailedState(NetworkInfo.DetailedState.CONNECTING, REASON_ENABLED, null);
 
+        try {
+            mProxyStatusService.send(Message.obtain(null, MSG_SETUP_REQUEST));
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to connect to proxy status service", e);
+            setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_PROXY_DOWN, null);
+            return false;
+        }
+        // We'll assume proxy is set up successfully. If not, a status change broadcast will be
+        // received afterwards to indicate any failure.
+        setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null);
         return true;
     }
 
@@ -116,7 +198,7 @@
     private void setDetailedState(NetworkInfo.DetailedState state, String reason,
             String extraInfo) {
         mNetworkInfo.setDetailedState(state, reason, extraInfo);
-        Message msg = getTargetHandler().obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
+        Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
         msg.sendToTarget();
     }
 }
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 10988c6..635a50f 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -48,6 +48,7 @@
     void setForegroundDispatch(in PendingIntent intent,
             in IntentFilter[] filters, in TechListParcel techLists);
     void setAppCallback(in IAppCallback callback);
+    void invokeBeam();
 
     void dispatch(in Tag tag);
 
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index de481cf..83d17ba 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -20,6 +20,7 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import java.nio.BufferUnderflowException;
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
@@ -474,6 +475,45 @@
     }
 
     /**
+     * Create a new NDEF record containing UTF-8 text data.<p>
+     *
+     * The caller can either specify the language code for the provided text,
+     * or otherwise the language code corresponding to the current default
+     * locale will be used.
+     *
+     * Reference specification: NFCForum-TS-RTD_Text_1.0
+     * @param languageCode The languageCode for the record. If locale is empty or null,
+     *                     the language code of the current default locale will be used.
+     * @param text   The text to be encoded in the record. Will be represented in UTF-8 format.
+     * @throws IllegalArgumentException if text is null
+     */
+    public static NdefRecord createTextRecord(String languageCode, String text) {
+        if (text == null) throw new NullPointerException("text is null");
+
+        byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
+
+        byte[] languageCodeBytes = null;
+        if (languageCode != null && !languageCode.isEmpty()) {
+            languageCodeBytes = languageCode.getBytes(StandardCharsets.US_ASCII);
+        } else {
+            languageCodeBytes = Locale.getDefault().getLanguage().
+                    getBytes(StandardCharsets.US_ASCII);
+        }
+        // We only have 6 bits to indicate ISO/IANA language code.
+        if (languageCodeBytes.length >= 64) {
+            throw new IllegalArgumentException("language code is too long, must be <64 bytes.");
+        }
+        ByteBuffer buffer = ByteBuffer.allocate(1 + languageCodeBytes.length + textBytes.length);
+
+        byte status = (byte) (languageCodeBytes.length & 0xFF);
+        buffer.put(status);
+        buffer.put(languageCodeBytes);
+        buffer.put(textBytes);
+
+        return new NdefRecord(TNF_WELL_KNOWN, RTD_TEXT, null, buffer.array());
+    }
+
+    /**
      * Construct an NDEF Record from its component fields.<p>
      * Recommend to use helpers such as {#createUri} or
      * {{@link #createExternal} where possible, since they perform
@@ -775,7 +815,7 @@
                     throw new FormatException("expected TNF_UNCHANGED in non-leading chunk");
                 } else if (!inChunk && tnf == NdefRecord.TNF_UNCHANGED) {
                     throw new FormatException("" +
-                    		"unexpected TNF_UNCHANGED in first chunk or unchunked record");
+                            "unexpected TNF_UNCHANGED in first chunk or unchunked record");
                 }
 
                 int typeLength = buffer.get() & 0xFF;
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 77c0234..8643f2e 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.app.Application;
+import android.content.Intent;
 import android.net.Uri;
 import android.nfc.NfcAdapter.ReaderCallback;
 import android.os.Binder;
@@ -327,6 +328,7 @@
         NfcAdapter.CreateNdefMessageCallback ndefCallback;
         NfcAdapter.CreateBeamUrisCallback urisCallback;
         NdefMessage message;
+        Activity activity;
         Uri[] uris;
         int flags;
         synchronized (NfcActivityManager.this) {
@@ -338,6 +340,7 @@
             message = state.ndefMessage;
             uris = state.uris;
             flags = state.flags;
+            activity = state.activity;
         }
 
         // Make callbacks without lock
@@ -362,7 +365,13 @@
                 }
             }
         }
-
+        if (uris != null && uris.length > 0) {
+            for (Uri uri : uris) {
+                // Grant the NFC process permission to read these URIs
+                activity.grantUriPermission("com.android.nfc", uri,
+                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            }
+        }
         return new BeamShareData(message, uris, flags);
     }
 
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index e8b7437..96a3947 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -1249,6 +1249,45 @@
     }
 
     /**
+     * Manually invoke Android Beam to share data.
+     *
+     * <p>The Android Beam animation is normally only shown when two NFC-capable
+     * devices come into range.
+     * By calling this method, an Activity can invoke the Beam animation directly
+     * even if no other NFC device is in range yet. The Beam animation will then
+     * prompt the user to tap another NFC-capable device to complete the data
+     * transfer.
+     *
+     * <p>The main advantage of using this method is that it avoids the need for the
+     * user to tap the screen to complete the transfer, as this method already
+     * establishes the direction of the transfer and the consent of the user to
+     * share data. Callers are responsible for making sure that the user has
+     * consented to sharing data on NFC tap.
+     *
+     * <p>Note that to use this method, the passed in Activity must have already
+     * set data to share over Beam by using method calls such as
+     * {@link #setNdefPushMessageCallback} or
+     * {@link #setBeamPushUrisCallback}.
+     *
+     * @param activity the current foreground Activity that has registered data to share
+     * @return whether the Beam animation was successfully invoked
+     */
+    public boolean invokeBeam(Activity activity) {
+        if (activity == null) {
+            throw new NullPointerException("activity may not be null.");
+        }
+        enforceResumed(activity);
+        try {
+            sService.invokeBeam();
+            return true;
+        } catch (RemoteException e) {
+            Log.e(TAG, "invokeBeam: NFC process has died.");
+            attemptDeadServiceRecovery(e);
+            return false;
+        }
+    }
+
+    /**
      * Enable NDEF message push over NFC while this Activity is in the foreground.
      *
      * <p>You must explicitly call this method every time the activity is
diff --git a/core/java/android/os/BatteryProperties.java b/core/java/android/os/BatteryProperties.java
index 2d67264..8f5cf8b 100644
--- a/core/java/android/os/BatteryProperties.java
+++ b/core/java/android/os/BatteryProperties.java
@@ -15,9 +15,6 @@
 
 package android.os;
 
-import android.os.Parcel;
-import android.os.Parcelable;
-
 /**
  * {@hide}
  */
@@ -33,6 +30,22 @@
     public int batteryTemperature;
     public String batteryTechnology;
 
+    public BatteryProperties() {
+    }
+
+    public void set(BatteryProperties other) {
+        chargerAcOnline = other.chargerAcOnline;
+        chargerUsbOnline = other.chargerUsbOnline;
+        chargerWirelessOnline = other.chargerWirelessOnline;
+        batteryStatus = other.batteryStatus;
+        batteryHealth = other.batteryHealth;
+        batteryPresent = other.batteryPresent;
+        batteryLevel = other.batteryLevel;
+        batteryVoltage = other.batteryVoltage;
+        batteryTemperature = other.batteryTemperature;
+        batteryTechnology = other.batteryTechnology;
+    }
+
     /*
      * Parcel read/write code must be kept in sync with
      * frameworks/native/services/batteryservice/BatteryProperties.cpp
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index dfba208..e91f7d7 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -588,8 +588,10 @@
         public static final int EVENT_FOREGROUND = 0x0002;
         // Event is about an application package that is at the top of the screen.
         public static final int EVENT_TOP = 0x0003;
+        // Event is about an application package that is at the top of the screen.
+        public static final int EVENT_SYNC = 0x0004;
         // Number of event types.
-        public static final int EVENT_COUNT = 0x0004;
+        public static final int EVENT_COUNT = 0x0005;
 
         public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
         public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
@@ -597,6 +599,8 @@
         public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
         public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
         public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
+        public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
+        public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
 
         // For CMD_EVENT.
         public int eventCode;
@@ -975,11 +979,11 @@
     };
 
     public static final String[] HISTORY_EVENT_NAMES = new String[] {
-            "null", "proc", "fg", "top"
+            "null", "proc", "fg", "top", "sync"
     };
 
     public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
-            "Nl", "Pr", "Fg", "Tp"
+            "Enl", "Epr", "Efg", "Etp", "Esy"
     };
 
     /**
diff --git a/core/java/android/os/Broadcaster.java b/core/java/android/os/Broadcaster.java
index 96dc61a..70dcdd8 100644
--- a/core/java/android/os/Broadcaster.java
+++ b/core/java/android/os/Broadcaster.java
@@ -171,10 +171,10 @@
     public void broadcast(Message msg)
     {
         synchronized (this) {
-        	if (mReg == null) {
-        		return;
-        	}
-        	
+            if (mReg == null) {
+                return;
+            }
+            
             int senderWhat = msg.what;
             Registration start = mReg;
             Registration r = start;
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 56176a4..069285a 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -25,8 +25,10 @@
 {
     // WARNING: The first four methods must remain the first three methods because their
     // transaction numbers must not change unless IPowerManager.cpp is also updated.
-    void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws);
-    void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName, int uidtoblame);
+    void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws,
+            String historyTag);
+    void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName,
+            int uidtoblame);
     void releaseWakeLock(IBinder lock, int flags);
     void updateWakeLockUids(IBinder lock, in int[] uids);
 
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 4d4c337..74ca3bb 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -662,6 +662,7 @@
         private boolean mRefCounted = true;
         private boolean mHeld;
         private WorkSource mWorkSource;
+        private String mHistoryTag;
 
         private final Runnable mReleaser = new Runnable() {
             public void run() {
@@ -748,7 +749,8 @@
                 // been explicitly released by the keyguard.
                 mHandler.removeCallbacks(mReleaser);
                 try {
-                    mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource);
+                    mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,
+                            mHistoryTag);
                 } catch (RemoteException e) {
                 }
                 mHeld = true;
@@ -855,6 +857,11 @@
         }
 
         /** @hide */
+        public void setHistoryTag(String tag) {
+            mHistoryTag = tag;
+        }
+
+        /** @hide */
         public void setUnimportantForLogging(boolean state) {
             if (state) mFlags |= UNIMPORTANT_FOR_LOGGING;
             else mFlags &= ~UNIMPORTANT_FOR_LOGGING;
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 8f6dda1..1ec5cd5 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -164,11 +164,13 @@
 
     /**
      * Returns whether the system supports multiple users.
-     * @return true if multiple users can be created, false if it is a single user device.
+     * @return true if multiple users can be created by user, false if it is a single user device.
      * @hide
      */
     public static boolean supportsMultipleUsers() {
-        return getMaxSupportedUsers() > 1;
+        return getMaxSupportedUsers() > 1
+                && SystemProperties.getBoolean("fw.show_multiuserui",
+                Resources.getSystem().getBoolean(R.bool.config_enableMultiUserUI));
     }
 
     /**
@@ -601,6 +603,26 @@
     }
 
     /**
+     * Returns true if the user switcher should be shown, this will be if there
+     * are multiple users that aren't managed profiles.
+     * @hide
+     * @return true if user switcher should be shown.
+     */
+    public boolean isUserSwitcherEnabled() {
+        List<UserInfo> users = getUsers(true);
+        if (users == null) {
+           return false;
+        }
+        int switchableUserCount = 0;
+        for (UserInfo user : users) {
+            if (user.supportsSwitchTo()) {
+                ++switchableUserCount;
+            }
+        }
+        return switchableUserCount > 1;
+    }
+
+    /**
      * Returns a serial number on this device for a given userHandle. User handles can be recycled
      * when deleting and creating users, but serial numbers are not reused until the device is wiped.
      * @param userHandle
diff --git a/core/java/android/preference/GenericInflater.java b/core/java/android/preference/GenericInflater.java
index 3003290..7de7d1c 100644
--- a/core/java/android/preference/GenericInflater.java
+++ b/core/java/android/preference/GenericInflater.java
@@ -191,7 +191,7 @@
     public void setFactory(Factory<T> factory) {
         if (mFactorySet) {
             throw new IllegalStateException("" +
-            		"A factory has already been set on this inflater");
+                    "A factory has already been set on this inflater");
         }
         if (factory == null) {
             throw new NullPointerException("Given factory can not be null");
diff --git a/core/java/android/text/style/BackgroundColorSpan.java b/core/java/android/text/style/BackgroundColorSpan.java
index 580a369..cda8015 100644
--- a/core/java/android/text/style/BackgroundColorSpan.java
+++ b/core/java/android/text/style/BackgroundColorSpan.java
@@ -26,9 +26,9 @@
 
     private final int mColor;
 
-	public BackgroundColorSpan(int color) {
-		mColor = color;
-	}
+    public BackgroundColorSpan(int color) {
+        mColor = color;
+    }
 
     public BackgroundColorSpan(Parcel src) {
         mColor = src.readInt();
@@ -46,12 +46,12 @@
         dest.writeInt(mColor);
     }
 
-	public int getBackgroundColor() {
-		return mColor;
-	}
+    public int getBackgroundColor() {
+        return mColor;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.bgColor = mColor;
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.bgColor = mColor;
+    }
 }
diff --git a/core/java/android/text/style/CharacterStyle.java b/core/java/android/text/style/CharacterStyle.java
index 14dfddd..5b95f1a 100644
--- a/core/java/android/text/style/CharacterStyle.java
+++ b/core/java/android/text/style/CharacterStyle.java
@@ -24,7 +24,7 @@
  * ones may just implement {@link UpdateAppearance}.
  */
 public abstract class CharacterStyle {
-	public abstract void updateDrawState(TextPaint tp);
+    public abstract void updateDrawState(TextPaint tp);
 
     /**
      * A given CharacterStyle can only applied to a single region of a given
diff --git a/core/java/android/text/style/ForegroundColorSpan.java b/core/java/android/text/style/ForegroundColorSpan.java
index 476124d..c9e09bd 100644
--- a/core/java/android/text/style/ForegroundColorSpan.java
+++ b/core/java/android/text/style/ForegroundColorSpan.java
@@ -26,9 +26,9 @@
 
     private final int mColor;
 
-	public ForegroundColorSpan(int color) {
-		mColor = color;
-	}
+    public ForegroundColorSpan(int color) {
+        mColor = color;
+    }
 
     public ForegroundColorSpan(Parcel src) {
         mColor = src.readInt();
@@ -46,12 +46,12 @@
         dest.writeInt(mColor);
     }
 
-	public int getForegroundColor() {
-		return mColor;
-	}
+    public int getForegroundColor() {
+        return mColor;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setColor(mColor);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setColor(mColor);
+    }
 }
diff --git a/core/java/android/text/style/MaskFilterSpan.java b/core/java/android/text/style/MaskFilterSpan.java
index 64ab0d8..2ff52a8f 100644
--- a/core/java/android/text/style/MaskFilterSpan.java
+++ b/core/java/android/text/style/MaskFilterSpan.java
@@ -21,18 +21,18 @@
 
 public class MaskFilterSpan extends CharacterStyle implements UpdateAppearance {
 
-	private MaskFilter mFilter;
+    private MaskFilter mFilter;
 
-	public MaskFilterSpan(MaskFilter filter) {
-		mFilter = filter;
-	}
+    public MaskFilterSpan(MaskFilter filter) {
+        mFilter = filter;
+    }
 
-	public MaskFilter getMaskFilter() {
-		return mFilter;
-	}
+    public MaskFilter getMaskFilter() {
+        return mFilter;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setMaskFilter(mFilter);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setMaskFilter(mFilter);
+    }
 }
diff --git a/core/java/android/text/style/MetricAffectingSpan.java b/core/java/android/text/style/MetricAffectingSpan.java
index a02b276..853ecc6 100644
--- a/core/java/android/text/style/MetricAffectingSpan.java
+++ b/core/java/android/text/style/MetricAffectingSpan.java
@@ -26,7 +26,7 @@
 extends CharacterStyle
 implements UpdateLayout {
 
-	public abstract void updateMeasureState(TextPaint p);
+    public abstract void updateMeasureState(TextPaint p);
 
     /**
      * Returns "this" for most MetricAffectingSpans, but for 
diff --git a/core/java/android/text/style/RasterizerSpan.java b/core/java/android/text/style/RasterizerSpan.java
index 75b5bcc..cae9640 100644
--- a/core/java/android/text/style/RasterizerSpan.java
+++ b/core/java/android/text/style/RasterizerSpan.java
@@ -21,18 +21,18 @@
 
 public class RasterizerSpan extends CharacterStyle implements UpdateAppearance {
 
-	private Rasterizer mRasterizer;
+    private Rasterizer mRasterizer;
 
-	public RasterizerSpan(Rasterizer r) {
-		mRasterizer = r;
-	}
+    public RasterizerSpan(Rasterizer r) {
+        mRasterizer = r;
+    }
 
-	public Rasterizer getRasterizer() {
-		return mRasterizer;
-	}
+    public Rasterizer getRasterizer() {
+        return mRasterizer;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setRasterizer(mRasterizer);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setRasterizer(mRasterizer);
+    }
 }
diff --git a/core/java/android/text/style/RelativeSizeSpan.java b/core/java/android/text/style/RelativeSizeSpan.java
index 9717362..632dbd4 100644
--- a/core/java/android/text/style/RelativeSizeSpan.java
+++ b/core/java/android/text/style/RelativeSizeSpan.java
@@ -23,11 +23,11 @@
 
 public class RelativeSizeSpan extends MetricAffectingSpan implements ParcelableSpan {
 
-	private final float mProportion;
+    private final float mProportion;
 
-	public RelativeSizeSpan(float proportion) {
-		mProportion = proportion;
-	}
+    public RelativeSizeSpan(float proportion) {
+        mProportion = proportion;
+    }
 
     public RelativeSizeSpan(Parcel src) {
         mProportion = src.readFloat();
@@ -45,17 +45,17 @@
         dest.writeFloat(mProportion);
     }
 
-	public float getSizeChange() {
-		return mProportion;
-	}
+    public float getSizeChange() {
+        return mProportion;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setTextSize(ds.getTextSize() * mProportion);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setTextSize(ds.getTextSize() * mProportion);
+    }
 
-	@Override
-	public void updateMeasureState(TextPaint ds) {
-		ds.setTextSize(ds.getTextSize() * mProportion);
-	}
+    @Override
+    public void updateMeasureState(TextPaint ds) {
+        ds.setTextSize(ds.getTextSize() * mProportion);
+    }
 }
diff --git a/core/java/android/text/style/ScaleXSpan.java b/core/java/android/text/style/ScaleXSpan.java
index 655064b..a22a5a1 100644
--- a/core/java/android/text/style/ScaleXSpan.java
+++ b/core/java/android/text/style/ScaleXSpan.java
@@ -23,11 +23,11 @@
 
 public class ScaleXSpan extends MetricAffectingSpan implements ParcelableSpan {
 
-	private final float mProportion;
+    private final float mProportion;
 
-	public ScaleXSpan(float proportion) {
-		mProportion = proportion;
-	}
+    public ScaleXSpan(float proportion) {
+        mProportion = proportion;
+    }
 
     public ScaleXSpan(Parcel src) {
         mProportion = src.readFloat();
@@ -45,17 +45,17 @@
         dest.writeFloat(mProportion);
     }
 
-	public float getScaleX() {
-		return mProportion;
-	}
+    public float getScaleX() {
+        return mProportion;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setTextScaleX(ds.getTextScaleX() * mProportion);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setTextScaleX(ds.getTextScaleX() * mProportion);
+    }
 
-	@Override
-	public void updateMeasureState(TextPaint ds) {
-		ds.setTextScaleX(ds.getTextScaleX() * mProportion);
-	}
+    @Override
+    public void updateMeasureState(TextPaint ds) {
+        ds.setTextScaleX(ds.getTextScaleX() * mProportion);
+    }
 }
diff --git a/core/java/android/text/style/StrikethroughSpan.java b/core/java/android/text/style/StrikethroughSpan.java
index b51363a..303e41574 100644
--- a/core/java/android/text/style/StrikethroughSpan.java
+++ b/core/java/android/text/style/StrikethroughSpan.java
@@ -40,8 +40,8 @@
     public void writeToParcel(Parcel dest, int flags) {
     }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setStrikeThruText(true);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setStrikeThruText(true);
+    }
 }
diff --git a/core/java/android/text/style/StyleSpan.java b/core/java/android/text/style/StyleSpan.java
index 8e6147c..b08f70e 100644
--- a/core/java/android/text/style/StyleSpan.java
+++ b/core/java/android/text/style/StyleSpan.java
@@ -33,17 +33,17 @@
  */
 public class StyleSpan extends MetricAffectingSpan implements ParcelableSpan {
 
-	private final int mStyle;
+    private final int mStyle;
 
-	/**
-	 * 
-	 * @param style An integer constant describing the style for this span. Examples
-	 * include bold, italic, and normal. Values are constants defined 
-	 * in {@link android.graphics.Typeface}.
-	 */
-	public StyleSpan(int style) {
-		mStyle = style;
-	}
+    /**
+     * 
+     * @param style An integer constant describing the style for this span. Examples
+     * include bold, italic, and normal. Values are constants defined 
+     * in {@link android.graphics.Typeface}.
+     */
+    public StyleSpan(int style) {
+        mStyle = style;
+    }
 
     public StyleSpan(Parcel src) {
         mStyle = src.readInt();
@@ -61,19 +61,19 @@
         dest.writeInt(mStyle);
     }
 
-	/**
-	 * Returns the style constant defined in {@link android.graphics.Typeface}. 
-	 */
-	public int getStyle() {
-		return mStyle;
-	}
+    /**
+     * Returns the style constant defined in {@link android.graphics.Typeface}. 
+     */
+    public int getStyle() {
+        return mStyle;
+    }
 
-	@Override
+    @Override
     public void updateDrawState(TextPaint ds) {
         apply(ds, mStyle);
     }
 
-	@Override
+    @Override
     public void updateMeasureState(TextPaint paint) {
         apply(paint, mStyle);
     }
diff --git a/core/java/android/text/style/UnderlineSpan.java b/core/java/android/text/style/UnderlineSpan.java
index b0cb0e8..80b2427 100644
--- a/core/java/android/text/style/UnderlineSpan.java
+++ b/core/java/android/text/style/UnderlineSpan.java
@@ -40,8 +40,8 @@
     public void writeToParcel(Parcel dest, int flags) {
     }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setUnderlineText(true);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setUnderlineText(true);
+    }
 }
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
index b758930..4c92e950 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -478,6 +478,7 @@
     @Override
     void flushLayerUpdates() {
         if (validate()) {
+            flushLayerChanges();
             mGlCanvas.flushLayerUpdates();
         }
     }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index effc9a6..99aee29 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -11556,6 +11556,11 @@
                     receiver.damageInParent();
                 }
             }
+
+            // Damage the entire IsolatedZVolume recieving this view's shadow.
+            if (getCastsShadow() && getTranslationZ() != 0) {
+                damageIsolatedZVolume();
+            }
         }
     }
 
@@ -11583,6 +11588,29 @@
     }
 
     /**
+     * Damage area of the screen covered by the current isolated Z volume
+     *
+     * This method will guarantee that any changes to shadows cast by a View
+     * are damaged on the screen for future redraw.
+     */
+    private void damageIsolatedZVolume() {
+        final AttachInfo ai = mAttachInfo;
+        if (ai != null) {
+            ViewParent p = getParent();
+            while (p != null) {
+                if (p instanceof ViewGroup) {
+                    final ViewGroup vg = (ViewGroup) p;
+                    if (vg.hasIsolatedZVolume()) {
+                        vg.damageInParent();
+                        return;
+                    }
+                }
+                p = p.getParent();
+            }
+        }
+    }
+
+    /**
      * Quick invalidation for View property changes (alpha, translationXY, etc.). We don't want to
      * set any flags or handle all of the cases handled by the default invalidation methods.
      * Instead, we just want to schedule a traversal in ViewRootImpl with the appropriate
@@ -11610,12 +11638,17 @@
         } else {
             damageInParent();
         }
+        if (invalidateParent && getCastsShadow() && getTranslationZ() != 0) {
+            damageIsolatedZVolume();
+        }
     }
 
     /**
      * Tells the parent view to damage this view's bounds.
+     *
+     * @hide
      */
-    private void damageInParent() {
+    protected void damageInParent() {
         final AttachInfo ai = mAttachInfo;
         final ViewParent p = mParent;
         if (p != null && ai != null) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a13b184..2b32d70 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -264,10 +264,10 @@
     int mScrollY;
     int mCurScrollY;
     Scroller mScroller;
-//    HardwareLayer mResizeBuffer;
-//    long mResizeBufferStartTime;
-//    int mResizeBufferDuration;
-//    static final Interpolator mResizeInterpolator = new AccelerateDecelerateInterpolator();
+    HardwareLayer mResizeBuffer;
+    long mResizeBufferStartTime;
+    int mResizeBufferDuration;
+    static final Interpolator mResizeInterpolator = new AccelerateDecelerateInterpolator();
     private ArrayList<LayoutTransition> mPendingTransitions;
 
     final ViewConfiguration mViewConfiguration;
@@ -931,17 +931,12 @@
         return mAppVisible ? mView.getVisibility() : View.GONE;
     }
 
-//    void disposeResizeBuffer() {
-//        if (mResizeBuffer != null && mAttachInfo.mHardwareRenderer != null) {
-//            mAttachInfo.mHardwareRenderer.safelyRun(new Runnable() {
-//                @Override
-//                public void run() {
-//                    mResizeBuffer.destroy();
-//                    mResizeBuffer = null;
-//                }
-//            });
-//        }
-//    }
+    void disposeResizeBuffer() {
+        if (mResizeBuffer != null) {
+            mResizeBuffer.destroy();
+            mResizeBuffer = null;
+        }
+    }
 
     /**
      * Add LayoutTransition to the list of transitions to be started in the next traversal.
@@ -1452,76 +1447,63 @@
                 final boolean visibleInsetsChanged = !mPendingVisibleInsets.equals(
                         mAttachInfo.mVisibleInsets);
                 if (contentInsetsChanged) {
-//                    TODO: Do something with this...
-//                    if (mWidth > 0 && mHeight > 0 && lp != null &&
-//                            ((lp.systemUiVisibility|lp.subtreeSystemUiVisibility)
-//                                    & View.SYSTEM_UI_LAYOUT_FLAGS) == 0 &&
-//                            mSurface != null && mSurface.isValid() &&
-//                            !mAttachInfo.mTurnOffWindowResizeAnim &&
-//                            mAttachInfo.mHardwareRenderer != null &&
-//                            mAttachInfo.mHardwareRenderer.isEnabled() &&
-//                            mAttachInfo.mHardwareRenderer.validate() &&
-//                            lp != null && !PixelFormat.formatHasAlpha(lp.format)) {
-//
-//                        disposeResizeBuffer();
-//
-//                        boolean completed = false;
-//                        HardwareCanvas hwRendererCanvas = mAttachInfo.mHardwareRenderer.getCanvas();
-//                        HardwareCanvas layerCanvas = null;
-//                        try {
-//                            if (mResizeBuffer == null) {
-//                                mResizeBuffer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
-//                                        mWidth, mHeight, false);
-//                            } else if (mResizeBuffer.getWidth() != mWidth ||
-//                                    mResizeBuffer.getHeight() != mHeight) {
-//                                mResizeBuffer.resize(mWidth, mHeight);
-//                            }
-//                            // TODO: should handle create/resize failure
-//                            layerCanvas = mResizeBuffer.start(hwRendererCanvas);
-//                            final int restoreCount = layerCanvas.save();
-//
-//                            int yoff;
-//                            final boolean scrolling = mScroller != null
-//                                    && mScroller.computeScrollOffset();
-//                            if (scrolling) {
-//                                yoff = mScroller.getCurrY();
-//                                mScroller.abortAnimation();
-//                            } else {
-//                                yoff = mScrollY;
-//                            }
-//
-//                            layerCanvas.translate(0, -yoff);
-//                            if (mTranslator != null) {
-//                                mTranslator.translateCanvas(layerCanvas);
-//                            }
-//
-//                            DisplayList displayList = mView.mDisplayList;
-//                            if (displayList != null && displayList.isValid()) {
-//                                layerCanvas.drawDisplayList(displayList, null,
-//                                        DisplayList.FLAG_CLIP_CHILDREN);
-//                            } else {
-//                                mView.draw(layerCanvas);
-//                            }
-//
-//                            drawAccessibilityFocusedDrawableIfNeeded(layerCanvas);
-//
-//                            mResizeBufferStartTime = SystemClock.uptimeMillis();
-//                            mResizeBufferDuration = mView.getResources().getInteger(
-//                                    com.android.internal.R.integer.config_mediumAnimTime);
-//                            completed = true;
-//
-//                            layerCanvas.restoreToCount(restoreCount);
-//                        } catch (OutOfMemoryError e) {
-//                            Log.w(TAG, "Not enough memory for content change anim buffer", e);
-//                        } finally {
-//                            if (mResizeBuffer != null) {
-//                                mResizeBuffer.end(hwRendererCanvas);
-//                                if (!completed) {
-//                                    disposeResizeBuffer();
-//                                }
-//                            }
-//                        }
-//                    }
+                    if (mWidth > 0 && mHeight > 0 && lp != null &&
+                            ((lp.systemUiVisibility|lp.subtreeSystemUiVisibility)
+                                    & View.SYSTEM_UI_LAYOUT_FLAGS) == 0 &&
+                            mSurface != null && mSurface.isValid() &&
+                            !mAttachInfo.mTurnOffWindowResizeAnim &&
+                            mAttachInfo.mHardwareRenderer != null &&
+                            mAttachInfo.mHardwareRenderer.isEnabled() &&
+                            lp != null && !PixelFormat.formatHasAlpha(lp.format)) {
+
+                        disposeResizeBuffer();
+
+                        if (mResizeBuffer == null) {
+                            mResizeBuffer = mAttachInfo.mHardwareRenderer.createDisplayListLayer(
+                                    mWidth, mHeight);
+                        }
+                        mResizeBuffer.prepare(mWidth, mHeight, false);
+                        DisplayList layerDisplayList = mResizeBuffer.startRecording();
+                        HardwareCanvas layerCanvas = layerDisplayList.start(mWidth, mHeight);
+                        final int restoreCount = layerCanvas.save();
+
+                        int yoff;
+                        final boolean scrolling = mScroller != null
+                                && mScroller.computeScrollOffset();
+                        if (scrolling) {
+                            yoff = mScroller.getCurrY();
+                            mScroller.abortAnimation();
+                        } else {
+                            yoff = mScrollY;
+                        }
+
+                        layerCanvas.translate(0, -yoff);
+                        if (mTranslator != null) {
+                            mTranslator.translateCanvas(layerCanvas);
+                        }
+
+                        DisplayList displayList = mView.mDisplayList;
+                        if (displayList != null && displayList.isValid()) {
+                            layerCanvas.drawDisplayList(displayList, null,
+                                    DisplayList.FLAG_CLIP_CHILDREN);
+                        } else {
+                            mView.draw(layerCanvas);
+                        }
+
+                        drawAccessibilityFocusedDrawableIfNeeded(layerCanvas);
+
+                        mResizeBufferStartTime = SystemClock.uptimeMillis();
+                        mResizeBufferDuration = mView.getResources().getInteger(
+                                com.android.internal.R.integer.config_mediumAnimTime);
+
+                        layerCanvas.restoreToCount(restoreCount);
+                        layerDisplayList.end();
+                        layerDisplayList.setCaching(true);
+                        layerDisplayList.setLeftTopRightBottom(0, 0, mWidth, mHeight);
+                        mTempRect.set(0, 0, mWidth, mHeight);
+                        mResizeBuffer.endRecording(mTempRect);
+                        mAttachInfo.mHardwareRenderer.flushLayerUpdates();
+                    }
                     mAttachInfo.mContentInsets.set(mPendingContentInsets);
                     if (DEBUG_LAYOUT) Log.v(TAG, "Content insets changing to: "
                             + mAttachInfo.mContentInsets);
@@ -1581,7 +1563,7 @@
                     if (mScroller != null) {
                         mScroller.abortAnimation();
                     }
-//                    disposeResizeBuffer();
+                    disposeResizeBuffer();
                     // Our surface is gone
                     if (mAttachInfo.mHardwareRenderer != null &&
                             mAttachInfo.mHardwareRenderer.isEnabled()) {
@@ -2180,10 +2162,10 @@
 
     @Override
     public void onHardwarePostDraw(HardwareCanvas canvas) {
-//        if (mResizeBuffer != null) {
-//            mResizePaint.setAlpha(mResizeAlpha);
-//            canvas.drawHardwareLayer(mResizeBuffer, 0.0f, mHardwareYOffset, mResizePaint);
-//        }
+        if (mResizeBuffer != null) {
+            mResizePaint.setAlpha(mResizeAlpha);
+            canvas.drawHardwareLayer(mResizeBuffer, 0.0f, mHardwareYOffset, mResizePaint);
+        }
         // TODO: this
         if (!HardwareRenderer.sUseRenderThread) {
             drawAccessibilityFocusedDrawableIfNeeded(canvas);
@@ -2342,17 +2324,17 @@
         final boolean scalingRequired = attachInfo.mScalingRequired;
 
         int resizeAlpha = 0;
-//        if (mResizeBuffer != null) {
-//            long deltaTime = SystemClock.uptimeMillis() - mResizeBufferStartTime;
-//            if (deltaTime < mResizeBufferDuration) {
-//                float amt = deltaTime/(float) mResizeBufferDuration;
-//                amt = mResizeInterpolator.getInterpolation(amt);
-//                animating = true;
-//                resizeAlpha = 255 - (int)(amt*255);
-//            } else {
-//                disposeResizeBuffer();
-//            }
-//        }
+        if (mResizeBuffer != null) {
+            long deltaTime = SystemClock.uptimeMillis() - mResizeBufferStartTime;
+            if (deltaTime < mResizeBufferDuration) {
+                float amt = deltaTime/(float) mResizeBufferDuration;
+                amt = mResizeInterpolator.getInterpolation(amt);
+                animating = true;
+                resizeAlpha = 255 - (int)(amt*255);
+            } else {
+                disposeResizeBuffer();
+            }
+        }
 
         final Rect dirty = mDirty;
         if (mSurfaceHolder != null) {
@@ -2362,7 +2344,7 @@
                 if (mScroller != null) {
                     mScroller.abortAnimation();
                 }
-//                disposeResizeBuffer();
+                disposeResizeBuffer();
             }
             return;
         }
@@ -2725,7 +2707,7 @@
         if (scrollY != mScrollY) {
             if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Pan scroll changed: old="
                     + mScrollY + " , new=" + scrollY);
-            if (!immediate /*&& mResizeBuffer == null*/) {
+            if (!immediate && mResizeBuffer == null) {
                 if (mScroller == null) {
                     mScroller = new Scroller(mView.getContext());
                 }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 3027be4..86fdae3 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -704,6 +704,11 @@
     private SavedState mPendingSync;
 
     /**
+     * Whether the view is in the process of detaching from its window.
+     */
+    private boolean mIsDetaching;
+
+    /**
      * Interface definition for a callback to be invoked when the list or grid
      * has been scrolled.
      */
@@ -2788,6 +2793,8 @@
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
 
+        mIsDetaching = true;
+
         // Dismiss the popup in case onSaveInstanceState() was not invoked
         dismissPopup();
 
@@ -2836,6 +2843,8 @@
             removeCallbacks(mTouchModeReset);
             mTouchModeReset.run();
         }
+
+        mIsDetaching = false;
     }
 
     @Override
@@ -3462,7 +3471,7 @@
             mPositionScroller.stop();
         }
 
-        if (!isAttachedToWindow()) {
+        if (mIsDetaching || !isAttachedToWindow()) {
             // Something isn't right.
             // Since we rely on being attached to get data set change notifications,
             // don't risk doing anything where we might try to resync and find things
@@ -3701,7 +3710,7 @@
                                     mTouchMode = TOUCH_MODE_REST;
                                     child.setPressed(false);
                                     setPressed(false);
-                                    if (!mDataChanged && isAttachedToWindow()) {
+                                    if (!mDataChanged && !mIsDetaching && isAttachedToWindow()) {
                                         performClick.run();
                                     }
                                 }
@@ -3976,7 +3985,7 @@
             mPositionScroller.stop();
         }
 
-        if (!isAttachedToWindow()) {
+        if (mIsDetaching || !isAttachedToWindow()) {
             // Something isn't right.
             // Since we rely on being attached to get data set change notifications,
             // don't risk doing anything where we might try to resync and find things
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 4ed48ff..04b18c1 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1335,27 +1335,30 @@
             }
 
             // Attempt to restore accessibility focus, if necessary.
-            final View newAccessibilityFocusedView = viewRootImpl.getAccessibilityFocusedHost();
-            if (newAccessibilityFocusedView == null) {
-                if (accessibilityFocusLayoutRestoreView != null
-                        && accessibilityFocusLayoutRestoreView.isAttachedToWindow()) {
-                    final AccessibilityNodeProvider provider =
-                            accessibilityFocusLayoutRestoreView.getAccessibilityNodeProvider();
-                    if (accessibilityFocusLayoutRestoreNode != null && provider != null) {
-                        final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(
-                                accessibilityFocusLayoutRestoreNode.getSourceNodeId());
-                        provider.performAction(virtualViewId,
-                                AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
-                    } else {
-                        accessibilityFocusLayoutRestoreView.requestAccessibilityFocus();
-                    }
-                } else if (accessibilityFocusPosition != INVALID_POSITION) {
-                    // Bound the position within the visible children.
-                    final int position = MathUtils.constrain(
-                            accessibilityFocusPosition - mFirstPosition, 0, getChildCount() - 1);
-                    final View restoreView = getChildAt(position);
-                    if (restoreView != null) {
-                        restoreView.requestAccessibilityFocus();
+            if (viewRootImpl != null) {
+                final View newAccessibilityFocusedView = viewRootImpl.getAccessibilityFocusedHost();
+                if (newAccessibilityFocusedView == null) {
+                    if (accessibilityFocusLayoutRestoreView != null
+                            && accessibilityFocusLayoutRestoreView.isAttachedToWindow()) {
+                        final AccessibilityNodeProvider provider =
+                                accessibilityFocusLayoutRestoreView.getAccessibilityNodeProvider();
+                        if (accessibilityFocusLayoutRestoreNode != null && provider != null) {
+                            final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(
+                                    accessibilityFocusLayoutRestoreNode.getSourceNodeId());
+                            provider.performAction(virtualViewId,
+                                    AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
+                        } else {
+                            accessibilityFocusLayoutRestoreView.requestAccessibilityFocus();
+                        }
+                    } else if (accessibilityFocusPosition != INVALID_POSITION) {
+                        // Bound the position within the visible children.
+                        final int position = MathUtils.constrain(
+                                accessibilityFocusPosition - mFirstPosition, 0,
+                                getChildCount() - 1);
+                        final View restoreView = getChildAt(position);
+                        if (restoreView != null) {
+                            restoreView.requestAccessibilityFocus();
+                        }
                     }
                 }
             }
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 65f1ab7..82e624d 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -667,6 +667,7 @@
         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
 
         boolean matchWidth = false;
+        boolean skippedMeasure = false;
 
         final int baselineChildIndex = mBaselineAlignedChildIndex;        
         final boolean useLargestChild = mUseLargestChild;
@@ -701,6 +702,7 @@
                 // there is any leftover space.
                 final int totalLength = mTotalLength;
                 mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
+                skippedMeasure = true;
             } else {
                 int oldHeight = Integer.MIN_VALUE;
 
@@ -827,9 +829,10 @@
         heightSize = heightSizeAndState & MEASURED_SIZE_MASK;
         
         // Either expand children with weight to take up available space or
-        // shrink them if they extend beyond our current bounds
+        // shrink them if they extend beyond our current bounds. If we skipped
+        // measurement on any children, we need to measure them now.
         int delta = heightSize - mTotalLength;
-        if (delta != 0 && totalWeight > 0.0f) {
+        if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
             float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
 
             mTotalLength = 0;
@@ -995,6 +998,7 @@
         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
 
         boolean matchHeight = false;
+        boolean skippedMeasure = false;
 
         if (mMaxAscent == null || mMaxDescent == null) {
             mMaxAscent = new int[VERTICAL_GRAVITY_COUNT];
@@ -1057,6 +1061,8 @@
                 if (baselineAligned) {
                     final int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                     child.measure(freeSpec, freeSpec);
+                } else {
+                    skippedMeasure = true;
                 }
             } else {
                 int oldWidth = Integer.MIN_VALUE;
@@ -1205,9 +1211,10 @@
         widthSize = widthSizeAndState & MEASURED_SIZE_MASK;
         
         // Either expand children with weight to take up available space or
-        // shrink them if they extend beyond our current bounds
+        // shrink them if they extend beyond our current bounds. If we skipped
+        // measurement on any children, we need to measure them now.
         int delta = widthSize - mTotalLength;
-        if (delta != 0 && totalWeight > 0.0f) {
+        if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
             float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
 
             maxAscent[0] = maxAscent[1] = maxAscent[2] = maxAscent[3] = -1;
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 63e1358..5de67c8 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1738,27 +1738,30 @@
             }
 
             // Attempt to restore accessibility focus, if necessary.
-            final View newAccessibilityFocusedView = viewRootImpl.getAccessibilityFocusedHost();
-            if (newAccessibilityFocusedView == null) {
-                if (accessibilityFocusLayoutRestoreView != null
-                        && accessibilityFocusLayoutRestoreView.isAttachedToWindow()) {
-                    final AccessibilityNodeProvider provider =
-                            accessibilityFocusLayoutRestoreView.getAccessibilityNodeProvider();
-                    if (accessibilityFocusLayoutRestoreNode != null && provider != null) {
-                        final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(
-                                accessibilityFocusLayoutRestoreNode.getSourceNodeId());
-                        provider.performAction(virtualViewId,
-                                AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
-                    } else {
-                        accessibilityFocusLayoutRestoreView.requestAccessibilityFocus();
-                    }
-                } else if (accessibilityFocusPosition != INVALID_POSITION) {
-                    // Bound the position within the visible children.
-                    final int position = MathUtils.constrain(
-                            accessibilityFocusPosition - mFirstPosition, 0, getChildCount() - 1);
-                    final View restoreView = getChildAt(position);
-                    if (restoreView != null) {
-                        restoreView.requestAccessibilityFocus();
+            if (viewRootImpl != null) {
+                final View newAccessibilityFocusedView = viewRootImpl.getAccessibilityFocusedHost();
+                if (newAccessibilityFocusedView == null) {
+                    if (accessibilityFocusLayoutRestoreView != null
+                            && accessibilityFocusLayoutRestoreView.isAttachedToWindow()) {
+                        final AccessibilityNodeProvider provider =
+                                accessibilityFocusLayoutRestoreView.getAccessibilityNodeProvider();
+                        if (accessibilityFocusLayoutRestoreNode != null && provider != null) {
+                            final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(
+                                    accessibilityFocusLayoutRestoreNode.getSourceNodeId());
+                            provider.performAction(virtualViewId,
+                                    AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
+                        } else {
+                            accessibilityFocusLayoutRestoreView.requestAccessibilityFocus();
+                        }
+                    } else if (accessibilityFocusPosition != INVALID_POSITION) {
+                        // Bound the position within the visible children.
+                        final int position = MathUtils.constrain(
+                                accessibilityFocusPosition - mFirstPosition, 0,
+                                getChildCount() - 1);
+                        final View restoreView = getChildAt(position);
+                        if (restoreView != null) {
+                            restoreView.requestAccessibilityFocus();
+                        }
                     }
                 }
             }
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 1155cbb..892ad68 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -35,11 +35,12 @@
 
     void noteEvent(int code, String name, int uid);
 
-    void noteStartWakelock(int uid, int pid, String name, int type, boolean unimportantForLogging);
+    void noteStartWakelock(int uid, int pid, String name, String historyName,
+            int type, boolean unimportantForLogging);
     void noteStopWakelock(int uid, int pid, String name, int type);
 
-    void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, int type,
-            boolean unimportantForLogging);
+    void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, String historyName,
+            int type, boolean unimportantForLogging);
     void noteStopWakelockFromSource(in WorkSource ws, int pid, String name, int type);
 
     void noteVibratorOn(int uid, long durationMillis);
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index 043964f..ec2d654 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -117,7 +117,7 @@
         /** - TODO: Enable when zz_ZY Pseudolocale is complete
          *  if (!localeList.contains("zz_ZY")) {
          *      localeList.add("zz_ZY");
-         *	}
+         *  }
          */
         }
         String[] locales = new String[localeList.size()];
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index 8282d23..e2a2b1e 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -17,6 +17,7 @@
 package com.android.internal.net;
 
 import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
@@ -26,6 +27,7 @@
 import android.os.SystemClock;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.ProcFileReader;
 
 import java.io.File;
@@ -165,22 +167,32 @@
     }
 
     public NetworkStats readNetworkStatsDetail() throws IOException {
-        return readNetworkStatsDetail(UID_ALL);
+        return readNetworkStatsDetail(UID_ALL, null, TAG_ALL, null);
     }
 
-    public NetworkStats readNetworkStatsDetail(int limitUid) throws IOException {
+    public NetworkStats readNetworkStatsDetail(int limitUid, String[] limitIfaces, int limitTag,
+            NetworkStats lastStats)
+            throws IOException {
         if (USE_NATIVE_PARSING) {
-            final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
-            if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), limitUid) != 0) {
+            final NetworkStats stats;
+            if (lastStats != null) {
+                stats = lastStats;
+                stats.setElapsedRealtime(SystemClock.elapsedRealtime());
+            } else {
+                stats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
+            }
+            if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), limitUid,
+                    limitIfaces, limitTag) != 0) {
                 throw new IOException("Failed to parse network stats");
             }
             if (SANITY_CHECK_NATIVE) {
-                final NetworkStats javaStats = javaReadNetworkStatsDetail(mStatsXtUid, limitUid);
+                final NetworkStats javaStats = javaReadNetworkStatsDetail(mStatsXtUid, limitUid,
+                        limitIfaces, limitTag);
                 assertEquals(javaStats, stats);
             }
             return stats;
         } else {
-            return javaReadNetworkStatsDetail(mStatsXtUid, limitUid);
+            return javaReadNetworkStatsDetail(mStatsXtUid, limitUid, limitIfaces, limitTag);
         }
     }
 
@@ -189,7 +201,8 @@
      * expected to monotonically increase since device boot.
      */
     @VisibleForTesting
-    public static NetworkStats javaReadNetworkStatsDetail(File detailPath, int limitUid)
+    public static NetworkStats javaReadNetworkStatsDetail(File detailPath, int limitUid,
+            String[] limitIfaces, int limitTag)
             throws IOException {
         final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
 
@@ -222,7 +235,9 @@
                 entry.txBytes = reader.nextLong();
                 entry.txPackets = reader.nextLong();
 
-                if (limitUid == UID_ALL || limitUid == entry.uid) {
+                if ((limitIfaces == null || ArrayUtils.contains(limitIfaces, entry.iface))
+                        && (limitUid == UID_ALL || limitUid == entry.uid)
+                        && (limitTag == TAG_ALL || limitTag == entry.tag)) {
                     stats.addValues(entry);
                 }
 
@@ -264,5 +279,5 @@
      */
     @VisibleForTesting
     public static native int nativeReadNetworkStatsDetail(
-            NetworkStats stats, String path, int limitUid);
+            NetworkStats stats, String path, int limitUid, String[] limitIfaces, int limitTag);
 }
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index 8a15c99..e0cf435 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -642,8 +642,8 @@
 
         final long radioDataUptimeMs
                 = mStats.getMobileRadioActiveTime(mBatteryRealtime, mStatsType) / 1000;
-        final double mobilePps = radioDataUptimeMs != 0
-                ? mobileData / (double)radioDataUptimeMs
+        final double mobilePps = (mobileData != 0 && radioDataUptimeMs != 0)
+                ? (mobileData / (double)radioDataUptimeMs)
                 : (((double)MOBILE_BPS) / 8 / 2048);
 
         return (MOBILE_POWER / mobilePps) / (60*60);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 274e267..8843500 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.os;
 
+import static android.net.NetworkStats.UID_ALL;
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
 
 import android.bluetooth.BluetoothDevice;
@@ -52,9 +53,9 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.net.NetworkStatsFactory;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.JournaledFile;
-import com.google.android.collect.Sets;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -63,7 +64,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -370,12 +370,17 @@
             new HashMap<String, KernelWakelockStats>();
 
     private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
-    private NetworkStats mLastSnapshot;
+    private NetworkStats mCurMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
+    private NetworkStats mLastMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
+    private NetworkStats mCurWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
+    private NetworkStats mLastWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
+    private NetworkStats mTmpNetworkStats;
+    private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
 
     @GuardedBy("this")
-    private HashSet<String> mMobileIfaces = Sets.newHashSet();
+    private String[] mMobileIfaces = new String[0];
     @GuardedBy("this")
-    private HashSet<String> mWifiIfaces = Sets.newHashSet();
+    private String[] mWifiIfaces = new String[0];
 
     // For debugging
     public BatteryStatsImpl() {
@@ -2006,7 +2011,7 @@
         addHistoryEventLocked(SystemClock.elapsedRealtime(), code, name, uid);
     }
 
-    public void noteStartWakeLocked(int uid, int pid, String name, int type,
+    public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
             boolean unimportantForLogging) {
         uid = mapUid(uid);
         final long elapsedRealtime = SystemClock.elapsedRealtime();
@@ -2018,7 +2023,7 @@
                 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
                         + Integer.toHexString(mHistoryCur.states));
                 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
-                mHistoryCur.wakelockTag.string = name;
+                mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
                 mHistoryCur.wakelockTag.uid = uid;
                 mWakeLockImportant = !unimportantForLogging;
                 addHistoryRecordLocked(elapsedRealtime);
@@ -2027,7 +2032,7 @@
                     // We'll try to update the last tag.
                     mHistoryLastWritten.wakelockTag = null;
                     mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
-                    mHistoryCur.wakelockTag.string = name;
+                    mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
                     mHistoryCur.wakelockTag.uid = uid;
                     addHistoryRecordLocked(elapsedRealtime);
                 }
@@ -2065,11 +2070,11 @@
         }
     }
 
-    public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type,
-            boolean unimportantForLogging) {
+    public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
+            String historyName, int type, boolean unimportantForLogging) {
         int N = ws.size();
         for (int i=0; i<N; i++) {
-            noteStartWakeLocked(ws.get(i), pid, name, type, unimportantForLogging);
+            noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging);
         }
     }
 
@@ -2286,7 +2291,8 @@
 
             // Fake a wake lock, so we consider the device waked as long
             // as the screen is on.
-            noteStartWakeLocked(-1, -1, "screen", WAKE_TYPE_PARTIAL, false);
+            noteStartWakeLocked(Process.myUid(), Process.myPid(), "screen", null,
+                    WAKE_TYPE_PARTIAL, false);
             
             // Update discharge amounts.
             if (mOnBatteryInternal) {
@@ -2954,16 +2960,45 @@
         }
     }
 
+    private static String[] includeInStringArray(String[] array, String str) {
+        if (ArrayUtils.indexOf(array, str) >= 0) {
+            return array;
+        }
+        String[] newArray = new String[array.length+1];
+        System.arraycopy(array, 0, newArray, 0, array.length);
+        newArray[array.length] = str;
+        return newArray;
+    }
+
+    private static String[] excludeFromStringArray(String[] array, String str) {
+        int index = ArrayUtils.indexOf(array, str);
+        if (index >= 0) {
+            String[] newArray = new String[array.length-1];
+            if (index > 0) {
+                System.arraycopy(array, 0, newArray, 0, index);
+            }
+            if (index < array.length-1) {
+                System.arraycopy(array, index+1, newArray, index, array.length-index-1);
+            }
+            return newArray;
+        }
+        return array;
+    }
+
     public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
         if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
-            mMobileIfaces.add(iface);
+            mMobileIfaces = includeInStringArray(mMobileIfaces, iface);
+            if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces);
         } else {
-            mMobileIfaces.remove(iface);
+            mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface);
+            if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces);
         }
         if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
-            mWifiIfaces.add(iface);
+            mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
+            if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
         } else {
-            mWifiIfaces.remove(iface);
+            mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
+            if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
         }
     }
 
@@ -5572,33 +5607,31 @@
     private void updateNetworkActivityLocked() {
         if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return;
 
-        final NetworkStats snapshot;
-        try {
-            snapshot = mNetworkStatsFactory.readNetworkStatsDetail();
-        } catch (IOException e) {
-            Log.wtf(TAG, "Failed to read network stats", e);
-            return;
-        }
+        if (mMobileIfaces.length > 0) {
+            final NetworkStats snapshot;
+            final NetworkStats last = mCurMobileSnapshot;
+            try {
+                snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
+                        mMobileIfaces, NetworkStats.TAG_NONE, mLastMobileSnapshot);
+            } catch (IOException e) {
+                Log.wtf(TAG, "Failed to read mobile network stats", e);
+                return;
+            }
 
-        if (mLastSnapshot == null) {
-            mLastSnapshot = snapshot;
-            return;
-        }
+            mCurMobileSnapshot = snapshot;
+            mLastMobileSnapshot = last;
 
-        final NetworkStats delta = snapshot.subtract(mLastSnapshot);
-        mLastSnapshot = snapshot;
+            final NetworkStats delta = NetworkStats.subtract(snapshot, last,
+                    null, null, mTmpNetworkStats);
+            mTmpNetworkStats = delta;
 
-        NetworkStats.Entry entry = null;
-        final int size = delta.size();
-        for (int i = 0; i < size; i++) {
-            entry = delta.getValues(i, entry);
+            final int size = delta.size();
+            for (int i = 0; i < size; i++) {
+                final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
 
-            if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
-            if (entry.tag != NetworkStats.TAG_NONE) continue;
+                if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
 
-            final Uid u = getUidStatsLocked(entry.uid);
-
-            if (mMobileIfaces.contains(entry.iface)) {
+                final Uid u = getUidStatsLocked(entry.uid);
                 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
                         entry.rxPackets);
                 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
@@ -5610,8 +5643,41 @@
                         entry.rxPackets);
                 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
                         entry.txPackets);
+            }
+        }
 
-            } else if (mWifiIfaces.contains(entry.iface)) {
+        if (mWifiIfaces.length > 0) {
+            final NetworkStats snapshot;
+            final NetworkStats last = mCurWifiSnapshot;
+            try {
+                snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
+                        mWifiIfaces, NetworkStats.TAG_NONE, mLastWifiSnapshot);
+            } catch (IOException e) {
+                Log.wtf(TAG, "Failed to read wifi network stats", e);
+                return;
+            }
+
+            mCurWifiSnapshot = snapshot;
+            mLastWifiSnapshot = last;
+
+            final NetworkStats delta = NetworkStats.subtract(snapshot, last,
+                    null, null, mTmpNetworkStats);
+            mTmpNetworkStats = delta;
+
+            final int size = delta.size();
+            for (int i = 0; i < size; i++) {
+                final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
+
+                if (DEBUG) {
+                    final NetworkStats.Entry cur = snapshot.getValues(i, null);
+                    Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
+                            + " tx=" + entry.txBytes + ", cur rx=" + cur.rxBytes
+                            + " tx=" + cur.txBytes);
+                }
+
+                if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
+
+                final Uid u = getUidStatsLocked(entry.uid);
                 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, entry.rxPackets);
                 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, entry.txPackets);
 
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index fae93ba..e8feacb 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -125,12 +125,18 @@
 static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream,
         int sampleSize, bool ditherImage) {
 
+    SkImageInfo bitmapInfo;
+    if (!bitmap->asImageInfo(&bitmapInfo)) {
+        ALOGW("bitmap has unknown configuration so no memory has been allocated");
+        return NULL;
+    }
+
     SkImageRef* pr;
     // only use ashmem for large images, since mmaps come at a price
     if (bitmap->getSize() >= 32 * 1024) {
-        pr = new SkImageRef_ashmem(stream, bitmap->config(), sampleSize);
+        pr = new SkImageRef_ashmem(bitmapInfo, stream, sampleSize);
     } else {
-        pr = new SkImageRef_GlobalPool(stream, bitmap->config(), sampleSize);
+        pr = new SkImageRef_GlobalPool(bitmapInfo, stream, sampleSize);
     }
     pr->setDitherImage(ditherImage);
     bitmap->setPixelRef(pr)->unref();
@@ -192,8 +198,15 @@
             return false;
         }
 
+        SkImageInfo bitmapInfo;
+        if (!bitmap->asImageInfo(&bitmapInfo)) {
+            ALOGW("unable to reuse a bitmap as the target has an unknown bitmap configuration");
+            return false;
+        }
+
         // Create a new pixelref with the new ctable that wraps the previous pixelref
-        SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef), ctable);
+        SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef),
+                bitmapInfo, bitmap->rowBytes(), ctable);
 
         bitmap->setPixelRef(pr)->unref();
         // since we're already allocated, we lockPixels right away
@@ -418,7 +431,7 @@
         }
 
         SkPaint paint;
-        paint.setFilterBitmap(true);
+        paint.setFilterLevel(SkPaint::kLow_FilterLevel);
 
         SkCanvas canvas(*outputBitmap);
         canvas.scale(sx, sy);
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index e98d45b..7420055 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -555,7 +555,7 @@
                 if (paint) {
                     filteredPaint = *paint;
                 }
-                filteredPaint.setFilterBitmap(true);
+                filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
                 canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
             } else {
                 canvas->drawBitmap(*bitmap, left_, top_, paint);
@@ -570,7 +570,7 @@
             if (paint) {
                 filteredPaint = *paint;
             }
-            filteredPaint.setFilterBitmap(true);
+            filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
 
             canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
 
@@ -593,7 +593,7 @@
             if (paint) {
                 filteredPaint = *paint;
             }
-            filteredPaint.setFilterBitmap(true);
+            filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
             canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
         } else {
             canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 66f9f3d..98edbdb 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -444,8 +444,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
-        SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)),
+AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage,
+        size_t rowBytes, jbyteArray storageObj, SkColorTable* ctable) :
+        SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)),
         fWrappedPixelRef(NULL) {
     SkASSERT(storage);
     SkASSERT(env);
@@ -463,10 +464,11 @@
 
 }
 
-AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable) :
-        SkMallocPixelRef(wrappedPixelRef.getAddr(), wrappedPixelRef.getSize(), ctable, false),
+AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
+        size_t rowBytes, SkColorTable* ctable) :
+        SkMallocPixelRef(info, wrappedPixelRef.getAddr(), rowBytes, ctable, false),
         fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ?
-            wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
+                wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
 {
     SkASSERT(fWrappedPixelRef);
     SkSafeRef(fWrappedPixelRef);
@@ -568,6 +570,14 @@
                           "bitmap size exceeds 32bits");
         return NULL;
     }
+
+    SkImageInfo bitmapInfo;
+    if (!bitmap->asImageInfo(&bitmapInfo)) {
+        jniThrowException(env, "java/lang/IllegalArgumentException",
+                "unknown bitmap configuration");
+        return NULL;
+    }
+
     size_t size = size64.get32();
     jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime,
                                                              gVMRuntime_newNonMovableArray,
@@ -581,7 +591,8 @@
         return NULL;
     }
     SkASSERT(addr);
-    SkPixelRef* pr = new AndroidPixelRef(env, (void*) addr, size, arrayObj, ctable);
+    SkPixelRef* pr = new AndroidPixelRef(env, bitmapInfo, (void*) addr,
+            bitmap->rowBytes(), arrayObj, ctable);
     bitmap->setPixelRef(pr)->unref();
     // since we're already allocated, we lockPixels right away
     // HeapAllocator behaves this way too
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 5f29604..cb154aa 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -92,15 +92,16 @@
 
 class AndroidPixelRef : public SkMallocPixelRef {
 public:
-    AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
-                    SkColorTable* ctable);
+    AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes,
+            jbyteArray storageObj, SkColorTable* ctable);
 
     /**
      * Creates an AndroidPixelRef that wraps (and refs) another to reuse/share
      * the same storage and java byte array refcounting, yet have a different
      * color table.
      */
-    AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable);
+    AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
+            size_t rowBytes, SkColorTable* ctable);
 
     virtual ~AndroidPixelRef();
 
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 6c81f06..189fe47 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -155,7 +155,8 @@
 
     static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
         NPE_CHECK_RETURN_VOID(env, paint);
-        GraphicsJNI::getNativePaint(env, paint)->setFilterBitmap(filterBitmap);
+        GraphicsJNI::getNativePaint(env, paint)->setFilterLevel(
+                filterBitmap ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
     }
 
     static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index bcf1273..912968a 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -214,7 +214,7 @@
 
     SkRegion* region = new SkRegion;
     size_t size = p->readInt32();
-    region->readFromMemory(p->readInplace(size));
+    region->readFromMemory(p->readInplace(size), size);
 
     return reinterpret_cast<jlong>(region);
 }
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 5b0a4b2..bf65dfc 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -69,22 +69,22 @@
     jclass eglconfigClassLocal = _env->FindClass("android/opengl/EGLConfig");
     eglconfigClass = (jclass) _env->NewGlobalRef(eglconfigClassLocal);
 
-    egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getHandle", "()I");
-    eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getHandle", "()I");
-    eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getHandle", "()I");
-    eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getHandle", "()I");
+    egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getNativeHandle", "()J");
+    eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getNativeHandle", "()J");
+    eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getNativeHandle", "()J");
+    eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getNativeHandle", "()J");
 
 
-    egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(I)V");
-    eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(I)V");
-    eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(I)V");
-    eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(I)V");
+    egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(J)V");
+    eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(J)V");
+    eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(J)V");
+    eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(J)V");
 
-    jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, (jint)EGL_NO_CONTEXT);
+    jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, reinterpret_cast<jlong>(EGL_NO_CONTEXT));
     eglNoContextObject = _env->NewGlobalRef(localeglNoContextObject);
-    jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, (jint)EGL_NO_DISPLAY);
+    jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, reinterpret_cast<jlong>(EGL_NO_DISPLAY));
     eglNoDisplayObject = _env->NewGlobalRef(localeglNoDisplayObject);
-    jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, (jint)EGL_NO_SURFACE);
+    jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, reinterpret_cast<jlong>(EGL_NO_SURFACE));
     eglNoSurfaceObject = _env->NewGlobalRef(localeglNoSurfaceObject);
 
 
@@ -106,7 +106,8 @@
                           "Object is set to null.");
     }
 
-    return (void*) (_env->CallIntMethod(obj, mid));
+    jlong handle = _env->CallLongMethod(obj, mid);
+    return reinterpret_cast<void*>(handle);
 }
 
 static jobject
@@ -126,7 +127,7 @@
            return eglNoSurfaceObject;
     }
 
-    return _env->NewObject(cls, con, (jint)handle);
+    return _env->NewObject(cls, con, reinterpret_cast<jlong>(handle));
 }
 
 // --------------------------------------------------------------------------
@@ -142,14 +143,26 @@
 /* EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id ) */
 static jobject
 android_eglGetDisplay
-  (JNIEnv *_env, jobject _this, jint display_id) {
+  (JNIEnv *_env, jobject _this, jlong display_id) {
     EGLDisplay _returnValue = (EGLDisplay) 0;
     _returnValue = eglGetDisplay(
-        (EGLNativeDisplayType)display_id
+        reinterpret_cast<EGLNativeDisplayType>(display_id)
     );
     return toEGLHandle(_env, egldisplayClass, egldisplayConstructor, _returnValue);
 }
 
+/* EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id ) */
+static jobject
+android_eglGetDisplayInt
+  (JNIEnv *_env, jobject _this, jint display_id) {
+
+    if (sizeof(void*) != sizeof(uint32_t)) {
+        jniThrowException(_env, "java/lang/UnsupportedOperationException", "eglGetDisplay");
+        return 0;
+    }
+    return android_eglGetDisplay(_env, _this, display_id);
+}
+
 /* EGLBoolean eglInitialize ( EGLDisplay dpy, EGLint *major, EGLint *minor ) */
 static jboolean
 android_eglInitialize
@@ -852,7 +865,7 @@
 /* EGLSurface eglCreatePbufferFromClientBuffer ( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list ) */
 static jobject
 android_eglCreatePbufferFromClientBuffer
-  (JNIEnv *_env, jobject _this, jobject dpy, jint buftype, jint buffer, jobject config, jintArray attrib_list_ref, jint offset) {
+  (JNIEnv *_env, jobject _this, jobject dpy, jint buftype, jlong buffer, jobject config, jintArray attrib_list_ref, jint offset) {
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
@@ -897,7 +910,7 @@
     _returnValue = eglCreatePbufferFromClientBuffer(
         (EGLDisplay)dpy_native,
         (EGLenum)buftype,
-        (EGLClientBuffer)buffer,
+        reinterpret_cast<EGLClientBuffer>(buffer),
         (EGLConfig)config_native,
         (EGLint *)attrib_list
     );
@@ -913,6 +926,16 @@
     return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
 }
 
+static jobject
+android_eglCreatePbufferFromClientBufferInt
+  (JNIEnv *_env, jobject _this, jobject dpy, jint buftype, jint buffer, jobject config, jintArray attrib_list_ref, jint offset) {
+    if(sizeof(void*) != sizeof(uint32_t)) {
+        jniThrowException(_env, "java/lang/UnsupportedOperationException", "eglCreatePbufferFromClientBuffer");
+        return 0;
+    }
+    return android_eglCreatePbufferFromClientBuffer(_env, _this, dpy, buftype, buffer, config, attrib_list_ref, offset);
+}
+
 /* EGLBoolean eglSurfaceAttrib ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value ) */
 static jboolean
 android_eglSurfaceAttrib
@@ -1207,7 +1230,8 @@
 static JNINativeMethod methods[] = {
 {"_nativeClassInit", "()V", (void*)nativeClassInit },
 {"eglGetError", "()I", (void *) android_eglGetError },
-{"eglGetDisplay", "(I)Landroid/opengl/EGLDisplay;", (void *) android_eglGetDisplay },
+{"eglGetDisplay", "(I)Landroid/opengl/EGLDisplay;", (void *) android_eglGetDisplayInt },
+{"eglGetDisplay", "(J)Landroid/opengl/EGLDisplay;", (void *) android_eglGetDisplay },
 {"eglInitialize", "(Landroid/opengl/EGLDisplay;[II[II)Z", (void *) android_eglInitialize },
 {"eglTerminate", "(Landroid/opengl/EGLDisplay;)Z", (void *) android_eglTerminate },
 {"eglQueryString", "(Landroid/opengl/EGLDisplay;I)Ljava/lang/String;", (void *) android_eglQueryString__Landroind_opengl_EGLDisplay_2I },
@@ -1224,7 +1248,8 @@
 {"eglQueryAPI", "()I", (void *) android_eglQueryAPI },
 {"eglWaitClient", "()Z", (void *) android_eglWaitClient },
 {"eglReleaseThread", "()Z", (void *) android_eglReleaseThread },
-{"eglCreatePbufferFromClientBuffer", "(Landroid/opengl/EGLDisplay;IILandroid/opengl/EGLConfig;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePbufferFromClientBuffer },
+{"eglCreatePbufferFromClientBuffer", "(Landroid/opengl/EGLDisplay;IILandroid/opengl/EGLConfig;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePbufferFromClientBufferInt },
+{"eglCreatePbufferFromClientBuffer", "(Landroid/opengl/EGLDisplay;IJLandroid/opengl/EGLConfig;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePbufferFromClientBuffer },
 {"eglSurfaceAttrib", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;II)Z", (void *) android_eglSurfaceAttrib },
 {"eglBindTexImage", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;I)Z", (void *) android_eglBindTexImage },
 {"eglReleaseTexImage", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;I)Z", (void *) android_eglReleaseTexImage },
diff --git a/core/jni/android_opengl_EGLExt.cpp b/core/jni/android_opengl_EGLExt.cpp
index 5179ddc..15899f5 100644
--- a/core/jni/android_opengl_EGLExt.cpp
+++ b/core/jni/android_opengl_EGLExt.cpp
@@ -70,22 +70,22 @@
     jclass eglconfigClassLocal = _env->FindClass("android/opengl/EGLConfig");
     eglconfigClass = (jclass) _env->NewGlobalRef(eglconfigClassLocal);
 
-    egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getHandle", "()I");
-    eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getHandle", "()I");
-    eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getHandle", "()I");
-    eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getHandle", "()I");
+    egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getNativeHandle", "()J");
+    eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getNativeHandle", "()J");
+    eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getNativeHandle", "()J");
+    eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getNativeHandle", "()J");
 
 
-    egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(I)V");
-    eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(I)V");
-    eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(I)V");
-    eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(I)V");
+    egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(J)V");
+    eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(J)V");
+    eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(J)V");
+    eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(J)V");
 
-    jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, (jint)EGL_NO_CONTEXT);
+    jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, reinterpret_cast<jlong>(EGL_NO_CONTEXT));
     eglNoContextObject = _env->NewGlobalRef(localeglNoContextObject);
-    jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, (jint)EGL_NO_DISPLAY);
+    jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, reinterpret_cast<jlong>(EGL_NO_DISPLAY));
     eglNoDisplayObject = _env->NewGlobalRef(localeglNoDisplayObject);
-    jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, (jint)EGL_NO_SURFACE);
+    jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, reinterpret_cast<jlong>(EGL_NO_SURFACE));
     eglNoSurfaceObject = _env->NewGlobalRef(localeglNoSurfaceObject);
 
 
@@ -107,7 +107,7 @@
                           "Object is set to null.");
     }
 
-    return (void*) (_env->CallIntMethod(obj, mid));
+    return reinterpret_cast<void*>(_env->CallLongMethod(obj, mid));
 }
 
 static jobject
@@ -127,7 +127,7 @@
            return eglNoSurfaceObject;
     }
 
-    return _env->NewObject(cls, con, (jint)handle);
+    return _env->NewObject(cls, con, reinterpret_cast<jlong>(handle));
 }
 
 // --------------------------------------------------------------------------
diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp
index cc34e99..21e19e1 100644
--- a/core/jni/android_opengl_GLES10.cpp
+++ b/core/jni/android_opengl_GLES10.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp
index 9284384..bc83234 100644
--- a/core/jni/android_opengl_GLES10Ext.cpp
+++ b/core/jni/android_opengl_GLES10Ext.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp
index 871e84d..a45f269 100644
--- a/core/jni/android_opengl_GLES11.cpp
+++ b/core/jni/android_opengl_GLES11.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
@@ -578,7 +578,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -679,7 +679,7 @@
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2302,7 +2302,7 @@
     glNormalPointer(
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -2529,7 +2529,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -2937,7 +2937,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp
index 3e038ad..05728ef 100644
--- a/core/jni/android_opengl_GLES11Ext.cpp
+++ b/core/jni/android_opengl_GLES11Ext.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp
index db03b70..d3e5014 100644
--- a/core/jni/android_opengl_GLES20.cpp
+++ b/core/jni/android_opengl_GLES20.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
@@ -1180,7 +1180,7 @@
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1804,7 +1804,7 @@
         (GLsizei *)length,
         (GLint *)size,
         (GLenum *)type,
-        (char *)name
+        reinterpret_cast<char *>(name)
     );
     if (_typeArray) {
         releasePointer(_env, _typeArray, type, JNI_TRUE);
@@ -2132,7 +2132,7 @@
         (GLsizei *)length,
         (GLint *)size,
         (GLenum *)type,
-        (char *)name
+        reinterpret_cast<char *>(name)
     );
     if (_typeArray) {
         releasePointer(_env, _typeArray, type, JNI_TRUE);
@@ -3212,7 +3212,7 @@
         (GLuint)shader,
         (GLsizei)bufsize,
         (GLsizei *)length,
-        (char *)source
+        reinterpret_cast<char *>(source)
     );
     if (_array) {
         releasePointer(_env, _array, length, JNI_TRUE);
@@ -5985,7 +5985,7 @@
         (GLenum)type,
         (GLboolean)normalized,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp
index 4c62a75..8821352 100644
--- a/core/jni/android_opengl_GLES30.cpp
+++ b/core/jni/android_opengl_GLES30.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
@@ -370,7 +370,7 @@
         (GLuint)end,
         (GLsizei)count,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -419,7 +419,7 @@
         (GLint)border,
         (GLenum)format,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -470,7 +470,7 @@
         (GLsizei)depth,
         (GLenum)format,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -534,7 +534,7 @@
         (GLsizei)depth,
         (GLint)border,
         (GLsizei)imageSize,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -585,7 +585,7 @@
         (GLsizei)depth,
         (GLenum)format,
         (GLsizei)imageSize,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -2134,7 +2134,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 480d0ac..c5ab284 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -61,54 +61,21 @@
 
 class ScreenshotPixelRef : public SkPixelRef {
 public:
-    ScreenshotPixelRef(SkColorTable* ctable) {
-        fCTable = ctable;
-        SkSafeRef(ctable);
+    ScreenshotPixelRef(const SkImageInfo& info, ScreenshotClient* screenshot) :
+      SkPixelRef(info),
+      mScreenshot(screenshot) {
         setImmutable();
     }
 
     virtual ~ScreenshotPixelRef() {
-        SkSafeUnref(fCTable);
-    }
-
-    status_t update(const sp<IBinder>& display, int width, int height,
-            int minLayer, int maxLayer, bool allLayers,
-            bool useIdentityTransform) {
-        status_t res = (width > 0 && height > 0)
-                ? (allLayers
-                        ? mScreenshot.update(display, width, height,
-                                useIdentityTransform)
-                        : mScreenshot.update(display, width, height,
-                                minLayer, maxLayer, useIdentityTransform))
-                : mScreenshot.update(display, useIdentityTransform);
-        if (res != NO_ERROR) {
-            return res;
-        }
-
-        return NO_ERROR;
-    }
-
-    uint32_t getWidth() const {
-        return mScreenshot.getWidth();
-    }
-
-    uint32_t getHeight() const {
-        return mScreenshot.getHeight();
-    }
-
-    uint32_t getStride() const {
-        return mScreenshot.getStride();
-    }
-
-    uint32_t getFormat() const {
-        return mScreenshot.getFormat();
+        delete mScreenshot;
     }
 
 protected:
     // overrides from SkPixelRef
     virtual void* onLockPixels(SkColorTable** ct) {
-        *ct = fCTable;
-        return (void*)mScreenshot.getPixels();
+        *ct = NULL;
+        return (void*)mScreenshot->getPixels();
     }
 
     virtual void onUnlockPixels() {
@@ -116,8 +83,7 @@
 
     SK_DECLARE_UNFLATTENABLE_OBJECT()
 private:
-    ScreenshotClient mScreenshot;
-    SkColorTable*    fCTable;
+    ScreenshotClient* mScreenshot;
 
     typedef SkPixelRef INHERITED;
 };
@@ -150,20 +116,6 @@
     ctrl->decStrong((void *)nativeCreate);
 }
 
-static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
-    /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
-        we can map to SkBitmap::kARGB_8888_Config, and optionally call
-        bitmap.setAlphaType(kOpaque_SkAlphaType) on the resulting SkBitmap
-        (as an accelerator)
-    */
-    switch (format) {
-    case PIXEL_FORMAT_RGBX_8888:    return SkBitmap::kARGB_8888_Config;
-    case PIXEL_FORMAT_RGBA_8888:    return SkBitmap::kARGB_8888_Config;
-    case PIXEL_FORMAT_RGB_565:      return SkBitmap::kRGB_565_Config;
-    default:                        return SkBitmap::kNo_Config;
-    }
-}
-
 static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj,
         jint width, jint height, jint minLayer, jint maxLayer, bool allLayers,
         bool useIdentityTransform) {
@@ -172,26 +124,57 @@
         return NULL;
     }
 
-    ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
-    if (pixels->update(displayToken, width, height,
-            minLayer, maxLayer, allLayers, useIdentityTransform) != NO_ERROR) {
-        delete pixels;
+    ScreenshotClient* screenshot = new ScreenshotClient();
+    status_t res;
+    if (width > 0 && height > 0) {
+        if (allLayers) {
+            res = screenshot->update(displayToken, width, height, useIdentityTransform);
+        } else {
+            res = screenshot->update(displayToken, width, height, minLayer, maxLayer,
+                    useIdentityTransform);
+        }
+    } else {
+        res = screenshot->update(displayToken, useIdentityTransform);
+    }
+    if (res != NO_ERROR) {
+        delete screenshot;
         return NULL;
     }
 
-    uint32_t w = pixels->getWidth();
-    uint32_t h = pixels->getHeight();
-    uint32_t s = pixels->getStride();
-    uint32_t f = pixels->getFormat();
-    ssize_t bpr = s * android::bytesPerPixel(f);
+    SkImageInfo screenshotInfo;
+    screenshotInfo.fWidth = screenshot->getWidth();
+    screenshotInfo.fHeight = screenshot->getHeight();
 
-    SkBitmap* bitmap = new SkBitmap();
-    bitmap->setConfig(convertPixelFormat(f), w, h, bpr);
-    if (f == PIXEL_FORMAT_RGBX_8888) {
-        bitmap->setAlphaType(kOpaque_SkAlphaType);
+    switch (screenshot->getFormat()) {
+        case PIXEL_FORMAT_RGBX_8888: {
+            screenshotInfo.fColorType = kRGBA_8888_SkColorType;
+            screenshotInfo.fAlphaType = kIgnore_SkAlphaType;
+            break;
+        }
+        case PIXEL_FORMAT_RGBA_8888: {
+            screenshotInfo.fColorType = kRGBA_8888_SkColorType;
+            screenshotInfo.fAlphaType = kPremul_SkAlphaType;
+            break;
+        }
+        case PIXEL_FORMAT_RGB_565: {
+            screenshotInfo.fColorType = kRGB_565_SkColorType;
+            screenshotInfo.fAlphaType = kIgnore_SkAlphaType;
+            break;
+        }
+        default: {
+            delete screenshot;
+            return NULL;
+        }
     }
 
-    if (w > 0 && h > 0) {
+    // takes ownership of ScreenshotClient
+    ScreenshotPixelRef* pixels = new ScreenshotPixelRef(screenshotInfo, screenshot);
+    const ssize_t rowBytes =
+            screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
+
+    SkBitmap* bitmap = new SkBitmap();
+    bitmap->setConfig(screenshotInfo, (size_t)rowBytes);
+    if (screenshotInfo.fWidth > 0 && screenshotInfo.fHeight > 0) {
         bitmap->setPixelRef(pixels)->unref();
         bitmap->lockPixels();
     } else {
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index 0b9ad9b..c84a466 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -37,6 +37,7 @@
 
 static struct {
     jfieldID size;
+    jfieldID capacity;
     jfieldID iface;
     jfieldID uid;
     jfieldID set;
@@ -49,7 +50,6 @@
 } gNetworkStatsClassInfo;
 
 struct stats_line {
-    int32_t idx;
     char iface[32];
     int32_t uid;
     int32_t set;
@@ -60,8 +60,41 @@
     int64_t txPackets;
 };
 
+static jobjectArray get_string_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
+{
+    if (!grow) {
+        jobjectArray array = (jobjectArray)env->GetObjectField(obj, field);
+        if (array != NULL) {
+            return array;
+        }
+    }
+    return env->NewObjectArray(size, gStringClass, NULL);
+}
+
+static jintArray get_int_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
+{
+    if (!grow) {
+        jintArray array = (jintArray)env->GetObjectField(obj, field);
+        if (array != NULL) {
+            return array;
+        }
+    }
+    return env->NewIntArray(size);
+}
+
+static jlongArray get_long_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
+{
+    if (!grow) {
+        jlongArray array = (jlongArray)env->GetObjectField(obj, field);
+        if (array != NULL) {
+            return array;
+        }
+    }
+    return env->NewLongArray(size);
+}
+
 static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
-        jstring path, jint limitUid) {
+        jstring path, jint limitUid, jobjectArray limitIfacesObj, jint limitTag) {
     ScopedUtfChars path8(env, path);
     if (path8.c_str() == NULL) {
         return -1;
@@ -72,50 +105,146 @@
         return -1;
     }
 
+    Vector<String8> limitIfaces;
+    if (limitIfacesObj != NULL && env->GetArrayLength(limitIfacesObj) > 0) {
+        int num = env->GetArrayLength(limitIfacesObj);
+        limitIfaces.setCapacity(num);
+        for (int i=0; i<num; i++) {
+            jstring string = (jstring)env->GetObjectArrayElement(limitIfacesObj, i);
+            ScopedUtfChars string8(env, string);
+            if (string8.c_str() != NULL) {
+                limitIfaces.add(String8(string8.c_str()));
+            }
+        }
+    }
+
     Vector<stats_line> lines;
 
     int lastIdx = 1;
+    int idx;
     char buffer[384];
     while (fgets(buffer, sizeof(buffer), fp) != NULL) {
         stats_line s;
         int64_t rawTag;
-        if (sscanf(buffer, "%d %31s 0x%llx %u %u %llu %llu %llu %llu", &s.idx,
-                s.iface, &rawTag, &s.uid, &s.set, &s.rxBytes, &s.rxPackets,
-                &s.txBytes, &s.txPackets) == 9) {
-            if (s.idx != lastIdx + 1) {
-                ALOGE("inconsistent idx=%d after lastIdx=%d", s.idx, lastIdx);
-                return -1;
+        char* pos = buffer;
+        char* endPos;
+        // First field is the index.
+        idx = (int)strtol(pos, &endPos, 10);
+        //ALOGI("Index #%d: %s", idx, buffer);
+        if (pos == endPos) {
+            // Skip lines that don't start with in index.  In particular,
+            // this will skip the initial header line.
+            continue;
+        }
+        if (idx != lastIdx + 1) {
+            ALOGE("inconsistent idx=%d after lastIdx=%d: %s", idx, lastIdx, buffer);
+            fclose(fp);
+            return -1;
+        }
+        lastIdx = idx;
+        pos = endPos;
+        // Skip whitespace.
+        while (*pos == ' ') {
+            pos++;
+        }
+        // Next field is iface.
+        int ifaceIdx = 0;
+        while (*pos != ' ' && *pos != 0 && ifaceIdx < (int)(sizeof(s.iface)-1)) {
+            s.iface[ifaceIdx] = *pos;
+            ifaceIdx++;
+            pos++;
+        }
+        if (*pos != ' ') {
+            ALOGE("bad iface: %s", buffer);
+            fclose(fp);
+            return -1;
+        }
+        s.iface[ifaceIdx] = 0;
+        if (limitIfaces.size() > 0) {
+            // Is this an iface the caller is interested in?
+            int i = 0;
+            while (i < (int)limitIfaces.size()) {
+                if (limitIfaces[i] == s.iface) {
+                    break;
+                }
+                i++;
             }
-            lastIdx = s.idx;
-
-            s.tag = rawTag >> 32;
+            if (i >= (int)limitIfaces.size()) {
+                // Nothing matched; skip this line.
+                //ALOGI("skipping due to iface: %s", buffer);
+                continue;
+            }
+        }
+        // Skip whitespace.
+        while (*pos == ' ') {
+            pos++;
+        }
+        // Next field is tag.
+        rawTag = strtoll(pos, &endPos, 16);
+        //ALOGI("Index #%d: %s", idx, buffer);
+        if (pos == endPos) {
+            ALOGE("bad tag: %s", pos);
+            fclose(fp);
+            return -1;
+        }
+        s.tag = rawTag >> 32;
+        if (limitTag != -1 && s.tag != limitTag) {
+            //ALOGI("skipping due to tag: %s", buffer);
+            continue;
+        }
+        pos = endPos;
+        // Skip whitespace.
+        while (*pos == ' ') {
+            pos++;
+        }
+        // Parse remaining fields.
+        if (sscanf(pos, "%u %u %llu %llu %llu %llu",
+                &s.uid, &s.set, &s.rxBytes, &s.rxPackets,
+                &s.txBytes, &s.txPackets) == 6) {
+            if (limitUid != -1 && limitUid != s.uid) {
+                //ALOGI("skipping due to uid: %s", buffer);
+                continue;
+            }
             lines.push_back(s);
+        } else {
+            //ALOGI("skipping due to bad remaining fields: %s", pos);
         }
     }
 
     if (fclose(fp) != 0) {
+        ALOGE("Failed to close netstats file");
         return -1;
     }
 
     int size = lines.size();
+    bool grow = size > env->GetIntField(stats, gNetworkStatsClassInfo.capacity);
 
-    ScopedLocalRef<jobjectArray> iface(env, env->NewObjectArray(size, gStringClass, NULL));
+    ScopedLocalRef<jobjectArray> iface(env, get_string_array(env, stats,
+            gNetworkStatsClassInfo.iface, size, grow));
     if (iface.get() == NULL) return -1;
-    ScopedIntArrayRW uid(env, env->NewIntArray(size));
+    ScopedIntArrayRW uid(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.uid, size, grow));
     if (uid.get() == NULL) return -1;
-    ScopedIntArrayRW set(env, env->NewIntArray(size));
+    ScopedIntArrayRW set(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.set, size, grow));
     if (set.get() == NULL) return -1;
-    ScopedIntArrayRW tag(env, env->NewIntArray(size));
+    ScopedIntArrayRW tag(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.tag, size, grow));
     if (tag.get() == NULL) return -1;
-    ScopedLongArrayRW rxBytes(env, env->NewLongArray(size));
+    ScopedLongArrayRW rxBytes(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.rxBytes, size, grow));
     if (rxBytes.get() == NULL) return -1;
-    ScopedLongArrayRW rxPackets(env, env->NewLongArray(size));
+    ScopedLongArrayRW rxPackets(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.rxPackets, size, grow));
     if (rxPackets.get() == NULL) return -1;
-    ScopedLongArrayRW txBytes(env, env->NewLongArray(size));
+    ScopedLongArrayRW txBytes(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.txBytes, size, grow));
     if (txBytes.get() == NULL) return -1;
-    ScopedLongArrayRW txPackets(env, env->NewLongArray(size));
+    ScopedLongArrayRW txPackets(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.txPackets, size, grow));
     if (txPackets.get() == NULL) return -1;
-    ScopedLongArrayRW operations(env, env->NewLongArray(size));
+    ScopedLongArrayRW operations(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.operations, size, grow));
     if (operations.get() == NULL) return -1;
 
     for (int i = 0; i < size; i++) {
@@ -132,15 +261,18 @@
     }
 
     env->SetIntField(stats, gNetworkStatsClassInfo.size, size);
-    env->SetObjectField(stats, gNetworkStatsClassInfo.iface, iface.get());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.txBytes, txBytes.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.txPackets, txPackets.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.operations, operations.getJavaArray());
+    if (grow) {
+        env->SetIntField(stats, gNetworkStatsClassInfo.capacity, size);
+        env->SetObjectField(stats, gNetworkStatsClassInfo.iface, iface.get());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.txBytes, txBytes.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.txPackets, txPackets.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.operations, operations.getJavaArray());
+    }
 
     return 0;
 }
@@ -157,7 +289,7 @@
 
 static JNINativeMethod gMethods[] = {
         { "nativeReadNetworkStatsDetail",
-                "(Landroid/net/NetworkStats;Ljava/lang/String;I)I",
+                "(Landroid/net/NetworkStats;Ljava/lang/String;I[Ljava/lang/String;I)I",
                 (void*) readNetworkStatsDetail }
 };
 
@@ -170,6 +302,7 @@
 
     jclass clazz = env->FindClass("android/net/NetworkStats");
     gNetworkStatsClassInfo.size = env->GetFieldID(clazz, "size", "I");
+    gNetworkStatsClassInfo.capacity = env->GetFieldID(clazz, "capacity", "I");
     gNetworkStatsClassInfo.iface = env->GetFieldID(clazz, "iface", "[Ljava/lang/String;");
     gNetworkStatsClassInfo.uid = env->GetFieldID(clazz, "uid", "[I");
     gNetworkStatsClassInfo.set = env->GetFieldID(clazz, "set", "[I");
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index b3b0049..7975987 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -129,7 +129,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void *>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
@@ -4359,7 +4359,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -4460,7 +4460,7 @@
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6099,7 +6099,7 @@
     glNormalPointer(
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -6326,7 +6326,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -6756,7 +6756,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -7196,7 +7196,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -7232,7 +7232,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 69ca648..010f812 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -563,8 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Umožňuje aplikaci ovládat telefonní funkce zařízení. Aplikace s tímto oprávněním smí bez upozornění přepínat sítě, zapínat a vypínat bezdrátový modul telefonu a podobně."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"čtení stavu a identity telefonu"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Umožňuje aplikaci získat přístup k telefonním funkcím zařízení. Toto oprávnění umožňuje aplikaci zjistit telefonní číslo telefonu, identifikační čísla zařízení, zda zrovna probíhá hovor, a vzdálené číslo, ke kterému je hovor připojen."</string>
-    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"čtení přesných stavů telefonů"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Umožňuje aplikaci používat přesné stavy telefonů. Toto oprávnění aplikaci umožňuje zjistit skutečný stav volání, zda je volání aktivní nebo na pozadí, zda volání selhalo, přesný stav datového připojení a zda datové připojení selhalo."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"čtení přesného stavu telefonování"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Umožňuje aplikaci zjišťovat přesný stav telefonování a mobilních dat. Toto oprávnění aplikaci umožňuje zjistit skutečný stav volání, zda je volání aktivní nebo na pozadí, zda volání selhalo, přesný stav datového připojení a zda datové připojení selhalo."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"bránění přechodu tabletu do režimu spánku"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"bránění přechodu telefonu do režimu spánku"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Umožňuje aplikaci zabránit přechodu tabletu do režimu spánku."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 6b12c26..545b317 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -563,7 +563,7 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite que la aplicación controle las funciones de teléfono del dispositivo. Una aplicación con este permiso puede cambiar redes, encender y apagar la radio del teléfono y tareas similares sin siquiera notificártelo."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"leer la identidad y el estado del dispositivo"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que la aplicación acceda a las funciones de teléfono del dispositivo. La aplicación puede utilizar este permiso para descubrir identificadores de dispositivos y números de teléfono, para saber si una llamada está activa y para conocer el número remoto con el que se ha establecido conexión mediante una llamada."</string>
-    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Leer estados precisos del teléfono"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"leer estados precisos del teléfono"</string>
     <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite que la aplicación acceda a los estados precisos del teléfono y determine el estado real de la llamada, si hay una llamada activa o en segundo plano, si se produjeron fallos en la llamada, el estado preciso de la conexión de datos y si hubo fallos relacionados con la conexión de datos."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"evitar que el tablet entre en estado de inactividad"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"evitar que el dispositivo entre en estado de inactividad"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 1fed273..1f2a6cc 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -423,7 +423,7 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"‏اجازه می‎دهد برنامه از هر رمزگشای رسانه نصب شده‌ای استفاده کند تا برای پخش رمزگشایی شود."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"مدیریت اطلاعات کاربری مورد اعتماد"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"‏به برنامه امکان می‌دهد گواهینامه‌های CA را به عنوان اطلاعات کاربری مورد اعتماد نصب یا حذف نصب کند."</string>
-    <string name="permlab_bindIdleService" msgid="816311765497613780">"اجرای برنامه در هنگام بی‌حرکت بودن دستگاه"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"اجرای برنامه در هنگام بدون فعالیت بودن دستگاه"</string>
     <string name="permdesc_bindIdleService" msgid="1767538493214100612">"‏این مجوز به سیستم Android امکان می‌دهد تا وقتی دستگاه استفاده نمی‌شود برنامه را در پس‌زمینه اجرا کند."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"خواندن/نوشتن منابع متعلق به تشخیص"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"‏به برنامه اجازه می‌دهد هر منبعی را که متعلق به گروه تشخیص است بخواند و در آن بنویسد؛ به‌عنوان مثال، فایل‌های /dev. این امر به‌صورت بالقوه می‌تواند بر پایدار بودن و امنیت سیستم تأثیر بگذارد. این تنها باید برای تشخیص‎‌های مختص سخت‌افزار توسط تولیدکننده یا اپراتور استفاده شود."</string>
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"خواندن وضعیت تلفن و شناسه"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"به برنامه اجازه می‌دهد به ویژگی‌های تلفن دستگاه شما دسترسی پیدا کند. این مجوز به برنامه اجازه می‌دهد شماره تلفن و شناسه‌های دستگاه، فعال بودن یک تماس و شماره راه دوری که با یک تماس متصل شده است را مشخص کند."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"خواندن وضعیت‌های دقیق تلفن"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"به برنامه امکان می‌دهد به وضعیت‌های دقیق تلفن دسترسی داشته باشد. این مجوز به برنامه امکان می‌دهد وضعیت واقعی تماس اینکه آیا تماس فعال است یا در پس‌زمینه قرار دارد، تماس‌های ناموفق، وضعیت دقیق اتصال داده و اتصال‌های ناموفق داده را تعیین کند."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"به برنامه امکان می‌دهد به وضعیت‌های دقیق تلفن دسترسی داشته باشد. این مجوز به برنامه امکان می‌دهد وضعیت واقعی تماس، اینکه آیا تماس فعال است یا در پس‌زمینه قرار دارد، تماس‌های ناموفق، وضعیت دقیق اتصال داده و اتصال‌های ناموفق داده را تعیین کند."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ممانعت از به خواب رفتن رایانهٔ لوحی"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ممانعت از به خواب رفتن تلفن"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"‏به برنامه اجازه می‎دهد تا از غیرفعال شدن رایانهٔ لوحی جلوگیری کند."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 4504bad..b048bbc 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -635,7 +635,7 @@
     <string name="permlab_bluetooth" msgid="6127769336339276828">"uparivanje s Bluetooth uređajima"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Aplikaciji omogućuje pregled konfiguracije Bluetootha na tabletnom računalu te uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Aplikaciji omogućuje pregled konfiguracije Bluetootha na telefonu te uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
-    <string name="permlab_nfc" msgid="4423351274757876953">"upravljaj beskontaktnom (NFC) komunikacijom"</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"upravljanje beskontaktnom komunikacijom (NFC)"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Aplikaciji omogućuje komunikaciju s oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"onemogućavanje zaključavanja zaslona"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Aplikaciji omogućuje onemogućavanje zaključavanja tipkovnice i svih pripadajućih sigurnosnih zaporki. Na primjer, telefon onemogućuje zaključavanje tipkovnice kod primanja dolaznog telefonskog poziva, nakon kojeg se zaključavanje tipkovnice ponovo omogućuje."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 92ab180..1547900 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"telefonállapot és azonosító olvasása"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lehetővé teszi az alkalmazás számára, hogy hozzáférjen az eszköz telefonálási funkcióihoz. Az engedéllyel rendelkező alkalmazás meghatározhatja a telefonszámot és eszközazonosítókat, hogy egy hívás aktív-e, valamint híváskor a másik fél telefonszámát."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"pontos telefonállapot megállapítása"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Engedélyezi, hogy az alkalmazás hozzáférjen a pontos telefonállapothoz. Az ilyen engedéllyel rendelkező alkalmazás képes meghatározni a valós hívási állapotot: hogy egy hívás aktív-e vagy a háttérben van, a hívás meghiúsult-e, illetve a pontos adatkapcsoltot és az adatkapcsolati műveletek meghiúsulását."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Engedélyezi, hogy az alkalmazás hozzáférjen a pontos telefonállapothoz. Az ilyen engedéllyel rendelkező alkalmazás képes meghatározni a valós hívási állapotot, azt, hogy egy hívás aktív-e vagy a háttérben van, a hívás meghiúsult-e, illetve képes meghatározni az adatkapcsolat pontos állapotát és az adatkapcsolati műveletek meghiúsulását."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"táblagép alvás üzemmódjának megakadályozása"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"telefon alvó üzemmódjának megakadályozása"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Lehetővé teszi az alkalmazás számára, hogy megakadályozza, hogy a táblagép alvó üzemmódra váltson."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index e08dd93..a8cb3d2 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"skaityti telefono būseną ir tapatybę"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Leidžiama programai pasiekti telefono funkcijas įrenginyje. Šis leidimas suteikia teisę programai nustatyti telefono numerį ir įrenginio ID, tai, ar skambutis aktyvus, ir skambučiu prijungtą nuotolinį numerį."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"skaityti tikslias telefono būsenas"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Programai leidžiama pasiekti tikslias telefono būsenas. Šiuo leidimu programai leidžiama nustatyti tikrą skambučio būseną, ar skambutis yra aktyvus, ar vyksta fone, ar paskambinti nepavyksta, tikslią duomenų ryšio būseną ir ar nepavyksta užmegzto duomenų ryšio."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Programai leidžiama pasiekti tikslias telefono būsenas. Šiuo leidimu programai leidžiama nustatyti tikrą skambučio būseną, ar skambutis yra aktyvus, ar vyksta fone, ar paskambinti nepavyksta, tikslią duomenų ryšio būseną ir ar nepavyksta užmegzti duomenų ryšio."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"neleisti planšetiniam kompiuteriui užmigti"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"neleisti telefonui snausti"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Leidžiama programai neleisti planšetiniam kompiuteriui užmigti."</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 2e584e5..6eae123 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lese telefonstatus og -identitet"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lar appen bruke enhetens telefonfunksjoner. Med denne tillatelsen kan appen finne telefonnummer og enhets-ID-er, registrere om en samtale pågår, og se det eksterne nummeret det opprettes en forbindelse med via oppringing."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"lese nøyaktige telefontilstander"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Gir appen tillatelse til å bruke nøyaktige telefontilstander. Denne tillatelsen gjør at appen kan fastslå den faktiske anropstatusen, om et anrop er aktivt eller i bakgrunnen, anropsfeil, nøyaktig status for datatilkobling og datatilkoblingsfeil."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Gir appen tilgang til nøyaktige telefontilstander. Denne tillatelsen gjør at appen kan fastslå den faktiske anropstatusen, om et anrop er aktivt eller i bakgrunnen, anropsfeil, nøyaktig status for datatilkobling og datatilkoblingsfeil."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"hindre nettbrettet fra å gå over til sovemodus"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"forhindre telefonen fra å sove"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Lar appen hindre nettbrettet fra å gå over i sovemodus."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index e0433a6..7610c06 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -423,7 +423,7 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite aplicaţiei să utilizeze orice decodor media instalat pentru a decodifica redarea."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gestionarea acreditărilor de încredere"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite aplicației să instaleze și să dezinstaleze certificate CA ca acreditări de încredere."</string>
-    <string name="permlab_bindIdleService" msgid="816311765497613780">"rulați aplicația în timp ce dispozitivul este inactiv"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"rulează aplicația în timp ce dispozitivul este inactiv"</string>
     <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Cu această permisiune, sistemul Android poate rula aplicația în fundal în timp ce dispozitivul nu este utilizat."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"citire/scriere în resursele deţinute de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite aplicaţiei să citească şi să scrie în orice resursă deţinută de grupul diag, de ex., fişierele din /dev. Această permisiune ar putea să afecteze stabilitatea şi securitatea sistemului. Permisiunea trebuie utilizată NUMAI de producător sau de operator pentru diagnostice specifice pentru hardware."</string>
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"citeşte starea şi identitatea telefonului"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite aplicaţiei să acceseze funcţiile de telefon ale dispozitivului. Cu această permisiune aplicaţia stabileşte numărul de telefon şi ID-urile de dispozitiv, dacă un apel este activ, precum şi numărul de la distanţă conectat printr-un apel."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"accesați stările exacte ale telefonului"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite aplicației să acceseze stările exacte ale telefonului. Cu această permisiune, aplicația poate să determine starea reală a apelului, dacă apelul este activ sau în fundal, dacă apelul nu reușește, starea exactă și întreruperile conexiunii de date."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite aplicației să acceseze stările exacte ale telefonului. Cu această permisiune, aplicația poate să determine starea reală a apelului, dacă apelul este activ sau în fundal, dacă apelul eșuează, starea exactă și întreruperile conexiunii de date."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"împiedicarea computerului tablet PC să intre în repaus"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"împiedicare intrare telefon în repaus"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite aplicaţiei să împiedice intrarea tabletei în stare de repaus."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 6d8aca7..2ffc435 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Приложение сможет использовать любой установленный дешифратор."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"Управление учетными данными"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Приложение сможет устанавливать сертификаты ЦС в качестве надежных учетных данных, а также удалять их."</string>
-    <string name="permlab_bindIdleService" msgid="816311765497613780">"запуск приложений в свящем режиме"</string>
-    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Система Android сможет запускать приложение в фоновом режиме, когда устройство не будет использоваться."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"выполнение приложения в спящем режиме"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Система Android сможет выполнять приложение в фоновом режиме, когда устройство не используется."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Чтение/запись данных в системы диагностики"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Приложение сможет считывать и записывать данные системы диагностики (например, файлы в каталоге /dev). Это может повлиять на стабильность и безопасность системы. Это разрешение должно использоваться ТОЛЬКО производителем или оператором для диагностики аппаратного обеспечения."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"Включение/отключение компонентов приложения"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 5e8c45b..783b0a4 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -424,7 +424,7 @@
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"upravljanje preverjenih poverilnic"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Aplikaciji dovoli nameščanje in odstranjevanje potrdil overitelja potrdil kot preverjenih poverilnic."</string>
     <string name="permlab_bindIdleService" msgid="816311765497613780">"izvajanje aplikacije ob nedejavnosti"</string>
-    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"To dovoljenje sistemu Android omogoča, da izvaja aplikacijo v ozadju, ko se naprava ne uporablja."</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"To dovoljenje sistemu Android omogoča, da izvaja aplikacijo v ozadju, ko naprava ni v uporabi."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"branje/pisanje v sredstva, ki so v lasti skupine za diagnostiko"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Programu omogoča branje in pisanje na poljuben vir, ki je v lasti skupine za diagnostiko; na primer datoteke v mapi /dev. To lahko vpliva na stabilnost in varnost sistema. To naj uporablja SAMO izdelovalec ali operater za diagnostiko, specifično za strojno opremo."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"omogočanje ali onemogočanje komponent programa"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 7cbe055..d6f7457 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1461,7 +1461,7 @@
     <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Gränsen för data via Wi-Fi har överskridits"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> över angiven gräns."</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"Bakgrundsdata är begränsade"</string>
-    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Tryck för att radera begränsning"</string>
+    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Tryck för att ta bort begränsning"</string>
     <string name="ssl_certificate" msgid="6510040486049237639">"Säkerhetscertifikat"</string>
     <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certifikatet är giltigt."</string>
     <string name="issued_to" msgid="454239480274921032">"Utfärdad till:"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 87afca6..7f17c76 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Huruhusu programu kutumia vyombo vyovyote vya habari vilivyosakinishwa ili kusimbua kwa ajili ya kucheza tena."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"dhibiti vitambulisho vinavyoaminika"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Huruhusu programu kusakinisha na kusanidua vyeti vya CA kama vitambulisho vinavyoaminika."</string>
-    <string name="permlab_bindIdleService" msgid="816311765497613780">"endesha programu wakati haifanyi kitu"</string>
-    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ruhusa hii huwezesha mfumo wa Android kuendesha programu chini chini wakati kifaa hakitumiki."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"endesha programu wakati kifaa hakifanyi kitu"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ruhusa hii huwezesha mfumo wa Android kuendesha programu chini kwa chini wakati kifaa hakitumiki."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"soma/andika kwa vyanzo vinavyomilikiwa na diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Inaruhusu programu kusoma na kuandika kwa chanzo chochote kinachomilikiwa na kikundi cha diag; kwa mfano, faili katika /dev. Hii inaweza kuathiri udhabiti na usalama wa mfumo. Hii inapaswa kutumiwa TU kwa utambuzi mahsusi wa maunzi na mtengenezaji au opareta."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"wezesha au lemeza vijenzi vya programu"</string>
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"kusoma hali na kitambulisho cha simu"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Inaruhusu programu kufikia vipengele vya simu vya kifaa. Idhini hii inaruhusu programu kutambua nambari ya simu na kifaa, kama simu ni amilifu, na nambari ya mbali iliyounganishwa kwa simu."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Soma hali sahihi ya simu"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Huruhusu programu kufikia hali sahihi ya simu. Ruhusa hii huwezesha programu kufahamu hali sahihi ya simu, iwapo simu inatumika au katika hali ya chini chini, simu inaposhindikana, hali sahihi ya muunganisho wa data na muunganisho wa data unaposhindikana."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Huruhusu programu kufikia hali sahihi ya simu. Ruhusa hii huwezesha programu kufahamu hali sahihi ya simu, iwapo simu inatumika au iko katika hali ya chini kwa chini, simu inaposhindikana, hali sahihi ya muunganisho wa data na muunganisho wa data unaposhindikana."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zuia kompyuta ndogo dhidi ya kulala"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"kuzuia simu isilale"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Inaruhusu programu kuzuia kompyuta kibao  kwenda kulala."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 08308c7..f59b2d1 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1363,7 +1363,7 @@
     <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"แตะเพื่อออกจากโหมดรถยนต์"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"การปล่อยสัญญาณหรือฮอตสปอตทำงานอยู่"</string>
     <string name="tethered_notification_message" msgid="6857031760103062982">"แตะเพื่อตั้งค่า"</string>
-    <string name="back_button_label" msgid="2300470004503343439">"ย้อนกลับ"</string>
+    <string name="back_button_label" msgid="2300470004503343439">"กลับ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ถัดไป"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ข้าม"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"การใช้งานข้อมูลมือถือในระดับสูง"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index d5ea7e2..4b5e48a 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -424,7 +424,7 @@
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"quản lý thông tin xác thực đáng tin cậy"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Cho phép ứng dụng cài đặt và gỡ cài đặt chứng chỉ CA dưới dạng thông tin xác thực đáng tin cậy."</string>
     <string name="permlab_bindIdleService" msgid="816311765497613780">"chạy ứng dụng trong thời gian rảnh"</string>
-    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Sự cho phép này cho phép hệ thống Android chạy ứng dụng trong nền khi thiết bị không được sử dụng."</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Quyền này cho phép hệ thống Android chạy ứng dụng trong nền khi thiết bị không được sử dụng."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"đọc/ghi vào tài nguyên do chẩn đoán sở hữu"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Cho phép ứng dụng đọc và ghi vào bất kỳ tài nguyên nào do nhóm chẩn đoán sở hữu; ví dụ: các tệp trong /dev. Quyền này có thể ảnh hưởng đến sự ổn định và tính bảo mật của hệ thống. CHỈ nên sử dụng quyền này cho các chẩn đoán phần cứng cụ thể của nhà sản xuất hoặc nhà cung cấp."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"bật hoặc tắt cấu phần ứng dụng"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 9d3879b..ebf11c4 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -76,7 +76,7 @@
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"默认显示本机号码,在下一次通话中也显示"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"未提供服务。"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"您无法更改来电显示设置。"</string>
-    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"访问受限情况已发生变化"</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"网络可用情况发生变化"</string>
     <string name="RestrictedOnData" msgid="8653794784690065540">"数据服务已禁用。"</string>
     <string name="RestrictedOnEmergency" msgid="6581163779072833665">"紧急服务已禁用。"</string>
     <string name="RestrictedOnNormal" msgid="4953867011389750673">"已禁用语音服务。"</string>
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"读取手机状态和身份"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允许该应用访问设备的电话功能。此权限可让该应用确定本机号码和设备 ID、是否正处于通话状态以及拨打的号码。"</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"读取确切的手机状态"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允许应用获取确切的手机状态。此权限可让应用确定实际通话状态、通话是在界面上进行还是在后台进行、通话未接通次数、确切的数据网络连接状态,以及数据网络连接失败次数。"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允许应用获取确切的手机状态。此权限可让应用确定实际通话状态、通话是在界面上进行还是在后台进行、通话未接通情况、确切的数据网络连接状态,以及数据网络连接失败情况。"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"阻止平板电脑进入休眠状态"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手机休眠"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允许应用阻止平板电脑进入休眠状态。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index d079ac5..ad2f63c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -563,8 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"允許應用程式控制裝置的電話功能。擁有這項權限的應用程式可在未通知您的情況下,任意切換網路、開啟或關閉手機無線電等。"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"讀取手機狀態和識別碼"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允許應用程式使用裝置的電話功能。這項權限可讓應用程式判讀手機號碼和裝置 ID、是否正在通話中,以及所撥打的對方號碼。"</string>
-    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"讀取精確手機狀態"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允許應用程式存取精確的手機狀態。這項權限可讓應用程式判別實際通話狀態、通話程序正在進行中或是在背景運作、通話失敗次數、精確數據連線狀態和數據連線失敗次數。"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"讀取手機精確狀態"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允許應用程式存取手機的精確狀態。這項權限可讓應用程式判別實際通話狀態,包括通話正在進行中或是在背景運作、通話失敗次數、精確數據連線狀態和數據連線失敗次數。"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"防止平板電腦進入休眠狀態"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手機進入待命狀態"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允許應用程式防止平板電腦進入休眠狀態。"</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 4647413..2efbca2 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -259,6 +259,17 @@
          applications can request this feature. Default value is false. -->
     <attr name="requiredForAllUsers" format="boolean" />
 
+    <!-- Flag to specifiy for which types of profile this application needs to be present.
+         Only pre-installed applications can request this feature. Default is none. -->
+    <attr name="requiredForProfile">
+        <!-- This application needs to be present for restricted profiles -->
+        <flag name="restricted" value="0x0001" />
+        <!-- This application needs to be present for managed profiles -->
+        <flag name="managed" value="0x0002" />
+        <!-- This application needs to be present for all types of profiles -->
+        <flag name="all" value="0xFFFF" />
+    </attr>
+
     <!-- Flag indicating whether the application can be debugged, even when
          running on a device that is running in user mode. -->
     <attr name="debuggable" format="boolean" />
@@ -901,6 +912,7 @@
         <attr name="hasCode" format="boolean" />
         <attr name="persistent" />
         <attr name="requiredForAllUsers" />
+        <attr name="requiredForProfile" />
         <!-- Specify whether the components in this application are enabled or not (that is, can be
              instantiated by the system).
              If "false", it overrides any component specific values (a value of "true" will not
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 519e2ae..8d68277 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1083,8 +1083,16 @@
     <!-- Name of the wimax state tracker clas -->
     <string name="config_wimaxStateTrackerClassname" translatable="false"></string>
 
-    <!-- Is the dreams feature supported? -->
+    <!-- Specifies whether the dreams feature should be supported.
+         When true, the system will allow the user to configure dreams (screensavers)
+         to launch when a user activity timeout occurs or the system is told to nap.
+         When false, the dreams feature will be disabled (this does not affect dozing).
+
+         Consider setting this resource to false or disabling dreams by default when a
+         doze component is specified below since dreaming will supercede dozing and
+         will prevent the system from entering a low power state until the dream ends. -->
     <bool name="config_dreamsSupported">true</bool>
+
     <!-- If supported, are dreams enabled? (by default) -->
     <bool name="config_dreamsEnabledByDefault">true</bool>
     <!-- If supported and enabled, are dreams activated when docked? (by default) -->
@@ -1181,6 +1189,8 @@
 
     <!--  Maximum number of supported users -->
     <integer name="config_multiuserMaximumUsers">1</integer>
+    <!-- Whether UI for multi user should be shown -->
+    <bool name="config_enableMultiUserUI">false</bool>
 
     <!-- Minimum span needed to begin a touch scaling gesture.
          If the span is equal to or greater than this size, a scaling gesture
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 66858fa..3106daa 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2106,6 +2106,7 @@
   <public type="attr" name="sharedElementName" />
   <public type="attr" name="transitionGroup" />
   <public type="attr" name="castsShadow" />
+  <public type="attr" name="requiredForProfile"/>
 
   <public type="id" name="shared_element_name" />
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b1bf781..9f368c4 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -289,6 +289,7 @@
   <java-symbol type="bool" name="config_useFixedVolume" />
   <java-symbol type="bool" name="config_forceDefaultOrientation" />
   <java-symbol type="bool" name="config_wifi_batched_scan_supported" />
+  <java-symbol type="bool" name="config_enableMultiUserUI"/>
 
   <java-symbol type="integer" name="config_cursorWindowSize" />
   <java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
index b942eb6..cad030a 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
@@ -252,26 +252,26 @@
                 if (!validateEapValue(eapValue)) {
                     throw new SAXException();
                 }
-		if (eapValue.equals("TLS")) {
-		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-		} else if (eapValue.equals("TTLS")) {
-		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
-		} else if (eapValue.equals("PEAP")) {
-		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
-		}
+                if (eapValue.equals("TLS")) {
+                    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+                } else if (eapValue.equals("TTLS")) {
+                    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
+                } else if (eapValue.equals("PEAP")) {
+                    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
+                }
                 eap = false;
             }
             if (phase2) {
                 String phase2Value = new String(ch, start, length);
-		if (phase2Value.equals("PAP")) {
+                if (phase2Value.equals("PAP")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
-		} else if (phase2Value.equals("MSCHAP")) {
+                } else if (phase2Value.equals("MSCHAP")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAP);
-		} else if (phase2Value.equals("MSCHAPV2")) {
+                } else if (phase2Value.equals("MSCHAPV2")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
-		} else if (phase2Value.equals("GTC")) {
+                } else if (phase2Value.equals("GTC")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-		}
+                }
                 phase2 = false;
             }
             if (identity) {
diff --git a/core/tests/coretests/src/android/app/TranslucentFancyActivity.java b/core/tests/coretests/src/android/app/TranslucentFancyActivity.java
index ec5ad7a..35abaaa 100644
--- a/core/tests/coretests/src/android/app/TranslucentFancyActivity.java
+++ b/core/tests/coretests/src/android/app/TranslucentFancyActivity.java
@@ -53,7 +53,7 @@
      * describe what is to be displayed in the screen.
      */
     @Override
-	protected void onCreate(Bundle icicle)
+    protected void onCreate(Bundle icicle)
     {
         // Be sure to call the super class.
         super.onCreate(icicle);
diff --git a/core/tests/coretests/src/android/app/activity/AbortReceiver.java b/core/tests/coretests/src/android/app/activity/AbortReceiver.java
index fef1775..8d5c022 100644
--- a/core/tests/coretests/src/android/app/activity/AbortReceiver.java
+++ b/core/tests/coretests/src/android/app/activity/AbortReceiver.java
@@ -32,7 +32,7 @@
 
     public void onReceive(Context context, Intent intent)
     {
-	//Log.i("AbortReceiver", "onReceiveIntent!");
+        //Log.i("AbortReceiver", "onReceiveIntent!");
         try {
             IBinder caller = intent.getIBinderExtra("caller");
             Parcel data = Parcel.obtain();
diff --git a/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java b/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java
index e969d10..9f402a5 100644
--- a/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java
+++ b/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java
@@ -24,19 +24,19 @@
 import android.util.Log;
 
 public class RemoteSubActivityScreen extends SubActivityScreen {
-	Handler mHandler = new Handler();
-	boolean mFirst = false;
+    Handler mHandler = new Handler();
+    boolean mFirst = false;
 
     public RemoteSubActivityScreen() {
     }
 
     @Override
     public void onCreate(Bundle icicle) {
-    	// We are running in a remote process, so want to have the sub-activity
-    	// sending the result back in the original process.
+        // We are running in a remote process, so want to have the sub-activity
+        // sending the result back in the original process.
         Intent intent = getIntent();
-    	intent.setClass(this, SubActivityScreen.class);
-    	
+        intent.setClass(this, SubActivityScreen.class);
+        
         super.onCreate(icicle);
         
         boolean kill = intent.getBooleanExtra("kill", false);
@@ -44,16 +44,16 @@
         //        + " kill=" + kill);
         
         if (kill) {
-	        // After finishing initialization, kill the process!  But only if
-	        // this is the first time...
-	        if (icicle == null) {
-		        mHandler.post(new Runnable() {
-		        	public void run() {
-		        		handleBeforeStopping();
-		        		Process.killProcess(Process.myPid());
-		        	}
-		        });
-	        }
+            // After finishing initialization, kill the process!  But only if
+            // this is the first time...
+            if (icicle == null) {
+                mHandler.post(new Runnable() {
+                    public void run() {
+                        handleBeforeStopping();
+                        Process.killProcess(Process.myPid());
+                    }
+                });
+            }
         }
     }
 }
diff --git a/core/tests/coretests/src/android/app/activity/SubActivityScreen.java b/core/tests/coretests/src/android/app/activity/SubActivityScreen.java
index 919c591..3caec7a 100644
--- a/core/tests/coretests/src/android/app/activity/SubActivityScreen.java
+++ b/core/tests/coretests/src/android/app/activity/SubActivityScreen.java
@@ -44,24 +44,24 @@
         // Move on to the next thing that will generate a result...  but only
         // if we are being launched for the first time.
         if (icicle == null) {
-	        if (mMode == PENDING_RESULT_MODE) {
-	            PendingIntent apr = createPendingResult(1, null,
-	                    Intent.FILL_IN_ACTION);
-	            Intent res = new Intent();
+            if (mMode == PENDING_RESULT_MODE) {
+                PendingIntent apr = createPendingResult(1, null,
+                        Intent.FILL_IN_ACTION);
+                Intent res = new Intent();
                 res.putExtra("tkey", "tval");
                 res.setAction("test");
-	            try {
-    	            apr.send(this, RESULT_OK, res);
-	            } catch (PendingIntent.CanceledException e) {
-	            }
-	        } else if (mMode < CHILD_OFFSET) {
-	            Intent intent = new Intent();
-	        	intent.setClass(this, SubActivityScreen.class);
-	            intent.putExtra("mode", CHILD_OFFSET+mMode);
-	            //System.out.println("*** Starting from onStart: " + intent);
-	            startActivityForResult(intent, 1);
-	            return;
-	        }
+                try {
+                    apr.send(this, RESULT_OK, res);
+                } catch (PendingIntent.CanceledException e) {
+                }
+            } else if (mMode < CHILD_OFFSET) {
+                Intent intent = new Intent();
+                intent.setClass(this, SubActivityScreen.class);
+                intent.putExtra("mode", CHILD_OFFSET+mMode);
+                //System.out.println("*** Starting from onStart: " + intent);
+                startActivityForResult(intent, 1);
+                return;
+            }
         }
     }
 
@@ -77,15 +77,15 @@
         //Log.i("foo", "SubActivityScreen pid=" + Process.myPid() + " onResume");
         
         if (mMode >= CHILD_OFFSET) {
-        	// Wait a little bit, to give our parent time to kill itself
-        	// if that is something it is into.
-        	try {
-	        	Thread.sleep(500);
-        	} catch (InterruptedException e) {
-        		setResult(RESULT_CANCELED, (new Intent()).setAction("Interrupted!"));
-        		finish();
-        		return;
-        	}
+            // Wait a little bit, to give our parent time to kill itself
+            // if that is something it is into.
+            try {
+                Thread.sleep(500);
+            } catch (InterruptedException e) {
+                setResult(RESULT_CANCELED, (new Intent()).setAction("Interrupted!"));
+                finish();
+                return;
+            }
             //System.out.println("Resuming sub-activity: mode=" + mMode);
             switch (mMode-CHILD_OFFSET) {
             case NO_RESULT_MODE:
diff --git a/core/tests/coretests/src/android/database/DatabaseCursorTest.java b/core/tests/coretests/src/android/database/DatabaseCursorTest.java
index 36f0f4b..08cd027 100644
--- a/core/tests/coretests/src/android/database/DatabaseCursorTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseCursorTest.java
@@ -51,8 +51,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-	File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
-	mDatabaseFile = new File(dbDir, "database_test.db");
+        File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
+        mDatabaseFile = new File(dbDir, "database_test.db");
 
         if (mDatabaseFile.exists()) {
             mDatabaseFile.delete();
diff --git a/core/tests/coretests/src/android/database/DatabaseStatementTest.java b/core/tests/coretests/src/android/database/DatabaseStatementTest.java
index 512d5cd..895d715 100644
--- a/core/tests/coretests/src/android/database/DatabaseStatementTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseStatementTest.java
@@ -41,8 +41,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-	File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
-	mDatabaseFile = new File(dbDir, "database_test.db");
+        File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
+        mDatabaseFile = new File(dbDir, "database_test.db");
 
         if (mDatabaseFile.exists()) {
             mDatabaseFile.delete();
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index d6b73fd..7676143 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -400,7 +400,7 @@
          * No color information is stored.
          * With this configuration, each pixel requires 1 byte of memory.
          */
-        ALPHA_8     (2),
+        ALPHA_8     (1),
 
         /**
          * Each pixel is stored on 2 bytes and only the RGB channels are
@@ -416,7 +416,7 @@
          * This configuration may be useful when using opaque bitmaps
          * that do not require high color fidelity.
          */
-        RGB_565     (4),
+        RGB_565     (3),
 
         /**
          * Each pixel is stored on 2 bytes. The three RGB color channels
@@ -438,7 +438,7 @@
          *             it is advised to use {@link #ARGB_8888} instead.
          */
         @Deprecated
-        ARGB_4444   (5),
+        ARGB_4444   (4),
 
         /**
          * Each pixel is stored on 4 bytes. Each channel (RGB and alpha
@@ -448,13 +448,13 @@
          * This configuration is very flexible and offers the best
          * quality. It should be used whenever possible.
          */
-        ARGB_8888   (6);
+        ARGB_8888   (5);
 
         final int nativeInt;
 
         @SuppressWarnings({"deprecation"})
         private static Config sConfigs[] = {
-            null, null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888
+            null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888
         };
         
         Config(int ni) {
diff --git a/graphics/java/android/graphics/LayerRasterizer.java b/graphics/java/android/graphics/LayerRasterizer.java
index dc307c6..5b356089 100644
--- a/graphics/java/android/graphics/LayerRasterizer.java
+++ b/graphics/java/android/graphics/LayerRasterizer.java
@@ -21,11 +21,11 @@
         native_instance = nativeConstructor();
     }
     
-	/**	Add a new layer (above any previous layers) to the rasterizer.
-		The layer will extract those fields that affect the mask from
-		the specified paint, but will not retain a reference to the paint
-		object itself, so it may be reused without danger of side-effects.
-	*/
+    /** Add a new layer (above any previous layers) to the rasterizer.
+        The layer will extract those fields that affect the mask from
+        the specified paint, but will not retain a reference to the paint
+        object itself, so it may be reused without danger of side-effects.
+    */
     public void addLayer(Paint paint, float dx, float dy) {
         nativeAddLayer(native_instance, paint.mNativePaint, dx, dy);
     }
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 9ad3e49..0eae67c 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -38,7 +38,7 @@
 
     private TileMode mTileMode;
 
-	/**	Create a shader that draws a linear gradient along a line.
+    /** Create a shader that draws a linear gradient along a line.
         @param x0           The x-coordinate for the start of the gradient line
         @param y0           The y-coordinate for the start of the gradient line
         @param x1           The x-coordinate for the end of the gradient line
@@ -48,8 +48,8 @@
                             each corresponding color in the colors array. If this is null,
                             the the colors are distributed evenly along the gradient line.
         @param  tile        The Shader tiling mode
-	*/
-	public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
+    */
+    public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
             TileMode tile) {
         if (colors.length < 2) {
             throw new IllegalArgumentException("needs >= 2 number of colors");
@@ -70,7 +70,7 @@
                 tile.nativeInt);
     }
 
-	/**	Create a shader that draws a linear gradient along a line.
+    /** Create a shader that draws a linear gradient along a line.
         @param x0       The x-coordinate for the start of the gradient line
         @param y0       The y-coordinate for the start of the gradient line
         @param x1       The x-coordinate for the end of the gradient line
@@ -78,8 +78,8 @@
         @param  color0  The color at the start of the gradient line.
         @param  color1  The color at the end of the gradient line.
         @param  tile    The Shader tiling mode
-	*/
-	public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,
+    */
+    public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,
             TileMode tile) {
         mType = TYPE_COLOR_START_AND_COLOR_END;
         mX0 = x0;
@@ -118,7 +118,7 @@
 
     private native long nativeCreate1(float x0, float y0, float x1, float y1,
             int colors[], float positions[], int tileMode);
-	private native long nativeCreate2(float x0, float y0, float x1, float y1,
+    private native long nativeCreate2(float x0, float y0, float x1, float y1,
             int color0, int color1, int tileMode);
     private native long nativePostCreate1(long native_shader, float x0, float y0, float x1, float y1,
             int colors[], float positions[], int tileMode);
diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index f10e5d6..c00c612 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -37,17 +37,17 @@
 
     private TileMode mTileMode;
 
-	/**	Create a shader that draws a radial gradient given the center and radius.
+    /** Create a shader that draws a radial gradient given the center and radius.
         @param x        The x-coordinate of the center of the radius
         @param y        The y-coordinate of the center of the radius
-		@param radius   Must be positive. The radius of the circle for this gradient
+        @param radius   Must be positive. The radius of the circle for this gradient
         @param colors   The colors to be distributed between the center and edge of the circle
         @param positions May be NULL. The relative position of
                         each corresponding color in the colors array. If this is NULL,
                         the the colors are distributed evenly between the center and edge of the circle.
         @param  tile    The Shader tiling mode
-	*/
-	public RadialGradient(float x, float y, float radius,
+    */
+    public RadialGradient(float x, float y, float radius,
                           int colors[], float positions[], TileMode tile) {
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
@@ -70,15 +70,15 @@
                 tile.nativeInt);
     }
 
-	/**	Create a shader that draws a radial gradient given the center and radius.
+    /** Create a shader that draws a radial gradient given the center and radius.
         @param x        The x-coordinate of the center of the radius
         @param y        The y-coordinate of the center of the radius
-		@param radius   Must be positive. The radius of the circle for this gradient
+        @param radius   Must be positive. The radius of the circle for this gradient
         @param color0   The color at the center of the circle.
         @param color1   The color at the edge of the circle.
         @param tile     The Shader tiling mode
-	*/
-	public RadialGradient(float x, float y, float radius,
+    */
+    public RadialGradient(float x, float y, float radius,
                           int color0, int color1, TileMode tile) {
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
@@ -119,7 +119,7 @@
 
     private static native long nativeCreate1(float x, float y, float radius,
             int colors[], float positions[], int tileMode);
-	private static native long nativeCreate2(float x, float y, float radius,
+    private static native long nativeCreate2(float x, float y, float radius,
             int color0, int color1, int tileMode);
 
     private static native long nativePostCreate1(long native_shader, float x, float y, float radius,
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 1f5d26c..4935b34 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -21,6 +21,7 @@
 #include <utils/Vector.h>
 
 #include "AmbientShadow.h"
+#include "ShadowTessellator.h"
 #include "Vertex.h"
 
 namespace android {
@@ -34,9 +35,7 @@
  *                  array.
  * @param vertexCount The length of caster's polygon in terms of number of
  *                    vertices.
- * @param rays The number of rays shooting out from the centroid.
- * @param layers The number of rings outside the polygon.
- * @param strength The darkness of the shadow, the higher, the darker.
+ * @param centroid3d The centroid of the shadow caster.
  * @param heightFactor The factor showing the higher the object, the lighter the
  *                     shadow.
  * @param geomFactor The factor scaling the geometry expansion along the normal.
@@ -45,21 +44,18 @@
  *               triangle strips mode.
  */
 void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount,
-        int rays, int layers, float strength, float heightFactor, float geomFactor,
+        const Vector3& centroid3d, float heightFactor, float geomFactor,
         VertexBuffer& shadowVertexBuffer) {
-
+    const int rays = SHADOW_RAY_COUNT;
+    const int layers = SHADOW_LAYER_COUNT;
     // Validate the inputs.
-    if (strength <= 0 || heightFactor <= 0 || layers <= 0 || rays <= 0
+    if (vertexCount < 3 || heightFactor <= 0 || layers <= 0 || rays <= 0
         || geomFactor <= 0) {
 #if DEBUG_SHADOW
         ALOGE("Invalid input for createAmbientShadow(), early return!");
 #endif
         return;
     }
-    int rings = layers + 1;
-    int size = rays * rings;
-    Vector2 centroid;
-    calculatePolygonCentroid(vertices, vertexCount, centroid);
 
     Vector<Vector2> dir; // TODO: use C++11 unique_ptr
     dir.setCapacity(rays);
@@ -75,7 +71,7 @@
         int edgeIndex;
         float edgeFraction;
         float rayDistance;
-        calculateIntersection(vertices, vertexCount, centroid, dir[i], edgeIndex,
+        calculateIntersection(vertices, vertexCount, centroid3d, dir[i], edgeIndex,
                 edgeFraction, rayDistance);
         rayDist[i] = rayDistance;
         if (edgeIndex < 0 || edgeIndex >= vertexCount) {
@@ -91,8 +87,7 @@
 
     // The output buffer length basically is roughly rays * layers, but since we
     // need triangle strips, so we need to duplicate vertices to accomplish that.
-    const int shadowVertexCount = (2 + rays + ((layers) * 2 * (rays + 1)));
-    AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(shadowVertexCount);
+    AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT);
 
     // Calculate the vertex of the shadows.
     //
@@ -101,110 +96,45 @@
     // calculate the normal N, which should be perpendicular to the edge of the
     // polygon (represented by the neighbor intersection points) .
     // Shadow's vertices will be generated as : P + N * scale.
-    int currentIndex = 0;
-    for (int r = 0; r < layers; r++) {
-        int firstInLayer = currentIndex;
-        for (int i = 0; i < rays; i++) {
+    int currentVertexIndex = 0;
+    for (int layerIndex = 0; layerIndex <= layers; layerIndex++) {
+        for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
 
             Vector2 normal(1.0f, 0.0f);
-            calculateNormal(rays, i, dir.array(), rayDist, normal);
+            calculateNormal(rays, rayIndex, dir.array(), rayDist, normal);
 
-            float opacity = strength * (0.5f) / (1 + rayHeight[i] / heightFactor);
+            float opacity = 1.0 / (1 + rayHeight[rayIndex] / heightFactor);
 
             // The vertex should be start from rayDist[i] then scale the
             // normalizeNormal!
-            Vector2 intersection = dir[i] * rayDist[i] + centroid;
+            Vector2 intersection = dir[rayIndex] * rayDist[rayIndex] +
+                    Vector2(centroid3d.x, centroid3d.y);
 
-            // Use 2 rings' vertices to complete one layer's strip
-            for (int j = r; j < (r + 2); j++) {
-                float jf = j / (float)(rings - 1);
-
-                float expansionDist = rayHeight[i] / heightFactor * geomFactor * jf;
-                AlphaVertex::set(&shadowVertices[currentIndex],
-                        intersection.x + normal.x * expansionDist,
-                        intersection.y + normal.y * expansionDist,
-                        (1 - jf) * opacity);
-                currentIndex++;
-            }
+            float layerRatio = layerIndex / (float)(layers);
+            // The higher the intersection is, the further the ambient shadow expanded.
+            float expansionDist = rayHeight[rayIndex] / heightFactor *
+                    geomFactor * (1 - layerRatio);
+            AlphaVertex::set(&shadowVertices[currentVertexIndex++],
+                    intersection.x + normal.x * expansionDist,
+                    intersection.y + normal.y * expansionDist,
+                    layerRatio * opacity);
         }
 
-        // From one layer to the next, we need to duplicate the vertex to
-        // continue as a single strip.
-        shadowVertices[currentIndex] = shadowVertices[firstInLayer];
-        currentIndex++;
-        shadowVertices[currentIndex] = shadowVertices[firstInLayer + 1];
-        currentIndex++;
     }
+    float centroidAlpha = 1.0 / (1 + centroid3d.z / heightFactor);
+    AlphaVertex::set(&shadowVertices[currentVertexIndex++],
+            centroid3d.x, centroid3d.y, centroidAlpha);
 
-    // After all rings are done, we need to jump into the polygon.
-    // In order to keep everything in a strip, we need to duplicate the last one
-    // of the rings and the first one inside the polygon.
-    int lastInRings = currentIndex - 1;
-    shadowVertices[currentIndex] = shadowVertices[lastInRings];
-    currentIndex++;
-
-    // We skip one and fill it back after we finish the internal triangles.
-    currentIndex++;
-    int firstInternal = currentIndex;
-
-    // Combine the internal area of the polygon into a triangle strip, too.
-    // The basic idea is zig zag between the intersection points.
-    // 0 -> (n - 1) -> 1 -> (n - 2) ...
-    for (int k = 0; k < rays; k++) {
-        int  i = k / 2;
-        if ((k & 1) == 1) { // traverse the inside in a zig zag pattern for strips
-            i = rays - i - 1;
-        }
-        float cast = rayDist[i] * (1 + rayHeight[i] / heightFactor);
-        float opacity = strength * (0.5f) / (1 + rayHeight[i] / heightFactor);
-        float t = rayDist[i];
-
-        AlphaVertex::set(&shadowVertices[currentIndex], dir[i].x * t + centroid.x,
-                dir[i].y * t + centroid.y, opacity);
-        currentIndex++;
-    }
-
-    currentIndex = firstInternal - 1;
-    shadowVertices[currentIndex] = shadowVertices[firstInternal];
-}
-
-/**
- * Calculate the centroid of a given polygon.
- *
- * @param vertices The shadow caster's polygon, which is represented in a
- *                 straight Vector3 array.
- * @param vertexCount The length of caster's polygon in terms of number of vertices.
- *
- * @param centroid Return the centroid of the polygon.
- */
-void AmbientShadow::calculatePolygonCentroid(const Vector3* vertices, int vertexCount,
-        Vector2& centroid) {
-    float sumx = 0;
-    float sumy = 0;
-    int p1 = vertexCount - 1;
-    float area = 0;
-    for (int p2 = 0; p2 < vertexCount; p2++) {
-        float x1 = vertices[p1].x;
-        float y1 = vertices[p1].y;
-        float x2 = vertices[p2].x;
-        float y2 = vertices[p2].y;
-        float a = (x1 * y2 - x2 * y1);
-        sumx += (x1 + x2) * a;
-        sumy += (y1 + y2) * a;
-        area += a;
-        p1 = p2;
-    }
-
-    if (area == 0) {
 #if DEBUG_SHADOW
-        ALOGE("Area is 0!");
-#endif
-        centroid.x = vertices[0].x;
-        centroid.y = vertices[0].y;
-    } else {
-        centroid.x = sumx / (3 * area);
-        centroid.y = sumy / (3 * area);
+    if (currentVertexIndex != SHADOW_VERTEX_COUNT) {
+        ALOGE("number of vertex generated for ambient shadow is wrong! "
+              "current: %d , expected: %d", currentVertexIndex, SHADOW_VERTEX_COUNT);
     }
+    for (int i = 0; i < SHADOW_VERTEX_COUNT; i++) {
+        ALOGD("ambient shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
+                shadowVertices[i].y, shadowVertices[i].alpha);
+    }
+#endif
 }
 
 /**
@@ -238,7 +168,7 @@
  * @param outRayDist Return the ray distance from centroid to the intersection.
  */
 void AmbientShadow::calculateIntersection(const Vector3* vertices, int vertexCount,
-        const Vector2& start, const Vector2& dir, int& outEdgeIndex,
+        const Vector3& start, const Vector2& dir, int& outEdgeIndex,
         float& outEdgeFraction, float& outRayDist) {
     float startX = start.x;
     float startY = start.y;
diff --git a/libs/hwui/AmbientShadow.h b/libs/hwui/AmbientShadow.h
index 079bdb7..20d1384 100644
--- a/libs/hwui/AmbientShadow.h
+++ b/libs/hwui/AmbientShadow.h
@@ -34,17 +34,15 @@
  */
 class AmbientShadow {
 public:
-    static void createAmbientShadow(const Vector3* poly, int polyLength, int rays,
-            int layers, float strength, float heightFactor, float geomFactor,
+    static void createAmbientShadow(const Vector3* poly, int polyLength,
+            const Vector3& centroid3d, float heightFactor, float geomFactor,
             VertexBuffer& shadowVertexBuffer);
 
 private:
-    static void calculatePolygonCentroid(const Vector3* poly, int len, Vector2& centroid);
-
     static void calculateRayDirections(int rays, Vector2* dir);
 
     static void calculateIntersection(const Vector3* poly, int nbVertices,
-            const Vector2& start, const Vector2& dir, int& outEdgeIndex,
+            const Vector3& start, const Vector2& dir, int& outEdgeIndex,
             float& outEdgeFraction, float& outRayDist);
 
     static void calculateNormal(int rays, int currentRayIndex, const Vector2* dir,
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 21cf658..1d58d96 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -23,6 +23,7 @@
 #include "DisplayListRenderer.h"
 #include "Properties.h"
 #include "LayerRenderer.h"
+#include "ShadowTessellator.h"
 
 namespace android {
 
@@ -86,7 +87,7 @@
 
     mRegionMesh = NULL;
     mMeshIndices = 0;
-
+    mShadowStripsIndices = 0;
     blend = false;
     lastSrcMode = GL_ZERO;
     lastDstMode = GL_ZERO;
@@ -223,6 +224,9 @@
     mMeshIndices = 0;
     mRegionMesh = NULL;
 
+    glDeleteBuffers(1, &mShadowStripsIndices);
+    mShadowStripsIndices = 0;
+
     fboCache.clear();
 
     programCache.clear();
@@ -404,7 +408,7 @@
     return false;
 }
 
-bool Caches::bindIndicesBuffer(const GLuint buffer) {
+bool Caches::bindIndicesBufferInternal(const GLuint buffer) {
     if (mCurrentIndicesBuffer != buffer) {
         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
         mCurrentIndicesBuffer = buffer;
@@ -413,7 +417,7 @@
     return false;
 }
 
-bool Caches::bindIndicesBuffer() {
+bool Caches::bindQuadIndicesBuffer() {
     if (!mMeshIndices) {
         uint16_t* regionIndices = new uint16_t[gMaxNumberOfQuads * 6];
         for (uint32_t i = 0; i < gMaxNumberOfQuads; i++) {
@@ -428,7 +432,7 @@
         }
 
         glGenBuffers(1, &mMeshIndices);
-        bool force = bindIndicesBuffer(mMeshIndices);
+        bool force = bindIndicesBufferInternal(mMeshIndices);
         glBufferData(GL_ELEMENT_ARRAY_BUFFER, gMaxNumberOfQuads * 6 * sizeof(uint16_t),
                 regionIndices, GL_STATIC_DRAW);
 
@@ -436,7 +440,23 @@
         return force;
     }
 
-    return bindIndicesBuffer(mMeshIndices);
+    return bindIndicesBufferInternal(mMeshIndices);
+}
+
+bool Caches::bindShadowIndicesBuffer() {
+    if (!mShadowStripsIndices) {
+        uint16_t* shadowIndices = new uint16_t[SHADOW_INDEX_COUNT];
+        ShadowTessellator::generateShadowIndices(shadowIndices);
+        glGenBuffers(1, &mShadowStripsIndices);
+        bool force = bindIndicesBufferInternal(mShadowStripsIndices);
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER, SHADOW_INDEX_COUNT * sizeof(uint16_t),
+            shadowIndices, GL_STATIC_DRAW);
+
+        delete[] shadowIndices;
+        return force;
+    }
+
+    return bindIndicesBufferInternal(mShadowStripsIndices);
 }
 
 bool Caches::unbindIndicesBuffer() {
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 2cc15cc..8c0c508 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -190,8 +190,8 @@
      * Binds a global indices buffer that can draw up to
      * gMaxNumberOfQuads quads.
      */
-    bool bindIndicesBuffer();
-    bool bindIndicesBuffer(const GLuint buffer);
+    bool bindQuadIndicesBuffer();
+    bool bindShadowIndicesBuffer();
     bool unbindIndicesBuffer();
 
     /**
@@ -381,6 +381,8 @@
     void initConstraints();
     void initStaticProperties();
 
+    bool bindIndicesBufferInternal(const GLuint buffer);
+
     static void eventMarkNull(GLsizei length, const GLchar* marker) { }
     static void startMarkNull(GLsizei length, const GLchar* marker) { }
     static void endMarkNull() { }
@@ -417,6 +419,7 @@
 
     // Global index buffer
     GLuint mMeshIndices;
+    GLuint mShadowStripsIndices;
 
     mutable Mutex mGarbageLock;
     Vector<Layer*> mLayerGarbage;
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 6144f3d..23c33ca 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -661,7 +661,8 @@
         if (mode == kNegativeZChildren && zValue > 0.0f) break;
 
         DisplayList* child = childOp->mDisplayList;
-        if (mode == kPositiveZChildren && zValue > 0.0f && child->mCastsShadow) {
+        if (mode == kPositiveZChildren && zValue > 0.0f
+                && child->mCastsShadow && child->mAlpha > 0.0f) {
             /* draw shadow with parent matrix applied, passing in the child's total matrix
              * TODO: consider depth in more complex scenarios (neg z, added shadow depth)
              */
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index b79a3b0..b52003c 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -498,7 +498,7 @@
                 }
 
                 checkTextureUpdate();
-                caches.bindIndicesBuffer();
+                caches.bindQuadIndicesBuffer();
 
                 if (!mDrawn) {
                     // If returns true, a VBO was bound and we must
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2da0fd3..9ac2792 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1902,7 +1902,7 @@
     } else {
         force = mCaches.unbindMeshBuffer();
     }
-    mCaches.bindIndicesBuffer();
+    mCaches.bindQuadIndicesBuffer();
 
     mCaches.bindPositionVertexPointer(force, vertices);
     if (mCaches.currentProgram->texCoords >= 0) {
@@ -1912,7 +1912,7 @@
 
 void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) {
     bool force = mCaches.unbindMeshBuffer();
-    mCaches.bindIndicesBuffer();
+    mCaches.bindQuadIndicesBuffer();
     mCaches.bindPositionVertexPointer(force, vertices, gVertexStride);
 }
 
@@ -2387,10 +2387,9 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, const SkPaint* paint,
-        bool useOffset) {
+status_t OpenGLRenderer::drawVertexBuffer(VertexBufferMode mode,
+        const VertexBuffer& vertexBuffer, const SkPaint* paint, bool useOffset) {
     // not missing call to quickReject/dirtyLayer, always done at a higher level
-
     if (!vertexBuffer.getVertexCount()) {
         // no vertices to draw
         return DrawGlInfo::kStatusDone;
@@ -2416,19 +2415,24 @@
     bool force = mCaches.unbindMeshBuffer();
     mCaches.bindPositionVertexPointer(true, vertices, isAA ? gAlphaVertexStride : gVertexStride);
     mCaches.resetTexCoordsVertexPointer();
-    mCaches.unbindIndicesBuffer();
+
 
     int alphaSlot = -1;
     if (isAA) {
         void* alphaCoords = ((GLbyte*) vertices) + gVertexAlphaOffset;
         alphaSlot = mCaches.currentProgram->getAttrib("vtxAlpha");
-
         // TODO: avoid enable/disable in back to back uses of the alpha attribute
         glEnableVertexAttribArray(alphaSlot);
         glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, gAlphaVertexStride, alphaCoords);
     }
 
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount());
+    if (mode == kVertexBufferMode_Standard) {
+        mCaches.unbindIndicesBuffer();
+        glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount());
+    } else {
+        mCaches.bindShadowIndicesBuffer();
+        glDrawElements(GL_TRIANGLE_STRIP, SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0);
+    }
 
     if (isAA) {
         glDisableVertexAttribArray(alphaSlot);
@@ -2457,7 +2461,7 @@
         dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
     }
 
-    return drawVertexBuffer(vertexBuffer, paint);
+    return drawVertexBuffer(kVertexBufferMode_Standard, vertexBuffer, paint);
 }
 
 /**
@@ -2488,7 +2492,7 @@
     dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
 
     bool useOffset = !paint->isAntiAlias();
-    return drawVertexBuffer(buffer, paint, useOffset);
+    return drawVertexBuffer(kVertexBufferMode_Standard, buffer, paint, useOffset);
 }
 
 status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
@@ -2508,7 +2512,7 @@
     dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
 
     bool useOffset = !paint->isAntiAlias();
-    return drawVertexBuffer(buffer, paint, useOffset);
+    return drawVertexBuffer(kVertexBufferMode_Standard, buffer, paint, useOffset);
 }
 
 status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
@@ -3231,17 +3235,24 @@
         casterTransform.mapPoint3d(casterPolygon[i]);
     }
 
+    // map the centroid of the caster into 3d
+    Vector2 centroid =  ShadowTessellator::centroid2d(
+            reinterpret_cast<const Vector2*>(casterVertices2d.array()),
+            casterVertexCount);
+    Vector3 centroid3d(centroid.x, centroid.y, 0);
+    casterTransform.mapPoint3d(centroid3d);
+
     // draw caster's shadows
     if (mCaches.propertyAmbientShadowStrength > 0) {
-        paint.setARGB(mCaches.propertyAmbientShadowStrength, 0, 0, 0);
+        paint.setARGB(casterAlpha * mCaches.propertyAmbientShadowStrength, 0, 0, 0);
         VertexBuffer ambientShadowVertexBuffer;
         ShadowTessellator::tessellateAmbientShadow(casterPolygon, casterVertexCount,
-                ambientShadowVertexBuffer);
-        drawVertexBuffer(ambientShadowVertexBuffer, &paint);
+                centroid3d, ambientShadowVertexBuffer);
+        drawVertexBuffer(kVertexBufferMode_Shadow, ambientShadowVertexBuffer, &paint);
     }
 
     if (mCaches.propertySpotShadowStrength > 0) {
-        paint.setARGB(mCaches.propertySpotShadowStrength, 0, 0, 0);
+        paint.setARGB(casterAlpha * mCaches.propertySpotShadowStrength, 0, 0, 0);
         VertexBuffer spotShadowVertexBuffer;
         Vector3 lightPosScale(mCaches.propertyLightPosXScale,
                 mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale);
@@ -3249,7 +3260,7 @@
                 lightPosScale, *currentTransform(), getWidth(), getHeight(),
                 spotShadowVertexBuffer);
 
-        drawVertexBuffer(spotShadowVertexBuffer, &paint);
+        drawVertexBuffer(kVertexBufferMode_Shadow, spotShadowVertexBuffer, &paint);
     }
 
     return DrawGlInfo::kStatusDrew;
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e4d133d..03beae3 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -117,6 +117,11 @@
     kModelViewMode_TranslateAndScale = 1,
 };
 
+enum VertexBufferMode {
+    kVertexBufferMode_Standard = 0,
+    kVertexBufferMode_Shadow = 1
+};
+
 ///////////////////////////////////////////////////////////////////////////////
 // Renderer
 ///////////////////////////////////////////////////////////////////////////////
@@ -629,8 +634,8 @@
      * @param paint The paint to render with
      * @param useOffset Offset the vertexBuffer (used in drawing non-AA lines)
      */
-    status_t drawVertexBuffer(const VertexBuffer& vertexBuffer, const SkPaint* paint,
-            bool useOffset = false);
+    status_t drawVertexBuffer(VertexBufferMode mode, const VertexBuffer& vertexBuffer,
+            const SkPaint* paint, bool useOffset = false);
 
     /**
      * Renders the convex hull defined by the specified path as a strip of polygons.
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index 7700ea0..526772b 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -31,18 +31,16 @@
     return a > b ? a : b;
 }
 
-void ShadowTessellator::tessellateAmbientShadow(const Vector3* casterPolygon, int casterVertexCount,
+void ShadowTessellator::tessellateAmbientShadow(const Vector3* casterPolygon,
+        int casterVertexCount, const Vector3& centroid3d,
         VertexBuffer& shadowVertexBuffer) {
     // A bunch of parameters to tweak the shadow.
     // TODO: Allow some of these changable by debug settings or APIs.
-    const int rays = 128;
-    const int layers = 2;
-    const float strength = 0.5;
     const float heightFactor = 128;
     const float geomFactor = 64;
 
-    AmbientShadow::createAmbientShadow(casterPolygon, casterVertexCount, rays, layers, strength,
-            heightFactor, geomFactor, shadowVertexBuffer);
+    AmbientShadow::createAmbientShadow(casterPolygon, casterVertexCount,
+            centroid3d, heightFactor, geomFactor, shadowVertexBuffer);
 
 }
 
@@ -51,9 +49,6 @@
         int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer) {
     // A bunch of parameters to tweak the shadow.
     // TODO: Allow some of these changable by debug settings or APIs.
-    const int rays = 256;
-    const int layers = 2;
-    const float strength = 0.5;
     int maximal = max(screenWidth, screenHeight);
     Vector3 lightCenter(screenWidth * lightPosScale.x, screenHeight * lightPosScale.y,
             maximal * lightPosScale.z);
@@ -70,9 +65,77 @@
     const float lightSize = maximal / 4;
     const int lightVertexCount = 16;
 
-    SpotShadow::createSpotShadow(casterPolygon, casterVertexCount, lightCenter, lightSize,
-            lightVertexCount, rays, layers, strength, shadowVertexBuffer);
+    SpotShadow::createSpotShadow(casterPolygon, casterVertexCount, lightCenter,
+            lightSize, lightVertexCount, shadowVertexBuffer);
 
 }
+
+void ShadowTessellator::generateShadowIndices(uint16_t* shadowIndices) {
+    int currentIndex = 0;
+    const int layers = SHADOW_LAYER_COUNT;
+    const int rays = SHADOW_RAY_COUNT;
+    // For the penumbra area.
+    for (int i = 0; i < layers; i++) {
+        for (int j = 0; j < rays; j++) {
+            shadowIndices[currentIndex++] = i * rays + j;
+            shadowIndices[currentIndex++] = (i + 1) * rays + j;
+        }
+        // To close the loop, back to the ray 0.
+        shadowIndices[currentIndex++] = i * rays;
+        shadowIndices[currentIndex++] = (i + 1) * rays;
+    }
+    uint16_t base = layers * rays;
+    uint16_t centroidIndex = (layers + 1) * rays;
+    // For the umbra area, using strips to simulate the fans.
+    for (int k = 0; k < rays; k++) {
+        shadowIndices[currentIndex++] = base + k;
+        shadowIndices[currentIndex++] = centroidIndex;
+    }
+    shadowIndices[currentIndex++] = base;
+
+#if DEBUG_SHADOW
+    if (currentIndex != SHADOW_INDEX_COUNT) {
+        ALOGE("vertex index count is wrong. current %d, expected %d",
+                currentIndex, SHADOW_INDEX_COUNT);
+    }
+    for (int i = 0; i < SHADOW_INDEX_COUNT; i++) {
+        ALOGD("vertex index is (%d, %d)", i, shadowIndices[i]);
+    }
+#endif
+}
+
+/**
+ * Calculate the centroid of a 2d polygon.
+ *
+ * @param poly The polygon, which is represented in a Vector2 array.
+ * @param polyLength The length of the polygon in terms of number of vertices.
+ * @return the centroid of the polygon.
+ */
+Vector2 ShadowTessellator::centroid2d(const Vector2* poly, int polyLength) {
+    double sumx = 0;
+    double sumy = 0;
+    int p1 = polyLength - 1;
+    double area = 0;
+    for (int p2 = 0; p2 < polyLength; p2++) {
+        double x1 = poly[p1].x;
+        double y1 = poly[p1].y;
+        double x2 = poly[p2].x;
+        double y2 = poly[p2].y;
+        double a = (x1 * y2 - x2 * y1);
+        sumx += (x1 + x2) * a;
+        sumy += (y1 + y2) * a;
+        area += a;
+        p1 = p2;
+    }
+
+    Vector2 centroid = poly[0];
+    if (area != 0) {
+        centroid = Vector2(sumx / (3 * area), sumy / (3 * area));
+    } else {
+        ALOGE("Area is 0 while computing centroid!");
+    }
+    return centroid;
+}
+
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h
index ef95609..c49fdcb1 100644
--- a/libs/hwui/ShadowTessellator.h
+++ b/libs/hwui/ShadowTessellator.h
@@ -20,18 +20,57 @@
 
 #include "Debug.h"
 #include "Matrix.h"
+#include "VertexBuffer.h"
 
 namespace android {
 namespace uirenderer {
 
+// All SHADOW_* are used to define all the geometry property of shadows.
+// Use a simplified example to illustrate the geometry setup here.
+// Assuming we use 6 rays and only 1 layer, Then we will have 2 hexagons, which
+// are 0 to 5 and 6 to 11. The area between them will be the penumbra area, and
+// the area inside the 2nd hexagon is the umbra.
+// Also, we need to add the centroid "12" to draw the umbra area as triangle fans.
+//
+// Triange strip indices for penumbra area: (0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 0, 6)
+// Triange strip indices for numbra area: (6, 12, 7, 12, 8, 12, 9, 12, 10, 12, 11, 12, 6)
+//                 0
+//
+//      5          6         1
+//           11         7
+//                12
+//           10         8
+//      4          9         2
+//
+//                 3
+
+// The total number of rays starting from the centroid of shadow area, in order
+// to generate the shadow geometry.
+#define SHADOW_RAY_COUNT 256
+
+// The total number of layers in the outer shadow area, 1 being the minimum.
+#define SHADOW_LAYER_COUNT 2
+
+// The total number of all the vertices representing the shadow.
+#define SHADOW_VERTEX_COUNT ((SHADOW_LAYER_COUNT + 1) * SHADOW_RAY_COUNT + 1)
+
+// The total number of indices used for drawing the shadow geometry as triangle strips.
+#define SHADOW_INDEX_COUNT (2 * SHADOW_RAY_COUNT + 1 + 2 * (SHADOW_RAY_COUNT + 1) * \
+        SHADOW_LAYER_COUNT)
+
 class ShadowTessellator {
 public:
-    static void tessellateAmbientShadow(const Vector3* casterPolygon, int casterVertexCount,
+    static void tessellateAmbientShadow(const Vector3* casterPolygon,
+            int casterVertexCount, const Vector3& centroid3d,
             VertexBuffer& shadowVertexBuffer);
 
     static void tessellateSpotShadow(const Vector3* casterPolygon, int casterVertexCount,
             const Vector3& lightPosScale, const mat4& receiverTransform,
             int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer);
+
+    static void generateShadowIndices(uint16_t*  shadowIndices);
+
+    static Vector2 centroid2d(const Vector2* poly, int polyLength);
 }; // ShadowTessellator
 
 }; // namespace uirenderer
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index 4c2299e..22d735bf 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <utils/Log.h>
 
+#include "ShadowTessellator.h"
 #include "SpotShadow.h"
 #include "Vertex.h"
 
@@ -70,35 +71,6 @@
 }
 
 /**
- * Calculate the centroid of a 2d polygon.
- *
- * @param poly The polygon, which is represented in a Vector2 array.
- * @param polyLength The length of the polygon in terms of number of vertices.
- * @return the centroid of the polygon.
- */
-Vector2 SpotShadow::centroid2d(const Vector2* poly, int polyLength) {
-    double sumx = 0;
-    double sumy = 0;
-    int p1 = polyLength - 1;
-    double area = 0;
-    for (int p2 = 0; p2 < polyLength; p2++) {
-        double x1 = poly[p1].x;
-        double y1 = poly[p1].y;
-        double x2 = poly[p2].x;
-        double y2 = poly[p2].y;
-        double a = (x1 * y2 - x2 * y1);
-        sumx += (x1 + x2) * a;
-        sumy += (y1 + y2) * a;
-        area += a;
-        p1 = p2;
-    }
-
-    double centroidx = sumx / (3 * area);
-    double centroidy = sumy / (3 * area);
-    return Vector2((float)centroidx, (float)centroidy);
-}
-
-/**
  * Sort points by their X coordinates
  *
  * @param points the points as a Vector2 array.
@@ -550,20 +522,17 @@
 * @param lightCenter the center of the light
 * @param lightSize the radius of the light source
 * @param lightVertexCount the vertex counter for the light polygon
-* @param rays the number of vertexes to create along the edges of the shadow
-* @param layers the number of layers of triangles strips to create
-* @param strength the "darkness" of the shadow
 * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
 *                            empty strip if error.
 *
 */
 void SpotShadow::createSpotShadow(const Vector3* poly, int polyLength,
         const Vector3& lightCenter, float lightSize, int lightVertexCount,
-        int rays, int layers, float strength, VertexBuffer& retStrips) {
+        VertexBuffer& retStrips) {
     Vector3 light[lightVertexCount * 3];
     computeLightPolygon(lightVertexCount, lightCenter, lightSize, light);
-    computeSpotShadow(light, lightVertexCount, lightCenter,
-            poly, polyLength, rays, layers, strength, retStrips);
+    computeSpotShadow(light, lightVertexCount, lightCenter, poly, polyLength,
+            retStrips);
 }
 
 /**
@@ -573,15 +542,12 @@
  * @param lightPolyLength number of vertexes of the light source polygon
  * @param poly x,y,z vertexes of a convex polygon that occludes the light source
  * @param polyLength number of vertexes of the occluding polygon
- * @param rays the number of vertexes to create along the edges of the shadow
- * @param layers the number of layers of triangles strips to create
- * @param strength the "darkness" of the shadow
  * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
  *                            empty strip if error.
  */
 void SpotShadow::computeSpotShadow(const Vector3* lightPoly, int lightPolyLength,
         const Vector3& lightCenter, const Vector3* poly, int polyLength,
-        int rays, int layers, float strength, VertexBuffer& shadowTriangleStrip) {
+        VertexBuffer& shadowTriangleStrip) {
     // Point clouds for all the shadowed vertices
     Vector2 shadowRegion[lightPolyLength * polyLength];
     // Shadow polygon from one point light.
@@ -671,7 +637,8 @@
 
         // Shrink the centroid's shadow by 10%.
         // TODO: Study the magic number of 10%.
-        Vector2 shadowCentroid = centroid2d(fakeUmbra, polyLength);
+        Vector2 shadowCentroid =
+                ShadowTessellator::centroid2d(fakeUmbra, polyLength);
         for (int i = 0; i < polyLength; i++) {
             fakeUmbra[i] = shadowCentroid * (1.0f - SHADOW_SHRINK_SCALE) +
                     fakeUmbra[i] * SHADOW_SHRINK_SCALE;
@@ -686,7 +653,7 @@
     }
 
     generateTriangleStrip(penumbra, penumbraLength, umbra, umbraLength,
-            rays, layers, strength, shadowTriangleStrip);
+            shadowTriangleStrip);
 }
 
 /**
@@ -696,22 +663,18 @@
  * @param penumbraLength The number of vertexes in the outer polygon
  * @param umbra The inner outer polygon x,y vertexes
  * @param umbraLength The number of vertexes in the inner polygon
- * @param rays The number of points along the polygons to create
- * @param layers The number of layers of triangle strips between the umbra and penumbra
- * @param strength The max alpha of the umbra
  * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
  *                            empty strip if error.
 **/
 void SpotShadow::generateTriangleStrip(const Vector2* penumbra, int penumbraLength,
-        const Vector2* umbra, int umbraLength, int rays, int layers,
-        float strength, VertexBuffer& shadowTriangleStrip) {
+        const Vector2* umbra, int umbraLength, VertexBuffer& shadowTriangleStrip) {
+    const int rays = SHADOW_RAY_COUNT;
+    const int layers = SHADOW_LAYER_COUNT;
 
-    int rings = layers + 1;
-    int size = rays * rings;
-
+    int size = rays * (layers + 1);
     float step = M_PI * 2 / rays;
     // Centroid of the umbra.
-    Vector2 centroid = centroid2d(umbra, umbraLength);
+    Vector2 centroid = ShadowTessellator::centroid2d(umbra, umbraLength);
 #if DEBUG_SHADOW
     ALOGD("centroid2d =  %f , %f", centroid.x, centroid.y);
 #endif
@@ -741,57 +704,29 @@
     int stripSize = getStripSize(rays, layers);
     AlphaVertex* shadowVertices = shadowTriangleStrip.alloc<AlphaVertex>(stripSize);
     int currentIndex = 0;
-    int firstInLayer = 0;
-    // Calculate the vertex values in the penumbra area.
-    for (int r = 0; r < layers; r++) {
-        firstInLayer = currentIndex;
-        for (int i = 0; i < rays; i++) {
-            float dx = sinf(step * i);
-            float dy = cosf(step * i);
 
-            for (int j = r; j < (r + 2); j++) {
-                float layerRatio = j / (float)(rings - 1);
-                float deltaDist = layerRatio * (umbraDistPerRay[i] - penumbraDistPerRay[i]);
-                float currentDist = penumbraDistPerRay[i] + deltaDist;
-                float op = calculateOpacity(layerRatio, deltaDist);
+    // Calculate the vertices (x, y, alpha) in the shadow area.
+    for (int layerIndex = 0; layerIndex <= layers; layerIndex++) {
+        for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
+            float dx = sinf(step * rayIndex);
+            float dy = cosf(step * rayIndex);
+                float layerRatio = layerIndex / (float) layers;
+                float deltaDist = layerRatio *
+                        (umbraDistPerRay[rayIndex] - penumbraDistPerRay[rayIndex]);
+                float currentDist = penumbraDistPerRay[rayIndex] + deltaDist;
+                float op = calculateOpacity(layerRatio);
                 AlphaVertex::set(&shadowVertices[currentIndex++],
-                        dx * currentDist + centroid.x,
-                        dy * currentDist + centroid.y,
-                        layerRatio * op * strength);
-            }
+                        dx * currentDist + centroid.x, dy * currentDist + centroid.y, op);
         }
-
-        // Duplicate the vertices from one layer to another one to make triangle
-        // strip.
-        shadowVertices[currentIndex++] = shadowVertices[firstInLayer + 0];
-        shadowVertices[currentIndex++] = shadowVertices[firstInLayer + 1];
     }
-
-    int lastInPenumbra = currentIndex - 1;
-    shadowVertices[currentIndex++] = shadowVertices[lastInPenumbra];
-
-    // Preallocate the vertices (index as [firstInUmbra - 1]) for jumping from
-    // the penumbra to umbra.
-    currentIndex++;
-    int firstInUmbra = currentIndex;
-
-    // traverse the umbra area in a zig zag pattern for strips.
-    const int innerRingStartIndex = firstInLayer + 1;
-    for (int k = 0; k < rays; k++) {
-        int i = k / 2;
-        if ((k & 1) == 1) {
-            i = rays - i - 1;
-        }
-        // copy already computed values for umbra vertices
-        shadowVertices[currentIndex++] = shadowVertices[innerRingStartIndex + i * 2];
-    }
-
-    // Back fill the one vertex for jumping from penumbra to umbra.
-    shadowVertices[firstInUmbra - 1] = shadowVertices[firstInUmbra];
-
+    // The centroid is in the umbra area, so the opacity is considered as 1.0.
+    AlphaVertex::set(&shadowVertices[currentIndex++], centroid.x, centroid.y, 1.0);
 #if DEBUG_SHADOW
+    if (currentIndex != SHADOW_VERTEX_COUNT) {
+        ALOGE("number of vertex generated for spot shadow is wrong!");
+    }
     for (int i = 0; i < currentIndex; i++) {
-        ALOGD("shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
+        ALOGD("spot shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
                 shadowVertices[i].y, shadowVertices[i].alpha);
     }
 #endif
@@ -819,17 +754,15 @@
 }
 
 /**
- * Calculate the opacity according to the distance and falloff ratio.
+ * Calculate the opacity according to the distance. Ideally, the opacity is 1.0
+ * in the umbra area, and fall off to 0.0 till the edge of penumbra area.
  *
- * @param distRatio The distance ratio of current sample between umbra and
- *                  penumbra area.
- * @param deltaDist The distance between current sample to the penumbra area.
+ * @param layerRatio The distance ratio of current sample between umbra and penumbra area.
+ *                   Penumbra edge is 0 and umbra edge is 1.
  * @return The opacity according to the distance between umbra and penumbra.
  */
-float SpotShadow::calculateOpacity(float distRatio, float deltaDist) {
-    // TODO: Experiment on the opacity calculation.
-    float falloffRatio = 1 + deltaDist * deltaDist;
-    return (distRatio + 1 - 1 / falloffRatio) / 2;
+float SpotShadow::calculateOpacity(float layerRatio) {
+    return (layerRatio * layerRatio + layerRatio) / 2.0;
 }
 
 /**
diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h
index a50d110..6727eac 100644
--- a/libs/hwui/SpotShadow.h
+++ b/libs/hwui/SpotShadow.h
@@ -28,24 +28,22 @@
 public:
     static void createSpotShadow(const Vector3* poly, int polyLength,
             const Vector3& lightCenter, float lightSize, int lightVertexCount,
-            int rays, int layers, float strength, VertexBuffer& retStrips);
+            VertexBuffer& retStrips);
 
 private:
     static void computeSpotShadow(const Vector3* lightPoly, int lightPolyLength,
             const Vector3& lightCenter, const Vector3* poly, int polyLength,
-            int rays, int layers, float strength, VertexBuffer& retstrips);
+            VertexBuffer& retstrips);
 
     static void computeLightPolygon(int points, const Vector3& lightCenter,
             float size, Vector3* ret);
 
     static int  getStripSize(int rays, int layers);
     static void smoothPolygon(int level, int rays, float* rayDist);
-    static float calculateOpacity(float jf, float deltaDist);
+    static float calculateOpacity(float jf);
     static float rayIntersectPoly(const Vector2* poly, int polyLength,
             const Vector2& point, float dx, float dy);
 
-    static Vector2 centroid2d(const Vector2* poly, int polyLength);
-
     static void xsort(Vector2* points, int pointsLength);
     static int hull(Vector2* points, int pointsLength, Vector2* retPoly);
     static bool ccw(double ax, double ay, double bx, double by, double cx, double cy);
@@ -65,8 +63,7 @@
             double x3, double y3, double x4, double y4, Vector2& ret);
 
     static void generateTriangleStrip(const Vector2* penumbra, int penumbraLength,
-            const Vector2* umbra, int umbraLength, int rays, int layers,
-            float strength, VertexBuffer& retstrips);
+            const Vector2* umbra, int umbraLength, VertexBuffer& retstrips);
 
     static const double EPSILON = 1e-7;
 
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/Android.mk b/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
index 300224a..3e07155 100644
--- a/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
@@ -11,7 +11,6 @@
 
 LOCAL_MODULE := accessorychat
 
-LOCAL_C_INCLUDES += bionic/libc/kernel/common
 LOCAL_STATIC_LIBRARIES := libusbhost libcutils
 LOCAL_LDLIBS += -lpthread
 LOCAL_CFLAGS := -g -O0
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/linux/usb/f_accessory.h b/libs/usb/tests/AccessoryChat/accessorychat/linux/usb/f_accessory.h
new file mode 100644
index 0000000..75e017c
--- /dev/null
+++ b/libs/usb/tests/AccessoryChat/accessorychat/linux/usb/f_accessory.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_USB_F_ACCESSORY_H
+#define _UAPI_LINUX_USB_F_ACCESSORY_H
+#define USB_ACCESSORY_VENDOR_ID 0x18D1
+#define USB_ACCESSORY_PRODUCT_ID 0x2D00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
+#define ACCESSORY_STRING_MANUFACTURER 0
+#define ACCESSORY_STRING_MODEL 1
+#define ACCESSORY_STRING_DESCRIPTION 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_STRING_VERSION 3
+#define ACCESSORY_STRING_URI 4
+#define ACCESSORY_STRING_SERIAL 5
+#define ACCESSORY_GET_PROTOCOL 51
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_SEND_STRING 52
+#define ACCESSORY_START 53
+#define ACCESSORY_REGISTER_HID 54
+#define ACCESSORY_UNREGISTER_HID 55
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_SET_HID_REPORT_DESC 56
+#define ACCESSORY_SEND_HID_EVENT 57
+#define ACCESSORY_SET_AUDIO_MODE 58
+#define ACCESSORY_GET_STRING_MANUFACTURER _IOW('M', 1, char[256])
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_GET_STRING_MODEL _IOW('M', 2, char[256])
+#define ACCESSORY_GET_STRING_DESCRIPTION _IOW('M', 3, char[256])
+#define ACCESSORY_GET_STRING_VERSION _IOW('M', 4, char[256])
+#define ACCESSORY_GET_STRING_URI _IOW('M', 5, char[256])
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_GET_STRING_SERIAL _IOW('M', 6, char[256])
+#define ACCESSORY_IS_START_REQUESTED _IO('M', 7)
+#define ACCESSORY_GET_AUDIO_MODE _IO('M', 8)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index ccb4304..ced3ec9 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1610,7 +1610,7 @@
      * @hide
      */
     public boolean sendNiResponse(int notifId, int userResponse) {
-    	try {
+        try {
             return mService.sendNiResponse(notifId, userResponse);
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in sendNiResponse: ", e);
diff --git a/media/java/android/media/IMediaHTTPConnection.aidl b/media/java/android/media/IMediaHTTPConnection.aidl
index 300211b..55ffc2e 100644
--- a/media/java/android/media/IMediaHTTPConnection.aidl
+++ b/media/java/android/media/IMediaHTTPConnection.aidl
@@ -29,5 +29,6 @@
     int readAt(long offset, int size);
     long getSize();
     String getMIMEType();
+    String getUri();
 }
 
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
index 2732fbc..67680a8 100644
--- a/media/java/android/media/MediaHTTPConnection.java
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.net.Uri;
 import android.os.IBinder;
 import android.os.StrictMode;
 import android.util.Log;
@@ -52,6 +51,7 @@
         native_setup();
     }
 
+    @Override
     public IBinder connect(String uri, String headers) {
         if (VERBOSE) {
             Log.d(TAG, "connect: uri=" + uri + ", headers=" + headers);
@@ -85,6 +85,7 @@
         return map;
     }
 
+    @Override
     public void disconnect() {
         teardownConnection();
         mHeaders = null;
@@ -120,7 +121,11 @@
                         "Range", "bytes=" + offset + "-");
             }
 
-            if (mConnection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL) {
+            int response = mConnection.getResponseCode();
+            // remember the current, possibly redirected URL
+            mURL = mConnection.getURL();
+
+            if (response == HttpURLConnection.HTTP_PARTIAL) {
                 // Partial content, we cannot just use getContentLength
                 // because what we want is not just the length of the range
                 // returned but the size of the full content if available.
@@ -145,16 +150,13 @@
                         }
                     }
                 }
-            } else if (mConnection.getResponseCode()
-                    != HttpURLConnection.HTTP_OK) {
+            } else if (response != HttpURLConnection.HTTP_OK) {
                 throw new IOException();
             } else {
                 mTotalSize = mConnection.getContentLength();
             }
 
-            if (offset > 0
-                    && mConnection.getResponseCode()
-                            != HttpURLConnection.HTTP_PARTIAL) {
+            if (offset > 0 && response != HttpURLConnection.HTTP_PARTIAL) {
                 // Some servers simply ignore "Range" requests and serve
                 // data from the start of the content.
                 throw new IOException();
@@ -174,6 +176,7 @@
         }
     }
 
+    @Override
     public int readAt(long offset, int size) {
         return native_readAt(offset, size);
     }
@@ -218,6 +221,7 @@
         }
     }
 
+    @Override
     public long getSize() {
         if (mConnection == null) {
             try {
@@ -230,6 +234,7 @@
         return mTotalSize;
     }
 
+    @Override
     public String getMIMEType() {
         if (mConnection == null) {
             try {
@@ -243,6 +248,11 @@
     }
 
     @Override
+    public String getUri() {
+        return mURL.toString();
+    }
+
+    @Override
     protected void finalize() {
         native_finalize();
     }
@@ -260,4 +270,5 @@
     }
 
     private int mNativeContext;
+
 }
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index f8a7bb6..21e2f4b 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -417,8 +417,8 @@
         setParameter("time-lapse-enable=1");
 
         double timeBetweenFrameCapture = 1 / fps;
-        int timeBetweenFrameCaptureMs = (int) (1000 * timeBetweenFrameCapture);
-        setParameter("time-between-time-lapse-frame-capture=" + timeBetweenFrameCaptureMs);
+        long timeBetweenFrameCaptureUs = (long) (1000000 * timeBetweenFrameCapture);
+        setParameter("time-between-time-lapse-frame-capture=" + timeBetweenFrameCaptureUs);
     }
 
     /**
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
index 599522b..d7069cac 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
@@ -58,6 +58,7 @@
     private MediaRecorder mRecorder;
 
     private int MIN_VIDEO_FPS = 5;
+    private int HIGH_SPEED_FPS = 120;
 
     private static final int CAMERA_ID = 0;
 
@@ -221,10 +222,12 @@
         return success;
     }
 
-    private boolean recordVideoFromSurface(int frameRate, int width, int height,
+    private boolean recordVideoFromSurface(
+            int frameRate, int captureRate, int width, int height,
             int videoFormat, int outFormat, String outFile, boolean videoOnly) {
         Log.v(TAG,"recordVideoFromSurface");
         MediaRecorder recorder = new MediaRecorder();
+        int sleepTime = 33; // normal capture at 33ms / frame
         try {
             if (!videoOnly) {
                 recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
@@ -233,6 +236,10 @@
             recorder.setOutputFormat(outFormat);
             recorder.setOutputFile(outFile);
             recorder.setVideoFrameRate(frameRate);
+            if (captureRate > 0) {
+                recorder.setCaptureRate(captureRate);
+                sleepTime = 1000 / captureRate;
+            }
             recorder.setVideoSize(width, height);
             recorder.setVideoEncoder(videoFormat);
             if (!videoOnly) {
@@ -256,7 +263,7 @@
                 String text = "Frame #" + i;
                 canvas.drawText(text, 100, 100, paint);
                 surface.unlockCanvasAndPost(canvas);
-                Thread.sleep(33);
+                Thread.sleep(sleepTime);
             }
 
             Log.v(TAG, "start");
@@ -270,7 +277,7 @@
                 String text = "Frame #" + i;
                 canvas.drawText(text, 100, 100, paint);
                 surface.unlockCanvasAndPost(canvas);
-                Thread.sleep(33);
+                Thread.sleep(sleepTime);
             }
 
             Log.v(TAG, "stop");
@@ -517,7 +524,7 @@
                 String filename = "/sdcard/surface_" +
                             (k==0?"video_only":"with_audio") + ".3gp";
 
-                success = recordVideoFromSurface(frameRate, 352, 288, codec,
+                success = recordVideoFromSurface(frameRate, 0, 352, 288, codec,
                         MediaRecorder.OutputFormat.THREE_GPP, filename,
                         k == 0 ? true : false /* videoOnly */);
                 if (success) {
@@ -532,4 +539,38 @@
         }
         assertTrue("testSurfaceRecording", noOfFailure == 0);
     }
+
+    // Test recording from surface source with/without audio
+    public void testSurfaceRecordingTimeLapse() {
+        boolean success = false;
+        int noOfFailure = 0;
+        try {
+            int codec = MediaRecorder.VideoEncoder.H264;
+            int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec);
+            for (int k = 0; k < 2; k++) {
+                // k==0: time lapse test, set capture rate to MIN_VIDEO_FPS
+                // k==1: slow motion test, set capture rate to HIGH_SPEED_FPS
+                String filename = "/sdcard/surface_" +
+                            (k==0 ? "time_lapse" : "slow_motion") + ".3gp";
+
+                // always set videoOnly=false, MediaRecorder should disable
+                // audio automatically with time lapse/slow motion
+                success = recordVideoFromSurface(frameRate,
+                        k==0 ? MIN_VIDEO_FPS : HIGH_SPEED_FPS,
+                        352, 288, codec,
+                        MediaRecorder.OutputFormat.THREE_GPP,
+                        filename, false /* videoOnly */);
+                if (success) {
+                    success = validateVideo(filename, 352, 288);
+                }
+                if (!success) {
+                    noOfFailure++;
+                }
+            }
+        } catch (Exception e) {
+            Log.v(TAG, e.toString());
+        }
+        assertTrue("testSurfaceRecordingTimeLapse", noOfFailure == 0);
+    }
+
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
index 8c76421..eb1a589 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
@@ -85,8 +85,8 @@
         super.setUp();
         mMockProvider = EasyMock.createMock(IContentProvider.class);
         mMediaInserter = new MediaInserter(mMockProvider,
-		mPackageName, TEST_BUFFER_SIZE);
-	mPackageName = getInstrumentation().getContext().getPackageName();
+        mPackageName, TEST_BUFFER_SIZE);
+        mPackageName = getInstrumentation().getContext().getPackageName();
         mFilesCounter = 0;
         mAudioCounter = 0;
         mVideoCounter = 0;
@@ -224,19 +224,19 @@
     @SmallTest
     public void testInsertContentsWithDifferentSizePerContentType() throws Exception {
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sFilesUri),
+        MediaUriMatcher.expectMediaUri(sFilesUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(1);
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sAudioUri),
+        MediaUriMatcher.expectMediaUri(sAudioUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(2);
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sVideoUri),
+        MediaUriMatcher.expectMediaUri(sVideoUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(3);
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sImagesUri),
+        MediaUriMatcher.expectMediaUri(sImagesUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(4);
         EasyMock.replay(mMockProvider);
diff --git a/opengl/java/android/opengl/EGL14.java b/opengl/java/android/opengl/EGL14.java
index b93557d..b6dd9c2 100644
--- a/opengl/java/android/opengl/EGL14.java
+++ b/opengl/java/android/opengl/EGL14.java
@@ -155,10 +155,18 @@
     );
 
     // C function EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id )
+    // TODO Deprecate the eglGetDisplay(int) API method
 
     public static native EGLDisplay eglGetDisplay(
         int display_id
     );
+    // TODO Unhide the eglGetDisplay(long) API method
+    /**
+     * {@hide}
+     */
+    public static native EGLDisplay eglGetDisplay(
+        long display_id
+    );
 
     // C function EGLBoolean eglInitialize ( EGLDisplay dpy, EGLint *major, EGLint *minor )
 
@@ -324,7 +332,7 @@
     );
 
     // C function EGLSurface eglCreatePbufferFromClientBuffer ( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list )
-
+    // TODO Deprecate the below method
     public static native EGLSurface eglCreatePbufferFromClientBuffer(
         EGLDisplay dpy,
         int buftype,
@@ -333,6 +341,18 @@
         int[] attrib_list,
         int offset
     );
+    // TODO Unhide the below method
+    /**
+     * {@hide}
+     */
+    public static native EGLSurface eglCreatePbufferFromClientBuffer(
+        EGLDisplay dpy,
+        int buftype,
+        long buffer,
+        EGLConfig config,
+        int[] attrib_list,
+        int offset
+    );
 
     // C function EGLBoolean eglSurfaceAttrib ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value )
 
diff --git a/opengl/java/android/opengl/EGLConfig.java b/opengl/java/android/opengl/EGLConfig.java
index a7a6bbb..9881070 100644
--- a/opengl/java/android/opengl/EGLConfig.java
+++ b/opengl/java/android/opengl/EGLConfig.java
@@ -22,7 +22,7 @@
  *
  */
 public class EGLConfig extends EGLObjectHandle {
-    private EGLConfig(int handle) {
+    private EGLConfig(long handle) {
         super(handle);
     }
 
@@ -32,6 +32,6 @@
         if (!(o instanceof EGLConfig)) return false;
 
         EGLConfig that = (EGLConfig) o;
-        return getHandle() == that.getHandle();
+        return getNativeHandle() == that.getNativeHandle();
     }
 }
diff --git a/opengl/java/android/opengl/EGLContext.java b/opengl/java/android/opengl/EGLContext.java
index c93bd6e..f791e7e 100644
--- a/opengl/java/android/opengl/EGLContext.java
+++ b/opengl/java/android/opengl/EGLContext.java
@@ -22,7 +22,7 @@
  *
  */
 public class EGLContext extends EGLObjectHandle {
-    private EGLContext(int handle) {
+    private EGLContext(long handle) {
         super(handle);
     }
 
@@ -32,6 +32,6 @@
         if (!(o instanceof EGLContext)) return false;
 
         EGLContext that = (EGLContext) o;
-        return getHandle() == that.getHandle();
+        return getNativeHandle() == that.getNativeHandle();
     }
 }
diff --git a/opengl/java/android/opengl/EGLDisplay.java b/opengl/java/android/opengl/EGLDisplay.java
index 5b8043a..e872761 100644
--- a/opengl/java/android/opengl/EGLDisplay.java
+++ b/opengl/java/android/opengl/EGLDisplay.java
@@ -22,7 +22,7 @@
  *
  */
 public class EGLDisplay extends EGLObjectHandle {
-    private EGLDisplay(int handle) {
+    private EGLDisplay(long handle) {
         super(handle);
     }
 
@@ -32,6 +32,6 @@
         if (!(o instanceof EGLDisplay)) return false;
 
         EGLDisplay that = (EGLDisplay) o;
-        return getHandle() == that.getHandle();
+        return getNativeHandle() == that.getNativeHandle();
     }
 }
diff --git a/opengl/java/android/opengl/EGLObjectHandle.java b/opengl/java/android/opengl/EGLObjectHandle.java
index d2710de..e6e3976 100644
--- a/opengl/java/android/opengl/EGLObjectHandle.java
+++ b/opengl/java/android/opengl/EGLObjectHandle.java
@@ -22,12 +22,20 @@
  *
  */
 public abstract class EGLObjectHandle {
-    private final int mHandle;
+    private final long mHandle;
 
+    // TODO Deprecate EGLObjectHandle(int) method
     protected EGLObjectHandle(int handle) {
         mHandle = handle;
     }
-
+    // TODO Unhide the EGLObjectHandle(long) method
+    /**
+     * {@hide}
+     */
+    protected EGLObjectHandle(long handle) {
+        mHandle = handle;
+    }
+    // TODO Deprecate getHandle() method in favor of getNativeHandle()
     /**
      * Returns the native handle of the wrapped EGL object. This handle can be
      * cast to the corresponding native type on the native side.
@@ -37,11 +45,27 @@
      * @return the native handle of the wrapped EGL object.
      */
     public int getHandle() {
-        return mHandle;
+        if ((mHandle & 0xffffffffL) != mHandle) {
+            throw new UnsupportedOperationException();
+        }
+        return (int)mHandle;
     }
 
+    // TODO Unhide getNativeHandle() method
+    /**
+     * {@hide}
+     */
+    public long getNativeHandle() {
+        return mHandle;
+    }
     @Override
     public int hashCode() {
-        return getHandle();
+        /*
+         * Based on the algorithm suggested in
+         * http://developer.android.com/reference/java/lang/Object.html
+         */
+        int result = 17;
+        result = 31 * result + (int) (mHandle ^ (mHandle >>> 32));
+        return result;
     }
 }
diff --git a/opengl/java/android/opengl/EGLSurface.java b/opengl/java/android/opengl/EGLSurface.java
index c379dc9..c200f72 100644
--- a/opengl/java/android/opengl/EGLSurface.java
+++ b/opengl/java/android/opengl/EGLSurface.java
@@ -22,7 +22,7 @@
  *
  */
 public class EGLSurface extends EGLObjectHandle {
-    private EGLSurface(int handle) {
+    private EGLSurface(long handle) {
         super(handle);
     }
 
@@ -32,6 +32,6 @@
         if (!(o instanceof EGLSurface)) return false;
 
         EGLSurface that = (EGLSurface) o;
-        return getHandle() == that.getHandle();
+        return getNativeHandle() == that.getNativeHandle();
     }
 }
diff --git a/opengl/java/android/opengl/GLES10.java b/opengl/java/android/opengl/GLES10.java
index db52b82..fed84d5 100644
--- a/opengl/java/android/opengl/GLES10.java
+++ b/opengl/java/android/opengl/GLES10.java
@@ -262,7 +262,7 @@
 
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
 
     private static Buffer _colorPointer;
diff --git a/opengl/java/android/opengl/GLES10Ext.java b/opengl/java/android/opengl/GLES10Ext.java
index 81fc59e..3dc26eb 100644
--- a/opengl/java/android/opengl/GLES10Ext.java
+++ b/opengl/java/android/opengl/GLES10Ext.java
@@ -22,7 +22,7 @@
 public class GLES10Ext {
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
     
     // C function GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent )
diff --git a/opengl/java/android/opengl/GLES11.java b/opengl/java/android/opengl/GLES11.java
index 1ca179b..bb69bba 100644
--- a/opengl/java/android/opengl/GLES11.java
+++ b/opengl/java/android/opengl/GLES11.java
@@ -147,7 +147,7 @@
 
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
 
     private static Buffer _pointSizePointerOES;
diff --git a/opengl/java/android/opengl/GLES11Ext.java b/opengl/java/android/opengl/GLES11Ext.java
index 484439a..04d1b5d 100644
--- a/opengl/java/android/opengl/GLES11Ext.java
+++ b/opengl/java/android/opengl/GLES11Ext.java
@@ -132,7 +132,7 @@
 
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
     
     private static final int GL_BYTE = GLES10.GL_BYTE;
diff --git a/opengl/java/android/opengl/GLES30.java b/opengl/java/android/opengl/GLES30.java
index 9164849..342ffa4 100644
--- a/opengl/java/android/opengl/GLES30.java
+++ b/opengl/java/android/opengl/GLES30.java
@@ -864,13 +864,13 @@
         int buffer
     );
 
-	// C function void glTransformFeedbackVaryings ( GLuint program, GLsizei count, const GLchar *varyings, GLenum bufferMode )
+    // C function void glTransformFeedbackVaryings ( GLuint program, GLsizei count, const GLchar *varyings, GLenum bufferMode )
 
-	public static native void glTransformFeedbackVaryings(
+    public static native void glTransformFeedbackVaryings(
         int program,
         String[] varyings,
         int bufferMode
-	);
+    );
 
     // C function void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name )
 
@@ -1245,14 +1245,14 @@
         int size
     );
 
-	// C function void glGetUniformIndices ( GLuint program, GLsizei uniformCount, const GLchar *const *uniformNames, GLuint *uniformIndices )
+    // C function void glGetUniformIndices ( GLuint program, GLsizei uniformCount, const GLchar *const *uniformNames, GLuint *uniformIndices )
 
-	public static native void glGetUniformIndices(
+    public static native void glGetUniformIndices(
         int program,
         String[] uniformNames,
         int[] uniformIndices,
         int uniformIndicesOffset
-	);
+    );
 
     // C function void glGetUniformIndices ( GLuint program, GLsizei uniformCount, const GLchar *const *uniformNames, GLuint *uniformIndices )
 
diff --git a/opengl/java/com/google/android/gles_jni/GLImpl.java b/opengl/java/com/google/android/gles_jni/GLImpl.java
index 6b23be9..d4c0c80 100644
--- a/opengl/java/com/google/android/gles_jni/GLImpl.java
+++ b/opengl/java/com/google/android/gles_jni/GLImpl.java
@@ -39,7 +39,7 @@
 
     native private static void _nativeClassInit();
     static {
-	_nativeClassInit();
+        _nativeClassInit();
     }
 
     Buffer _colorPointer = null;
diff --git a/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml b/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml
new file mode 100644
index 0000000..ebd0a64
--- /dev/null
+++ b/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2014, 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 the host view that generally contains two sub views: the widget view
+    and the security view. -->
+<com.android.keyguard.KeyguardSimpleHostView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_host_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <com.android.keyguard.KeyguardSecurityContainer
+        android:id="@+id/keyguard_security_container"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/keyguard_security_height"
+        android:clipChildren="false"
+        android:clipToPadding="false"
+        android:padding="0dp"
+        android:layout_gravity="center">
+        <com.android.keyguard.KeyguardSecurityViewFlipper
+            android:id="@+id/view_flipper"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:clipChildren="false"
+            android:clipToPadding="false"
+            android:paddingTop="@dimen/keyguard_security_view_margin"
+            android:gravity="center">
+        </com.android.keyguard.KeyguardSecurityViewFlipper>
+    </com.android.keyguard.KeyguardSecurityContainer>
+
+</com.android.keyguard.KeyguardSimpleHostView>
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index 7ac94bd..1e79ee4 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -1051,9 +1051,6 @@
     }
 
     private void enableUserSelectorIfNecessary() {
-        if (!UserManager.supportsMultipleUsers()) {
-            return; // device doesn't support multi-user mode
-        }
         final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         if (um == null) {
             Throwable t = new Throwable();
@@ -1063,61 +1060,53 @@
         }
 
         // if there are multiple users, we need to enable to multi-user switcher
-        final List<UserInfo> users = um.getUsers(true);
-        if (users == null) {
-            Throwable t = new Throwable();
-            t.fillInStackTrace();
-            Log.e(TAG, "list of users is null.", t);
+        if (!um.isUserSwitcherEnabled()) {
             return;
         }
 
         final View multiUserView = findViewById(R.id.keyguard_user_selector);
         if (multiUserView == null) {
-            Throwable t = new Throwable();
-            t.fillInStackTrace();
-            Log.e(TAG, "can't find user_selector in layout.", t);
+            if (DEBUG) Log.d(TAG, "can't find user_selector in layout.");
             return;
         }
 
-        if (users.size() > 1) {
-            if (multiUserView instanceof KeyguardMultiUserSelectorView) {
-                mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
-                mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
-                mKeyguardMultiUserSelectorView.addUsers(users);
-                UserSwitcherCallback callback = new UserSwitcherCallback() {
-                    @Override
-                    public void hideSecurityView(int duration) {
-                        getSecurityContainer().animate().alpha(0).setDuration(duration);
-                    }
-
-                    @Override
-                    public void showSecurityView() {
-                        getSecurityContainer().setAlpha(1.0f);
-                    }
-
-                    @Override
-                    public void showUnlockHint() {
-                        if (getSecurityContainer() != null) {
-                            getSecurityContainer().showUsabilityHint();
-                        }
-                    }
-
-                    @Override
-                    public void userActivity() {
-                        if (mViewMediatorCallback != null) {
-                            mViewMediatorCallback.userActivity();
-                        }
-                    }
-                };
-                mKeyguardMultiUserSelectorView.setCallback(callback);
-            } else {
-                Throwable t = new Throwable();
-                t.fillInStackTrace();
-                if (multiUserView == null) {
-                    Log.e(TAG, "could not find the user_selector.", t);
-                } else {
-                    Log.e(TAG, "user_selector is the wrong type.", t);
+        if (multiUserView instanceof KeyguardMultiUserSelectorView) {
+            mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
+            mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
+            mKeyguardMultiUserSelectorView.addUsers(um.getUsers(true));
+            UserSwitcherCallback callback = new UserSwitcherCallback() {
+                @Override
+                public void hideSecurityView(int duration) {
+                    getSecurityContainer().animate().alpha(0).setDuration(duration);
                 }
+
+                @Override
+                public void showSecurityView() {
+                    getSecurityContainer().setAlpha(1.0f);
+                }
+
+                @Override
+                public void showUnlockHint() {
+                    if (getSecurityContainer() != null) {
+                        getSecurityContainer().showUsabilityHint();
+                    }
+                }
+
+                @Override
+                public void userActivity() {
+                    if (mViewMediatorCallback != null) {
+                        mViewMediatorCallback.userActivity();
+                    }
+                }
+            };
+            mKeyguardMultiUserSelectorView.setCallback(callback);
+        } else {
+            Throwable t = new Throwable();
+            t.fillInStackTrace();
+            if (multiUserView == null) {
+                Log.e(TAG, "could not find the user_selector.", t);
+            } else {
+                Log.e(TAG, "user_selector is the wrong type.", t);
             }
         }
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
index 7975d8e..06815e1 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
@@ -76,11 +76,13 @@
         Collections.sort(users, mOrderAddedComparator);
 
         for (UserInfo user: users) {
-            KeyguardMultiUserAvatar uv = createAndAddUser(user);
-            if (user.id == activeUser.id) {
-                mActiveUserAvatar = uv;
+            if (user.supportsSwitchTo()) {
+                KeyguardMultiUserAvatar uv = createAndAddUser(user);
+                if (user.id == activeUser.id) {
+                    mActiveUserAvatar = uv;
+                }
+                uv.setActive(false, false, null);
             }
-            uv.setActive(false, false, null);
         }
         mActiveUserAvatar.lockPressed(true);
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index 43165eb..40087cd 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -71,6 +71,7 @@
 
     // Timeout used for keypresses
     static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
+    private static final boolean ENABLE_SIMPLE_KEYGUARD = false;
 
     private final Context mContext;
     private final ViewManager mViewManager;
@@ -312,7 +313,7 @@
         if (force || mKeyguardView == null) {
             mKeyguardHost.setCustomBackground(null);
             mKeyguardHost.removeAllViews();
-            int layout = allowNotificationsOnSecureKeyguard()
+            int layout = (allowNotificationsOnSecureKeyguard() && ENABLE_SIMPLE_KEYGUARD)
                     ? R.layout.keyguard_simple_host_view
                     : R.layout.keyguard_host_view;
             if (mCurrentLayout != layout) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
index e0ee4e0..151177e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -704,7 +704,7 @@
 
     private void maybeSendUserPresentBroadcast() {
         if (mSystemReady && mLockPatternUtils.isLockScreenDisabled()
-                && mUserManager.getUsers(true).size() == 1) {
+                && !mUserManager.isUserSwitcherEnabled()) {
             // Lock screen is disabled because the user has set the preference to "None".
             // In this case, send out ACTION_USER_PRESENT here instead of in
             // handleKeyguardDone()
@@ -940,7 +940,7 @@
             return;
         }
 
-        if (mUserManager.getUsers(true).size() < 2
+        if (!mUserManager.isUserSwitcherEnabled()
                 && mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
             return;
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 69f7152..7410b9d 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -183,4 +183,7 @@
     <!-- Default for Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE -->
     <integer name="def_wifi_scan_always_available">0</integer>
 
+    <!-- Default for Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1==on -->
+    <integer name="def_lock_screen_show_notifications">1</integer>
+
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index f316d88..b546689 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -69,7 +69,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 98;
+    private static final int DATABASE_VERSION = 99;
 
     private Context mContext;
     private int mUserHandle;
@@ -1556,6 +1556,24 @@
             upgradeVersion = 98;
         }
 
+        if (upgradeVersion == 98) {
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                SQLiteStatement stmt = null;
+                try {
+                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
+                            + " VALUES(?,?);");
+                    loadIntegerSetting(stmt, Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                            R.integer.def_lock_screen_show_notifications);
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                    if (stmt != null) stmt.close();
+                }
+            }
+            upgradeVersion = 99;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
diff --git a/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml b/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml
deleted file mode 100644
index 5b6778e..0000000
--- a/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/anim/ease_out_interpolator.xml
-**
-** Copyright 2007, 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.
-*/
--->
-
-<decelerateInterpolator 
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:factor="10.0" />
diff --git a/packages/SystemUI/res/anim/lights_out_in.xml b/packages/SystemUI/res/anim/lights_out_in.xml
deleted file mode 100644
index f76a452..0000000
--- a/packages/SystemUI/res/anim/lights_out_in.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:fromYDelta="-100%p" android:toYDelta="0"
-        android:duration="@android:integer/config_mediumAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-    <alpha android:fromAlpha="0.5" android:toAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/lights_out_out.xml b/packages/SystemUI/res/anim/lights_out_out.xml
deleted file mode 100644
index 610ac7a..0000000
--- a/packages/SystemUI/res/anim/lights_out_out.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:toYDelta="-100%p" android:fromYDelta="0" 
-        android:duration="@android:integer/config_mediumAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-    <alpha android:toAlpha="0.5" android:fromAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/notification_dnd_off.xml b/packages/SystemUI/res/anim/notification_dnd_off.xml
deleted file mode 100644
index 4e88855..0000000
--- a/packages/SystemUI/res/anim/notification_dnd_off.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:fromXDelta="100%p" android:toXDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/notification_dnd_on.xml b/packages/SystemUI/res/anim/notification_dnd_on.xml
deleted file mode 100644
index 309943b..0000000
--- a/packages/SystemUI/res/anim/notification_dnd_on.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:toXDelta="100%p" android:fromXDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-</set>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index b5c24d7..033e56d 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -72,7 +72,7 @@
     <string name="use_mtp_button_title" msgid="4333504413563023626">"ต่อเชื่อมเป็นโปรแกรมเล่นสื่อ (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"ต่อเชื่อมเป็นกล้องถ่ายรูป (PTP)"</string>
     <string name="installer_cd_button_title" msgid="2312667578562201583">"ติดตั้งแอปพลิเคชัน Android File Transfer ของ Mac"</string>
-    <string name="accessibility_back" msgid="567011538994429120">"ย้อนกลับ"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"กลับ"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"หน้าแรก"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"เมนู"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"แอปพลิเคชันล่าสุด"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 4427466..b9a59dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -71,9 +71,9 @@
             final StatusBarNotification na = a.notification;
             final StatusBarNotification nb = b.notification;
             int d = na.getScore() - nb.getScore();
-	    if (a.interruption != b.interruption) {
-	      return a.interruption ? 1 : -1;
-	    } else if (d != 0) {
+            if (a.interruption != b.interruption) {
+                return a.interruption ? 1 : -1;
+            } else if (d != 0) {
                 return d;
             } else {
                 return (int) (na.getNotification().when - nb.getNotification().when);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 4d7ff5e..bcb818a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -312,7 +312,7 @@
             public void onClick(View v) {
                 collapsePanels();
                 final UserManager um = UserManager.get(mContext);
-                if (um.getUsers(true).size() > 1) {
+                if (um.isUserSwitcherEnabled()) {
                     // Since keyguard and systemui were merged into the same process to save
                     // memory, they share the same Looper and graphics context.  As a result,
                     // there's no way to allow concurrent animation while keyguard inflates.
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index f82ca22..0120a03 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -363,36 +363,38 @@
     }
 
     private void addUsersToMenu(ArrayList<Action> items) {
-        List<UserInfo> users = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
-                .getUsers();
-        if (users.size() > 1) {
+        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        if (um.isUserSwitcherEnabled()) {
+            List<UserInfo> users = um.getUsers();
             UserInfo currentUser = getCurrentUser();
             for (final UserInfo user : users) {
-                boolean isCurrentUser = currentUser == null
-                        ? user.id == 0 : (currentUser.id == user.id);
-                Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
-                        : null;
-                SinglePressAction switchToUser = new SinglePressAction(
-                        com.android.internal.R.drawable.ic_menu_cc, icon,
-                        (user.name != null ? user.name : "Primary")
-                        + (isCurrentUser ? " \u2714" : "")) {
-                    public void onPress() {
-                        try {
-                            ActivityManagerNative.getDefault().switchUser(user.id);
-                        } catch (RemoteException re) {
-                            Log.e(TAG, "Couldn't switch user " + re);
+                if (user.supportsSwitchTo()) {
+                    boolean isCurrentUser = currentUser == null
+                            ? user.id == 0 : (currentUser.id == user.id);
+                    Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
+                            : null;
+                    SinglePressAction switchToUser = new SinglePressAction(
+                            com.android.internal.R.drawable.ic_menu_cc, icon,
+                            (user.name != null ? user.name : "Primary")
+                            + (isCurrentUser ? " \u2714" : "")) {
+                        public void onPress() {
+                            try {
+                                ActivityManagerNative.getDefault().switchUser(user.id);
+                            } catch (RemoteException re) {
+                                Log.e(TAG, "Couldn't switch user " + re);
+                            }
                         }
-                    }
 
-                    public boolean showDuringKeyguard() {
-                        return true;
-                    }
+                        public boolean showDuringKeyguard() {
+                            return true;
+                        }
 
-                    public boolean showBeforeProvisioning() {
-                        return false;
-                    }
-                };
-                items.add(switchToUser);
+                        public boolean showBeforeProvisioning() {
+                            return false;
+                        }
+                    };
+                    items.add(switchToUser);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index e534a88..f03a8e0 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -492,7 +492,7 @@
 
         PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*");
-        
+
         mTimeTickSender = PendingIntent.getBroadcastAsUser(getContext(), 0,
                 new Intent(Intent.ACTION_TIME_TICK).addFlags(
                         Intent.FLAG_RECEIVER_REGISTERED_ONLY
@@ -1283,13 +1283,7 @@
                                 setWakelockWorkSource(alarm.operation, alarm.workSource);
                                 mWakeLock.setUnimportantForLogging(
                                         alarm.operation == mTimeTickSender);
-                                // XXX debugging
-                                /*
-                                Intent intent = alarm.operation.getIntent();
-                                mWakeLock.setTag(intent.getAction() != null ? intent.getAction()
-                                        : (intent.getComponent() != null
-                                                ? intent.getComponent().toShortString() : TAG));
-                                */
+                                mWakeLock.setHistoryTag(alarm.operation.getTag("*alarm*:"));
                                 mWakeLock.acquire();
                             }
                             final InFlight inflight = new InFlight(AlarmManagerService.this,
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 6e72e24..0ebbd8a 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -108,6 +108,7 @@
     private final Object mLock = new Object();
 
     private BatteryProperties mBatteryProps;
+    private final BatteryProperties mLastBatteryProps = new BatteryProperties();
     private boolean mBatteryLevelCritical;
     private int mLastBatteryStatus;
     private int mLastBatteryHealth;
@@ -281,6 +282,8 @@
                 mBatteryProps = props;
                 // Process the new values.
                 processValuesLocked();
+            } else {
+                mLastBatteryProps.set(props);
             }
         }
     }
@@ -617,6 +620,9 @@
                 String key = args[1];
                 String value = args[2];
                 try {
+                    if (!mUpdatesStopped) {
+                        mLastBatteryProps.set(mBatteryProps);
+                    }
                     boolean update = true;
                     if ("ac".equals(key)) {
                         mBatteryProps.chargerAcOnline = Integer.parseInt(value) != 0;
@@ -649,13 +655,16 @@
             } else if (args.length == 1 && "reset".equals(args[0])) {
                 long ident = Binder.clearCallingIdentity();
                 try {
-                    mUpdatesStopped = false;
+                    if (mUpdatesStopped) {
+                        mBatteryProps.set(mLastBatteryProps);
+                        processValuesLocked();
+                    }
                 } finally {
                     Binder.restoreCallingIdentity(ident);
                 }
             } else {
                 pw.println("Dump current battery state, or:");
-                pw.println("  set ac|usb|wireless|status|level|invalid <value>");
+                pw.println("  set [ac|usb|wireless|status|level|invalid] <value>");
                 pw.println("  reset");
             }
         }
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 546324a..0d6f548 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -1005,7 +1005,7 @@
                         mState = BluetoothAdapter.STATE_OFF;
                         // enable
                         handleEnable(mQuietEnable);
-		    } else if (mBinding || mBluetooth != null) {
+                    } else if (mBinding || mBluetooth != null) {
                         Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
                         userMsg.arg2 = 1 + msg.arg2;
                         // if user is switched when service is being binding
@@ -1014,7 +1014,7 @@
                         if (DBG) {
                             Log.d(TAG, "delay MESSAGE_USER_SWITCHED " + userMsg.arg2);
                         }
-		    }
+                    }
                     break;
                 }
             }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 342336e..36907ed 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -33,6 +33,7 @@
 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
 
 import android.app.AlarmManager;
+import android.app.AppOpsManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -44,7 +45,9 @@
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
@@ -169,9 +172,9 @@
     private static final String TAG = "ConnectivityService";
 
     private static final boolean DBG = true;
-    private static final boolean VDBG = true;
+    private static final boolean VDBG = false;
 
-    private static final boolean LOGD_RULES = true;
+    private static final boolean LOGD_RULES = false;
 
     // TODO: create better separation between radio types and network types
 
@@ -414,6 +417,8 @@
 
     private SettingsObserver mSettingsObserver;
 
+    private AppOpsManager mAppOpsManager;
+
     NetworkConfig[] mNetConfigs;
     int mNetworksDefined;
 
@@ -697,6 +702,8 @@
         filter = new IntentFilter();
         filter.addAction(CONNECTED_TO_PROVISIONING_NETWORK_ACTION);
         mContext.registerReceiver(mProvisioningReceiver, filter);
+
+        mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
     }
 
     /**
@@ -1531,6 +1538,40 @@
     }
 
     /**
+     * Check if the address falls into any of currently running VPN's route's.
+     */
+    private boolean isAddressUnderVpn(InetAddress address) {
+        synchronized (mVpns) {
+            synchronized (mRoutesLock) {
+                int uid = UserHandle.getCallingUserId();
+                Vpn vpn = mVpns.get(uid);
+                if (vpn == null) {
+                    return false;
+                }
+
+                // Check if an exemption exists for this address.
+                for (LinkAddress destination : mExemptAddresses) {
+                    if (!NetworkUtils.addressTypeMatches(address, destination.getAddress())) {
+                        continue;
+                    }
+
+                    int prefix = destination.getNetworkPrefixLength();
+                    InetAddress addrMasked = NetworkUtils.getNetworkPart(address, prefix);
+                    InetAddress destMasked = NetworkUtils.getNetworkPart(destination.getAddress(),
+                            prefix);
+
+                    if (addrMasked.equals(destMasked)) {
+                        return false;
+                    }
+                }
+
+                // Finally check if the address is covered by the VPN.
+                return vpn.isAddressCovered(address);
+            }
+        }
+    }
+
+    /**
      * @deprecated use requestRouteToHostAddress instead
      *
      * Ensure that a network route exists to deliver traffic to the specified
@@ -1541,14 +1582,14 @@
      * desired
      * @return {@code true} on success, {@code false} on failure
      */
-    public boolean requestRouteToHost(int networkType, int hostAddress) {
+    public boolean requestRouteToHost(int networkType, int hostAddress, String packageName) {
         InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
 
         if (inetAddress == null) {
             return false;
         }
 
-        return requestRouteToHostAddress(networkType, inetAddress.getAddress());
+        return requestRouteToHostAddress(networkType, inetAddress.getAddress(), packageName);
     }
 
     /**
@@ -1560,11 +1601,40 @@
      * desired
      * @return {@code true} on success, {@code false} on failure
      */
-    public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
+    public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress,
+            String packageName) {
         enforceChangePermission();
         if (mProtectedNetworks.contains(networkType)) {
             enforceConnectivityInternalPermission();
         }
+        boolean exempt;
+        InetAddress addr;
+        try {
+            addr = InetAddress.getByAddress(hostAddress);
+        } catch (UnknownHostException e) {
+            if (DBG) log("requestRouteToHostAddress got " + e.toString());
+            return false;
+        }
+        // System apps may request routes bypassing the VPN to keep other networks working.
+        if (Binder.getCallingUid() == Process.SYSTEM_UID) {
+            exempt = true;
+        } else {
+            mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
+            try {
+                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(packageName,
+                        0);
+                exempt = (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+            } catch (NameNotFoundException e) {
+                throw new IllegalArgumentException("Failed to find calling package details", e);
+            }
+        }
+
+        // Non-exempt routeToHost's can only be added if the host is not covered by the VPN.
+        // This can be either because the VPN's routes do not cover the destination or a
+        // system application added an exemption that covers this destination.
+        if (!exempt && isAddressUnderVpn(addr)) {
+            return false;
+        }
 
         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
             if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
@@ -1591,18 +1661,13 @@
         }
         final long token = Binder.clearCallingIdentity();
         try {
-            InetAddress addr = InetAddress.getByAddress(hostAddress);
             LinkProperties lp = tracker.getLinkProperties();
-            boolean ok = addRouteToAddress(lp, addr, EXEMPT);
+            boolean ok = addRouteToAddress(lp, addr, exempt);
             if (DBG) log("requestRouteToHostAddress ok=" + ok);
             return ok;
-        } catch (UnknownHostException e) {
-            if (DBG) log("requestRouteToHostAddress got " + e.toString());
         } finally {
             Binder.restoreCallingIdentity(token);
         }
-        if (DBG) log("requestRouteToHostAddress X bottom return false");
-        return false;
     }
 
     private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable,
@@ -4334,7 +4399,7 @@
 
                             // Make a route to host so we check the specific interface.
                             if (mCs.requestRouteToHostAddress(ConnectivityManager.TYPE_MOBILE_HIPRI,
-                                    hostAddr.getAddress())) {
+                                    hostAddr.getAddress(), null)) {
                                 // Wait a short time to be sure the route is established ??
                                 log("isMobileOk:"
                                         + " wait to establish route to hostAddr=" + hostAddr);
@@ -4504,7 +4569,6 @@
          * @param seconds
          */
         private static void sleep(int seconds) {
-            log("XXXXX sleeping for " + seconds + " sec");
             long stopTime = System.nanoTime() + (seconds * 1000000000);
             long sleepTime;
             while ((sleepTime = stopTime - System.nanoTime()) > 0) {
@@ -4513,7 +4577,6 @@
                 } catch (InterruptedException ignored) {
                 }
             }
-            log("XXXXX returning from sleep");
         }
 
         private static void log(String s) {
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 3924fe8..74de577 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -20,6 +20,7 @@
 import static android.Manifest.permission.DUMP;
 import static android.Manifest.permission.SHUTDOWN;
 import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.TrafficStats.UID_TETHERING;
@@ -1271,7 +1272,7 @@
     public NetworkStats getNetworkStatsDetail() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            return mStatsFactory.readNetworkStatsDetail(UID_ALL);
+            return mStatsFactory.readNetworkStatsDetail(UID_ALL, null, TAG_ALL, null);
         } catch (IOException e) {
             throw new IllegalStateException(e);
         }
@@ -1432,7 +1433,7 @@
     public NetworkStats getNetworkStatsUidDetail(int uid) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            return mStatsFactory.readNetworkStatsDetail(uid);
+            return mStatsFactory.readNetworkStatsDetail(uid, null, TAG_ALL, null);
         } catch (IOException e) {
             throw new IllegalStateException(e);
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7b2fc50..3bb1d0d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5547,6 +5547,38 @@
     }
 
     @Override
+    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
+        if (!(pendingResult instanceof PendingIntentRecord)) {
+            return null;
+        }
+        try {
+            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
+            Intent intent = res.key.requestIntent;
+            if (intent != null) {
+                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
+                        || res.lastTagPrefix.equals(prefix))) {
+                    return res.lastTag;
+                }
+                res.lastTagPrefix = prefix;
+                StringBuilder sb = new StringBuilder(128);
+                if (prefix != null) {
+                    sb.append(prefix);
+                }
+                if (intent.getAction() != null) {
+                    sb.append(intent.getAction());
+                } else if (intent.getComponent() != null) {
+                    intent.getComponent().appendShortString(sb);
+                } else {
+                    sb.append("?");
+                }
+                return res.lastTag = sb.toString();
+            }
+        } catch (ClassCastException e) {
+        }
+        return null;
+    }
+
+    @Override
     public void setProcessLimit(int max) {
         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
                 "setProcessLimit()");
@@ -7107,6 +7139,15 @@
     }
 
     @Override
+    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
+        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+                "deleteActivityContainer()");
+        synchronized (this) {
+            mStackSupervisor.deleteActivityContainer(container);
+        }
+    }
+
+    @Override
     public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
             throws RemoteException {
         synchronized (this) {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 98bb357..5d23fc3 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -598,7 +598,7 @@
             int requestCode, int resultCode,
             Intent resultData) {
         ActivityResult r = new ActivityResult(from, resultWho,
-        		requestCode, resultCode, resultData);
+                requestCode, resultCode, resultData);
         if (results == null) {
             results = new ArrayList<ResultInfo>();
         }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 3a837e8..9636de7 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -523,7 +523,7 @@
     }
 
     void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
-		// TODO: Put all stacks in supervisor and iterate through them instead.
+        // TODO: Put all stacks in supervisor and iterate through them instead.
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
@@ -2180,13 +2180,28 @@
             ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
             if (top != null) {
                 // TODO: Make sure the next activity doesn't start up when top is destroyed.
-                stack.destroyActivityLocked(top, true, true, "stack removal");
+                stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
             }
             mActivityContainers.removeAt(ndx);
             container.detachLocked();
         }
     }
 
+    void deleteActivityContainer(IActivityContainer container) {
+        ActivityContainer activityContainer = (ActivityContainer)container;
+        if (activityContainer != null) {
+            activityContainer.mStack.destroyActivitiesLocked(null, true,
+                    "deleteActivityContainer");
+            final ActivityRecord parent = activityContainer.mParentActivity;
+            if (parent != null) {
+                parent.mChildContainers.remove(activityContainer);
+            }
+            final int stackId = activityContainer.mStackId;
+            mActivityContainers.remove(stackId);
+            mWindowManager.removeStack(stackId);
+        }
+    }
+
     private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
         ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
         if (activityDisplay == null) {
@@ -2557,6 +2572,7 @@
         pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
         pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
         pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
+        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
     }
 
     ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 059aa2b..da85835 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -126,11 +126,11 @@
         }
     }
 
-    public void noteStartWakelock(int uid, int pid, String name, int type,
+    public void noteStartWakelock(int uid, int pid, String name, String historyName, int type,
             boolean unimportantForLogging) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteStartWakeLocked(uid, pid, name, type, unimportantForLogging);
+            mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging);
         }
     }
 
@@ -141,11 +141,12 @@
         }
     }
 
-    public void noteStartWakelockFromSource(WorkSource ws, int pid, String name, int type,
-            boolean unimportantForLogging) {
+    public void noteStartWakelockFromSource(WorkSource ws, int pid, String name,
+            String historyName, int type, boolean unimportantForLogging) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteStartWakeFromSourceLocked(ws, pid, name, type, unimportantForLogging);
+            mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName,
+                    type, unimportantForLogging);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 00fa216..98999e9 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -41,6 +41,8 @@
     boolean canceled = false;
 
     String stringName;
+    String lastTagPrefix;
+    String lastTag;
     
     final static class Key {
         final int type;
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index d87387f..af08d57 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -44,6 +44,7 @@
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
 import android.net.NetworkInfo;
+import android.net.NetworkUtils;
 import android.net.RouteInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.os.Binder;
@@ -74,6 +75,7 @@
 import java.io.File;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
@@ -430,6 +432,18 @@
         return tun;
     }
 
+    /**
+     * Check if a given address is covered by the VPN's routing rules.
+     */
+    public boolean isAddressCovered(InetAddress address) {
+        synchronized (Vpn.this) {
+            if (!isRunningLocked()) {
+                return false;
+            }
+            return RouteInfo.selectBestRoute(mConfig.routes, address) != null;
+        }
+    }
+
     private boolean isRunningLocked() {
         return mVpnUsers != null;
     }
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 0185a21..95bfd2f 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -53,6 +53,7 @@
 import android.content.pm.UserInfo;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
+import android.os.BatteryStats;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -60,6 +61,7 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -75,6 +77,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.IBatteryStats;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.accounts.AccountManagerService;
@@ -172,6 +175,7 @@
 
     private final NotificationManager mNotificationMgr;
     private AlarmManager mAlarmService = null;
+    private final IBatteryStats mBatteryStats;
 
     private SyncStorageEngine mSyncStorageEngine;
 
@@ -435,6 +439,8 @@
         }
         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
+                BatteryStats.SERVICE_NAME));
 
         // This WakeLock is used to ensure that we stay awake between the time that we receive
         // a sync alarm notification and when we finish processing it. We need to do this
@@ -1123,6 +1129,7 @@
         final int mSyncAdapterUid;
         SyncInfo mSyncInfo;
         boolean mIsLinkedToDeath = false;
+        String mEventName;
 
         /**
          * Create an ActiveSyncContext for an impending sync and grab the wakelock for that
@@ -1201,6 +1208,13 @@
                     new UserHandle(mSyncOperation.target.userId));
             if (!bindResult) {
                 mBound = false;
+            } else {
+                try {
+                    mEventName = serviceComponent.flattenToShortString();
+                    mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_SYNC_START,
+                            serviceComponent.flattenToShortString(), mSyncAdapterUid);
+                } catch (RemoteException e) {
+                }
             }
             return bindResult;
         }
@@ -1216,6 +1230,11 @@
             if (mBound) {
                 mBound = false;
                 mContext.unbindService(this);
+                try {
+                    mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_SYNC_FINISH,
+                            mEventName, mSyncAdapterUid);
+                } catch (RemoteException e) {
+                }
             }
             mSyncWakeLock.release();
             mSyncWakeLock.setWorkSource(null);
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 09be3a8..e1ccf46 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -130,7 +130,7 @@
      * Called when a wake lock is acquired.
      */
     public void onWakeLockAcquired(int flags, String tag, String packageName,
-            int ownerUid, int ownerPid, WorkSource workSource) {
+            int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
         if (DEBUG) {
             Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
                     + "\", packageName=" + packageName
@@ -143,11 +143,11 @@
             boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
                     && ownerUid == Process.SYSTEM_UID;
             if (workSource != null) {
-                mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, monitorType,
-                        unimportantForLogging);
+                mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, historyTag,
+                        monitorType, unimportantForLogging);
             } else {
-                mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, monitorType,
-                        unimportantForLogging);
+                mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
+                        monitorType, unimportantForLogging);
                 // XXX need to deal with disabled operations.
                 mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
                         AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 0ba55b6..4395502 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -632,7 +632,7 @@
     }
 
     private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,
-            WorkSource ws, int uid, int pid) {
+            WorkSource ws, String historyTag, int uid, int pid) {
         synchronized (mLock) {
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
@@ -647,11 +647,11 @@
                 if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
                     // Update existing wake lock.  This shouldn't happen but is harmless.
                     notifyWakeLockReleasedLocked(wakeLock);
-                    wakeLock.updateProperties(flags, tag, packageName, ws, uid, pid);
+                    wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);
                     notifyWakeLockAcquiredLocked(wakeLock);
                 }
             } else {
-                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, uid, pid);
+                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);
                 try {
                     lock.linkToDeath(wakeLock, 0);
                 } catch (RemoteException ex) {
@@ -786,7 +786,8 @@
         if (mSystemReady) {
             wakeLock.mNotifiedAcquired = true;
             mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
-                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
+                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
+                    wakeLock.mHistoryTag);
         }
     }
 
@@ -1553,7 +1554,7 @@
             return false;
         }
         if (!isBeingKeptAwakeLocked()) {
-            if (!mIsPowered && !mDreamsEnabledByDefaultConfig) {
+            if (!mIsPowered && !mDreamsEnabledOnBatteryConfig) {
                 return false;
             }
             if (!mIsPowered
@@ -2274,17 +2275,19 @@
         public String mTag;
         public final String mPackageName;
         public WorkSource mWorkSource;
+        public String mHistoryTag;
         public final int mOwnerUid;
         public final int mOwnerPid;
         public boolean mNotifiedAcquired;
 
         public WakeLock(IBinder lock, int flags, String tag, String packageName,
-                WorkSource workSource, int ownerUid, int ownerPid) {
+                WorkSource workSource, String historyTag, int ownerUid, int ownerPid) {
             mLock = lock;
             mFlags = flags;
             mTag = tag;
             mPackageName = packageName;
             mWorkSource = copyWorkSource(workSource);
+            mHistoryTag = historyTag;
             mOwnerUid = ownerUid;
             mOwnerPid = ownerPid;
         }
@@ -2304,7 +2307,7 @@
         }
 
         public void updateProperties(int flags, String tag, String packageName,
-                WorkSource workSource, int ownerUid, int ownerPid) {
+                WorkSource workSource, String historyTag, int ownerUid, int ownerPid) {
             if (!mPackageName.equals(packageName)) {
                 throw new IllegalStateException("Existing wake lock package name changed: "
                         + mPackageName + " to " + packageName);
@@ -2320,6 +2323,7 @@
             mFlags = flags;
             mTag = tag;
             updateWorkSource(workSource);
+            mHistoryTag = historyTag;
         }
 
         public boolean hasSameWorkSource(WorkSource workSource) {
@@ -2517,12 +2521,12 @@
         @Override // Binder call
         public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,
                 String packageName, int uid) {
-            acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid));
+            acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null);
         }
 
         @Override // Binder call
         public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
-                WorkSource ws) {
+                WorkSource ws, String historyTag) {
             if (lock == null) {
                 throw new IllegalArgumentException("lock must not be null");
             }
@@ -2543,7 +2547,7 @@
             final int pid = Binder.getCallingPid();
             final long ident = Binder.clearCallingIdentity();
             try {
-                acquireWakeLockInternal(lock, flags, tag, packageName, ws, uid, pid);
+                acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 68834d8..d4bcd5c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -102,9 +102,8 @@
 
     final WindowManagerService mService;
 
-    static final int DEFER_DETACH = 1;
-    static final int DEFER_REMOVAL = 2;
-    int mDeferredActions;
+    /** Remove this display when animation on it has completed. */
+    boolean mDeferredRemoval;
 
     /**
      * @param display May not be null.
@@ -302,6 +301,49 @@
         }
     }
 
+    boolean isAnimating() {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final TaskStack stack = mStacks.get(stackNdx);
+            if (stack.isAnimating()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void checkForDeferredActions() {
+        boolean animating = false;
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final TaskStack stack = mStacks.get(stackNdx);
+            if (stack.isAnimating()) {
+                animating = true;
+            } else {
+                if (stack.mDeferDetach) {
+                    mService.detachStackLocked(this, stack);
+                }
+                final ArrayList<Task> tasks = stack.getTasks();
+                for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+                    final Task task = tasks.get(taskNdx);
+                    AppTokenList tokens = task.mAppTokens;
+                    for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+                        AppWindowToken wtoken = tokens.get(tokenNdx);
+                        if (wtoken.mDeferRemoval) {
+                            wtoken.mDeferRemoval = false;
+                            mService.removeAppFromTaskLocked(wtoken);
+                        }
+                    }
+                    if (task.mDeferRemoval) {
+                        task.mDeferRemoval = false;
+                        mService.removeTaskLocked(task);
+                    }
+                }
+            }
+        }
+        if (!animating && mDeferredRemoval) {
+            mService.onDisplayRemoved(mDisplayId);
+        }
+    }
+
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
         final String subPrefix = "  " + prefix;
@@ -325,7 +367,8 @@
             pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
             pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
             pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
-            pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded);
+            pw.print(subPrefix); pw.print("deferred="); pw.print(mDeferredRemoval);
+                pw.print(" layoutNeeded="); pw.println(layoutNeeded);
         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
             final TaskStack stack = mStacks.get(stackNdx);
             pw.print(prefix); pw.print("mStacks[" + stackNdx + "]"); pw.println(stack.mStackId);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index c70bc62..81db8b3 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -75,6 +75,9 @@
     /** Application tokens that are exiting, but still on screen for animations. */
     final AppTokenList mExitingAppTokens = new AppTokenList();
 
+    /** Detach this stack from its display when animation completes. */
+    boolean mDeferDetach;
+
     TaskStack(WindowManagerService service, int stackId) {
         mService = service;
         mStackId = stackId;
@@ -362,36 +365,9 @@
         mAnimationBackgroundSurface.mDimSurface.destroy();
     }
 
-    void checkForDeferredActions() {
-        if (mDisplayContent != null &&
-                (mDisplayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0 &&
-                !isAnimating()) {
-            mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_DETACH;
-            if ((mDisplayContent.mDeferredActions & DisplayContent.DEFER_REMOVAL) != 0) {
-                mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_REMOVAL;
-                mService.onDisplayRemoved(mDisplayContent.getDisplayId());
-            }
-            mService.detachStack(mStackId);
-        }
-        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
-            final Task task = mTasks.get(taskNdx);
-            AppTokenList tokens = task.mAppTokens;
-            for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
-                AppWindowToken wtoken = tokens.get(tokenNdx);
-                if (wtoken.mDeferRemoval) {
-                    wtoken.mDeferRemoval = false;
-                    mService.removeAppFromTaskLocked(wtoken);
-                }
-            }
-            if (task.mDeferRemoval) {
-                task.mDeferRemoval = false;
-                mService.removeTaskLocked(task);
-            }
-        }
-    }
-
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
+        pw.print(prefix); pw.print("mDeferDetach="); pw.println(mDeferDetach);
         for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
             pw.print(prefix); pw.println(mTasks.get(taskNdx));
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f03f9a2..6e1724a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -188,6 +188,7 @@
     static final boolean DEBUG_WINDOW_TRACE = false;
     static final boolean DEBUG_TASK_MOVEMENT = false;
     static final boolean DEBUG_STACK = false;
+    static final boolean DEBUG_DISPLAY = false;
     static final boolean SHOW_SURFACE_ALLOC = false;
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -4929,6 +4930,11 @@
         }
     }
 
+    void detachStackLocked(DisplayContent displayContent, TaskStack stack) {
+        displayContent.detachStack(stack);
+        stack.detachDisplay();
+    }
+
     public void detachStack(int stackId) {
         synchronized (mWindowMap) {
             TaskStack stack = mStackIdToStack.get(stackId);
@@ -4936,16 +4942,19 @@
                 final DisplayContent displayContent = stack.getDisplayContent();
                 if (displayContent != null) {
                     if (stack.isAnimating()) {
-                        displayContent.mDeferredActions |= DisplayContent.DEFER_DETACH;
+                        stack.mDeferDetach = true;
                         return;
                     }
-                    displayContent.detachStack(stack);
-                    stack.detachDisplay();
+                    detachStackLocked(displayContent, stack);
                 }
             }
         }
     }
 
+    public void removeStack(int stackId) {
+        mStackIdToStack.remove(stackId);
+    }
+
     void removeTaskLocked(Task task) {
         final int taskId = task.taskId;
         final TaskStack stack = task.mStack;
@@ -9501,9 +9510,9 @@
             }
         }
 
-        // Remove all deferred Stacks, tasks, and activities.
-        for (int stackNdx = mPendingStacksRemove.size() - 1; stackNdx >= 0; --stackNdx) {
-            mPendingStacksRemove.removeAt(stackNdx).checkForDeferredActions();
+        // Remove all deferred displays stacks, tasks, and activities.
+        for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
+            mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
         }
 
         setFocusedStackFrame();
@@ -10788,6 +10797,7 @@
     private DisplayContent newDisplayContentLocked(final Display display) {
         DisplayContent displayContent = new DisplayContent(display, this);
         final int displayId = display.getDisplayId();
+        if (DEBUG_DISPLAY) Slog.v(TAG, "Adding display=" + display);
         mDisplayContents.put(displayId, displayContent);
 
         DisplayInfo displayInfo = displayContent.getDisplayInfo();
@@ -10889,10 +10899,11 @@
     private void handleDisplayRemovedLocked(int displayId) {
         final DisplayContent displayContent = getDisplayContentLocked(displayId);
         if (displayContent != null) {
-            if ((displayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0) {
-                displayContent.mDeferredActions |= DisplayContent.DEFER_REMOVAL;
+            if (displayContent.isAnimating()) {
+                displayContent.mDeferredRemoval = true;
                 return;
             }
+            if (DEBUG_DISPLAY) Slog.v(TAG, "Removing display=" + displayContent);
             mDisplayContents.delete(displayId);
             displayContent.close();
             if (displayId == Display.DEFAULT_DISPLAY) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index f98b724..93f6d22 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -430,7 +430,6 @@
             mService.mPendingRemove.add(mWin);
             mWin.mRemoveOnExit = false;
         }
-        mService.mPendingStacksRemove.add(mWin.getStack());
         mAnimator.hideWallpapersLocked(mWin);
     }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 83dbbb2..91d77fb 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -851,9 +851,8 @@
                 }
             }
 
-            if (!disableNonCoreServices
-                    && context.getResources().getBoolean(R.bool.config_dreamsSupported)) {
-                // Dreams (interactive idle-time views, a/k/a screen savers)
+            if (!disableNonCoreServices) {
+                // Dreams (interactive idle-time views, a/k/a screen savers, and doze mode)
                 mSystemServiceManager.startService(DreamManagerService.class);
             }
 
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 8ae3824..0f20dde 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -226,9 +226,9 @@
                 final Handler handler) {
         }
 
-		@Override
-		public void invalidateCache(int userId) {
-		}
+        @Override
+        public void invalidateCache(int userId) {
+        }
     }
 
     static public class MyMockContext extends MockContext {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index d5dd9a6..b925856 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -99,6 +99,13 @@
     // which need debouncing.
     private static final int UPDATE_DELAY = 1000;
 
+    // Time we received a request to enter USB accessory mode
+    private long mAccessoryModeRequestTime = 0;
+
+    // Timeout for entering USB request mode.
+    // Request is cancelled if host does not configure device within 10 seconds.
+    private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000;
+
     private static final String BOOT_MODE_PROPERTY = "ro.bootmode";
 
     private UsbHandler mHandler;
@@ -206,6 +213,8 @@
     }
 
     private void startAccessoryMode() {
+        if (!mHasUsbAccessory) return;
+
         mAccessoryStrings = nativeGetAccessoryStrings();
         boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE);
         // don't start accessory mode if our mandatory strings have not been set
@@ -224,6 +233,7 @@
         }
 
         if (functions != null) {
+            mAccessoryModeRequestTime = SystemClock.elapsedRealtime();
             setCurrentFunctions(functions, false);
         }
     }
@@ -452,6 +462,8 @@
         }
 
         private void setEnabledFunctions(String functions, boolean makeDefault) {
+            if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions
+                    + " makeDefault: " + makeDefault);
 
             // Do not update persystent.sys.usb.config if the device is booted up
             // with OEM specific mode.
@@ -513,9 +525,17 @@
         }
 
         private void updateCurrentAccessory() {
-            if (!mHasUsbAccessory) return;
+            // We are entering accessory mode if we have received a request from the host
+            // and the request has not timed out yet.
+            boolean enteringAccessoryMode =
+                    mAccessoryModeRequestTime > 0 &&
+                        SystemClock.elapsedRealtime() <
+                            mAccessoryModeRequestTime + ACCESSORY_REQUEST_TIMEOUT;
 
-            if (mConfigured) {
+            if (mConfigured && enteringAccessoryMode) {
+                // successfully entered accessory mode
+                mAccessoryModeRequestTime = 0;
+
                 if (mAccessoryStrings != null) {
                     mCurrentAccessory = new UsbAccessory(mAccessoryStrings);
                     Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
@@ -526,7 +546,7 @@
                 } else {
                     Slog.e(TAG, "nativeGetAccessoryStrings failed");
                 }
-            } else if (!mConnected) {
+            } else if (!enteringAccessoryMode) {
                 // make sure accessory mode is off
                 // and restore default functions
                 Slog.d(TAG, "exited USB accessory mode");
@@ -556,6 +576,8 @@
                 }
             }
 
+            if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " connected: " + mConnected
+                                    + " configured: " + mConfigured);
             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
         }
 
@@ -595,9 +617,7 @@
                     if (containsFunction(mCurrentFunctions,
                             UsbManager.USB_FUNCTION_ACCESSORY)) {
                         updateCurrentAccessory();
-                    }
-
-                    if (!mConnected) {
+                    } else if (!mConnected) {
                         // restore defaults when USB is disconnected
                         setEnabledFunctions(mDefaultFunctions, false);
                     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 23e4d77..d28d76d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1823,10 +1823,11 @@
     }
 
     /**
-     * Perform the specified type of NV config reset.
-     * Used for device configuration by some CDMA operators.
+     * Perform the specified type of NV config reset. The radio will be taken offline
+     * and the device must be rebooted after the operation. Used for device
+     * configuration by some CDMA operators.
      *
-     * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset).
+     * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
      * @return true on success; false on any failure.
      * @hide
      */
@@ -1840,24 +1841,4 @@
         }
         return false;
     }
-
-    /**
-     * Change the radio to the specified mode.
-     * Used for device configuration by some operators.
-     *
-     * @param radioMode is 0 for offline mode, 1 for online mode, 2 for low-power mode,
-     *                  or 3 to reset the radio.
-     * @return true on success; false on any failure.
-     * @hide
-     */
-    public boolean setRadioMode(int radioMode) {
-        try {
-            return getITelephony().setRadioMode(radioMode);
-        } catch (RemoteException ex) {
-            Rlog.e(TAG, "setRadioMode RemoteException", ex);
-        } catch (NullPointerException ex) {
-            Rlog.e(TAG, "setRadioMode NPE", ex);
-        }
-        return false;
-    }
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 370e27a..554a9cb 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -395,21 +395,12 @@
     boolean nvWriteCdmaPrl(in byte[] preferredRoamingList);
 
     /**
-     * Perform the specified type of NV config reset.
-     * Used for device configuration by some CDMA operators.
+     * Perform the specified type of NV config reset. The radio will be taken offline
+     * and the device must be rebooted after the operation. Used for device
+     * configuration by some CDMA operators.
      *
      * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset).
      * @return true on success; false on any failure.
      */
     boolean nvResetConfig(int resetType);
-
-    /**
-     * Change the radio to the specified mode.
-     * Used for device configuration by some operators.
-     *
-     * @param radioMode is 0 for offline mode, 1 for online mode, 2 for low-power mode,
-     *                  or 3 to reset the radio.
-     * @return true on success; false on any failure.
-     */
-    boolean setRadioMode(int radioMode);
 }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 6015df0..d338857 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -115,8 +115,9 @@
     int DEACTIVATE_REASON_PDP_RESET = 2;
 
     /* NV config radio reset types. */
-    int NV_CONFIG_RESET_FACTORY = 1;
-    int NV_CONFIG_RESET_NV_ONLY = 2;
+    int NV_CONFIG_RELOAD_RESET = 1;
+    int NV_CONFIG_ERASE_RESET = 2;
+    int NV_CONFIG_FACTORY_RESET = 3;
 
 /*
 cat include/telephony/ril.h | \
diff --git a/test-runner/src/junit/runner/FailureDetailView.java b/test-runner/src/junit/runner/FailureDetailView.java
index 1b8365a..c846191 100644
--- a/test-runner/src/junit/runner/FailureDetailView.java
+++ b/test-runner/src/junit/runner/FailureDetailView.java
@@ -12,7 +12,7 @@
 public interface FailureDetailView {
     // The following definition was removed for compatibility with Android
     // libraries.
-    // 	/**
+    //  /**
     //   * Returns the component used to present the TraceView
     //   */
     //  public Component getComponent();
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
index ef885e3..ec02d34 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
@@ -117,7 +117,7 @@
         }
 
         @Override
-	public void execute(CommandStack stack) {
+        public void execute(CommandStack stack) {
             Filter filter = null;
             try {
                 filter = stack.getFactory().createFilterByClassName(mClassName,
diff --git a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
index 25ac2f0..299e6bb 100644
--- a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
+++ b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
@@ -81,11 +81,11 @@
         
         /* Uri Edit Text */
         mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_URI, 
-        		R.string.uri_edit_text_label));
+                R.string.uri_edit_text_label));
         
         /* Email Address Edit Text */
         mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS, 
-        		R.string.email_address_edit_text_label));
+                R.string.email_address_edit_text_label));
         
         /* Email Subject Text */
         mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT, 
@@ -142,7 +142,7 @@
     private View buildEntryView(int inputType, int label) {
 
         
-    	View view = mInflater.inflate(R.layout.sample_edit_text, mParent, false);
+        View view = mInflater.inflate(R.layout.sample_edit_text, mParent, false);
         
         EditText editText = (EditText) view.findViewById(R.id.data);
         editText.setInputType(inputType);
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
index a1c5fd2..2db11c5 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
@@ -24,26 +24,26 @@
 
 public class BigEditTextActivityNonScrollablePanScanTests extends ImfBaseTestCase<BigEditTextActivityNonScrollablePanScan> {
 
-	public final String TAG = "BigEditTextActivityNonScrollablePanScanTests";
-	
+    public final String TAG = "BigEditTextActivityNonScrollablePanScanTests";
+    
     public BigEditTextActivityNonScrollablePanScanTests() {
         super(BigEditTextActivityNonScrollablePanScan.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {
-	    // Give the IME 2 seconds to appear.
-	    pause(2000);
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {
+        // Give the IME 2 seconds to appear.
+        pause(2000);
         
-	    View rootView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getRootView();
-	    View servedView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getDefaultFocusedView();
-	        
-	    assertNotNull(rootView);
-	    assertNotNull(servedView);
-	    
-	    destructiveCheckImeInitialState(rootView, servedView);
-	    
+        View rootView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getRootView();
+        View servedView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getDefaultFocusedView();
+            
+        assertNotNull(rootView);
+        assertNotNull(servedView);
+        
+        destructiveCheckImeInitialState(rootView, servedView);
+        
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
index 2e0b0eb..1050794 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
@@ -24,14 +24,14 @@
 
 public class BigEditTextActivityNonScrollableResizeTests extends ImfBaseTestCase<BigEditTextActivityNonScrollableResize> {
 
-	public final String TAG = "BigEditTextActivityNonScrollableResizeTests";
-	
+    public final String TAG = "BigEditTextActivityNonScrollableResizeTests";
+    
     public BigEditTextActivityNonScrollableResizeTests() {
         super(BigEditTextActivityNonScrollableResize.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
         pause(2000);
         
         View rootView = ((BigEditTextActivityNonScrollableResize) mTargetActivity).getRootView();
@@ -43,6 +43,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
             
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
index d3eefb5..1e848b0 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
@@ -24,14 +24,14 @@
 
 public class BigEditTextActivityScrollablePanScanTests extends ImfBaseTestCase<BigEditTextActivityScrollablePanScan> {
 
-	public final String TAG = "BigEditTextActivityScrollablePanScanTests";
-	
+    public final String TAG = "BigEditTextActivityScrollablePanScanTests";
+    
     public BigEditTextActivityScrollablePanScanTests() {
         super(BigEditTextActivityScrollablePanScan.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
         pause(2000);
         
         View rootView = ((BigEditTextActivityScrollablePanScan) mTargetActivity).getRootView();
@@ -43,6 +43,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
             
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
index 5c40e6d..de607d6 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
@@ -24,15 +24,15 @@
 
 public class BigEditTextActivityScrollableResizeTests extends ImfBaseTestCase<BigEditTextActivityScrollableResize> {
 
-	public final String TAG = "BigEditTextActivityScrollableResizeTests";
-	
+    public final String TAG = "BigEditTextActivityScrollableResizeTests";
+    
     public BigEditTextActivityScrollableResizeTests() {
         super(BigEditTextActivityScrollableResize.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {       
-	    // Give the IME 2 seconds to appear.
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {       
+        // Give the IME 2 seconds to appear.
         pause(2000);
         
         View rootView = ((BigEditTextActivityScrollableResize) mTargetActivity).getRootView();
@@ -44,6 +44,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
             
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
index 9a93133..c521905 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
@@ -24,14 +24,14 @@
 
 public class BottomEditTextActivityPanScanTests extends ImfBaseTestCase<BottomEditTextActivityPanScan> {
 
-	public final String TAG = "BottomEditTextActivityPanScanTests";
-	
+    public final String TAG = "BottomEditTextActivityPanScanTests";
+    
     public BottomEditTextActivityPanScanTests() {
         super(BottomEditTextActivityPanScan.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {
         // Give the IME 2 seconds to appear.
         pause(2000);
         
@@ -44,6 +44,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
         
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java b/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
index ae900c3..f6f97b5 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
@@ -23,8 +23,8 @@
 
 public class ButtonActivityTest extends ImfBaseTestCase<ButtonActivity> {
 
-	final public String TAG = "ButtonActivityTest";
-	
+    final public String TAG = "ButtonActivityTest";
+    
     public ButtonActivityTest() {
         super(ButtonActivity.class);
     }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
index ed5b0c9..6147d3c 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
@@ -22,21 +22,21 @@
 
 public class OneEditTextActivityNotSelectedTests extends ImfBaseTestCase<OneEditTextActivityNotSelected> {
 
-	public final String TAG = "OneEditTextActivityNotSelectedTests";
-	
+    public final String TAG = "OneEditTextActivityNotSelectedTests";
+    
     public OneEditTextActivityNotSelectedTests() {
         super(OneEditTextActivityNotSelected.class);
     }
     
-	@LargeTest
-	public void testSoftKeyboardNoAutoPop() {
-	    
-	    // Give the IME 2 seconds to appear.
-	    pause(2000);
-	    
-	    assertFalse(mImm.isAcceptingText());
-	    
-	    View rootView = ((OneEditTextActivityNotSelected) mTargetActivity).getRootView();
+    @LargeTest
+    public void testSoftKeyboardNoAutoPop() {
+        
+        // Give the IME 2 seconds to appear.
+        pause(2000);
+        
+        assertFalse(mImm.isAcceptingText());
+        
+        View rootView = ((OneEditTextActivityNotSelected) mTargetActivity).getRootView();
         View servedView = ((OneEditTextActivityNotSelected) mTargetActivity).getDefaultFocusedView();
         
         assertNotNull(rootView);
@@ -45,6 +45,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
         
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
index cceed16..3bd35a7 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
@@ -37,7 +37,7 @@
     }
 
     @SmallTest
-	public void testREORDER_TASKS() {
+    public void testREORDER_TASKS() {
         try {
             mAm.moveTaskToFront(0, 0, null);
             fail("IActivityManager.moveTaskToFront did not throw SecurityException as"
@@ -67,7 +67,7 @@
         } catch (RemoteException e) {
             fail("Unexpected remote exception");
         }
-	}
+    }
 
     @SmallTest
     public void testCHANGE_CONFIGURATION() {
diff --git a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
index 4dfe0fe..322b853 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
@@ -32,7 +32,7 @@
  */
 public class ServiceManagerPermissionTests extends TestCase {
     @SmallTest
-	public void testAddService() {
+    public void testAddService() {
         try {
             // The security in the service manager is that you can't replace
             // a service that is already published.
@@ -43,7 +43,7 @@
         } catch (SecurityException e) {
             // expected
         }
-	}
+    }
 
     @SmallTest
     public void testSetPermissionController() {
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index df32ee1..6f5788a 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -41,7 +41,7 @@
     }
 
     @SmallTest
-	public void testMANAGE_APP_TOKENS() {
+    public void testMANAGE_APP_TOKENS() {
         try {
             mWm.pauseKeyDispatching(null);
             fail("IWindowManager.pauseKeyDispatching did not throw SecurityException as"