am e7866887: docs: M Preview landing page

* commit 'e78668876ed0dfc25fac604b5048509f72d92c53':
  docs: M Preview landing page
diff --git a/api/current.txt b/api/current.txt
index 35423fd..7737487 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -547,6 +547,7 @@
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
     field public static final int extraTension = 16843371; // 0x101026b
+    field public static final int extractNativeLibs = 16843990; // 0x10104d6
     field public static final int factor = 16843219; // 0x10101d3
     field public static final int fadeDuration = 16843384; // 0x1010278
     field public static final int fadeEnabled = 16843390; // 0x101027e
@@ -8366,6 +8367,7 @@
     field public static final int FLAG_ALLOW_TASK_REPARENTING = 32; // 0x20
     field public static final int FLAG_DEBUGGABLE = 2; // 0x2
     field public static final int FLAG_EXTERNAL_STORAGE = 262144; // 0x40000
+    field public static final int FLAG_EXTRACT_NATIVE_LIBS = 268435456; // 0x10000000
     field public static final int FLAG_FACTORY_TEST = 16; // 0x10
     field public static final int FLAG_FULL_BACKUP_ONLY = 67108864; // 0x4000000
     field public static final int FLAG_HAS_CODE = 4; // 0x4
@@ -16994,6 +16996,7 @@
   }
 
   public final class IpPrefix implements android.os.Parcelable {
+    method public boolean contains(java.net.InetAddress);
     method public int describeContents();
     method public java.net.InetAddress getAddress();
     method public int getPrefixLength();
@@ -17513,7 +17516,7 @@
     method public static android.net.http.HttpResponseCache getInstalled();
     method public int getNetworkCount();
     method public int getRequestCount();
-    method public static android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException;
+    method public static synchronized android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException;
     method public long maxSize();
     method public java.net.CacheRequest put(java.net.URI, java.net.URLConnection) throws java.io.IOException;
     method public long size();
@@ -18440,6 +18443,7 @@
 
   public final class NfcEvent {
     field public final android.nfc.NfcAdapter nfcAdapter;
+    field public final byte peerLlcpVersion;
   }
 
   public final class NfcManager {
@@ -26514,6 +26518,7 @@
   public class Script extends android.renderscript.BaseObj {
     method public void bindAllocation(android.renderscript.Allocation, int);
     method protected android.renderscript.Script.FieldID createFieldID(int, android.renderscript.Element);
+    method protected android.renderscript.Script.InvokeID createInvokeID(int);
     method protected android.renderscript.Script.KernelID createKernelID(int, int, android.renderscript.Element, android.renderscript.Element);
     method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
     method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
@@ -26554,6 +26559,9 @@
   public static final class Script.FieldID extends android.renderscript.BaseObj {
   }
 
+  public static final class Script.InvokeID extends android.renderscript.BaseObj {
+  }
+
   public static final class Script.KernelID extends android.renderscript.BaseObj {
   }
 
@@ -26578,12 +26586,19 @@
   }
 
   public final class ScriptGroup extends android.renderscript.BaseObj {
-    method public void execute();
-    method public void setInput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
-    method public void setOutput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
+    method public java.lang.Object[] execute(java.lang.Object...);
+    method public deprecated void execute();
+    method public deprecated void setInput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
+    method public deprecated void setOutput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
   }
 
-  public static final class ScriptGroup.Builder {
+  public static final class ScriptGroup.Binding {
+    ctor public ScriptGroup.Binding(android.renderscript.Script.FieldID, java.lang.Object);
+    method public android.renderscript.Script.FieldID getField();
+    method public java.lang.Object getValue();
+  }
+
+  public static final deprecated class ScriptGroup.Builder {
     ctor public ScriptGroup.Builder(android.renderscript.RenderScript);
     method public android.renderscript.ScriptGroup.Builder addConnection(android.renderscript.Type, android.renderscript.Script.KernelID, android.renderscript.Script.FieldID);
     method public android.renderscript.ScriptGroup.Builder addConnection(android.renderscript.Type, android.renderscript.Script.KernelID, android.renderscript.Script.KernelID);
@@ -26591,6 +26606,25 @@
     method public android.renderscript.ScriptGroup create();
   }
 
+  public static final class ScriptGroup.Builder2 {
+    ctor public ScriptGroup.Builder2(android.renderscript.RenderScript);
+    method public android.renderscript.ScriptGroup.Input addInput();
+    method public android.renderscript.ScriptGroup.Closure addInvoke(android.renderscript.Script.InvokeID, java.lang.Object...);
+    method public android.renderscript.ScriptGroup.Closure addKernel(android.renderscript.Script.KernelID, android.renderscript.Type, java.lang.Object...);
+    method public android.renderscript.ScriptGroup create(java.lang.String, android.renderscript.ScriptGroup.Future...);
+  }
+
+  public static final class ScriptGroup.Closure extends android.renderscript.BaseObj {
+    method public android.renderscript.ScriptGroup.Future getGlobal(android.renderscript.Script.FieldID);
+    method public android.renderscript.ScriptGroup.Future getReturn();
+  }
+
+  public static final class ScriptGroup.Future {
+  }
+
+  public static final class ScriptGroup.Input {
+  }
+
   public abstract class ScriptIntrinsic extends android.renderscript.Script {
   }
 
@@ -41517,7 +41551,7 @@
     method public static double nextUp(double);
     method public static float nextUp(float);
     method public static double pow(double, double);
-    method public static synchronized double random();
+    method public static double random();
     method public static double rint(double);
     method public static long round(double);
     method public static int round(float);
diff --git a/api/system-current.txt b/api/system-current.txt
index fe0e2e4..1041cb7 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -617,6 +617,7 @@
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
     field public static final int extraTension = 16843371; // 0x101026b
+    field public static final int extractNativeLibs = 16843990; // 0x10104d6
     field public static final int factor = 16843219; // 0x10101d3
     field public static final int fadeDuration = 16843384; // 0x1010278
     field public static final int fadeEnabled = 16843390; // 0x101027e
@@ -8614,6 +8615,7 @@
     field public static final int FLAG_ALLOW_TASK_REPARENTING = 32; // 0x20
     field public static final int FLAG_DEBUGGABLE = 2; // 0x2
     field public static final int FLAG_EXTERNAL_STORAGE = 262144; // 0x40000
+    field public static final int FLAG_EXTRACT_NATIVE_LIBS = 268435456; // 0x10000000
     field public static final int FLAG_FACTORY_TEST = 16; // 0x10
     field public static final int FLAG_FULL_BACKUP_ONLY = 67108864; // 0x4000000
     field public static final int FLAG_HAS_CODE = 4; // 0x4
@@ -18257,6 +18259,7 @@
   }
 
   public final class IpPrefix implements android.os.Parcelable {
+    method public boolean contains(java.net.InetAddress);
     method public int describeContents();
     method public java.net.InetAddress getAddress();
     method public int getPrefixLength();
@@ -18841,7 +18844,7 @@
     method public static android.net.http.HttpResponseCache getInstalled();
     method public int getNetworkCount();
     method public int getRequestCount();
-    method public static android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException;
+    method public static synchronized android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException;
     method public long maxSize();
     method public java.net.CacheRequest put(java.net.URI, java.net.URLConnection) throws java.io.IOException;
     method public long size();
@@ -20024,6 +20027,7 @@
 
   public final class NfcEvent {
     field public final android.nfc.NfcAdapter nfcAdapter;
+    field public final byte peerLlcpVersion;
   }
 
   public final class NfcManager {
@@ -28113,6 +28117,7 @@
   public class Script extends android.renderscript.BaseObj {
     method public void bindAllocation(android.renderscript.Allocation, int);
     method protected android.renderscript.Script.FieldID createFieldID(int, android.renderscript.Element);
+    method protected android.renderscript.Script.InvokeID createInvokeID(int);
     method protected android.renderscript.Script.KernelID createKernelID(int, int, android.renderscript.Element, android.renderscript.Element);
     method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
     method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
@@ -28153,6 +28158,9 @@
   public static final class Script.FieldID extends android.renderscript.BaseObj {
   }
 
+  public static final class Script.InvokeID extends android.renderscript.BaseObj {
+  }
+
   public static final class Script.KernelID extends android.renderscript.BaseObj {
   }
 
@@ -28177,12 +28185,19 @@
   }
 
   public final class ScriptGroup extends android.renderscript.BaseObj {
-    method public void execute();
-    method public void setInput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
-    method public void setOutput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
+    method public java.lang.Object[] execute(java.lang.Object...);
+    method public deprecated void execute();
+    method public deprecated void setInput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
+    method public deprecated void setOutput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
   }
 
-  public static final class ScriptGroup.Builder {
+  public static final class ScriptGroup.Binding {
+    ctor public ScriptGroup.Binding(android.renderscript.Script.FieldID, java.lang.Object);
+    method public android.renderscript.Script.FieldID getField();
+    method public java.lang.Object getValue();
+  }
+
+  public static final deprecated class ScriptGroup.Builder {
     ctor public ScriptGroup.Builder(android.renderscript.RenderScript);
     method public android.renderscript.ScriptGroup.Builder addConnection(android.renderscript.Type, android.renderscript.Script.KernelID, android.renderscript.Script.FieldID);
     method public android.renderscript.ScriptGroup.Builder addConnection(android.renderscript.Type, android.renderscript.Script.KernelID, android.renderscript.Script.KernelID);
@@ -28190,6 +28205,25 @@
     method public android.renderscript.ScriptGroup create();
   }
 
+  public static final class ScriptGroup.Builder2 {
+    ctor public ScriptGroup.Builder2(android.renderscript.RenderScript);
+    method public android.renderscript.ScriptGroup.Input addInput();
+    method public android.renderscript.ScriptGroup.Closure addInvoke(android.renderscript.Script.InvokeID, java.lang.Object...);
+    method public android.renderscript.ScriptGroup.Closure addKernel(android.renderscript.Script.KernelID, android.renderscript.Type, java.lang.Object...);
+    method public android.renderscript.ScriptGroup create(java.lang.String, android.renderscript.ScriptGroup.Future...);
+  }
+
+  public static final class ScriptGroup.Closure extends android.renderscript.BaseObj {
+    method public android.renderscript.ScriptGroup.Future getGlobal(android.renderscript.Script.FieldID);
+    method public android.renderscript.ScriptGroup.Future getReturn();
+  }
+
+  public static final class ScriptGroup.Future {
+  }
+
+  public static final class ScriptGroup.Input {
+  }
+
   public abstract class ScriptIntrinsic extends android.renderscript.Script {
   }
 
@@ -44055,7 +44089,7 @@
     method public static double nextUp(double);
     method public static float nextUp(float);
     method public static double pow(double, double);
-    method public static synchronized double random();
+    method public static double random();
     method public static double rint(double);
     method public static long round(double);
     method public static int round(float);
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index dd5e0ea..ce6d7b5 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -56,6 +56,7 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_EXECUTABLES)/asan
 LOCAL_MODULE_STEM := app_process
 LOCAL_ADDRESS_SANITIZER := true
+LOCAL_CLANG := true
 
 LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
 
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 92762c3..5055b29 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -1082,7 +1082,8 @@
         public Node clone() {
             try {
                 Node node = (Node) super.clone();
-                node.animation = (Animator) animation.clone();
+                node.animation = animation.clone();
+                node.done = false;
                 return node;
             } catch (CloneNotSupportedException e) {
                throw new AssertionError();
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 9709555..2be3e23 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -1389,6 +1389,12 @@
         anim.mInitialized = false;
         anim.mPlayingState = STOPPED;
         anim.mStartedDelay = false;
+        anim.mStarted = false;
+        anim.mRunning = false;
+        anim.mPaused = false;
+        anim.mResumed = false;
+        anim.mStartListenersCalled = false;
+
         PropertyValuesHolder[] oldValues = mValues;
         if (oldValues != null) {
             int numValues = oldValues.length;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 6cbfee7..850bc1f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -257,23 +257,18 @@
         }
     }
 
-    static final class AcquiringProviderRecord {
-        IActivityManager.ContentProviderHolder holder;
-        boolean acquiring = true;
-        int requests = 1;
-        // Set if there was a runtime exception when trying to acquire the provider.
-        RuntimeException runtimeException = null;
-    }
-
     // The lock of mProviderMap protects the following variables.
-    final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap = new ArrayMap<>();
-    final ArrayMap<ProviderKey, AcquiringProviderRecord> mAcquiringProviderMap = new ArrayMap<>();
-    final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap = new ArrayMap<>();
-    final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders = new ArrayMap<>();
-    final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName = new ArrayMap<>();
+    final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
+        = new ArrayMap<ProviderKey, ProviderClientRecord>();
+    final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap
+        = new ArrayMap<IBinder, ProviderRefCount>();
+    final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders
+        = new ArrayMap<IBinder, ProviderClientRecord>();
+    final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
+            = new ArrayMap<ComponentName, ProviderClientRecord>();
 
     final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
-            = new ArrayMap<>();
+        = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
 
     final GcIdler mGcIdler = new GcIdler();
     boolean mGcIdlerScheduled = false;
@@ -350,7 +345,7 @@
         }
     }
 
-    static final class ProviderClientRecord {
+    final class ProviderClientRecord {
         final String[] mNames;
         final IContentProvider mProvider;
         final ContentProvider mLocalProvider;
@@ -4650,74 +4645,23 @@
 
     public final IContentProvider acquireProvider(
             Context c, String auth, int userId, boolean stable) {
-        final ProviderKey key = new ProviderKey(auth, userId);
-        final IContentProvider provider = acquireExistingProvider(c, key, stable);
+        final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
         if (provider != null) {
             return provider;
         }
-        AcquiringProviderRecord r;
-        boolean first = false;
-        synchronized (mAcquiringProviderMap) {
-            r = mAcquiringProviderMap.get(key);
-            if (r == null) {
-                r = new AcquiringProviderRecord();
-                mAcquiringProviderMap.put(key, r);
-                first = true;
-            } else {
-                r.requests++;
-            }
-        }
 
+        // There is a possible race here.  Another thread may try to acquire
+        // the same provider at the same time.  When this happens, we want to ensure
+        // that the first one wins.
+        // Note that we cannot hold the lock while acquiring and installing the
+        // provider since it might take a long time to run and it could also potentially
+        // be re-entrant in the case where the provider is in the same process.
         IActivityManager.ContentProviderHolder holder = null;
         try {
-            if (first) {
-                // Multiple threads may try to acquire the same provider at the same time.
-                // When this happens, we only let the first one really gets provider.
-                // Other threads just wait for its result.
-                // Note that we cannot hold the lock while acquiring and installing the
-                // provider since it might take a long time to run and it could also potentially
-                // be re-entrant in the case where the provider is in the same process.
-                holder = ActivityManagerNative.getDefault().getContentProvider(
-                        getApplicationThread(), auth, userId, stable);
-            } else {
-                synchronized (r) {
-                    while (r.acquiring) {
-                        try {
-                            r.wait();
-                        } catch (InterruptedException e) {
-                        }
-                    }
-                    holder = r.holder;
-                }
-            }
+            holder = ActivityManagerNative.getDefault().getContentProvider(
+                    getApplicationThread(), auth, userId, stable);
         } catch (RemoteException ex) {
-        } catch (RuntimeException e) {
-            synchronized (r) {
-                r.runtimeException = e;
-            }
-        } finally {
-            if (first) {
-                synchronized (r) {
-                    r.holder = holder;
-                    r.acquiring = false;
-                    r.notifyAll();
-                }
-            }
-
-            synchronized (mAcquiringProviderMap) {
-                if (--r.requests == 0) {
-                    mAcquiringProviderMap.remove(key);
-                }
-            }
-
-            if (r.runtimeException != null) {
-                // Was set when the first thread tried to acquire the provider,
-                // but we should make sure it is thrown for all threads trying to
-                // acquire the provider.
-                throw r.runtimeException;
-            }
         }
-
         if (holder == null) {
             Slog.e(TAG, "Failed to find provider info for " + auth);
             return null;
@@ -4800,12 +4744,8 @@
 
     public final IContentProvider acquireExistingProvider(
             Context c, String auth, int userId, boolean stable) {
-        return acquireExistingProvider(c, new ProviderKey(auth, userId), stable);
-    }
-
-    final IContentProvider acquireExistingProvider(
-            Context c, ProviderKey key, boolean stable) {
         synchronized (mProviderMap) {
+            final ProviderKey key = new ProviderKey(auth, userId);
             final ProviderClientRecord pr = mProviderMap.get(key);
             if (pr == null) {
                 return null;
@@ -4816,7 +4756,7 @@
             if (!jBinder.isBinderAlive()) {
                 // The hosting process of the provider has died; we can't
                 // use this one.
-                Log.i(TAG, "Acquiring provider " + key.authority + " for user " +  key.userId
+                Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
                         + ": existing object's process dead");
                 handleUnstableProviderDiedLocked(jBinder, true);
                 return null;
@@ -5138,12 +5078,18 @@
                     if (DEBUG_PROVIDER) {
                         Slog.v(TAG, "installProvider: lost the race, updating ref count");
                     }
-                    // The provider has already been installed, so we need
-                    // to increase reference count to the existing one, but
-                    // only if release is needed (that is, it is not running
-                    // in the system process or local to the process).
+                    // We need to transfer our new reference to the existing
+                    // ref count, releasing the old one...  but only if
+                    // release is needed (that is, it is not running in the
+                    // system process).
                     if (!noReleaseNeeded) {
                         incProviderRefLocked(prc, stable);
+                        try {
+                            ActivityManagerNative.getDefault().removeContentProvider(
+                                    holder.connection, stable);
+                        } catch (RemoteException e) {
+                            //do nothing content provider object is dead any way
+                        }
                     }
                 } else {
                     ProviderClientRecord client = installProviderAuthoritiesLocked(
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index 8e86824..7eb4b2f 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -221,10 +221,10 @@
             int appWidgetId, int intentFlags, int requestCode, @Nullable Bundle options) {
         try {
             IntentSender intentSender = sService.createAppWidgetConfigIntentSender(
-                    mContextOpPackageName, appWidgetId, intentFlags);
+                    mContextOpPackageName, appWidgetId);
             if (intentSender != null) {
-                activity.startIntentSenderForResult(intentSender, requestCode, null, 0, 0, 0,
-                        options);
+                activity.startIntentSenderForResult(intentSender, requestCode, null, 0,
+                        intentFlags, intentFlags, options);
             } else {
                 throw new ActivityNotFoundException();
             }
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index b3c558b..4a087da 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -346,6 +346,11 @@
     public static final int FLAG_USES_CLEARTEXT_TRAFFIC = 1<<27;
 
     /**
+     * When set installer extracts native libs from .apk files.
+     */
+    public static final int FLAG_EXTRACT_NATIVE_LIBS = 1<<28;
+
+    /**
      * Value for {@link #flags}: true if code from this application will need to be
      * loaded into other applications' processes. On devices that support multiple
      * instruction sets, this implies the code might be loaded into a process that's
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 5320929..53aa6ff 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -268,6 +268,7 @@
 
         public final boolean coreApp;
         public final boolean multiArch;
+        public final boolean extractNativeLibs;
 
         public PackageLite(String codePath, ApkLite baseApk, String[] splitNames,
                 String[] splitCodePaths, int[] splitRevisionCodes) {
@@ -283,6 +284,7 @@
             this.splitRevisionCodes = splitRevisionCodes;
             this.coreApp = baseApk.coreApp;
             this.multiArch = baseApk.multiArch;
+            this.extractNativeLibs = baseApk.extractNativeLibs;
         }
 
         public List<String> getAllCodePaths() {
@@ -309,10 +311,12 @@
         public final Signature[] signatures;
         public final boolean coreApp;
         public final boolean multiArch;
+        public final boolean extractNativeLibs;
 
         public ApkLite(String codePath, String packageName, String splitName, int versionCode,
                 int revisionCode, int installLocation, List<VerifierInfo> verifiers,
-                Signature[] signatures, boolean coreApp, boolean multiArch) {
+                Signature[] signatures, boolean coreApp, boolean multiArch,
+                boolean extractNativeLibs) {
             this.codePath = codePath;
             this.packageName = packageName;
             this.splitName = splitName;
@@ -323,6 +327,7 @@
             this.signatures = signatures;
             this.coreApp = coreApp;
             this.multiArch = multiArch;
+            this.extractNativeLibs = extractNativeLibs;
         }
     }
 
@@ -1269,6 +1274,7 @@
         int revisionCode = 0;
         boolean coreApp = false;
         boolean multiArch = false;
+        boolean extractNativeLibs = true;
 
         for (int i = 0; i < attrs.getAttributeCount(); i++) {
             final String attr = attrs.getAttributeName(i);
@@ -1307,14 +1313,17 @@
                     final String attr = attrs.getAttributeName(i);
                     if ("multiArch".equals(attr)) {
                         multiArch = attrs.getAttributeBooleanValue(i, false);
-                        break;
+                    }
+                    if ("extractNativeLibs".equals(attr)) {
+                        extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
                     }
                 }
             }
         }
 
         return new ApkLite(codePath, packageSplit.first, packageSplit.second, versionCode,
-                revisionCode, installLocation, verifiers, signatures, coreApp, multiArch);
+                revisionCode, installLocation, verifiers, signatures, coreApp, multiArch,
+                extractNativeLibs);
     }
 
     /**
@@ -2567,6 +2576,12 @@
             ai.flags |= ApplicationInfo.FLAG_MULTIARCH;
         }
 
+        if (sa.getBoolean(
+                com.android.internal.R.styleable.AndroidManifestApplication_extractNativeLibs,
+                true)) {
+            ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
+        }
+
         String str;
         str = sa.getNonConfigurationString(
                 com.android.internal.R.styleable.AndroidManifestApplication_permission, 0);
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 24a7d33..3cda39a 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -91,8 +91,6 @@
     private static final String[] EMPTY_STRING_ARRAY = new String[0];
     private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
 
-    private static final Pattern TRIM_SQL_PATTERN = Pattern.compile("[\\s]*\\n+[\\s]*");
-
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
     private final SQLiteConnectionPool mPool;
@@ -1203,7 +1201,11 @@
     }
 
     private static String trimSqlForDisplay(String sql) {
-        return TRIM_SQL_PATTERN.matcher(sql).replaceAll(" ");
+        // Note: Creating and caching a regular expression is expensive at preload-time
+        //       and stops compile-time initialization. This pattern is only used when
+        //       dumping the connection, which is a rare (mainly error) case. So:
+        //       DO NOT CACHE.
+        return sql.replaceAll("[\\s]*\\n+[\\s]*", " ");
     }
 
     /**
@@ -1437,9 +1439,6 @@
     }
 
     private static final class Operation {
-        private static final SimpleDateFormat sDateFormat =
-                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
-
         public long mStartTime;
         public long mEndTime;
         public String mKind;
@@ -1494,7 +1493,11 @@
         }
 
         private String getFormattedStartTime() {
-            return sDateFormat.format(new Date(mStartTime));
+            // Note: SimpleDateFormat is not thread-safe, cannot be compile-time created, and is
+            //       relatively expensive to create during preloading. This method is only used
+            //       when dumping a connection, which is a rare (mainly error) case. So:
+            //       DO NOT CACHE.
+            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(mStartTime));
         }
     }
 }
diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java
index b268986..6b4f2d5 100644
--- a/core/java/android/net/IpPrefix.java
+++ b/core/java/android/net/IpPrefix.java
@@ -170,6 +170,21 @@
     }
 
     /**
+     * Determines whether the prefix contains the specified address.
+     *
+     * @param address An {@link InetAddress} to test.
+     * @return {@code true} if the prefix covers the given address.
+     */
+    public boolean contains(InetAddress address) {
+        byte[] addrBytes = (address == null) ? null : address.getAddress();
+        if (addrBytes == null || addrBytes.length != this.address.length) {
+            return false;
+        }
+        NetworkUtils.maskRawAddress(addrBytes, prefixLength);
+        return Arrays.equals(this.address, addrBytes);
+    }
+
+    /**
      * Returns a string representation of this {@code IpPrefix}.
      *
      * @return a string such as {@code "192.0.2.0/24"} or {@code "2001:db8:1:2::/64"}.
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index cfd20a0..90a2460 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -367,13 +367,7 @@
      * @return {@code true} if the destination and prefix length cover the given address.
      */
     public boolean matches(InetAddress destination) {
-        if (destination == null) return false;
-
-        // match the route destination and destination with prefix length
-        InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
-                mDestination.getPrefixLength());
-
-        return mDestination.getAddress().equals(dstNet);
+        return mDestination.contains(destination);
     }
 
     /**
diff --git a/core/java/android/nfc/IAppCallback.aidl b/core/java/android/nfc/IAppCallback.aidl
index 9599308..c027d54 100644
--- a/core/java/android/nfc/IAppCallback.aidl
+++ b/core/java/android/nfc/IAppCallback.aidl
@@ -24,7 +24,7 @@
  */
 interface IAppCallback
 {
-    BeamShareData createBeamShareData();
-    void onNdefPushComplete();
+    BeamShareData createBeamShareData(byte peerLlcpVersion);
+    void onNdefPushComplete(byte peerLlcpVersion);
     void onTagDiscovered(in Tag tag);
 }
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index d009295..76bd0ec 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -46,7 +46,6 @@
     static final Boolean DBG = false;
 
     final NfcAdapter mAdapter;
-    final NfcEvent mDefaultEvent;  // cached NfcEvent (its currently always the same)
 
     // All objects in the lists are protected by this
     final List<NfcApplicationState> mApps;  // Application(s) that have NFC state. Usually one
@@ -200,7 +199,6 @@
         mAdapter = adapter;
         mActivities = new LinkedList<NfcActivityState>();
         mApps = new ArrayList<NfcApplicationState>(1);  // Android VM usually has 1 app
-        mDefaultEvent = new NfcEvent(mAdapter);
     }
 
     public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
@@ -354,13 +352,14 @@
 
     /** Callback from NFC service, usually on binder thread */
     @Override
-    public BeamShareData createBeamShareData() {
+    public BeamShareData createBeamShareData(byte peerLlcpVersion) {
         NfcAdapter.CreateNdefMessageCallback ndefCallback;
         NfcAdapter.CreateBeamUrisCallback urisCallback;
         NdefMessage message;
         Activity activity;
         Uri[] uris;
         int flags;
+        NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion);
         synchronized (NfcActivityManager.this) {
             NfcActivityState state = findResumedActivityState();
             if (state == null) return null;
@@ -375,10 +374,10 @@
 
         // Make callbacks without lock
         if (ndefCallback != null) {
-            message  = ndefCallback.createNdefMessage(mDefaultEvent);
+            message  = ndefCallback.createNdefMessage(event);
         }
         if (urisCallback != null) {
-            uris = urisCallback.createBeamUris(mDefaultEvent);
+            uris = urisCallback.createBeamUris(event);
             if (uris != null) {
                 ArrayList<Uri> validUris = new ArrayList<Uri>();
                 for (Uri uri : uris) {
@@ -412,7 +411,7 @@
 
     /** Callback from NFC service, usually on binder thread */
     @Override
-    public void onNdefPushComplete() {
+    public void onNdefPushComplete(byte peerLlcpVersion) {
         NfcAdapter.OnNdefPushCompleteCallback callback;
         synchronized (NfcActivityManager.this) {
             NfcActivityState state = findResumedActivityState();
@@ -420,10 +419,10 @@
 
             callback = state.onNdefPushCompleteCallback;
         }
-
+        NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion);
         // Make callback without lock
         if (callback != null) {
-            callback.onNdefPushComplete(mDefaultEvent);
+            callback.onNdefPushComplete(event);
         }
     }
 
diff --git a/core/java/android/nfc/NfcEvent.java b/core/java/android/nfc/NfcEvent.java
index 860700a..cf1d71a 100644
--- a/core/java/android/nfc/NfcEvent.java
+++ b/core/java/android/nfc/NfcEvent.java
@@ -38,7 +38,14 @@
      */
     public final NfcAdapter nfcAdapter;
 
-    NfcEvent(NfcAdapter nfcAdapter) {
+    /**
+     * The LLCP version of the peer associated with the NFC event.
+     * The major version is in the top nibble, the minor version is in the bottom nibble.
+     */
+    public final byte peerLlcpVersion;
+
+    NfcEvent(NfcAdapter nfcAdapter, byte peerLlcpVersion) {
         this.nfcAdapter = nfcAdapter;
+        this.peerLlcpVersion = peerLlcpVersion;
     }
 }
diff --git a/core/java/android/security/keymaster/KeymasterArgument.java b/core/java/android/security/keymaster/KeymasterArgument.java
index 9a1c894..9adde35 100644
--- a/core/java/android/security/keymaster/KeymasterArgument.java
+++ b/core/java/android/security/keymaster/KeymasterArgument.java
@@ -42,6 +42,7 @@
                         case KeymasterDefs.KM_INT_REP:
                             return new KeymasterIntArgument(tag, in);
                         case KeymasterDefs.KM_LONG:
+                        case KeymasterDefs.KM_LONG_REP:
                             return new KeymasterLongArgument(tag, in);
                         case KeymasterDefs.KM_DATE:
                             return new KeymasterDateArgument(tag, in);
diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java
index 8ed288c..82f65c7 100644
--- a/core/java/android/security/keymaster/KeymasterArguments.java
+++ b/core/java/android/security/keymaster/KeymasterArguments.java
@@ -63,6 +63,12 @@
         }
     }
 
+    public void addLongs(int tag, long... values) {
+        for (long value : values) {
+            addLong(tag, value);
+        }
+    }
+
     public void addBoolean(int tag) {
         mArguments.add(new KeymasterBooleanArgument(tag));
     }
@@ -111,8 +117,13 @@
     }
 
     public long getLong(int tag, long defaultValue) {
-        if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_LONG) {
-            throw new IllegalArgumentException("Tag is not a long type: " + tag);
+        switch (KeymasterDefs.getTagType(tag)) {
+            case KeymasterDefs.KM_LONG:
+                break; // Accepted type
+            case KeymasterDefs.KM_LONG_REP:
+                throw new IllegalArgumentException("Repeatable tags must use getLongs: " + tag);
+            default:
+                throw new IllegalArgumentException("Tag is not a long type: " + tag);
         }
         KeymasterArgument arg = getArgumentByTag(tag);
         if (arg == null) {
@@ -175,6 +186,19 @@
         return values;
     }
 
+    public List<Long> getLongs(int tag) {
+        if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_LONG_REP) {
+            throw new IllegalArgumentException("Tag is not a repeating long: " + tag);
+        }
+        List<Long> values = new ArrayList<Long>();
+        for (KeymasterArgument arg : mArguments) {
+            if (arg.tag == tag) {
+                values.add(((KeymasterLongArgument) arg).value);
+            }
+        }
+        return values;
+    }
+
     public int size() {
         return mArguments.size();
     }
diff --git a/core/java/android/security/keymaster/KeymasterLongArgument.java b/core/java/android/security/keymaster/KeymasterLongArgument.java
index d51d7e6..e04ce5d 100644
--- a/core/java/android/security/keymaster/KeymasterLongArgument.java
+++ b/core/java/android/security/keymaster/KeymasterLongArgument.java
@@ -29,6 +29,7 @@
         super(tag);
         switch (KeymasterDefs.getTagType(tag)) {
             case KeymasterDefs.KM_LONG:
+            case KeymasterDefs.KM_LONG_REP:
                 break; // OK.
             default:
                 throw new IllegalArgumentException("Bad long tag " + tag);
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 1674950..016541f 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -17,6 +17,7 @@
 package android.service.wallpaper;
 
 import android.content.res.TypedArray;
+import android.graphics.Canvas;
 import android.os.SystemProperties;
 import android.view.WindowInsets;
 
@@ -185,6 +186,7 @@
 
         DisplayManager mDisplayManager;
         Display mDisplay;
+        private int mDisplayState;
 
         final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() {
             {
@@ -228,7 +230,19 @@
                 throw new UnsupportedOperationException(
                         "Wallpapers do not support keep screen on");
             }
-            
+
+            @Override
+            public Canvas lockCanvas() {
+                if (mDisplayState == Display.STATE_DOZE
+                        || mDisplayState == Display.STATE_DOZE_SUSPEND) {
+                    try {
+                        mSession.pokeDrawLock(mWindow);
+                    } catch (RemoteException e) {
+                        // System server died, can be ignored.
+                    }
+                }
+                return super.lockCanvas();
+            }
         };
 
         final class WallpaperInputEventReceiver extends InputEventReceiver {
@@ -831,9 +845,12 @@
             
             mWindow.setSession(mSession);
 
+            mLayout.packageName = getPackageName();
+
             mDisplayManager = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE);
             mDisplayManager.registerDisplayListener(mDisplayListener, mCaller.getHandler());
             mDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
+            mDisplayState = mDisplay.getState();
 
             if (DEBUG) Log.v(TAG, "onCreate(): " + this);
             onCreate(mSurfaceHolder);
@@ -873,8 +890,8 @@
 
         void reportVisibility() {
             if (!mDestroyed) {
-                boolean visible = mVisible
-                        & mDisplay != null && mDisplay.getState() != Display.STATE_OFF;
+                mDisplayState = mDisplay == null ? Display.STATE_UNKNOWN : mDisplay.getState();
+                boolean visible = mVisible && mDisplayState != Display.STATE_OFF;
                 if (mReportedVisible != visible) {
                     mReportedVisible = visible;
                     if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index a237afd..27304f5 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -1040,14 +1040,10 @@
             return methods;
         }
 
-        final ArrayList<Method> declaredMethods = new ArrayList();
-        klass.getDeclaredMethodsUnchecked(false, declaredMethods);
+        methods = klass.getDeclaredMethodsUnchecked(false);
 
         final ArrayList<Method> foundMethods = new ArrayList<Method>();
-        final int count = declaredMethods.size();
-        for (int i = 0; i < count; i++) {
-            final Method method = declaredMethods.get(i);
-
+        for (final Method method : methods) {
             // Ensure the method return and parameter types can be resolved.
             try {
                 method.getReturnType();
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
index 008d38b..faac392 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -41,8 +41,7 @@
     void deleteAllHosts();
     RemoteViews getAppWidgetViews(String callingPackage, int appWidgetId);
     int[] getAppWidgetIdsForHost(String callingPackage, int hostId);
-    IntentSender createAppWidgetConfigIntentSender(String callingPackage, int appWidgetId,
-            int intentFlags);
+    IntentSender createAppWidgetConfigIntentSender(String callingPackage, int appWidgetId);
 
     //
     // for AppWidgetManager
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index 02f675c..f479f4f 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -33,6 +33,7 @@
 import android.content.pm.PackageParser.PackageParserException;
 import android.os.Build;
 import android.os.SELinux;
+import android.os.SystemProperties;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.util.Slog;
@@ -74,6 +75,7 @@
 
         final long[] apkHandles;
         final boolean multiArch;
+        final boolean extractNativeLibs;
 
         public static Handle create(File packageFile) throws IOException {
             try {
@@ -86,14 +88,16 @@
 
         public static Handle create(Package pkg) throws IOException {
             return create(pkg.getAllCodePaths(),
-                    (pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0);
+                    (pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0,
+                    (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0);
         }
 
         public static Handle create(PackageLite lite) throws IOException {
-            return create(lite.getAllCodePaths(), lite.multiArch);
+            return create(lite.getAllCodePaths(), lite.multiArch, lite.extractNativeLibs);
         }
 
-        private static Handle create(List<String> codePaths, boolean multiArch) throws IOException {
+        private static Handle create(List<String> codePaths, boolean multiArch,
+                boolean extractNativeLibs) throws IOException {
             final int size = codePaths.size();
             final long[] apkHandles = new long[size];
             for (int i = 0; i < size; i++) {
@@ -108,12 +112,13 @@
                 }
             }
 
-            return new Handle(apkHandles, multiArch);
+            return new Handle(apkHandles, multiArch, extractNativeLibs);
         }
 
-        Handle(long[] apkHandles, boolean multiArch) {
+        Handle(long[] apkHandles, boolean multiArch, boolean extractNativeLibs) {
             this.apkHandles = apkHandles;
             this.multiArch = multiArch;
+            this.extractNativeLibs = extractNativeLibs;
             mGuard.open("close");
         }
 
@@ -146,8 +151,8 @@
 
     private static native long nativeSumNativeBinaries(long handle, String cpuAbi);
 
-    private native static int nativeCopyNativeBinaries(long handle,
-            String sharedLibraryPath, String abiToCopy);
+    private native static int nativeCopyNativeBinaries(long handle, String sharedLibraryPath,
+            String abiToCopy, boolean extractNativeLibs, boolean hasNativeBridge);
 
     private static long sumNativeBinaries(Handle handle, String abi) {
         long sum = 0;
@@ -167,7 +172,8 @@
      */
     public static int copyNativeBinaries(Handle handle, File sharedLibraryDir, String abi) {
         for (long apkHandle : handle.apkHandles) {
-            int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi);
+            int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi,
+                    handle.extractNativeLibs, HAS_NATIVE_BRIDGE);
             if (res != INSTALL_SUCCEEDED) {
                 return res;
             }
@@ -218,7 +224,8 @@
     /**
      * Remove the native binaries of a given package. This deletes the files
      */
-    public static void removeNativeBinariesFromDirLI(File nativeLibraryRoot, boolean deleteRootDir) {
+    public static void removeNativeBinariesFromDirLI(File nativeLibraryRoot,
+            boolean deleteRootDir) {
         if (DEBUG_NATIVE) {
             Slog.w(TAG, "Deleting native binaries from: " + nativeLibraryRoot.getPath());
         }
@@ -247,7 +254,8 @@
             // asked to or this will prevent installation of future updates.
             if (deleteRootDir) {
                 if (!nativeLibraryRoot.delete()) {
-                    Slog.w(TAG, "Could not delete native binary directory: " + nativeLibraryRoot.getPath());
+                    Slog.w(TAG, "Could not delete native binary directory: " +
+                            nativeLibraryRoot.getPath());
                 }
             }
         }
@@ -416,6 +424,9 @@
     // We don't care about the other return values for now.
     private static final int BITCODE_PRESENT = 1;
 
+    private static final boolean HAS_NATIVE_BRIDGE =
+            !"0".equals(SystemProperties.get("ro.dalvik.vm.native.bridge", "0"));
+
     private static native int hasRenderscriptBitcode(long apkHandle);
 
     public static boolean hasRenderscriptBitcode(Handle handle) throws IOException {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 50ddbd1..d44959b 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -267,7 +267,12 @@
                     if (false) {
                         Log.v(TAG, "Preloading " + line + "...");
                     }
-                    Class.forName(line);
+                    // Load and explicitly initialize the given class. Use
+                    // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
+                    // (to derive the caller's class-loader). Use true to force initialization, and
+                    // null for the boot classpath class-loader (could as well cache the
+                    // class-loader of this class in a variable).
+                    Class.forName(line, true, null);
                     count++;
                 } catch (ClassNotFoundException e) {
                     Log.w(TAG, "Class not found for preloading: " + line);
diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java
index 89990c2..6d4e058 100644
--- a/core/java/com/android/internal/widget/SwipeDismissLayout.java
+++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java
@@ -111,7 +111,7 @@
     }
 
     private void init(Context context) {
-        ViewConfiguration vc = ViewConfiguration.get(getContext());
+        ViewConfiguration vc = ViewConfiguration.get(context);
         mSlop = vc.getScaledTouchSlop();
         mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
         mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
@@ -216,6 +216,8 @@
         if (mVelocityTracker == null) {
             return super.onTouchEvent(ev);
         }
+        // offset because the view is translated during swipe
+        ev.offsetLocation(mTranslationX, 0);
         switch (ev.getActionMasked()) {
             case MotionEvent.ACTION_UP:
                 updateDismiss(ev);
@@ -290,7 +292,7 @@
             float deltaX = ev.getRawX() - mDownX;
             float deltaY = ev.getRawY() - mDownY;
             if ((deltaX * deltaX) + (deltaY * deltaY) > mSlop * mSlop) {
-                mSwiping = deltaX > mSlop * 2 && Math.abs(deltaY) < mSlop * 2;
+                mSwiping = deltaX > mSlop * 2 && Math.abs(deltaY) < Math.abs(deltaX);
             } else {
                 mSwiping = false;
             }
@@ -299,9 +301,9 @@
 
     private void updateDismiss(MotionEvent ev) {
         float deltaX = ev.getRawX() - mDownX;
+        mVelocityTracker.addMovement(ev);
+        mVelocityTracker.computeCurrentVelocity(1000);
         if (!mDismissed) {
-            mVelocityTracker.addMovement(ev);
-            mVelocityTracker.computeCurrentVelocity(1000);
 
             if (deltaX > (getWidth() * DISMISS_MIN_DRAG_WIDTH_RATIO) &&
                     ev.getRawX() >= mLastX) {
@@ -311,7 +313,9 @@
         // Check if the user tried to undo this.
         if (mDismissed && mSwiping) {
             // Check if the user's finger is actually back
-            if (deltaX < (getWidth() * DISMISS_MIN_DRAG_WIDTH_RATIO)) {
+            if (deltaX < (getWidth() * DISMISS_MIN_DRAG_WIDTH_RATIO) ||
+                    // or user is flinging back left
+                    mVelocityTracker.getXVelocity() < -mMinFlingVelocity) {
                 mDismissed = false;
             }
         }
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 0d83e93..0bfc0c9 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -536,7 +536,6 @@
  */
 int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
 {
-    int result = -1;
     JavaVMInitArgs initArgs;
     char propBuf[PROPERTY_VALUE_MAX];
     char stackTraceFileBuf[sizeof("-Xstacktracefile:")-1 + PROPERTY_VALUE_MAX];
@@ -587,6 +586,7 @@
     char localeOption[sizeof("-Duser.locale=") + PROPERTY_VALUE_MAX];
     char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX];
     char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX];
+    char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX];
 
     bool checkJni = false;
     property_get("dalvik.vm.checkjni", propBuf, "");
@@ -705,7 +705,7 @@
     if (!hasFile("/system/etc/preloaded-classes")) {
         ALOGE("Missing preloaded-classes file, /system/etc/preloaded-classes not found: %s\n",
               strerror(errno));
-        goto bail;
+        return -1;
     }
     addOption("-Ximage-compiler-option");
     addOption("--image-classes=/system/etc/preloaded-classes");
@@ -860,6 +860,18 @@
     // Dalvik-cache pruning counter.
     parseRuntimeOption("dalvik.vm.zygote.max-boot-retry", cachePruneBuf,
                        "-Xzygote-max-boot-retry=");
+#if defined(__LP64__)
+    const char* cpu_abilist_property_name = "ro.product.cpu.abilist64";
+#else
+    const char* cpu_abilist_property_name = "ro.product.cpu.abilist32";
+#endif  // defined(__LP64__)
+    property_get(cpu_abilist_property_name, propBuf, "");
+    if (propBuf[0] == '\0') {
+        ALOGE("%s is not expected to be empty", cpu_abilist_property_name);
+        return -1;
+    }
+    snprintf(cpuAbiListBuf, sizeof(cpuAbiListBuf), "--cpu-abilist=%s", propBuf);
+    addOption(cpuAbiListBuf);
 
     initArgs.version = JNI_VERSION_1_4;
     initArgs.options = mOptions.editArray();
@@ -875,13 +887,10 @@
      */
     if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
         ALOGE("JNI_CreateJavaVM failed\n");
-        goto bail;
+        return -1;
     }
 
-    result = 0;
-
-bail:
-    return result;
+    return 0;
 }
 
 char* AndroidRuntime::toSlashClassName(const char* className)
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index ceec0e3..610bdc8 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -574,24 +574,33 @@
         return NULL;
     }
 
-    SkBitmap* bitmap = new SkBitmap;
+    SkAutoTDelete<SkBitmap> bitmap(new SkBitmap);
 
-    bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType), rowBytes);
+    if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType), rowBytes)) {
+        return NULL;
+    }
 
     SkColorTable* ctable = NULL;
     if (colorType == kIndex_8_SkColorType) {
         int count = p->readInt32();
+        if (count < 0 || count > 256) {
+            // The data is corrupt, since SkColorTable enforces a value between 0 and 256,
+            // inclusive.
+            return NULL;
+        }
         if (count > 0) {
             size_t size = count * sizeof(SkPMColor);
             const SkPMColor* src = (const SkPMColor*)p->readInplace(size);
+            if (src == NULL) {
+                return NULL;
+            }
             ctable = new SkColorTable(src, count);
         }
     }
 
-    jbyteArray buffer = GraphicsJNI::allocateJavaPixelRef(env, bitmap, ctable);
+    jbyteArray buffer = GraphicsJNI::allocateJavaPixelRef(env, bitmap.get(), ctable);
     if (NULL == buffer) {
         SkSafeUnref(ctable);
-        delete bitmap;
         return NULL;
     }
 
@@ -603,7 +612,6 @@
     android::status_t status = p->readBlob(size, &blob);
     if (status) {
         doThrowRE(env, "Could not read bitmap from parcel blob.");
-        delete bitmap;
         return NULL;
     }
 
@@ -613,8 +621,8 @@
 
     blob.release();
 
-    return GraphicsJNI::createBitmap(env, bitmap, buffer, getPremulBitmapCreateFlags(isMutable),
-            NULL, NULL, density);
+    return GraphicsJNI::createBitmap(env, bitmap.detach(), buffer,
+            getPremulBitmapCreateFlags(isMutable), NULL, NULL, density);
 }
 
 static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 3c1993e..9307ff9 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -33,6 +33,7 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#include <inttypes.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -173,7 +174,11 @@
 static install_status_t
 copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char* fileName)
 {
-    jstring* javaNativeLibPath = (jstring*) arg;
+    void** args = reinterpret_cast<void**>(arg);
+    jstring* javaNativeLibPath = (jstring*) args[0];
+    jboolean extractNativeLibs = *(jboolean*) args[1];
+    jboolean hasNativeBridge = *(jboolean*) args[2];
+
     ScopedUtfChars nativeLibPath(env, *javaNativeLibPath);
 
     size_t uncompLen;
@@ -181,13 +186,31 @@
     long crc;
     time_t modTime;
 
-    if (!zipFile->getEntryInfo(zipEntry, NULL, &uncompLen, NULL, NULL, &when, &crc)) {
+    int method;
+    off64_t offset;
+
+    if (!zipFile->getEntryInfo(zipEntry, &method, &uncompLen, NULL, &offset, &when, &crc)) {
         ALOGD("Couldn't read zip entry info\n");
         return INSTALL_FAILED_INVALID_APK;
-    } else {
-        struct tm t;
-        ZipUtils::zipTimeToTimespec(when, &t);
-        modTime = mktime(&t);
+    }
+
+    if (!extractNativeLibs) {
+        // check if library is uncompressed and page-aligned
+        if (method != ZipFileRO::kCompressStored) {
+            ALOGD("Library '%s' is compressed - will not be able to open it directly from apk.\n",
+                fileName);
+            return INSTALL_FAILED_INVALID_APK;
+        }
+
+        if (offset % PAGE_SIZE != 0) {
+            ALOGD("Library '%s' is not page-aligned - will not be able to open it directly from"
+                " apk.\n", fileName);
+            return INSTALL_FAILED_INVALID_APK;
+        }
+
+        if (!hasNativeBridge) {
+          return INSTALL_SUCCEEDED;
+        }
     }
 
     // Build local file path
@@ -208,6 +231,9 @@
     }
 
     // Only copy out the native file if it's different.
+    struct tm t;
+    ZipUtils::zipTimeToTimespec(when, &t);
+    modTime = mktime(&t);
     struct stat64 st;
     if (!isFileDifferent(localFileName, uncompLen, modTime, crc, &st)) {
         return INSTALL_SUCCEEDED;
@@ -465,10 +491,12 @@
 
 static jint
 com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz,
-        jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi)
+        jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi,
+        jboolean extractNativeLibs, jboolean hasNativeBridge)
 {
+    void* args[] = { &javaNativeLibPath, &extractNativeLibs, &hasNativeBridge };
     return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi,
-            copyFileIfChanged, &javaNativeLibPath);
+            copyFileIfChanged, reinterpret_cast<void*>(args));
 }
 
 static jlong
@@ -548,7 +576,7 @@
             "(J)V",
             (void *)com_android_internal_content_NativeLibraryHelper_close},
     {"nativeCopyNativeBinaries",
-            "(JLjava/lang/String;Ljava/lang/String;)I",
+            "(JLjava/lang/String;Ljava/lang/String;ZZ)I",
             (void *)com_android_internal_content_NativeLibraryHelper_copyNativeBinaries},
     {"nativeSumNativeBinaries",
             "(JLjava/lang/String;)J",
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index ea592cf..f69772a 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1021,6 +1021,10 @@
          <p>The default value of this attribute is <code>false</code>. -->
     <attr name="resumeWhilePausing" format="boolean" />
 
+    <!-- When set installer will extract native libraries. If set to false
+         libraries in the apk must be stored and page-aligned.  -->
+    <attr name="extractNativeLibs" format="boolean"/>
+
     <!-- The <code>manifest</code> tag is the root of an
          <code>AndroidManifest.xml</code> file,
          describing the contents of an Android package (.apk) file.  One
@@ -1151,8 +1155,8 @@
              @hide -->
         <attr name="usesCleartextTraffic" />
         <attr name="multiArch" />
+        <attr name="extractNativeLibs" />
     </declare-styleable>
-    
     <!-- The <code>permission</code> tag declares a security permission that can be
          used to control access from other packages to specific components or
          features in your package (or other packages).  See the
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9a33ef9..37247b0 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -437,6 +437,9 @@
          point on the move. A value of 0 means no periodic scans will be used in the framework. -->
     <integer translatable="false" name="config_wifi_framework_scan_interval">300000</integer>
 
+    <!-- Integer indicating disconnect mode scan interval in milliseconds -->
+    <integer translatable="false" name="config_wifi_disconnected_scan_interval">10000</integer>
+
     <!-- Integer indicating associated partial scan interval in milliseconds -->
     <integer translatable="false" name="config_wifi_framework_associated_scan_interval">20000</integer>
 
@@ -2096,4 +2099,10 @@
 
     <!-- Keyguard component -->
     <string name="config_keyguardComponent" translatable="false">com.android.systemui/com.android.systemui.keyguard.KeyguardService</string>
+
+    <!-- This config is used to force VoiceInteractionService to start on certain low ram devices. -->
+    <bool name="config_forceEnableVoiceInteractionService">false</bool>
+
+    <!-- This config is ued to determine whether animations are allowed in low power mode. -->
+    <bool name="config_allowAnimationsInLowPowerMode">false</bool>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2bb9aa8..bfd0d26 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2598,4 +2598,5 @@
     <public type="style" name="Theme.DeviceDefault.Dialog.Alert" />
     <public type="style" name="Theme.DeviceDefault.Light.Dialog.Alert" />
 
+  <public type="attr" name="extractNativeLibs" />
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index da0a5c1..afa67b7 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -281,6 +281,8 @@
   <java-symbol type="bool" name="config_enableScreenshotChord" />
   <java-symbol type="bool" name="config_bluetooth_default_profiles" />
   <java-symbol type="bool" name="config_enableWifiDisplay" />
+  <java-symbol type="bool" name="config_forceEnableVoiceInteractionService" />
+  <java-symbol type="bool" name="config_allowAnimationsInLowPowerMode" />
   <java-symbol type="bool" name="config_useDevInputEventForAudioJack" />
   <java-symbol type="bool" name="config_safe_media_volume_enabled" />
   <java-symbol type="bool" name="config_camera_sound_forced" />
@@ -371,6 +373,7 @@
   <java-symbol type="integer" name="config_shortPressOnSleepBehavior" />
   <java-symbol type="integer" name="config_wifi_framework_scan_interval" />
   <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
+  <java-symbol type="integer" name="config_wifi_disconnected_scan_interval" />
   <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
   <java-symbol type="integer" name="db_connection_pool_size" />
   <java-symbol type="integer" name="db_journal_size_limit" />
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index e04c214..4b82c3d 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -184,10 +184,10 @@
         result.putInt("ap-discovered", ssidAppearInScanResultsCount);
         getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, result);
         if (i == mScanIterations + 1) {
-            writeOutput(String.format("iteration %d out of %d", i, mScanIterations));
+            writeOutput(String.format("iteration %d out of %d", i - 1, mScanIterations));
             writeOutput(String.format("average scanning time is %d", scanTimeSum / (i - 1)));
             writeOutput(String.format("ssid appear %d out of %d scan iterations",
-                    ssidAppearInScanResultsCount, i));
+                    ssidAppearInScanResultsCount, i - 1));
         }
     }
 
@@ -289,7 +289,7 @@
         getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, result);
         if (i == mReconnectIterations + 1) {
             writeOutput(String.format("iteration %d out of %d",
-                    i, mReconnectIterations));
+                    i - 1, mReconnectIterations));
         }
     }
 }
diff --git a/core/tests/coretests/apks/install_jni_lib/Android.mk b/core/tests/coretests/apks/install_jni_lib/Android.mk
index b61ea8e..7322e8d 100644
--- a/core/tests/coretests/apks/install_jni_lib/Android.mk
+++ b/core/tests/coretests/apks/install_jni_lib/Android.mk
@@ -23,6 +23,14 @@
     libnativehelper
 
 LOCAL_MODULE := libframeworks_coretests_jni
+
+# this does not prevent build system
+# from installing library to /system/lib
 LOCAL_MODULE_TAGS := tests
 
+# .. we want to avoid that... so we put it somewhere
+# bionic linker cant find it without outside help (nativetests):
+LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
index 957fc4a..e0b616c 100644
--- a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
+++ b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
@@ -27,8 +27,8 @@
     { "checkFunction", "()I", (void*) checkFunction },
 };
 
-int register_com_android_framework_coretests_JNITests(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "com/android/framework/coretests/JNITests", sMethods,
+int register_com_android_frameworks_coretests_JNITests(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/android/frameworks/coretests/JNITests", sMethods,
             NELEM(sMethods));
 }
 
@@ -46,7 +46,7 @@
         return JNI_ERR;
     }
 
-    if ((status = android::register_com_android_framework_coretests_JNITests(e)) < 0) {
+    if ((status = android::register_com_android_frameworks_coretests_JNITests(e)) < 0) {
         return JNI_ERR;
     }
 
diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
new file mode 100644
index 0000000..6ee6ffa
--- /dev/null
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := install_jni_lib_open_from_apk
+
+LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES := true
+
+include $(FrameworkCoreTests_BUILD_PACKAGE)
diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml b/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml
new file mode 100644
index 0000000..190f894
--- /dev/null
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.frameworks.coretests.install_jni_lib_open_from_apk">
+
+    <application android:hasCode="true" android:label="@string/app_name" android:extractNativeLibs="false">
+        <activity android:name="com.android.frameworks.coretests.OpenFromApkActivity"
+           android:label="@string/app_name">
+          <intent-filter>
+            <action android:name="android.intent.action.MAIN" />
+            <category android:name="android.intent.category.LAUNCHER" />
+          </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml b/core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml
new file mode 100644
index 0000000..8c2a0bf
--- /dev/null
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string name="app_name">Load From Apk Test</string>
+</resources>
diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java
new file mode 100644
index 0000000..4f9176c
--- /dev/null
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 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.
+ *
+ */
+
+package com.android.frameworks.coretests;
+
+public class JNITests {
+  static {
+    System.loadLibrary("frameworks_coretests_jni");
+  }
+
+  public static native int checkFunction();
+}
diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java
new file mode 100644
index 0000000..524cad7c
--- /dev/null
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 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.
+ *
+ */
+
+package com.android.frameworks.coretests;
+
+import android.app.Activity;
+import android.widget.TextView;
+import android.os.Bundle;
+
+public class OpenFromApkActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        TextView  tv = new TextView(this);
+
+        int i = JNITests.checkFunction();
+
+        tv.setText("All is well: i=" + i);
+
+        setContentView(tv);
+    }
+
+}
diff --git a/core/tests/coretests/src/android/net/IpPrefixTest.java b/core/tests/coretests/src/android/net/IpPrefixTest.java
index cf278fb..fcc6389 100644
--- a/core/tests/coretests/src/android/net/IpPrefixTest.java
+++ b/core/tests/coretests/src/android/net/IpPrefixTest.java
@@ -29,6 +29,10 @@
 
 public class IpPrefixTest extends TestCase {
 
+    private static InetAddress Address(String addr) {
+        return InetAddress.parseNumericAddress(addr);
+    }
+
     // Explicitly cast everything to byte because "error: possible loss of precision".
     private static final byte[] IPV4_BYTES = { (byte) 192, (byte) 0, (byte) 2, (byte) 4};
     private static final byte[] IPV6_BYTES = {
@@ -209,6 +213,34 @@
     }
 
     @SmallTest
+    public void testContains() {
+        IpPrefix p = new IpPrefix("2001:db8:f00::ace:d00d/127");
+        assertTrue(p.contains(Address("2001:db8:f00::ace:d00c")));
+        assertTrue(p.contains(Address("2001:db8:f00::ace:d00d")));
+        assertFalse(p.contains(Address("2001:db8:f00::ace:d00e")));
+        assertFalse(p.contains(Address("2001:db8:f00::bad:d00d")));
+        assertFalse(p.contains(Address("2001:4868:4860::8888")));
+        assertFalse(p.contains(null));
+        assertFalse(p.contains(Address("8.8.8.8")));
+
+        p = new IpPrefix("192.0.2.0/23");
+        assertTrue(p.contains(Address("192.0.2.43")));
+        assertTrue(p.contains(Address("192.0.3.21")));
+        assertFalse(p.contains(Address("192.0.0.21")));
+        assertFalse(p.contains(Address("8.8.8.8")));
+        assertFalse(p.contains(Address("2001:4868:4860::8888")));
+
+        IpPrefix ipv6Default = new IpPrefix("::/0");
+        assertTrue(ipv6Default.contains(Address("2001:db8::f00")));
+        assertFalse(ipv6Default.contains(Address("192.0.2.1")));
+
+        IpPrefix ipv4Default = new IpPrefix("0.0.0.0/0");
+        assertTrue(ipv4Default.contains(Address("255.255.255.255")));
+        assertTrue(ipv4Default.contains(Address("192.0.2.1")));
+        assertFalse(ipv4Default.contains(Address("2001:db8::f00")));
+    }
+
+    @SmallTest
     public void testHashCode() {
         IpPrefix p;
         int oldCode = -1;
diff --git a/core/tests/coretests/src/android/net/RouteInfoTest.java b/core/tests/coretests/src/android/net/RouteInfoTest.java
index 0b88bc7..831fefd 100644
--- a/core/tests/coretests/src/android/net/RouteInfoTest.java
+++ b/core/tests/coretests/src/android/net/RouteInfoTest.java
@@ -90,6 +90,7 @@
         assertFalse(r.matches(Address("2001:db8:f00::ace:d00e")));
         assertFalse(r.matches(Address("2001:db8:f00::bad:d00d")));
         assertFalse(r.matches(Address("2001:4868:4860::8888")));
+        assertFalse(r.matches(Address("8.8.8.8")));
 
         r = new PatchedRouteInfo(Prefix("192.0.2.0/23"), null, "wlan0");
         assertTrue(r.matches(Address("192.0.2.43")));
diff --git a/docs/html/reference/com/google/android/gms/fitness/data/Field.html b/docs/html/reference/com/google/android/gms/fitness/data/Field.html
index 91bf861..0f97e7e 100644
--- a/docs/html/reference/com/google/android/gms/fitness/data/Field.html
+++ b/docs/html/reference/com/google/android/gms/fitness/data/Field.html
@@ -151,7 +151,7 @@
 
 <a name="top"></a>
 
-<!-- dialog to prompt lang pref change when loaded from hardcoded URL 
+<!-- dialog to prompt lang pref change when loaded from hardcoded URL
 <div id="langMessage" style="display:none">
   <div>
     <div class="lang en">
@@ -201,7 +201,7 @@
   <div id="header-wrapper">
     <div id="header">
 
-    
+
 
 
       <div class="wrap" id="header-wrap">
@@ -245,8 +245,8 @@
         </ul>
 
 
-        
-        
+
+
 <div class="menu-container">
   <div class="moremenu">
     <div id="more-btn"></div>
@@ -267,8 +267,8 @@
         <li><a href="http://source.android.com">Android Open Source Project</a></li>
       </ul>
 
-      
-      
+
+
         <div class="header">Language</div>
           <div id="language" class="locales">
             <select name="language" onChange="changeLangPref(this.value, true)">
@@ -286,8 +286,8 @@
           loadLangPref();
             //-->
         </script>
-      
-      
+
+
       <br class="clearfix" />
     </div><!-- end 'mid' -->
     <div class="bottom"></div>
@@ -401,10 +401,10 @@
                 </li>
                 <li><a href="/google/index.html">Google Services</a>
                 </li>
-                
+
                   <li><a href="/samples/index.html">Samples</a>
                   </li>
-                
+
               </ul>
             </li>
             <li class="distribute last">
@@ -424,14 +424,14 @@
       </div><!-- end header-wrap.wrap -->
     </div><!-- end header -->
 
-  
+
     <!-- Secondary x-nav -->
     <div id="nav-x">
         <div class="wrap" style="position:relative;z-index:1">
 
-        
-        
-        
+
+
+
 
             <ul class="nav-x col-9 develop" style="width:100%">
                 <li class="training"><a href="/training/index.html"
@@ -469,17 +469,17 @@
                 <li class="google"><a href="/google/index.html"
                   >Google Services</a>
                 </li>
-                
+
                   <li class="samples"><a href="/samples/index.html"
                     >Samples</a>
                   </li>
-                
+
             </ul>
         </div>
     </div>
     <!-- /Sendondary x-nav DEVELOP -->
 
-  
+
 
     <div id="searchResults" class="wrap" style="display:none;">
       <h2 id="searchTitle">Results</h2>
@@ -492,7 +492,7 @@
       <a class="logo" href="#top"></a>
       <a class="top" href="#top"></a>
       <ul class="breadcrumb">
-        
+
         <li class="current">Field</li>
       </ul>
     </div>
@@ -502,7 +502,7 @@
 
 
 
-  
+
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
@@ -759,12 +759,12 @@
 </script>
 
 
-        
+
 
       </div>
       <script type="text/javascript">
        showGoogleRefTree();
-    
+
       </script>
     </div> <!-- end side-nav -->
     <script>
@@ -774,7 +774,7 @@
     </script>
 
 
-     
+
 
 
 
@@ -784,21 +784,21 @@
 
 
 
-  
-   
-  
-  
-  
-  
 
-  
-   
-  
-  
-   
-  
-  
-  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 <div class="sum-details-links">
@@ -810,22 +810,22 @@
 
 
   <a href="#constants">Constants</a>
-  
+
 
 
   &#124; <a href="#inhconstants">Inherited Constants</a>
-  
+
 
 
   &#124; <a href="#lfields">Fields</a>
-  
+
 
 
 
 
 
   &#124; <a href="#pubmethods">Methods</a>
-  
+
 
 
 
@@ -835,9 +835,9 @@
 
 </div><!-- end sum-details-links -->
 <div class="api-level">
-  
-  
-  
+
+
+
 
 </div>
 </div><!-- end api-info-block -->
@@ -847,31 +847,31 @@
 
 <div id="jd-header">
     public
-     
-    final 
-    
+
+    final
+
     class
 <h1 itemprop="name">Field</h1>
 
 
 
-  
+
     extends Object<br/>
-  
-  
-  
-
-  
-  
-      implements 
-      
-        Parcelable 
-      
-  
-  
 
 
-    
+
+
+
+
+      implements
+
+        Parcelable
+
+
+
+
+
+
 
 
 </div><!-- end header -->
@@ -883,18 +883,18 @@
 
 
     <tr>
-         	
+
         <td colspan="2" class="jd-inheritance-class-cell">java.lang.Object</td>
     </tr>
-    
+
 
     <tr>
-        
+
             <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
-         	
+
         <td colspan="1" class="jd-inheritance-class-cell">com.google.android.gms.fitness.data.Field</td>
     </tr>
-    
+
 
 </table>
 
@@ -962,31 +962,31 @@
 <table id="constants" class="jd-sumtable"><tr><th colspan="12">Constants</th></tr>
 
 
-    
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FORMAT_FLOAT">FORMAT_FLOAT</a></td>
         <td class="jd-descrcol" width="100%">
           Format constant indicating the field holds float values.
-          
-    
+
+
 
         </td>
     </tr>
-    
-    
+
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FORMAT_INT32">FORMAT_INT32</a></td>
         <td class="jd-descrcol" width="100%">
           Format constant indicating the field holds integer values.
-          
-    
+
+
 
         </td>
     </tr>
-    
-    
+
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FORMAT_MAP">FORMAT_MAP</a></td>
@@ -1305,33 +1305,33 @@
   </div>
   <div id="inherited-constants-android.os.Parcelable-summary" style="display: none;">
     <table class="jd-sumtable-expando">
-    
 
-    
+
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol">CONTENTS_FILE_DESCRIPTOR</td>
         <td class="jd-descrcol" width="100%">
-          
-          
-    
+
+
+
 
         </td>
     </tr>
-    
-    
+
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol">PARCELABLE_WRITE_RETURN_VALUE</td>
         <td class="jd-descrcol" width="100%">
-          
-          
-    
+
+
+
 
         </td>
     </tr>
-    
-    
+
+
 </table>
   </div>
 </div>
@@ -1347,7 +1347,7 @@
 <table id="lfields" class="jd-sumtable"><tr><th colspan="12">Fields</th></tr>
 
 
-    
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1357,13 +1357,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_ACCURACY">FIELD_ACCURACY</a></td>
           <td class="jd-descrcol" width="100%">
             The accuracy of an accompanied value (such as location).
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1373,13 +1373,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_ACTIVITY">FIELD_ACTIVITY</a></td>
           <td class="jd-descrcol" width="100%">
             An activity type of <code><a href="/reference/com/google/android/gms/fitness/FitnessActivities.html">FitnessActivities</a></code>, encoded as an integer for efficiency.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1389,13 +1389,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_ALTITUDE">FIELD_ALTITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             An altitude of a location represented as a float, in meters above sea level.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1405,13 +1405,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_AVERAGE">FIELD_AVERAGE</a></td>
           <td class="jd-descrcol" width="100%">
             An average value.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1421,13 +1421,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_BPM">FIELD_BPM</a></td>
           <td class="jd-descrcol" width="100%">
             A heart rate in beats per minute.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1437,13 +1437,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_CALORIES">FIELD_CALORIES</a></td>
           <td class="jd-descrcol" width="100%">
             Calories in kcal.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1469,13 +1469,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_CONFIDENCE">FIELD_CONFIDENCE</a></td>
           <td class="jd-descrcol" width="100%">
             The confidence of an accompanied value, specified as a value between 0.0 and 100.0.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1485,13 +1485,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_DISTANCE">FIELD_DISTANCE</a></td>
           <td class="jd-descrcol" width="100%">
             A distance in meters.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1501,13 +1501,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_DURATION">FIELD_DURATION</a></td>
           <td class="jd-descrcol" width="100%">
             A duration in milliseconds.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1533,13 +1533,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_HEIGHT">FIELD_HEIGHT</a></td>
           <td class="jd-descrcol" width="100%">
             A height in meters.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1549,13 +1549,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_HIGH_LATITUDE">FIELD_HIGH_LATITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A high latitude of a location bounding box represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1565,13 +1565,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_HIGH_LONGITUDE">FIELD_HIGH_LONGITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A high longitude of a location bounding box represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1581,13 +1581,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LATITUDE">FIELD_LATITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A latitude of a location represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1597,13 +1597,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LONGITUDE">FIELD_LONGITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A longitude of a location represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1613,13 +1613,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LOW_LATITUDE">FIELD_LOW_LATITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A low latitude of a location bounding box represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1629,13 +1629,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LOW_LONGITUDE">FIELD_LOW_LONGITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A low longitude of a location bounding box represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1645,13 +1645,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_MAX">FIELD_MAX</a></td>
           <td class="jd-descrcol" width="100%">
             A maximum value.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1677,13 +1677,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_MIN">FIELD_MIN</a></td>
           <td class="jd-descrcol" width="100%">
             A minimum value.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1725,13 +1725,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_PERCENTAGE">FIELD_PERCENTAGE</a></td>
           <td class="jd-descrcol" width="100%">
             A percentage value, between 0 and 100.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1741,13 +1741,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_REVOLUTIONS">FIELD_REVOLUTIONS</a></td>
           <td class="jd-descrcol" width="100%">
             A count of revolutions.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1757,13 +1757,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_RPM">FIELD_RPM</a></td>
           <td class="jd-descrcol" width="100%">
             Revolutions per minute or rate per minute.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1773,13 +1773,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_SPEED">FIELD_SPEED</a></td>
           <td class="jd-descrcol" width="100%">
             A speed in meter/sec.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1789,13 +1789,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_STEPS">FIELD_STEPS</a></td>
           <td class="jd-descrcol" width="100%">
             A count of steps.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1805,13 +1805,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_WATTS">FIELD_WATTS</a></td>
           <td class="jd-descrcol" width="100%">
             Power in watts.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1821,13 +1821,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_WEIGHT">FIELD_WEIGHT</a></td>
           <td class="jd-descrcol" width="100%">
             A weight in kilograms.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
 
 </table>
 
@@ -1846,129 +1846,129 @@
 
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             int</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#describeContents()">describeContents</a></span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             boolean</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#equals(java.lang.Object)">equals</a></span>(Object that)</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             int</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#getFormat()">getFormat</a></span>()</nobr>
-        
+
         <div class="jd-descrdiv">
           Returns the format of the field, as one of the format constant values.
-          
-    
+
+
 
         </div>
-  
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             String</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#getName()">getName</a></span>()</nobr>
-        
+
         <div class="jd-descrdiv">
           Returns the name of the field.
-          
-    
+
+
 
         </div>
-  
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             int</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#hashCode()">hashCode</a></span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             String</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#toString()">toString</a></span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#writeToParcel(android.os.Parcel, int)">writeToParcel</a></span>(Parcel dest, int flags)</nobr>
-        
+
   </td></tr>
 
 
@@ -2003,182 +2003,182 @@
   </div>
   <div id="inherited-methods-java.lang.Object-summary" style="display: none;">
     <table class="jd-sumtable-expando">
-    
 
 
-	 
+
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             Object</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">clone</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             boolean</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">equals</span>(Object arg0)</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">finalize</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             Class&lt;?&gt;</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">getClass</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             int</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">hashCode</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">notify</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">notifyAll</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             String</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">toString</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">wait</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">wait</span>(long arg0, int arg1)</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">wait</span>(long arg0)</nobr>
-        
+
   </td></tr>
 
 
@@ -2205,7 +2205,7 @@
   </div>
   <div id="inherited-methods-android.os.Parcelable-summary" style="display: none;">
     <table class="jd-sumtable-expando">
-    
+
 
 
 
@@ -2232,6 +2232,7 @@
 
 
 
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
@@ -3196,40 +3197,40 @@
 
 <A NAME="NUTRIENT_TOTAL_FAT"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         String
       </span>
         NUTRIENT_TOTAL_FAT
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Total fat in grams.
 </p></div>
 
-    
+
         <div class="jd-tagdata">
         <span class="jd-tagtitle">Constant Value: </span>
         <span>
-            
+
                 "fat.total"
-            
+
         </span>
         </div>
-    
+
     </div>
 </div>
 
@@ -3237,40 +3238,40 @@
 
 <A NAME="NUTRIENT_TRANS_FAT"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         String
       </span>
         NUTRIENT_TRANS_FAT
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Trans fat in grams.
 </p></div>
 
-    
+
         <div class="jd-tagdata">
         <span class="jd-tagtitle">Constant Value: </span>
         <span>
-            
+
                 "fat.trans"
-            
+
         </span>
         </div>
-    
+
     </div>
 </div>
 
@@ -3321,31 +3322,31 @@
 
 <A NAME="NUTRIENT_VITAMIN_C"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         String
       </span>
         NUTRIENT_VITAMIN_C
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Vitamin C amount in milligrams.
 </p></div>
 
-    
+
         <div class="jd-tagdata">
         <span class="jd-tagtitle">Constant Value: </span>
         <span>
@@ -3372,31 +3373,31 @@
 
 <A NAME="FIELD_ACCURACY"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_ACCURACY
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>The accuracy of an accompanied value (such as location).
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3404,33 +3405,33 @@
 
 <A NAME="FIELD_ACTIVITY"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_ACTIVITY
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>An activity type of <code><a href="/reference/com/google/android/gms/fitness/FitnessActivities.html">FitnessActivities</a></code>, encoded as an integer for efficiency.  The
  activity value should be stored using <code><a href="/reference/com/google/android/gms/fitness/data/Value.html#setActivity(java.lang.String)">setActivity(String)</a></code>,
  and read using <code><a href="/reference/com/google/android/gms/fitness/data/Value.html#asActivity()">asActivity()</a></code>
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3438,32 +3439,32 @@
 
 <A NAME="FIELD_ALTITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_ALTITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>An altitude of a location represented as a float, in meters above sea level.
  Some location samples don't have an altitude value so this field might not be set.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3471,31 +3472,31 @@
 
 <A NAME="FIELD_AVERAGE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_AVERAGE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>An average value.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3503,31 +3504,31 @@
 
 <A NAME="FIELD_BPM"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_BPM
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A heart rate in beats per minute.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3535,31 +3536,31 @@
 
 <A NAME="FIELD_CALORIES"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_CALORIES
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Calories in kcal.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3599,31 +3600,31 @@
 
 <A NAME="FIELD_CONFIDENCE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_CONFIDENCE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>The confidence of an accompanied value, specified as a value between 0.0 and 100.0.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3631,31 +3632,31 @@
 
 <A NAME="FIELD_DISTANCE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_DISTANCE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A distance in meters.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3663,31 +3664,31 @@
 
 <A NAME="FIELD_DURATION"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_DURATION
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A duration in milliseconds.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3727,31 +3728,31 @@
 
 <A NAME="FIELD_HEIGHT"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_HEIGHT
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A height in meters.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3759,31 +3760,31 @@
 
 <A NAME="FIELD_HIGH_LATITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_HIGH_LATITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A high latitude of a location bounding box represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3791,31 +3792,31 @@
 
 <A NAME="FIELD_HIGH_LONGITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_HIGH_LONGITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A high longitude of a location bounding box represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3823,31 +3824,31 @@
 
 <A NAME="FIELD_LATITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_LATITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A latitude of a location represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3855,31 +3856,31 @@
 
 <A NAME="FIELD_LONGITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_LONGITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A longitude of a location represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3887,31 +3888,31 @@
 
 <A NAME="FIELD_LOW_LATITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_LOW_LATITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A low latitude of a location bounding box represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3919,31 +3920,31 @@
 
 <A NAME="FIELD_LOW_LONGITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_LOW_LONGITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A low longitude of a location bounding box represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3951,31 +3952,31 @@
 
 <A NAME="FIELD_MAX"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_MAX
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A maximum value.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4015,31 +4016,31 @@
 
 <A NAME="FIELD_MIN"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_MIN
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A minimum value.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4113,31 +4114,31 @@
 
 <A NAME="FIELD_PERCENTAGE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_PERCENTAGE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A percentage value, between 0 and 100.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4145,31 +4146,31 @@
 
 <A NAME="FIELD_REVOLUTIONS"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_REVOLUTIONS
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A count of revolutions.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4177,31 +4178,31 @@
 
 <A NAME="FIELD_RPM"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_RPM
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Revolutions per minute or rate per minute.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4209,31 +4210,31 @@
 
 <A NAME="FIELD_SPEED"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_SPEED
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A speed in meter/sec.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4241,31 +4242,31 @@
 
 <A NAME="FIELD_STEPS"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_STEPS
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A count of steps.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4273,31 +4274,31 @@
 
 <A NAME="FIELD_WATTS"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_WATTS
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Power in watts.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4305,31 +4306,31 @@
 
 <A NAME="FIELD_WEIGHT"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_WEIGHT
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A weight in kilograms.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4354,14 +4355,14 @@
 
 <A NAME="describeContents()"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         int
       </span>
       <span class="sympad">describeContents</span>
@@ -4369,15 +4370,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
 
     </div>
@@ -4386,14 +4387,14 @@
 
 <A NAME="equals(java.lang.Object)"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         boolean
       </span>
       <span class="sympad">equals</span>
@@ -4401,15 +4402,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
 
     </div>
@@ -4418,14 +4419,14 @@
 
 <A NAME="getFormat()"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         int
       </span>
       <span class="sympad">getFormat</span>
@@ -4433,15 +4434,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Returns the format of the field, as one of the format constant values.
 </p></div>
 
@@ -4451,14 +4452,14 @@
 
 <A NAME="getName()"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         String
       </span>
       <span class="sympad">getName</span>
@@ -4466,15 +4467,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Returns the name of the field.
 </p></div>
 
@@ -4484,14 +4485,14 @@
 
 <A NAME="hashCode()"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         int
       </span>
       <span class="sympad">hashCode</span>
@@ -4499,15 +4500,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
 
     </div>
@@ -4516,14 +4517,14 @@
 
 <A NAME="toString()"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         String
       </span>
       <span class="sympad">toString</span>
@@ -4531,15 +4532,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
 
     </div>
@@ -4548,14 +4549,14 @@
 
 <A NAME="writeToParcel(android.os.Parcel, int)"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         void
       </span>
       <span class="sympad">writeToParcel</span>
@@ -4563,15 +4564,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
 
     </div>
@@ -4589,17 +4590,17 @@
 <A NAME="navbar_top"></A>
 
 <div id="footer" class="wrap" >
-        
+
 
   <div id="copyright">
-    
+
   Except as noted, this content is licensed under <a
-  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
+  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>.
   For details and restrictions, see the <a href="/license.html">
   Content License</a>.
   </div>
   <div id="build_info">
-    
+
 <script src="/timestamp.js" type="text/javascript"></script>
 <script>document.write(BUILD_TIMESTAMP)</script>
 
@@ -4607,7 +4608,7 @@
 
 
   <div id="footerlinks">
-    
+
   <p>
     <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
     <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
@@ -4620,7 +4621,7 @@
 
 </div><!-- end doc-content -->
 
-</div> <!-- end body-content --> 
+</div> <!-- end body-content -->
 
 
 
diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java
index 5fae831..3b25ba6 100644
--- a/keystore/java/android/security/AndroidKeyPairGenerator.java
+++ b/keystore/java/android/security/AndroidKeyPairGenerator.java
@@ -17,7 +17,7 @@
 package android.security;
 
 import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
 import com.android.org.conscrypt.OpenSSLEngine;
 
 import java.security.InvalidAlgorithmParameterException;
@@ -206,9 +206,9 @@
     }
 
     private static int getDefaultKeySize(int keyType) {
-        if (keyType == NativeCrypto.EVP_PKEY_EC) {
+        if (keyType == NativeConstants.EVP_PKEY_EC) {
             return EC_DEFAULT_KEY_SIZE;
-        } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
+        } else if (keyType == NativeConstants.EVP_PKEY_RSA) {
             return RSA_DEFAULT_KEY_SIZE;
         }
         return -1;
@@ -216,12 +216,12 @@
 
     private static void checkValidKeySize(String keyAlgorithm, int keyType, int keySize)
             throws InvalidAlgorithmParameterException {
-        if (keyType == NativeCrypto.EVP_PKEY_EC) {
+        if (keyType == NativeConstants.EVP_PKEY_EC) {
             if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
                 throw new InvalidAlgorithmParameterException("EC keys must be >= "
                         + EC_MIN_KEY_SIZE + " and <= " + EC_MAX_KEY_SIZE);
             }
-        } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
+        } else if (keyType == NativeConstants.EVP_PKEY_RSA) {
             if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
                 throw new InvalidAlgorithmParameterException("RSA keys must be >= "
                         + RSA_MIN_KEY_SIZE + " and <= " + RSA_MAX_KEY_SIZE);
@@ -234,7 +234,7 @@
 
     private static void checkCorrectParametersSpec(int keyType, int keySize,
             AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException {
-        if (keyType == NativeCrypto.EVP_PKEY_RSA && spec != null) {
+        if (keyType == NativeConstants.EVP_PKEY_RSA && spec != null) {
             if (spec instanceof RSAKeyGenParameterSpec) {
                 RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
                 if (keySize != -1 && keySize != rsaSpec.getKeysize()) {
@@ -260,7 +260,7 @@
 
     private static byte[][] getArgsForKeyType(int keyType, AlgorithmParameterSpec spec) {
         switch (keyType) {
-            case NativeCrypto.EVP_PKEY_RSA:
+            case NativeConstants.EVP_PKEY_RSA:
                 if (spec instanceof RSAKeyGenParameterSpec) {
                     RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
                     return new byte[][] { rsaSpec.getPublicExponent().toByteArray() };
diff --git a/keystore/java/android/security/CryptoOperationException.java b/keystore/java/android/security/CryptoOperationException.java
deleted file mode 100644
index 00c142f..0000000
--- a/keystore/java/android/security/CryptoOperationException.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security;
-
-/**
- * Base class for exceptions during cryptographic operations which cannot throw a suitable checked
- * exception.
- *
- * <p>The contract of the majority of crypto primitives/operations (e.g. {@code Cipher} or
- * {@code Signature}) is that they can throw a checked exception during initialization, but are not
- * permitted to throw a checked exception during operation. Because crypto operations can fail
- * for a variety of reasons after initialization, this base class provides type-safety for unchecked
- * exceptions that may be thrown in those cases.
- *
- * @hide
- */
-public class CryptoOperationException extends RuntimeException {
-
-    /**
-     * Constructs a new {@code CryptoOperationException} without detail message and cause.
-     */
-    public CryptoOperationException() {
-        super();
-    }
-
-    /**
-     * Constructs a new {@code CryptoOperationException} with the provided detail message and no
-     * cause.
-     */
-    public CryptoOperationException(String message) {
-        super(message);
-    }
-
-    /**
-     * Constructs a new {@code CryptoOperationException} with the provided detail message and cause.
-     */
-    public CryptoOperationException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    /**
-     * Constructs a new {@code CryptoOperationException} with the provided cause.
-     */
-    public CryptoOperationException(Throwable cause) {
-        super(cause);
-    }
-}
diff --git a/keystore/java/android/security/KeyExpiredException.java b/keystore/java/android/security/KeyExpiredException.java
index 35a5acc..e64bffa 100644
--- a/keystore/java/android/security/KeyExpiredException.java
+++ b/keystore/java/android/security/KeyExpiredException.java
@@ -16,13 +16,15 @@
 
 package android.security;
 
+import java.security.InvalidKeyException;
+
 /**
  * Indicates that a cryptographic operation failed because the employed key's validity end date
  * is in the past.
  *
  * @hide
  */
-public class KeyExpiredException extends CryptoOperationException {
+public class KeyExpiredException extends InvalidKeyException {
 
     /**
      * Constructs a new {@code KeyExpiredException} without detail message and cause.
diff --git a/keystore/java/android/security/KeyNotYetValidException.java b/keystore/java/android/security/KeyNotYetValidException.java
index f1c2cac..d36d80c 100644
--- a/keystore/java/android/security/KeyNotYetValidException.java
+++ b/keystore/java/android/security/KeyNotYetValidException.java
@@ -16,13 +16,15 @@
 
 package android.security;
 
+import java.security.InvalidKeyException;
+
 /**
  * Indicates that a cryptographic operation failed because the employed key's validity start date
  * is in the future.
  *
  * @hide
  */
-public class KeyNotYetValidException extends CryptoOperationException {
+public class KeyNotYetValidException extends InvalidKeyException {
 
     /**
      * Constructs a new {@code KeyNotYetValidException} without detail message and cause.
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 84a664e..3bc1b17 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -16,7 +16,7 @@
 
 package android.security;
 
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
 
 import android.os.Binder;
 import android.os.IBinder;
@@ -30,6 +30,7 @@
 import android.security.keymaster.OperationResult;
 import android.util.Log;
 
+import java.security.InvalidKeyException;
 import java.util.Locale;
 
 /**
@@ -87,9 +88,9 @@
 
     static int getKeyTypeForAlgorithm(String keyType) {
         if ("RSA".equalsIgnoreCase(keyType)) {
-            return NativeCrypto.EVP_PKEY_RSA;
+            return NativeConstants.EVP_PKEY_RSA;
         } else if ("EC".equalsIgnoreCase(keyType)) {
-            return NativeCrypto.EVP_PKEY_EC;
+            return NativeConstants.EVP_PKEY_EC;
         } else {
             return -1;
         }
@@ -508,7 +509,11 @@
         }
     }
 
-    public static KeyStoreException getKeyStoreException(int errorCode) {
+    /**
+     * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error
+     * code.
+     */
+    static KeyStoreException getKeyStoreException(int errorCode) {
         if (errorCode > 0) {
             // KeyStore layer error
             switch (errorCode) {
@@ -544,7 +549,11 @@
         }
     }
 
-    public static CryptoOperationException getCryptoOperationException(KeyStoreException e) {
+    /**
+     * Returns an {@link InvalidKeyException} corresponding to the provided
+     * {@link KeyStoreException}.
+     */
+    static InvalidKeyException getInvalidKeyException(KeyStoreException e) {
         switch (e.getErrorCode()) {
             case KeymasterDefs.KM_ERROR_KEY_EXPIRED:
                 return new KeyExpiredException();
@@ -553,11 +562,15 @@
             case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED:
                 return new UserNotAuthenticatedException();
             default:
-                return new CryptoOperationException("Crypto operation failed", e);
+                return new InvalidKeyException("Keystore operation failed", e);
         }
     }
 
-    public static CryptoOperationException getCryptoOperationException(int errorCode) {
-        return getCryptoOperationException(getKeyStoreException(errorCode));
+    /**
+     * Returns an {@link InvalidKeyException} corresponding to the provided keystore/keymaster error
+     * code.
+     */
+    static InvalidKeyException getInvalidKeyException(int errorCode) {
+        return getInvalidKeyException(getKeyStoreException(errorCode));
     }
 }
diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java
index 37e00b2..3b13e83 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/KeyStoreCipherSpi.java
@@ -136,6 +136,14 @@
     private Long mOperationHandle;
     private KeyStoreCryptoOperationChunkedStreamer mMainDataStreamer;
 
+    /**
+     * Encountered exception which could not be immediately thrown because it was encountered inside
+     * a method that does not throw checked exception. This exception will be thrown from
+     * {@code engineDoFinal}. Once such an exception is encountered, {@code engineUpdate} and
+     * {@code engineDoFinal} start ignoring input data.
+     */
+    private Exception mCachedException;
+
     protected KeyStoreCipherSpi(
             int keymasterAlgorithm,
             int keymasterBlockMode,
@@ -152,29 +160,62 @@
 
     @Override
     protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
-        init(opmode, key, random);
-        initAlgorithmSpecificParameters();
-        ensureKeystoreOperationInitialized();
+        resetAll();
+
+        boolean success = false;
+        try {
+            init(opmode, key, random);
+            initAlgorithmSpecificParameters();
+            try {
+                ensureKeystoreOperationInitialized();
+            } catch (InvalidAlgorithmParameterException e) {
+                throw new InvalidKeyException(e);
+            }
+            success = true;
+        } finally {
+            if (!success) {
+                resetAll();
+            }
+        }
     }
 
     @Override
     protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
             throws InvalidKeyException, InvalidAlgorithmParameterException {
-        init(opmode, key, random);
-        initAlgorithmSpecificParameters(params);
-        ensureKeystoreOperationInitialized();
+        resetAll();
+
+        boolean success = false;
+        try {
+            init(opmode, key, random);
+            initAlgorithmSpecificParameters(params);
+            ensureKeystoreOperationInitialized();
+            success = true;
+        } finally {
+            if (!success) {
+                resetAll();
+            }
+        }
     }
 
     @Override
     protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
             SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
-        init(opmode, key, random);
-        initAlgorithmSpecificParameters(params);
-        ensureKeystoreOperationInitialized();
+        resetAll();
+
+        boolean success = false;
+        try {
+            init(opmode, key, random);
+            initAlgorithmSpecificParameters(params);
+            ensureKeystoreOperationInitialized();
+            success = true;
+        } finally {
+            if (!success) {
+                resetAll();
+            }
+        }
     }
 
     private void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
-        resetAll();
         if (!(key instanceof KeyStoreSecretKey)) {
             throw new InvalidKeyException(
                     "Unsupported key: " + ((key != null) ? key.getClass().getName() : "null"));
@@ -207,6 +248,7 @@
         mOperationToken = null;
         mOperationHandle = null;
         mMainDataStreamer = null;
+        mCachedException = null;
     }
 
     private void resetWhilePreservingInitState() {
@@ -218,12 +260,17 @@
         mOperationHandle = null;
         mMainDataStreamer = null;
         mAdditionalEntropyForBegin = null;
+        mCachedException = null;
     }
 
-    private void ensureKeystoreOperationInitialized() {
+    private void ensureKeystoreOperationInitialized() throws InvalidKeyException,
+            InvalidAlgorithmParameterException {
         if (mMainDataStreamer != null) {
             return;
         }
+        if (mCachedException != null) {
+            return;
+        }
         if (mKey == null) {
             throw new IllegalStateException("Not initialized");
         }
@@ -252,11 +299,15 @@
         if (opResult == null) {
             throw new KeyStoreConnectException();
         } else if (opResult.resultCode != KeyStore.NO_ERROR) {
-            throw KeyStore.getCryptoOperationException(opResult.resultCode);
+            switch (opResult.resultCode) {
+                case KeymasterDefs.KM_ERROR_INVALID_NONCE:
+                    throw new InvalidAlgorithmParameterException("Invalid IV");
+            }
+            throw KeyStore.getInvalidKeyException(opResult.resultCode);
         }
 
         if (opResult.token == null) {
-            throw new CryptoOperationException("Keystore returned null operation token");
+            throw new IllegalStateException("Keystore returned null operation token");
         }
         mOperationToken = opResult.token;
         mOperationHandle = opResult.operationHandle;
@@ -270,7 +321,15 @@
 
     @Override
     protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
-        ensureKeystoreOperationInitialized();
+        if (mCachedException != null) {
+            return null;
+        }
+        try {
+            ensureKeystoreOperationInitialized();
+        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+            mCachedException = e;
+            return null;
+        }
 
         if (inputLen == 0) {
             return null;
@@ -280,7 +339,8 @@
         try {
             output = mMainDataStreamer.update(input, inputOffset, inputLen);
         } catch (KeyStoreException e) {
-            throw KeyStore.getCryptoOperationException(e);
+            mCachedException = e;
+            return null;
         }
 
         if (output.length == 0) {
@@ -309,7 +369,16 @@
     @Override
     protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
             throws IllegalBlockSizeException, BadPaddingException {
-        ensureKeystoreOperationInitialized();
+        if (mCachedException != null) {
+            throw (IllegalBlockSizeException)
+                    new IllegalBlockSizeException().initCause(mCachedException);
+        }
+
+        try {
+            ensureKeystoreOperationInitialized();
+        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+            throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
+        }
 
         byte[] output;
         try {
@@ -323,7 +392,7 @@
                 case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
                     throw new AEADBadTagException();
                 default:
-                    throw KeyStore.getCryptoOperationException(e);
+                    throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
             }
         }
 
@@ -584,11 +653,11 @@
             if (mIv == null) {
                 mIv = returnedIv;
             } else if ((returnedIv != null) && (!Arrays.equals(returnedIv, mIv))) {
-                throw new CryptoOperationException("IV in use differs from provided IV");
+                throw new IllegalStateException("IV in use differs from provided IV");
             }
         } else {
             if (returnedIv != null) {
-                throw new CryptoOperationException(
+                throw new IllegalStateException(
                         "IV in use despite IV not being used by this transformation");
             }
         }
diff --git a/keystore/java/android/security/KeyStoreConnectException.java b/keystore/java/android/security/KeyStoreConnectException.java
index 8ed6e04..1aa3aec 100644
--- a/keystore/java/android/security/KeyStoreConnectException.java
+++ b/keystore/java/android/security/KeyStoreConnectException.java
@@ -21,7 +21,7 @@
  *
  * @hide
  */
-public class KeyStoreConnectException extends CryptoOperationException {
+public class KeyStoreConnectException extends IllegalStateException {
     public KeyStoreConnectException() {
         super("Failed to communicate with keystore service");
     }
diff --git a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
index aafd2fa..0619199 100644
--- a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
@@ -136,7 +136,7 @@
                     // More input is available, but it wasn't included into the previous chunk
                     // because the chunk reached its maximum permitted size.
                     // Shouldn't have happened.
-                    throw new CryptoOperationException("Nothing consumed from max-sized chunk: "
+                    throw new IllegalStateException("Nothing consumed from max-sized chunk: "
                             + chunk.length + " bytes");
                 }
                 mBuffered = chunk;
@@ -148,7 +148,7 @@
                 mBufferedOffset = opResult.inputConsumed;
                 mBufferedLength = chunk.length - opResult.inputConsumed;
             } else {
-                throw new CryptoOperationException("Consumed more than provided: "
+                throw new IllegalStateException("Consumed more than provided: "
                         + opResult.inputConsumed + ", provided: " + chunk.length);
             }
 
@@ -160,7 +160,7 @@
                         try {
                             bufferedOutput.write(opResult.output);
                         } catch (IOException e) {
-                            throw new CryptoOperationException("Failed to buffer output", e);
+                            throw new IllegalStateException("Failed to buffer output", e);
                         }
                     }
                 } else {
@@ -173,7 +173,7 @@
                         try {
                             bufferedOutput.write(opResult.output);
                         } catch (IOException e) {
-                            throw new CryptoOperationException("Failed to buffer output", e);
+                            throw new IllegalStateException("Failed to buffer output", e);
                         }
                         return bufferedOutput.toByteArray();
                     }
@@ -233,10 +233,10 @@
         }
 
         if (opResult.inputConsumed < chunk.length) {
-            throw new CryptoOperationException("Keystore failed to consume all input. Provided: "
+            throw new IllegalStateException("Keystore failed to consume all input. Provided: "
                     + chunk.length + ", consumed: " + opResult.inputConsumed);
         } else if (opResult.inputConsumed > chunk.length) {
-            throw new CryptoOperationException("Keystore consumed more input than provided"
+            throw new IllegalStateException("Keystore consumed more input than provided"
                     + " . Provided: " + chunk.length + ", consumed: " + opResult.inputConsumed);
         }
 
diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/KeyStoreHmacSpi.java
index a19bbda..175369c 100644
--- a/keystore/java/android/security/KeyStoreHmacSpi.java
+++ b/keystore/java/android/security/KeyStoreHmacSpi.java
@@ -69,9 +69,10 @@
     private final int mKeymasterDigest;
     private final int mMacSizeBytes;
 
-    private String mKeyAliasInKeyStore;
+    // Fields below are populated by engineInit and should be preserved after engineDoFinal.
+    private KeyStoreSecretKey mKey;
 
-    // The fields below are reset by the engineReset operation.
+    // Fields below are reset when engineDoFinal succeeds.
     private KeyStoreCryptoOperationChunkedStreamer mChunkedStreamer;
     private IBinder mOperationToken;
     private Long mOperationHandle;
@@ -89,28 +90,39 @@
     @Override
     protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
             InvalidAlgorithmParameterException {
+        resetAll();
+
+        boolean success = false;
+        try {
+            init(key, params);
+            ensureKeystoreOperationInitialized();
+            success = true;
+        } finally {
+            if (!success) {
+                resetAll();
+            }
+        }
+    }
+
+    private void init(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
+        InvalidAlgorithmParameterException {
         if (key == null) {
             throw new InvalidKeyException("key == null");
         } else if (!(key instanceof KeyStoreSecretKey)) {
             throw new InvalidKeyException(
                     "Only Android KeyStore secret keys supported. Key: " + key);
         }
+        mKey = (KeyStoreSecretKey) key;
 
         if (params != null) {
             throw new InvalidAlgorithmParameterException(
                     "Unsupported algorithm parameters: " + params);
         }
 
-        mKeyAliasInKeyStore = ((KeyStoreSecretKey) key).getAlias();
-        if (mKeyAliasInKeyStore == null) {
-            throw new InvalidKeyException("Key's KeyStore alias not known");
-        }
-        engineReset();
-        ensureKeystoreOperationInitialized();
     }
 
-    @Override
-    protected void engineReset() {
+    private void resetAll() {
+        mKey = null;
         IBinder operationToken = mOperationToken;
         if (operationToken != null) {
             mOperationToken = null;
@@ -120,11 +132,26 @@
         mChunkedStreamer = null;
     }
 
-    private void ensureKeystoreOperationInitialized() {
+    private void resetWhilePreservingInitState() {
+        IBinder operationToken = mOperationToken;
+        if (operationToken != null) {
+            mOperationToken = null;
+            mKeyStore.abort(operationToken);
+        }
+        mOperationHandle = null;
+        mChunkedStreamer = null;
+    }
+
+    @Override
+    protected void engineReset() {
+        resetWhilePreservingInitState();
+    }
+
+    private void ensureKeystoreOperationInitialized() throws InvalidKeyException {
         if (mChunkedStreamer != null) {
             return;
         }
-        if (mKeyAliasInKeyStore == null) {
+        if (mKey == null) {
             throw new IllegalStateException("Not initialized");
         }
 
@@ -132,7 +159,8 @@
         keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC);
         keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
 
-        OperationResult opResult = mKeyStore.begin(mKeyAliasInKeyStore,
+        OperationResult opResult = mKeyStore.begin(
+                mKey.getAlias(),
                 KeymasterDefs.KM_PURPOSE_SIGN,
                 true,
                 keymasterArgs,
@@ -141,10 +169,10 @@
         if (opResult == null) {
             throw new KeyStoreConnectException();
         } else if (opResult.resultCode != KeyStore.NO_ERROR) {
-            throw KeyStore.getCryptoOperationException(opResult.resultCode);
+            throw KeyStore.getInvalidKeyException(opResult.resultCode);
         }
         if (opResult.token == null) {
-            throw new CryptoOperationException("Keystore returned null operation token");
+            throw new IllegalStateException("Keystore returned null operation token");
         }
         mOperationToken = opResult.token;
         mOperationHandle = opResult.operationHandle;
@@ -160,31 +188,39 @@
 
     @Override
     protected void engineUpdate(byte[] input, int offset, int len) {
-        ensureKeystoreOperationInitialized();
+        try {
+            ensureKeystoreOperationInitialized();
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException("Failed to reinitialize MAC", e);
+        }
 
         byte[] output;
         try {
             output = mChunkedStreamer.update(input, offset, len);
         } catch (KeyStoreException e) {
-            throw KeyStore.getCryptoOperationException(e);
+            throw new IllegalStateException("Keystore operation failed", e);
         }
         if ((output != null) && (output.length != 0)) {
-            throw new CryptoOperationException("Update operation unexpectedly produced output");
+            throw new IllegalStateException("Update operation unexpectedly produced output");
         }
     }
 
     @Override
     protected byte[] engineDoFinal() {
-        ensureKeystoreOperationInitialized();
+        try {
+            ensureKeystoreOperationInitialized();
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException("Failed to reinitialize MAC", e);
+        }
 
         byte[] result;
         try {
             result = mChunkedStreamer.doFinal(null, 0, 0);
         } catch (KeyStoreException e) {
-            throw KeyStore.getCryptoOperationException(e);
+            throw new IllegalStateException("Keystore operation failed", e);
         }
 
-        engineReset();
+        resetWhilePreservingInitState();
         return result;
     }
 
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
index 87e7ee6..dde3b8f 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -200,7 +200,8 @@
         int errorCode = mKeyStore.generateKey(
                 keyAliasInKeystore, args, additionalEntropy, flags, new KeyCharacteristics());
         if (errorCode != KeyStore.NO_ERROR) {
-            throw KeyStore.getCryptoOperationException(errorCode);
+            throw new IllegalStateException(
+                    "Keystore operation failed", KeyStore.getKeyStoreException(errorCode));
         }
         String keyAlgorithmJCA =
                 KeymasterUtils.getJcaSecretKeyAlgorithm(mKeymasterAlgorithm, mKeymasterDigest);
diff --git a/keystore/java/android/security/UserNotAuthenticatedException.java b/keystore/java/android/security/UserNotAuthenticatedException.java
index e6342ef..d0410b8 100644
--- a/keystore/java/android/security/UserNotAuthenticatedException.java
+++ b/keystore/java/android/security/UserNotAuthenticatedException.java
@@ -16,13 +16,15 @@
 
 package android.security;
 
+import java.security.InvalidKeyException;
+
 /**
  * Indicates that a cryptographic operation could not be performed because the user has not been
  * authenticated recently enough.
  *
  * @hide
  */
-public class UserNotAuthenticatedException extends CryptoOperationException {
+public class UserNotAuthenticatedException extends InvalidKeyException {
 
     /**
      * Constructs a new {@code UserNotAuthenticatedException} without detail message and cause.
diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
index 7a88dee..a7046dd2 100644
--- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
@@ -18,7 +18,7 @@
 
 import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
 
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
 import com.android.org.conscrypt.OpenSSLEngine;
 
 import android.test.AndroidTestCase;
@@ -768,7 +768,7 @@
         assertAliases(new String[] {});
 
         assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+                KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
                 null));
 
         assertAliases(new String[] { TEST_ALIAS_1 });
@@ -797,7 +797,7 @@
         assertAliases(new String[] {});
 
         assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+                KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
                 null));
 
         assertTrue("Should contain generated private key", mKeyStore.containsAlias(TEST_ALIAS_1));
@@ -1963,7 +1963,7 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
+                    NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
 
             Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
 
@@ -2019,7 +2019,7 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
+                    NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
 
             X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
                     TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
@@ -2032,7 +2032,7 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_2;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
+                    NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
 
             X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
                     TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
@@ -2064,7 +2064,7 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias,
-                    android.security.KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024,
+                    android.security.KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024,
                     android.security.KeyStore.FLAG_NONE, null));
 
             X509Certificate cert =
@@ -2116,7 +2116,7 @@
         assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
 
         assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3,
-                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+                KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
                 null));
 
         assertEquals("The keystore size should match expected", 3, mKeyStore.size());
@@ -2184,7 +2184,7 @@
     private void setupKey() throws Exception {
         final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
         assertTrue(mAndroidKeyStore
-                .generate(privateKeyAlias, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024,
+                .generate(privateKeyAlias, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024,
                         KeyStore.FLAG_ENCRYPTED, null));
 
         X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1,
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 1a5552a..916b1ba 100644
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -32,7 +32,7 @@
 import android.test.AssertionFailedError;
 import android.test.MoreAsserts;
 import android.test.suitebuilder.annotation.MediumTest;
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Date;
@@ -365,7 +365,7 @@
 
     public void testGenerate_NotInitialized_Fail() throws Exception {
         assertFalse("Should fail when keystore is not initialized",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
     }
 
@@ -373,7 +373,7 @@
         mKeyStore.password(TEST_PASSWD);
         mKeyStore.lock();
         assertFalse("Should fail when keystore is locked",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
     }
 
@@ -381,7 +381,7 @@
         assertTrue(mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key when unlocked",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
@@ -391,7 +391,7 @@
         assertTrue(mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key when unlocked",
-                mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
@@ -401,7 +401,7 @@
         assertTrue(mKeyStore.password(TEST_PASSWD));
 
         assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID,
-                    NativeCrypto.EVP_PKEY_RSA, RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
+                    NativeConstants.EVP_PKEY_RSA, RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
@@ -447,7 +447,7 @@
     public void testSign_Success() throws Exception {
         mKeyStore.password(TEST_PASSWD);
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
@@ -458,7 +458,7 @@
     public void testVerify_Success() throws Exception {
         mKeyStore.password(TEST_PASSWD);
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
@@ -486,7 +486,7 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
@@ -520,7 +520,7 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
@@ -554,7 +554,7 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertFalse("Should not be able to revoke not existent grant",
@@ -566,7 +566,7 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
@@ -584,7 +584,7 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                         RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
@@ -605,7 +605,7 @@
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
@@ -644,7 +644,7 @@
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
diff --git a/libs/androidfw/ObbFile.cpp b/libs/androidfw/ObbFile.cpp
index 195fa9a..95332a3 100644
--- a/libs/androidfw/ObbFile.cpp
+++ b/libs/androidfw/ObbFile.cpp
@@ -337,7 +337,9 @@
         return false;
     }
 
-    ftruncate(fd, mFooterStart);
+    if (ftruncate(fd, mFooterStart) == -1) {
+        return false;
+    }
 
     return true;
 }
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
index b2886bb..541d871 100644
--- a/media/java/android/media/MediaHTTPConnection.java
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -32,6 +32,7 @@
 import java.net.MalformedURLException;
 import java.net.NoRouteToHostException;
 import java.net.ProtocolException;
+import java.net.UnknownServiceException;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -337,7 +338,10 @@
         } catch (NoRouteToHostException e) {
             Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
             return MEDIA_ERROR_UNSUPPORTED;
-        } catch (IOException e) {
+        } catch (UnknownServiceException e) {
+            Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
+            return MEDIA_ERROR_UNSUPPORTED;
+        }catch (IOException e) {
             if (VERBOSE) {
                 Log.d(TAG, "readAt " + offset + " / " + size + " => -1");
             }
diff --git a/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk
index 27d1b23..19e44e3 100644
--- a/packages/PrintSpooler/Android.mk
+++ b/packages/PrintSpooler/Android.mk
@@ -18,6 +18,8 @@
 
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res frameworks/support/v7/recyclerview/res
+LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages android.support.v7.recyclerview
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_SRC_FILES += \
         src/com/android/printspooler/renderer/IPdfRenderer.aidl \
@@ -30,4 +32,4 @@
 
 include $(BUILD_PACKAGE)
 
-include $(call all-makefiles-under, $(LOCAL_PATH))
\ No newline at end of file
+include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 1ca772f..ecbdcb7 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -4225,8 +4225,9 @@
     /** {@inheritDoc} */
     @Override
     public int finishPostLayoutPolicyLw() {
-        if (mWinShowWhenLocked != null &&
-                mWinShowWhenLocked != mTopFullscreenOpaqueWindowState) {
+        if (mWinShowWhenLocked != null && mTopFullscreenOpaqueWindowState != null &&
+                mWinShowWhenLocked.getAppToken() != mTopFullscreenOpaqueWindowState.getAppToken()
+                && isKeyguardLocked()) {
             // A dialog is dismissing the keyguard. Put the wallpaper behind it and hide the
             // fullscreen window.
             // TODO: Make sure FLAG_SHOW_WALLPAPER is restored when dialog is dismissed. Or not.
diff --git a/preloaded-classes b/preloaded-classes
index 151766f..7a41bb2 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -828,6 +828,11 @@
 android.hardware.usb.UsbDevice
 android.hardware.usb.UsbDeviceConnection
 android.hardware.usb.UsbRequest
+# Initializing android.icu.impl.ICUBinary loads the ICU data.
+# Opening the files in the Zygote avoids StrictMode violations.
+# It also ensures the ICU data files are mapped on boot and all
+# apps will be consistent (even if files are added to /data).
+android.icu.impl.ICUBinary
 android.inputmethodservice.ExtractEditText
 android.location.Location
 android.location.Location$1
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index 65056ac..dda468a 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -66,7 +66,6 @@
     }
 
     /**
-     * @hide Pending API review
      * InvokeID is an identifier for an invoke function. It is used
      * as an identifier for ScriptGroup creation.
      *
@@ -86,7 +85,6 @@
 
     private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>();
     /**
-     * @hide Pending API review
      * Only to be used by generated reflected classes.
      */
     protected InvokeID createInvokeID(int slot) {
diff --git a/rs/java/android/renderscript/ScriptGroup.java b/rs/java/android/renderscript/ScriptGroup.java
index 51c838f..be8b0fd 100644
--- a/rs/java/android/renderscript/ScriptGroup.java
+++ b/rs/java/android/renderscript/ScriptGroup.java
@@ -16,32 +16,30 @@
 
 package android.renderscript;
 
+import android.util.Log;
+import android.util.Pair;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
- * ScriptGroup creates a group of kernels that are executed
- * together with one execution call as if they were a single kernel.
- * The kernels may be connected internally or to an external allocation.
- * The intermediate results for internal connections are not observable
- * after the execution of the script.
+ * A group of kernels that are executed
+ * together with one execution call as if they were a single kernel
  * <p>
- * External connections are grouped into inputs and outputs.
- * All outputs are produced by a script kernel and placed into a
- * user-supplied allocation. Inputs provide the input of a kernel.
- * Inputs bound to script globals are set directly upon the script.
+ * In addition to kernels, a script group may contain invocable functions as well.
+ * A script group may take inputs and generate outputs, which are consumed and
+ * produced by its member kernels.
+ * Inside a script group, outputs from one kernel can be passed to another kernel as inputs.
+ * The API disallows cyclic dependencies among kernels in a script group,
+ * effectively making it a directed acyclic graph (DAG) of kernels.
  * <p>
- * A ScriptGroup must contain at least one kernel. A ScriptGroup
- * must contain only a single directed acyclic graph (DAG) of
- * script kernels and connections. Attempting to create a
- * ScriptGroup with multiple DAGs or attempting to create
- * a cycle within a ScriptGroup will throw an exception.
- * <p>
- * Currently, all kernels in a ScriptGroup must be from separate
- * Script objects. Attempting to use multiple kernels from the same
- * Script object will result in an {@link android.renderscript.RSInvalidStateException}.
- *
+ * Grouping kernels together allows for more efficient execution. For example,
+ * runtime and compiler optimization can be applied to reduce computation and
+ * communication overhead, and to make better use of the CPU and the GPU.
  **/
 public final class ScriptGroup extends BaseObj {
+    private static final String TAG = "ScriptGroup";
     IO mOutputs[];
     IO mInputs[];
 
@@ -88,15 +86,364 @@
     }
 
 
+    /**
+     * An opaque class for closures
+     * <p>
+     * A closure represents a function call to a kernel or invocable function,
+     * combined with arguments and values for global variables. A closure is
+     * created using the {@link android.renderscript.ScriptGroup.Builder2#addKernel} or
+     * {@link android.renderscript.ScriptGroup.Builder2#addInvoke}
+     * method.
+     */
+
+    public static final class Closure extends BaseObj {
+        private Object[] mArgs;
+        private Allocation mReturnValue;
+        private Map<Script.FieldID, Object> mBindings;
+
+        private Future mReturnFuture;
+        private Map<Script.FieldID, Future> mGlobalFuture;
+
+        private FieldPacker mFP;
+
+        private static final String TAG = "Closure";
+
+        Closure(long id, RenderScript rs) {
+            super(id, rs);
+        }
+
+        Closure(RenderScript rs, Script.KernelID kernelID, Type returnType,
+                       Object[] args, Map<Script.FieldID, Object> globals) {
+            super(0, rs);
+
+            mArgs = args;
+            mReturnValue = Allocation.createTyped(rs, returnType);
+            mBindings = globals;
+            mGlobalFuture = new HashMap<Script.FieldID, Future>();
+
+            int numValues = args.length + globals.size();
+
+            long[] fieldIDs = new long[numValues];
+            long[] values = new long[numValues];
+            int[] sizes = new int[numValues];
+            long[] depClosures = new long[numValues];
+            long[] depFieldIDs = new long[numValues];
+
+            int i;
+            for (i = 0; i < args.length; i++) {
+                Object obj = args[i];
+                fieldIDs[i] = 0;
+                if (obj instanceof Input) {
+                    Input unbound = (Input)obj;
+                    unbound.addReference(this, i);
+                } else {
+                    retrieveValueAndDependenceInfo(rs, i, args[i], values, sizes,
+                                                   depClosures, depFieldIDs);
+                }
+            }
+
+            for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) {
+                Object obj = entry.getValue();
+                Script.FieldID fieldID = entry.getKey();
+                fieldIDs[i] = fieldID.getID(rs);
+                if (obj instanceof Input) {
+                    Input unbound = (Input)obj;
+                    unbound.addReference(this, fieldID);
+                } else {
+                    retrieveValueAndDependenceInfo(rs, i, obj, values,
+                                                   sizes, depClosures, depFieldIDs);
+                }
+                i++;
+            }
+
+            long id = rs.nClosureCreate(kernelID.getID(rs), mReturnValue.getID(rs),
+                                        fieldIDs, values, sizes, depClosures, depFieldIDs);
+
+            setID(id);
+        }
+
+        Closure(RenderScript rs, Script.InvokeID invokeID,
+                       Object[] args, Map<Script.FieldID, Object> globals) {
+            super(0, rs);
+            mFP = FieldPacker.createFromArray(args);
+
+            mArgs = args;
+            mBindings = globals;
+            mGlobalFuture = new HashMap<Script.FieldID, Future>();
+
+            int numValues = globals.size();
+
+            long[] fieldIDs = new long[numValues];
+            long[] values = new long[numValues];
+            int[] sizes = new int[numValues];
+            long[] depClosures = new long[numValues];
+            long[] depFieldIDs = new long[numValues];
+
+            int i = 0;
+            for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) {
+                Object obj = entry.getValue();
+                Script.FieldID fieldID = entry.getKey();
+                fieldIDs[i] = fieldID.getID(rs);
+                if (obj instanceof Input) {
+                    Input unbound = (Input)obj;
+                    unbound.addReference(this, fieldID);
+                } else {
+                    retrieveValueAndDependenceInfo(rs, i, obj, values,
+                                                   sizes, depClosures, depFieldIDs);
+                }
+                i++;
+            }
+
+            long id = rs.nInvokeClosureCreate(invokeID.getID(rs), mFP.getData(), fieldIDs,
+                                              values, sizes);
+
+            setID(id);
+        }
+
+        private static
+                void retrieveValueAndDependenceInfo(RenderScript rs,
+                                                    int index, Object obj,
+                                                    long[] values, int[] sizes,
+                                                    long[] depClosures,
+                                                    long[] depFieldIDs) {
+
+            if (obj instanceof Future) {
+                Future f = (Future)obj;
+                obj = f.getValue();
+                depClosures[index] = f.getClosure().getID(rs);
+                Script.FieldID fieldID = f.getFieldID();
+                depFieldIDs[index] = fieldID != null ? fieldID.getID(rs) : 0;
+                if (obj == null) {
+                    // Value is originally created by the owner closure
+                    values[index] = 0;
+                    sizes[index] = 0;
+                    return;
+                }
+            } else {
+                depClosures[index] = 0;
+                depFieldIDs[index] = 0;
+            }
+
+            ValueAndSize vs = new ValueAndSize(rs, obj);
+            values[index] = vs.value;
+            sizes[index] = vs.size;
+        }
+
+        /**
+         * Returns the future for the return value
+         *
+         * @return a future
+         */
+
+        public Future getReturn() {
+            if (mReturnFuture == null) {
+                mReturnFuture = new Future(this, null, mReturnValue);
+            }
+
+            return mReturnFuture;
+        }
+
+        /**
+         * Returns the future for a global variable
+         *
+         * @param field the field ID for the global variable
+         * @return a future
+         */
+
+        public Future getGlobal(Script.FieldID field) {
+            Future f = mGlobalFuture.get(field);
+
+            if (f == null) {
+                // If the field is not bound to this closure, this will return a future
+                // without an associated value (reference). So this is not working for
+                // cross-module (cross-script) linking in this case where a field not
+                // explicitly bound.
+                f = new Future(this, field, mBindings.get(field));
+                mGlobalFuture.put(field, f);
+            }
+
+            return f;
+        }
+
+        void setArg(int index, Object obj) {
+            mArgs[index] = obj;
+            ValueAndSize vs = new ValueAndSize(mRS, obj);
+            mRS.nClosureSetArg(getID(mRS), index, vs.value, vs.size);
+        }
+
+        void setGlobal(Script.FieldID fieldID, Object obj) {
+            mBindings.put(fieldID, obj);
+            ValueAndSize vs = new ValueAndSize(mRS, obj);
+            mRS.nClosureSetGlobal(getID(mRS), fieldID.getID(mRS), vs.value, vs.size);
+        }
+
+        private static final class ValueAndSize {
+            public ValueAndSize(RenderScript rs, Object obj) {
+                if (obj instanceof Allocation) {
+                    value = ((Allocation)obj).getID(rs);
+                    size = -1;
+                } else if (obj instanceof Boolean) {
+                    value = ((Boolean)obj).booleanValue() ? 1 : 0;
+                    size = 4;
+                } else if (obj instanceof Integer) {
+                    value = ((Integer)obj).longValue();
+                    size = 4;
+                } else if (obj instanceof Long) {
+                    value = ((Long)obj).longValue();
+                    size = 8;
+                } else if (obj instanceof Float) {
+                    value = ((Float)obj).longValue();
+                    size = 4;
+                } else if (obj instanceof Double) {
+                    value = ((Double)obj).longValue();
+                    size = 8;
+                }
+            }
+            public long value;
+            public int size;
+        }
+    }
+
+    /**
+     * An opaque class for futures
+     * <p>
+     * A future represents an output of a closure, either the return value of
+     * the function, or the value of a global variable written by the function.
+     * A future is created by calling the {@link Closure#getReturn}  or
+     * {@link Closure#getGlobal} method.
+     */
+
+    public static final class Future {
+        Closure mClosure;
+        Script.FieldID mFieldID;
+        Object mValue;
+
+        Future(Closure closure, Script.FieldID fieldID, Object value) {
+            mClosure = closure;
+            mFieldID = fieldID;
+            mValue = value;
+        }
+
+        Closure getClosure() { return mClosure; }
+        Script.FieldID getFieldID() { return mFieldID; }
+        Object getValue() { return mValue; }
+    }
+
+    /**
+     * An opaque class for script group inputs
+     * <p>
+     * Created by calling the {@link Builder2#addInput} method. The value
+     * is assigned in {@link ScriptGroup#execute(Object...)} method as
+     * one of its arguments. Arguments to the execute method should be in
+     * the same order as intputs are added using the addInput method.
+     */
+
+    public static final class Input {
+        // Either mFieldID or mArgIndex should be set but not both.
+        List<Pair<Closure, Script.FieldID>> mFieldID;
+        // -1 means unset. Legal values are 0 .. n-1, where n is the number of
+        // arguments for the referencing closure.
+        List<Pair<Closure, Integer>> mArgIndex;
+
+        Input() {
+            mFieldID = new ArrayList<Pair<Closure, Script.FieldID>>();
+            mArgIndex = new ArrayList<Pair<Closure, Integer>>();
+        }
+
+        void addReference(Closure closure, int index) {
+            mArgIndex.add(Pair.create(closure, Integer.valueOf(index)));
+        }
+
+        void addReference(Closure closure, Script.FieldID fieldID) {
+            mFieldID.add(Pair.create(closure, fieldID));
+        }
+
+        void set(Object value) {
+            for (Pair<Closure, Integer> p : mArgIndex) {
+                Closure closure = p.first;
+                int index = p.second.intValue();
+                closure.setArg(index, value);
+            }
+            for (Pair<Closure, Script.FieldID> p : mFieldID) {
+                Closure closure = p.first;
+                Script.FieldID fieldID = p.second;
+                closure.setGlobal(fieldID, value);
+            }
+        }
+    }
+
+    private String mName;
+    private List<Closure> mClosures;
+    private List<Input> mInputs2;
+    private Future[] mOutputs2;
+
     ScriptGroup(long id, RenderScript rs) {
         super(id, rs);
     }
 
+    ScriptGroup(RenderScript rs, String name, List<Closure> closures,
+                 List<Input> inputs, Future[] outputs) {
+        super(0, rs);
+        mName = name;
+        mClosures = closures;
+        mInputs2 = inputs;
+        mOutputs2 = outputs;
+
+        long[] closureIDs = new long[closures.size()];
+        for (int i = 0; i < closureIDs.length; i++) {
+            closureIDs[i] = closures.get(i).getID(rs);
+        }
+        long id = rs.nScriptGroup2Create(name, ScriptC.mCachePath, closureIDs);
+        setID(id);
+    }
+
+    /**
+     * Executes a script group
+     *
+     * @param inputs inputs to the script group
+     * @return outputs of the script group as an array of objects
+     */
+
+    public Object[] execute(Object... inputs) {
+        if (inputs.length < mInputs2.size()) {
+            Log.e(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
+                  "less than expected " + mInputs2.size());
+            return null;
+        }
+
+        if (inputs.length > mInputs2.size()) {
+            Log.i(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
+                  "more than expected " + mInputs2.size());
+        }
+
+        for (int i = 0; i < mInputs2.size(); i++) {
+            Object obj = inputs[i];
+            if (obj instanceof Future || obj instanceof Input) {
+                Log.e(TAG, this.toString() + ": input " + i +
+                      " is a future or unbound value");
+                return null;
+            }
+            Input unbound = mInputs2.get(i);
+            unbound.set(obj);
+        }
+
+        mRS.nScriptGroup2Execute(getID(mRS));
+
+        Object[] outputObjs = new Object[mOutputs2.length];
+        int i = 0;
+        for (Future f : mOutputs2) {
+            outputObjs[i++] = f.getValue();
+        }
+        return outputObjs;
+    }
+
     /**
      * Sets an input of the ScriptGroup. This specifies an
      * Allocation to be used for kernels that require an input
      * Allocation provided from outside of the ScriptGroup.
      *
+     * @deprecated Set arguments to {@link #execute(Object...)} instead.
+     *
      * @param s The ID of the kernel where the allocation should be
      *          connected.
      * @param a The allocation to connect.
@@ -117,6 +464,8 @@
      * Allocation to be used for the kernels that require an output
      * Allocation visible after the ScriptGroup is executed.
      *
+     * @deprecated Use return value of {@link #execute(Object...)} instead.
+     *
      * @param s The ID of the kernel where the allocation should be
      *          connected.
      * @param a The allocation to connect.
@@ -136,6 +485,9 @@
      * Execute the ScriptGroup.  This will run all the kernels in
      * the ScriptGroup.  No internal connection results will be visible
      * after execution of the ScriptGroup.
+     *
+     * @deprecated Use {@link #execute} instead.
+     *
      */
     public void execute() {
         mRS.nScriptGroupExecute(getID(mRS));
@@ -164,6 +516,8 @@
      * Once all connections are made, a call to {@link #create} will
      * return the ScriptGroup object.
      *
+     * @deprecated Use {@link Builder2} instead.
+     *
      */
     public static final class Builder {
         private RenderScript mRS;
@@ -464,7 +818,210 @@
 
     }
 
+    /**
+     * Represents a binding of a value to a global variable in a
+     * kernel or invocable function. Used in closure creation.
+     */
+
+    public static final class Binding {
+        private final Script.FieldID mField;
+        private final Object mValue;
+
+        /**
+         * Returns a Binding object that binds value to field
+         *
+         * @param field the Script.FieldID of the global variable
+         * @param value the value
+         */
+
+        public Binding(Script.FieldID field, Object value) {
+            mField = field;
+            mValue = value;
+        }
+
+        /**
+         * Returns the field ID
+         */
+
+        public Script.FieldID getField() { return mField; }
+
+        /**
+         * Returns the value
+         */
+
+        public Object getValue() { return mValue; }
+    }
+
+    /**
+     * The builder class for creating script groups
+     * <p>
+     * A script group is created using closures (see class {@link Closure}).
+     * A closure is a function call to a kernel or
+     * invocable function. Each function argument or global variable accessed inside
+     * the function is bound to 1) a known value, 2) a script group input
+     * (see class {@link Input}), or 3) a
+     * future (see class {@link Future}).
+     * A future is the output of a closure, either the return value of the
+     * function or a global variable written by that function.
+     * <p>
+     * Closures are created using the {@link #addKernel} or {@link #addInvoke}
+     * methods.
+     * When a closure is created, futures from previously created closures
+     * can be used as its inputs.
+     * External script group inputs can be used as inputs to individual closures as well.
+     * An external script group input is created using the {@link #addInput} method.
+     * A script group is created by a call to the {@link #create} method, which
+     * accepts an array of futures as the outputs for the script group.
+     * <p>
+     * Closures in a script group can be evaluated in any order as long as the
+     * following conditions are met:
+     * 1) a closure must be evaluated before any other closures that take its
+     * futures as inputs;
+     * 2) all closures added before an invoke closure must be evaluated
+     * before it;
+     * and 3) all closures added after an invoke closure must be evaluated after
+     * it.
+     * As a special case, the order that the closures are added is a legal
+     * evaluation order. However, other evaluation orders are possible, including
+     * concurrently evaluating independent closures.
+     */
+
+    public static final class Builder2 {
+        RenderScript mRS;
+        List<Closure> mClosures;
+        List<Input> mInputs;
+        private static final String TAG = "ScriptGroup.Builder2";
+
+        /**
+         * Returns a Builder object
+         *
+         * @param rs the RenderScript context
+         */
+        public Builder2(RenderScript rs) {
+            mRS = rs;
+            mClosures = new ArrayList<Closure>();
+            mInputs = new ArrayList<Input>();
+        }
+
+        /**
+         * Adds a closure for a kernel
+         *
+         * @param k Kernel ID for the kernel function
+         * @param returnType Allocation type for the return value
+         * @param args arguments to the kernel function
+         * @param globalBindings bindings for global variables
+         * @return a closure
+         */
+
+        private Closure addKernelInternal(Script.KernelID k, Type returnType, Object[] args,
+                                          Map<Script.FieldID, Object> globalBindings) {
+            Closure c = new Closure(mRS, k, returnType, args, globalBindings);
+            mClosures.add(c);
+            return c;
+        }
+
+        /**
+         * Adds a closure for an invocable function
+         *
+         * @param invoke Invoke ID for the invocable function
+         * @param args arguments to the invocable function
+         * @param globalBindings bindings for global variables
+         * @return a closure
+         */
+
+        private Closure addInvokeInternal(Script.InvokeID invoke, Object[] args,
+                                          Map<Script.FieldID, Object> globalBindings) {
+            Closure c = new Closure(mRS, invoke, args, globalBindings);
+            mClosures.add(c);
+            return c;
+        }
+
+        /**
+         * Adds a script group input
+         *
+         * @return a script group input, which can be used as an argument or a value to
+         *     a global variable for creating closures
+         */
+        public Input addInput() {
+            Input unbound = new Input();
+            mInputs.add(unbound);
+            return unbound;
+        }
+
+        /**
+         * Adds a closure for a kernel
+         *
+         * @param k Kernel ID for the kernel function
+         * @param argsAndBindings arguments followed by bindings for global variables
+         * @return a closure
+         */
+
+        public Closure addKernel(Script.KernelID k, Type returnType, Object... argsAndBindings) {
+            ArrayList<Object> args = new ArrayList<Object>();
+            Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
+            if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
+                return null;
+            }
+            return addKernelInternal(k, returnType, args.toArray(), bindingMap);
+        }
+
+        /**
+         * Adds a closure for an invocable function
+         *
+         * @param invoke Invoke ID for the invocable function
+         * @param argsAndBindings arguments followed by bindings for global variables
+         * @return a closure
+         */
+
+        public Closure addInvoke(Script.InvokeID invoke, Object... argsAndBindings) {
+            ArrayList<Object> args = new ArrayList<Object>();
+            Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
+            if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
+                return null;
+            }
+            return addInvokeInternal(invoke, args.toArray(), bindingMap);
+        }
+
+        /**
+         * Creates a script group
+         *
+         * @param name name for the script group. Legal names can only contain letters, digits,
+         *        '-', or '_'. The name can be no longer than 100 characters.
+         * @param outputs futures intended as outputs of the script group
+         * @return a script group
+         */
+
+        public ScriptGroup create(String name, Future... outputs) {
+            if (name == null || name.isEmpty() || name.length() > 100 ||
+                !name.equals(name.replaceAll("[^a-zA-Z0-9-]", "_"))) {
+                throw new RSIllegalArgumentException("invalid script group name");
+            }
+            ScriptGroup ret = new ScriptGroup(mRS, name, mClosures, mInputs, outputs);
+            return ret;
+        }
+
+        private boolean seperateArgsAndBindings(Object[] argsAndBindings,
+                                                ArrayList<Object> args,
+                                                Map<Script.FieldID, Object> bindingMap) {
+            int i;
+            for (i = 0; i < argsAndBindings.length; i++) {
+                if (argsAndBindings[i] instanceof Binding) {
+                    break;
+                }
+                args.add(argsAndBindings[i]);
+            }
+
+            for (; i < argsAndBindings.length; i++) {
+                if (!(argsAndBindings[i] instanceof Binding)) {
+                    return false;
+                }
+                Binding b = (Binding)argsAndBindings[i];
+                bindingMap.put(b.getField(), b.getValue());
+            }
+
+            return true;
+        }
+
+    }
 
 }
-
-
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 7623514..1545557 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -673,8 +673,7 @@
     }
 
     @Override
-    public IntentSender createAppWidgetConfigIntentSender(String callingPackage, int appWidgetId,
-            int intentFlags) {
+    public IntentSender createAppWidgetConfigIntentSender(String callingPackage, int appWidgetId) {
         final int userId = UserHandle.getCallingUserId();
 
         if (DEBUG) {
@@ -704,7 +703,6 @@
             Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
             intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
             intent.setComponent(provider.info.configure);
-            intent.setFlags(intentFlags);
 
             // All right, create the sender.
             final long identity = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index dbfb8fb..41d784c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1288,10 +1288,11 @@
 
     final ServiceThread mHandlerThread;
     final MainHandler mHandler;
+    final UiHandler mUiHandler;
 
-    final class MainHandler extends Handler {
-        public MainHandler(Looper looper) {
-            super(looper, null, true);
+    final class UiHandler extends Handler {
+        public UiHandler() {
+            super(com.android.server.UiThread.get().getLooper(), null, true);
         }
 
         @Override
@@ -1404,15 +1405,6 @@
                 d.show();
                 ensureBootCompleted();
             } break;
-            case UPDATE_CONFIGURATION_MSG: {
-                final ContentResolver resolver = mContext.getContentResolver();
-                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
-            } break;
-            case GC_BACKGROUND_PROCESSES_MSG: {
-                synchronized (ActivityManagerService.this) {
-                    performAppGcsIfAppropriateLocked();
-                }
-            } break;
             case WAIT_FOR_DEBUGGER_MSG: {
                 synchronized (ActivityManagerService.this) {
                     ProcessRecord app = (ProcessRecord)msg.obj;
@@ -1433,6 +1425,88 @@
                     }
                 }
             } break;
+            case SHOW_UID_ERROR_MSG: {
+                if (mShowDialogs) {
+                    AlertDialog d = new BaseErrorDialog(mContext);
+                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+                    d.setCancelable(false);
+                    d.setTitle(mContext.getText(R.string.android_system_label));
+                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
+                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
+                            obtainMessage(DISMISS_DIALOG_MSG, d));
+                    d.show();
+                }
+            } break;
+            case SHOW_FINGERPRINT_ERROR_MSG: {
+                if (mShowDialogs) {
+                    AlertDialog d = new BaseErrorDialog(mContext);
+                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+                    d.setCancelable(false);
+                    d.setTitle(mContext.getText(R.string.android_system_label));
+                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
+                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
+                            obtainMessage(DISMISS_DIALOG_MSG, d));
+                    d.show();
+                }
+            } break;
+            case SHOW_COMPAT_MODE_DIALOG_MSG: {
+                synchronized (ActivityManagerService.this) {
+                    ActivityRecord ar = (ActivityRecord) msg.obj;
+                    if (mCompatModeDialog != null) {
+                        if (mCompatModeDialog.mAppInfo.packageName.equals(
+                                ar.info.applicationInfo.packageName)) {
+                            return;
+                        }
+                        mCompatModeDialog.dismiss();
+                        mCompatModeDialog = null;
+                    }
+                    if (ar != null && false) {
+                        if (mCompatModePackages.getPackageAskCompatModeLocked(
+                                ar.packageName)) {
+                            int mode = mCompatModePackages.computeCompatModeLocked(
+                                    ar.info.applicationInfo);
+                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
+                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
+                                mCompatModeDialog = new CompatModeDialog(
+                                        ActivityManagerService.this, mContext,
+                                        ar.info.applicationInfo);
+                                mCompatModeDialog.show();
+                            }
+                        }
+                    }
+                }
+                break;
+            }
+            case START_USER_SWITCH_MSG: {
+                showUserSwitchDialog(msg.arg1, (String) msg.obj);
+                break;
+            }
+            case DISMISS_DIALOG_MSG: {
+                final Dialog d = (Dialog) msg.obj;
+                d.dismiss();
+                break;
+            }
+            }
+        }
+    }
+
+    final class MainHandler extends Handler {
+        public MainHandler(Looper looper) {
+            super(looper, null, true);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+            case UPDATE_CONFIGURATION_MSG: {
+                final ContentResolver resolver = mContext.getContentResolver();
+                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
+            } break;
+            case GC_BACKGROUND_PROCESSES_MSG: {
+                synchronized (ActivityManagerService.this) {
+                    performAppGcsIfAppropriateLocked();
+                }
+            } break;
             case SERVICE_TIMEOUT_MSG: {
                 if (mDidDexOpt) {
                     mDidDexOpt = false;
@@ -1497,30 +1571,6 @@
                     }
                 }
             } break;
-            case SHOW_UID_ERROR_MSG: {
-                if (mShowDialogs) {
-                    AlertDialog d = new BaseErrorDialog(mContext);
-                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
-                    d.setCancelable(false);
-                    d.setTitle(mContext.getText(R.string.android_system_label));
-                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
-                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
-                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
-                    d.show();
-                }
-            } break;
-            case SHOW_FINGERPRINT_ERROR_MSG: {
-                if (mShowDialogs) {
-                    AlertDialog d = new BaseErrorDialog(mContext);
-                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
-                    d.setCancelable(false);
-                    d.setTitle(mContext.getText(R.string.android_system_label));
-                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
-                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
-                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
-                    d.show();
-                }
-            } break;
             case PROC_START_TIMEOUT_MSG: {
                 if (mDidDexOpt) {
                     mDidDexOpt = false;
@@ -1621,34 +1671,6 @@
                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
                 }
             } break;
-            case SHOW_COMPAT_MODE_DIALOG_MSG: {
-                synchronized (ActivityManagerService.this) {
-                    ActivityRecord ar = (ActivityRecord)msg.obj;
-                    if (mCompatModeDialog != null) {
-                        if (mCompatModeDialog.mAppInfo.packageName.equals(
-                                ar.info.applicationInfo.packageName)) {
-                            return;
-                        }
-                        mCompatModeDialog.dismiss();
-                        mCompatModeDialog = null;
-                    }
-                    if (ar != null && false) {
-                        if (mCompatModePackages.getPackageAskCompatModeLocked(
-                                ar.packageName)) {
-                            int mode = mCompatModePackages.computeCompatModeLocked(
-                                    ar.info.applicationInfo);
-                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
-                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
-                                mCompatModeDialog = new CompatModeDialog(
-                                        ActivityManagerService.this, mContext,
-                                        ar.info.applicationInfo);
-                                mCompatModeDialog.show();
-                            }
-                        }
-                    }
-                }
-                break;
-            }
             case DISPATCH_PROCESSES_CHANGED: {
                 dispatchProcessesChanged();
                 break;
@@ -1669,10 +1691,6 @@
                 thread.start();
                 break;
             }
-            case START_USER_SWITCH_MSG: {
-                showUserSwitchDialog(msg.arg1, (String) msg.obj);
-                break;
-            }
             case REPORT_USER_SWITCH_MSG: {
                 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
                 break;
@@ -1780,11 +1798,6 @@
                 }
                 break;
             }
-            case DISMISS_DIALOG_MSG: {
-                final Dialog d = (Dialog) msg.obj;
-                d.dismiss();
-                break;
-            }
             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
                 synchronized (ActivityManagerService.this) {
                     int i = mTaskStackListeners.beginBroadcast();
@@ -2079,6 +2092,7 @@
                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
         mHandlerThread.start();
         mHandler = new MainHandler(mHandlerThread.getLooper());
+        mUiHandler = new UiHandler();
 
         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
                 "foreground", BROADCAST_FG_TIMEOUT, false);
@@ -2444,7 +2458,7 @@
         Message msg = Message.obtain();
         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
         msg.obj = r.task.askedCompatMode ? null : r;
-        mHandler.sendMessage(msg);
+        mUiHandler.sendMessage(msg);
     }
 
     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
@@ -5101,20 +5115,20 @@
                 map.put("activity", activity);
             }
 
-            mHandler.sendMessage(msg);
+            mUiHandler.sendMessage(msg);
         }
     }
 
     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
         if (!mLaunchWarningShown) {
             mLaunchWarningShown = true;
-            mHandler.post(new Runnable() {
+            mUiHandler.post(new Runnable() {
                 @Override
                 public void run() {
                     synchronized (ActivityManagerService.this) {
                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
                         d.show();
-                        mHandler.postDelayed(new Runnable() {
+                        mUiHandler.postDelayed(new Runnable() {
                             @Override
                             public void run() {
                                 synchronized (ActivityManagerService.this) {
@@ -5803,17 +5817,20 @@
             if (app.isolated) {
                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
             }
-            app.kill(reason, true);
-            handleAppDiedLocked(app, true, allowRestart);
-            removeLruProcessLocked(app);
-
+            boolean willRestart = false;
             if (app.persistent && !app.isolated) {
                 if (!callerWillRestart) {
-                    addAppLocked(app.info, false, null /* ABI override */);
+                    willRestart = true;
                 } else {
                     needRestart = true;
                 }
             }
+            app.kill(reason, true);
+            handleAppDiedLocked(app, willRestart, allowRestart);
+            if (willRestart) {
+                removeLruProcessLocked(app);
+                addAppLocked(app.info, false, null /* ABI override */);
+            }
         } else {
             mRemovedProcesses.add(app);
         }
@@ -8054,7 +8071,7 @@
             msg.what = WAIT_FOR_DEBUGGER_MSG;
             msg.obj = app;
             msg.arg1 = waiting ? 1 : 0;
-            mHandler.sendMessage(msg);
+            mUiHandler.sendMessage(msg);
         }
     }
 
@@ -11359,7 +11376,7 @@
                     Message msg = Message.obtain();
                     msg.what = SHOW_FACTORY_ERROR_MSG;
                     msg.getData().putCharSequence("msg", errorMsg);
-                    mHandler.sendMessage(msg);
+                    mUiHandler.sendMessage(msg);
                 }
             }
         }
@@ -11409,14 +11426,14 @@
                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
                             + " data partition or your device will be unstable.");
-                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
+                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
                 }
             } catch (RemoteException e) {
             }
 
             if (!Build.isFingerprintConsistent()) {
                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
-                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
+                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
             }
 
             long ident = Binder.clearCallingIdentity();
@@ -11702,7 +11719,7 @@
                 data.put("violationMask", violationMask);
                 data.put("info", info);
                 msg.obj = data;
-                mHandler.sendMessage(msg);
+                mUiHandler.sendMessage(msg);
 
                 Binder.restoreCallingIdentity(origId);
             }
@@ -12157,7 +12174,7 @@
             data.put("result", result);
             data.put("app", r);
             msg.obj = data;
-            mHandler.sendMessage(msg);
+            mUiHandler.sendMessage(msg);
 
             Binder.restoreCallingIdentity(origId);
         }
@@ -14891,7 +14908,7 @@
             }
         }
 
-        for (int i=0; i<cpr.connections.size(); i++) {
+        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
             ContentProviderConnection conn = cpr.connections.get(i);
             if (conn.waiting) {
                 // If this connection is waiting for the provider, then we don't
@@ -14983,10 +15000,11 @@
         boolean restart = false;
 
         // Remove published content providers.
-        for (int i=app.pubProviders.size()-1; i>=0; i--) {
+        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
             final boolean always = app.bad || !allowRestart;
-            if (removeDyingProviderLocked(app, cpr, always) || always) {
+            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
+            if ((inLaunching || always) && !cpr.connections.isEmpty()) {
                 // We left the provider in the launching list, need to
                 // restart it.
                 restart = true;
@@ -15004,7 +15022,7 @@
 
         // Unregister from connected content providers.
         if (!app.conProviders.isEmpty()) {
-            for (int i=0; i<app.conProviders.size(); i++) {
+            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
                 ContentProviderConnection conn = app.conProviders.get(i);
                 conn.provider.connections.remove(conn);
                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
@@ -15019,9 +15037,8 @@
         // XXX Commented out for now.  Trying to figure out a way to reproduce
         // the actual situation to identify what is actually going on.
         if (false) {
-            for (int i=0; i<mLaunchingProviders.size(); i++) {
-                ContentProviderRecord cpr = (ContentProviderRecord)
-                        mLaunchingProviders.get(i);
+            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
+                ContentProviderRecord cpr = mLaunchingProviders.get(i);
                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
                     synchronized (cpr) {
                         cpr.launchingApp = null;
@@ -15034,7 +15051,7 @@
         skipCurrentReceiverLocked(app);
 
         // Unregister any receivers.
-        for (int i=app.receivers.size()-1; i>=0; i--) {
+        for (int i = app.receivers.size() - 1; i >= 0; i--) {
             removeReceiverLocked(app.receivers.valueAt(i));
         }
         app.receivers.clear();
@@ -15052,7 +15069,7 @@
             }
         }
 
-        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
+        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
             ProcessChangeItem item = mPendingProcessChanges.get(i);
             if (item.pid == app.pid) {
                 mPendingProcessChanges.remove(i);
@@ -15127,18 +15144,14 @@
         // and if any run in this process then either schedule a restart of
         // the process or kill the client waiting for it if this process has
         // gone bad.
-        int NL = mLaunchingProviders.size();
         boolean restart = false;
-        for (int i=0; i<NL; i++) {
+        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
             ContentProviderRecord cpr = mLaunchingProviders.get(i);
             if (cpr.launchingApp == app) {
-                if (!alwaysBad && !app.bad) {
+                if (!alwaysBad && !app.bad && !cpr.connections.isEmpty()) {
                     restart = true;
                 } else {
                     removeDyingProviderLocked(app, cpr, true);
-                    // cpr should have been removed from mLaunchingProviders
-                    NL = mLaunchingProviders.size();
-                    i--;
                 }
             }
         }
@@ -18922,8 +18935,8 @@
             userName = userInfo.name;
             mTargetUserId = userId;
         }
-        mHandler.removeMessages(START_USER_SWITCH_MSG);
-        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
+        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
+        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
         return true;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ada16e7..d89fa15 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -780,8 +780,14 @@
     final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
             boolean dontWait) {
         if (mPausingActivity != null) {
-            Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity);
-            completePauseLocked(false);
+            Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
+                    + " state=" + mPausingActivity.state);
+            if (!mService.isSleeping()) {
+                // Avoid recursion among check for sleep and complete pause during sleeping.
+                // Because activity will be paused immediately after resume, just let pause
+                // be completed by the order of activity paused from clients.
+                completePauseLocked(false);
+            }
         }
         ActivityRecord prev = mResumedActivity;
         if (prev == null) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index aef9067..e9df96b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -340,6 +340,7 @@
 
     final boolean mHasPermanentDpad;
     final long mDrawLockTimeoutMillis;
+    final boolean mAllowAnimationsInLowPowerMode;
 
     final boolean mAllowBootMessages;
 
@@ -844,6 +845,8 @@
                 com.android.internal.R.bool.config_defaultInTouchMode);
         mDrawLockTimeoutMillis = context.getResources().getInteger(
                 com.android.internal.R.integer.config_drawLockTimeoutMillis);
+        mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
         mInputManager = inputManager; // Must be before createDisplayContentLocked.
         mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
         mDisplaySettings = new DisplaySettings();
@@ -869,7 +872,7 @@
             @Override
             public void onLowPowerModeChanged(boolean enabled) {
                 synchronized (mWindowMap) {
-                    if (mAnimationsDisabled != enabled) {
+                    if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {
                         mAnimationsDisabled = enabled;
                         dispatchNewAnimatorScaleLocked(null);
                     }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index f5d4867..e8cdc55 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -28,6 +28,8 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
@@ -79,6 +81,7 @@
         mResolver = context.getContentResolver();
         mDbHelper = new DatabaseHelper(context);
         mSoundTriggerHelper = new SoundTriggerHelper(context);
+        mServiceStub = new VoiceInteractionManagerServiceStub();
     }
 
     @Override
@@ -104,8 +107,7 @@
     }
 
     // implementation entry point and binder service
-    private final VoiceInteractionManagerServiceStub mServiceStub
-            = new VoiceInteractionManagerServiceStub();
+    private final VoiceInteractionManagerServiceStub mServiceStub;
 
     class VoiceInteractionManagerServiceStub extends IVoiceInteractionManagerService.Stub {
 
@@ -113,6 +115,11 @@
 
         private boolean mSafeMode;
         private int mCurUser;
+        private final boolean mEnableService;
+
+        VoiceInteractionManagerServiceStub() {
+            mEnableService = shouldEnableService(mContext.getResources());
+        }
 
         @Override
         public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
@@ -136,8 +143,7 @@
                     Settings.Secure.VOICE_INTERACTION_SERVICE, userHandle);
             ComponentName curRecognizer = getCurRecognizer(userHandle);
             VoiceInteractionServiceInfo curInteractorInfo = null;
-            if (curInteractorStr == null && curRecognizer != null
-                    && !ActivityManager.isLowRamDeviceStatic()) {
+            if (curInteractorStr == null && curRecognizer != null && mEnableService) {
                 // If there is no interactor setting, that means we are upgrading
                 // from an older platform version.  If the current recognizer is not
                 // set or matches the preferred recognizer, then we want to upgrade
@@ -155,7 +161,7 @@
 
             // If we are on a svelte device, make sure an interactor is not currently
             // enabled; if it is, turn it off.
-            if (ActivityManager.isLowRamDeviceStatic() && curInteractorStr != null) {
+            if (!mEnableService && curInteractorStr != null) {
                 if (!TextUtils.isEmpty(curInteractorStr)) {
                     setCurInteractor(null, userHandle);
                     curInteractorStr = "";
@@ -184,7 +190,7 @@
             }
 
             // Initializing settings, look for an interactor first (but only on non-svelte).
-            if (curInteractorInfo == null && !ActivityManager.isLowRamDeviceStatic()) {
+            if (curInteractorInfo == null && mEnableService) {
                 curInteractorInfo = findAvailInteractor(userHandle, null);
             }
 
@@ -210,6 +216,12 @@
             }
         }
 
+        private boolean shouldEnableService(Resources res) {
+            // VoiceInteractionService should not be enabled on low ram devices unless it has the config flag.
+            return !ActivityManager.isLowRamDeviceStatic()
+                    || res.getBoolean(com.android.internal.R.bool.config_forceEnableVoiceInteractionService);
+        }
+
         public void systemRunning(boolean safeMode) {
             mSafeMode = safeMode;
 
@@ -659,6 +671,7 @@
             }
             synchronized (this) {
                 pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)\n");
+                pw.println("  mEnableService: " + mEnableService);
                 if (mImpl == null) {
                     pw.println("  (No active implementation)");
                     return;
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
index 610c867..e9b5d6e 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
@@ -23,6 +23,8 @@
 
 import android.graphics.Shader.TileMode;
 
+import java.awt.image.ColorModel;
+
 /**
  * Delegate implementing the native methods of android.graphics.BitmapShader
  *
@@ -124,6 +126,11 @@
                 localMatrix = new java.awt.geom.AffineTransform();
             }
 
+            if (!colorModel.isCompatibleRaster(mImage.getRaster())) {
+                // Fallback to the default ARGB color model
+                colorModel = ColorModel.getRGBdefault();
+            }
+
             return new BitmapShaderContext(canvasMatrix, localMatrix, colorModel);
         }
 
@@ -153,8 +160,9 @@
 
             @Override
             public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
-                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
+                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
+                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
+                    mColorModel.isAlphaPremultiplied(), null);
 
                 int[] data = new int[w*h];
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
index 55c4b98..703719c 100644
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
@@ -172,8 +172,9 @@
 
             @Override
             public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
-                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
+                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
+                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
+                    mColorModel.isAlphaPremultiplied(), null);
 
                 int[] data = new int[w*h];
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
index eb29835..04e423b 100644
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
@@ -160,8 +160,9 @@
 
             @Override
             public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
-                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
+                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
+                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
+                    mColorModel.isAlphaPremultiplied(), null);
 
                 int[] data = new int[w*h];
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
index 95a57a9..544ba98 100644
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
@@ -152,8 +152,9 @@
 
             @Override
             public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
-                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
+                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
+                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
+                    mColorModel.isAlphaPremultiplied(), null);
 
                 int[] data = new int[w*h];
 
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index 5db9556..2e649c3 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -16,19 +16,15 @@
 
 package android.view;
 
-import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.MergeCookie;
 import com.android.ide.common.rendering.api.ResourceReference;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.support.RecyclerViewUtil;
-import com.android.layoutlib.bridge.android.support.RecyclerViewUtil.LayoutManagerType;
 import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
 import com.android.resources.ResourceType;
 import com.android.util.Pair;
 
@@ -233,22 +229,6 @@
             if (viewKey != null) {
                 bc.addViewKey(view, viewKey);
             }
-            if (RenderSessionImpl.isInstanceOf(view, RecyclerViewUtil.CN_RECYCLER_VIEW)) {
-                String type = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES,
-                                BridgeConstants.ATTR_LAYOUT_MANAGER_TYPE);
-                if (type != null) {
-                    LayoutManagerType layoutManagerType = LayoutManagerType.getByLogicalName(type);
-                    if (layoutManagerType == null) {
-                        layoutManagerType = LayoutManagerType.getByClassName(type);
-                    }
-                    if (layoutManagerType == null) {
-                        // add the classname itself.
-                        bc.addCookie(view, type);
-                    } else {
-                        bc.addCookie(view, layoutManagerType);
-                    }
-                }
-            }
         }
     }
 
diff --git a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
index ec3a8d6..30512aa 100644
--- a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
+++ b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
@@ -19,6 +19,7 @@
 import com.android.layoutlib.bridge.impl.ResourceHelper;
 
 import android.graphics.Canvas;
+import android.graphics.Canvas_Delegate;
 import android.graphics.LinearGradient;
 import android.graphics.Outline;
 import android.graphics.Paint;
@@ -125,6 +126,9 @@
 
     private static void sideShadow(Canvas canvas, Paint edgePaint,
             RectF edgeShadowRect, float dx, float dy, int rotations) {
+        if (isRectEmpty(edgeShadowRect)) {
+            return;
+        }
         int saved = canvas.save();
         canvas.translate(dx, dy);
         canvas.rotate(rotations * PERPENDICULAR_ANGLE);
@@ -153,4 +157,15 @@
         canvas.drawPath(path, paint);
         canvas.restoreToCount(saved);
     }
+
+    /**
+     * Differs from {@link RectF#isEmpty()} as this first converts the rect to int and then checks.
+     * <p/>
+     * This is required because {@link Canvas_Delegate#native_drawRect(long, float, float, float,
+     * float, long)} casts the co-ordinates to int and we want to ensure that it doesn't end up
+     * drawing empty rectangles, which results in IllegalArgumentException.
+     */
+    private static boolean isRectEmpty(RectF rect) {
+        return (int) rect.left >= (int) rect.right || (int) rect.top >= (int) rect.bottom;
+    }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 4d2c2fc..c6d60f8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -181,7 +181,7 @@
      */
     private static LayoutLog sCurrentLog = sDefaultLog;
 
-    private static final int LAST_SUPPORTED_FEATURE = Features.PREFERENCES_RENDERING;
+    private static final int LAST_SUPPORTED_FEATURE = Features.RENDER_ALL_DRAWABLE_STATES;
 
     @Override
     public int getApiLevel() {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
index e0f87fd..feb2590 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
@@ -86,11 +86,14 @@
     }
 
     @Override
-    public Result render(long timeout) {
+    public Result render(long timeout, boolean forceMeasure) {
         try {
             Bridge.prepareThread();
             mLastResult = mSession.acquire(timeout);
             if (mLastResult.isSuccess()) {
+                if (forceMeasure) {
+                    mSession.invalidateRenderingSize();
+                }
                 mLastResult = mSession.render(false /*freshRender*/);
             }
         } finally {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 3f553e7..2cbbeba 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -92,6 +92,8 @@
 import java.util.List;
 import java.util.Map;
 
+import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE;
+
 /**
  * Custom implementation of Context/Activity to handle non compiled resources.
  */
@@ -305,7 +307,7 @@
         // check if this is a style resource
         if (value instanceof StyleResourceValue) {
             // get the id that will represent this style.
-            outValue.resourceId = getDynamicIdByStyle((StyleResourceValue)value);
+            outValue.resourceId = getDynamicIdByStyle((StyleResourceValue) value);
             return true;
         }
 
@@ -783,6 +785,14 @@
     }
 
 
+    @Override
+    public String getPackageName() {
+        if (mApplicationInfo.packageName == null) {
+            mApplicationInfo.packageName = mLayoutlibCallback.getFlag(FLAG_KEY_APPLICATION_PACKAGE);
+        }
+        return mApplicationInfo.packageName;
+    }
+
     // ------------- private new methods
 
     /**
@@ -1190,12 +1200,6 @@
     }
 
     @Override
-    public String getPackageName() {
-        // pass
-        return null;
-    }
-
-    @Override
     public String getBasePackageName() {
         // pass
         return null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java
new file mode 100644
index 0000000..b98f96f
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.layoutlib.bridge.android;
+
+import com.android.ide.common.rendering.api.RenderParams;
+import com.android.ide.common.rendering.api.SessionParams.Key;
+
+/**
+ * This contains all known keys for the {@link RenderParams#getFlag(Key)}.
+ * <p/>
+ * The IDE has its own copy of this class which may be newer or older than this one.
+ * <p/>
+ * Constants should never be modified or removed from this class.
+ */
+public final class RenderParamsFlags {
+
+    public static final Key<String> FLAG_KEY_ROOT_TAG =
+            new Key<String>("rootTag", String.class);
+    public static final Key<Boolean> FLAG_KEY_DISABLE_BITMAP_CACHING =
+            new Key<Boolean>("disableBitmapCaching", Boolean.class);
+    public static final Key<Boolean> FLAG_KEY_RENDER_ALL_DRAWABLE_STATES =
+            new Key<Boolean>("renderAllDrawableStates", Boolean.class);
+    /**
+     * To tell LayoutLib that the IDE supports RecyclerView.
+     * <p/>
+     * Default is false.
+     */
+    public static final Key<Boolean> FLAG_KEY_RECYCLER_VIEW_SUPPORT =
+            new Key<Boolean>("recyclerViewSupport", Boolean.class);
+    /**
+     * The application package name. Used via
+     * {@link com.android.ide.common.rendering.api.LayoutlibCallback#getFlag(Key)}
+     */
+    public static final Key<String> FLAG_KEY_APPLICATION_PACKAGE =
+            new Key<String>("applicationPackage", String.class);
+
+    // Disallow instances.
+    private RenderParamsFlags() {}
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/SessionParamsFlags.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/SessionParamsFlags.java
deleted file mode 100644
index 22b5192..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/SessionParamsFlags.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.ide.common.rendering.api.SessionParams;
-
-/**
- * This contains all known keys for the {@link SessionParams#getFlag(SessionParams.Key)}.
- * <p/>
- * The IDE has its own copy of this class which may be newer or older than this one.
- * <p/>
- * Constants should never be modified or removed from this class.
- */
-public final class SessionParamsFlags {
-
-    public static final SessionParams.Key<String> FLAG_KEY_ROOT_TAG =
-            new SessionParams.Key<String>("rootTag", String.class);
-    public static final SessionParams.Key<Boolean> FLAG_KEY_RECYCLER_VIEW_SUPPORT =
-            new SessionParams.Key<Boolean>("recyclerViewSupport", Boolean.class);
-
-    // Disallow instances.
-    private SessionParamsFlags() {}
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
index aac5d33..e4c7288 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
@@ -23,15 +23,16 @@
 import com.android.ide.common.rendering.api.SessionParams;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.SessionParamsFlags;
+import com.android.layoutlib.bridge.android.RenderParamsFlags;
 
 import android.content.Context;
 import android.view.View;
-import android.widget.LinearLayout;
 
 import java.lang.reflect.Method;
 
-import static com.android.layoutlib.bridge.util.ReflectionUtils.*;
+import static com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
+import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
+import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
 
 /**
  * Utility class for working with android.support.v7.widget.RecyclerView
@@ -39,17 +40,15 @@
 @SuppressWarnings("SpellCheckingInspection")  // for "recycler".
 public class RecyclerViewUtil {
 
-    /**
-     * Used by {@link LayoutManagerType}.
-     * <p/>
-     * Not declared inside the enum, since it needs to be accessible in the constructor.
-     */
-    private static final Object CONTEXT = new Object();
-
-    public static final String CN_RECYCLER_VIEW = "android.support.v7.widget.RecyclerView";
+    private static final String RV_PKG_PREFIX = "android.support.v7.widget.";
+    public static final String CN_RECYCLER_VIEW = RV_PKG_PREFIX + "RecyclerView";
     private static final String CN_LAYOUT_MANAGER = CN_RECYCLER_VIEW + "$LayoutManager";
     private static final String CN_ADAPTER = CN_RECYCLER_VIEW + "$Adapter";
 
+    // LinearLayoutManager related constants.
+    private static final String CN_LINEAR_LAYOUT_MANAGER = RV_PKG_PREFIX + "LinearLayoutManager";
+    private static final Class<?>[] LLM_CONSTRUCTOR_SIGNATURE = new Class<?>[]{Context.class};
+
     /**
      * Tries to create an Adapter ({@code android.support.v7.widget.RecyclerView.Adapter} and a
      * LayoutManager {@code RecyclerView.LayoutManager} and assign these to the {@code RecyclerView}
@@ -71,39 +70,35 @@
 
     private static void setLayoutManager(@NonNull View recyclerView, @NonNull BridgeContext context,
             @NonNull LayoutlibCallback callback) throws ReflectionException {
-        Object cookie = context.getCookie(recyclerView);
-        assert cookie == null || cookie instanceof LayoutManagerType || cookie instanceof String;
-        if (!(cookie instanceof LayoutManagerType)) {
-            if (cookie != null) {
-                // TODO: When layoutlib API is updated, try to load the class with a null
-                // constructor or a constructor taking one argument - the context.
-                Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED,
-                        "LayoutManager (" + cookie + ") not found, falling back to " +
-                                "LinearLayoutManager", null);
-            }
-            cookie = LayoutManagerType.getDefault();
+        if (getLayoutManager(recyclerView) == null) {
+            // Only set the layout manager if not already set by the recycler view.
+            Object layoutManager = createLayoutManager(context, callback);
+            setProperty(recyclerView, CN_LAYOUT_MANAGER, layoutManager, "setLayoutManager");
         }
-        Object layoutManager = createLayoutManager((LayoutManagerType) cookie, context, callback);
-        setProperty(recyclerView, CN_LAYOUT_MANAGER, layoutManager, "setLayoutManager");
     }
 
+    /** Creates a LinearLayoutManager using the provided context. */
     @Nullable
-    private static Object createLayoutManager(@Nullable LayoutManagerType type,
-            @NonNull Context context, @NonNull LayoutlibCallback callback)
+    private static Object createLayoutManager(@NonNull Context context,
+            @NonNull LayoutlibCallback callback)
             throws ReflectionException {
-        if (type == null) {
-            type = LayoutManagerType.getDefault();
-        }
         try {
-            return callback.loadView(type.getClassName(), type.getSignature(), type.getArgs(context));
+            return callback.loadView(CN_LINEAR_LAYOUT_MANAGER, LLM_CONSTRUCTOR_SIGNATURE,
+                    new Object[]{ context});
         } catch (Exception e) {
             throw new ReflectionException(e);
         }
     }
 
     @Nullable
+    private static Object getLayoutManager(View recyclerview) throws ReflectionException {
+        Method getLayoutManager = getMethod(recyclerview.getClass(), "getLayoutManager");
+        return getLayoutManager != null ? invoke(getLayoutManager, recyclerview) : null;
+    }
+
+    @Nullable
     private static Object createAdapter(@NonNull SessionParams params) throws ReflectionException {
-        Boolean ideSupport = params.getFlag(SessionParamsFlags.FLAG_KEY_RECYCLER_VIEW_SUPPORT);
+        Boolean ideSupport = params.getFlag(RenderParamsFlags.FLAG_KEY_RECYCLER_VIEW_SUPPORT);
         if (ideSupport != Boolean.TRUE) {
             return null;
         }
@@ -145,74 +140,4 @@
         }
         throw new RuntimeException("invalid object/classname combination.");
     }
-
-    /** Supported LayoutManagers. */
-    public enum LayoutManagerType {
-        LINEAR_LAYOUT_MANGER("Linear",
-                "android.support.v7.widget.LinearLayoutManager",
-                new Class[]{Context.class}, new Object[]{CONTEXT}),
-        GRID_LAYOUT_MANAGER("Grid",
-                "android.support.v7.widget.GridLayoutManager",
-                new Class[]{Context.class, int.class}, new Object[]{CONTEXT, 2}),
-        STAGGERED_GRID_LAYOUT_MANAGER("StaggeredGrid",
-                "android.support.v7.widget.StaggeredGridLayoutManager",
-                new Class[]{int.class, int.class}, new Object[]{2, LinearLayout.VERTICAL});
-
-        private String mLogicalName;
-        private String mClassName;
-        private Class[] mSignature;
-        private Object[] mArgs;
-
-        LayoutManagerType(String logicalName, String className, Class[] signature, Object[] args) {
-            mLogicalName = logicalName;
-            mClassName = className;
-            mSignature = signature;
-            mArgs = args;
-        }
-
-        String getClassName() {
-            return mClassName;
-        }
-
-        Class[] getSignature() {
-            return mSignature;
-        }
-
-        @NonNull
-        Object[] getArgs(Context context) {
-            Object[] args = new Object[mArgs.length];
-            System.arraycopy(mArgs, 0, args, 0, mArgs.length);
-            for (int i = 0; i < args.length; i++) {
-                if (args[i] == CONTEXT) {
-                    args[i] = context;
-                }
-            }
-            return args;
-        }
-
-        @NonNull
-        public static LayoutManagerType getDefault() {
-            return LINEAR_LAYOUT_MANGER;
-        }
-
-        @Nullable
-        public static LayoutManagerType getByLogicalName(@NonNull String logicalName) {
-            for (LayoutManagerType type : values()) {
-                if (logicalName.equals(type.mLogicalName)) {
-                    return type;
-                }
-            }
-            return null;
-        }
-
-        @Nullable
-        public static LayoutManagerType getByClassName(@NonNull String className) {
-            for (LayoutManagerType type : values()) {
-                if (className.equals(type.mClassName)) {
-                    return type;
-                }
-            }
-            return null;
-        }
-    }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
index 9f9b968..dc89d0c 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
@@ -74,7 +74,7 @@
     }
 
     public static String getTime(int platformVersion) {
-        if (platformVersion == 0) {
+        if (isGreaterOrEqual(platformVersion, LOLLIPOP_MR1)) {
             return "5:10";
         }
         if (platformVersion < GINGERBREAD) {
@@ -117,7 +117,7 @@
     }
 
     public static String getWifiIconType(int platformVersion) {
-        return platformVersion == 0 ? "xml" : "png";
+        return isGreaterOrEqual(platformVersion, LOLLIPOP) ? "xml" : "png";
     }
 
     /**
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
index 9450b6c..04aadff 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
@@ -21,6 +21,10 @@
 
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.util.AttributeSet;
+import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
@@ -29,6 +33,21 @@
     /** Navigation bar background color attribute name. */
     private static final String ATTR_COLOR = "navigationBarColor";
 
+    /**
+     * Constructor to be used when creating the {@link NavigationBar} as a regular control.
+     * This is currently used by the theme editor.
+     */
+    public NavigationBar(Context context, AttributeSet attrs)
+            throws XmlPullParserException {
+        this((BridgeContext) context,
+                Density.getEnum(((BridgeContext) context).getMetrics().densityDpi),
+                LinearLayout.HORIZONTAL, // In this mode, it doesn't need to be render vertically
+                ((BridgeContext) context).getConfiguration().getLayoutDirection() ==
+                        View.LAYOUT_DIRECTION_RTL,
+                (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0,
+                context.getApplicationInfo().targetSdkVersion);
+    }
+
     public NavigationBar(BridgeContext context, Density density, int orientation, boolean isRtl,
             boolean rtlEnabled, int simulatedPlatformVersion) throws XmlPullParserException {
         super(context, orientation, "/bars/navigation_bar.xml", "navigation_bar.xml",
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
index e5f1f68..a0ed0e8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
@@ -25,7 +25,9 @@
 
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
 import android.widget.ImageView;
@@ -39,7 +41,20 @@
 
     private final int mSimulatedPlatformVersion;
     /** Status bar background color attribute name. */
-    private static final String ATTR_COLOR = "colorPrimaryDark";
+    private static final String ATTR_COLOR = "statusBarColor";
+
+    /**
+     * Constructor to be used when creating the {@link StatusBar} as a regular control. This
+     * is currently used by the theme editor.
+     */
+    public StatusBar(Context context, AttributeSet attrs) throws XmlPullParserException {
+        this((BridgeContext) context,
+                Density.getEnum(((BridgeContext) context).getMetrics().densityDpi),
+                LinearLayout.HORIZONTAL, // In this mode, it doesn't need to be render vertically
+                ((BridgeContext) context).getConfiguration().getLayoutDirection() ==
+                        View.LAYOUT_DIRECTION_RTL,
+                context.getApplicationInfo().targetSdkVersion);
+    }
 
     public StatusBar(BridgeContext context, Density density, int direction, boolean RtlEnabled,
             int simulatedPlatformVersion) throws XmlPullParserException {
@@ -50,6 +65,7 @@
 
         // FIXME: use FILL_H?
         setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT);
+
         int color = getThemeAttrColor(ATTR_COLOR, true);
         setBackgroundColor(color == 0 ? Config.getStatusBarColor(simulatedPlatformVersion) : color);
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
index 3a0321a..c34f9b5 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
@@ -35,6 +35,7 @@
 import java.awt.Color;
 import java.awt.Composite;
 import java.awt.Graphics2D;
+import java.awt.Rectangle;
 import java.awt.RenderingHints;
 import java.awt.Shape;
 import java.awt.geom.AffineTransform;
@@ -615,8 +616,22 @@
                 return;
             }
 
-            int width = layer.getImage().getWidth();
-            int height = layer.getImage().getHeight();
+            int width;
+            int height;
+            Rectangle clipBounds = originalGraphics.getClipBounds();
+            if (clipBounds != null) {
+                if (clipBounds.width == 0 || clipBounds.height == 0) {
+                    // Clip is 0 so no need to paint anything.
+                    return;
+                }
+                // If we have clipBounds available, use them as they will always be
+                // smaller than the full layer size.
+                width = clipBounds.width;
+                height = clipBounds.height;
+            } else {
+                width = layer.getImage().getWidth();
+                height = layer.getImage().getHeight();
+            }
 
             // Create a temporary image to which the color filter will be applied.
             BufferedImage image = new BufferedImage(width, height,
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
index 6513c5f..9e26502 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
@@ -22,12 +22,14 @@
 import com.android.ide.common.rendering.api.Result;
 import com.android.ide.common.rendering.api.Result.Status;
 import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.RenderParamsFlags;
 import com.android.resources.ResourceType;
 
 import android.graphics.Bitmap;
 import android.graphics.Bitmap_Delegate;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
 import android.view.AttachInfo_Accessor;
 import android.view.View.MeasureSpec;
 import android.widget.FrameLayout;
@@ -37,6 +39,10 @@
 import java.awt.Graphics2D;
 import java.awt.image.BufferedImage;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}.
  *
@@ -68,11 +74,37 @@
             return Status.ERROR_NOT_A_DRAWABLE.createResult();
         }
 
+        Drawable d = ResourceHelper.getDrawable(drawableResource, context);
+
+        final Boolean allStates =
+                params.getFlag(RenderParamsFlags.FLAG_KEY_RENDER_ALL_DRAWABLE_STATES);
+        if (allStates == Boolean.TRUE) {
+            final List<BufferedImage> result;
+
+            if (d instanceof StateListDrawable) {
+                result = new ArrayList<BufferedImage>();
+                final StateListDrawable stateList = (StateListDrawable) d;
+                for (int i = 0; i < stateList.getStateCount(); i++) {
+                    final Drawable stateDrawable = stateList.getStateDrawable(i);
+                    result.add(renderImage(hardwareConfig, stateDrawable, context));
+                }
+            } else {
+                result = Collections.singletonList(renderImage(hardwareConfig, d, context));
+            }
+
+            return Status.SUCCESS.createResult(result);
+        } else {
+            BufferedImage image = renderImage(hardwareConfig, d, context);
+            return Status.SUCCESS.createResult(image);
+        }
+    }
+
+    private BufferedImage renderImage(HardwareConfig hardwareConfig, Drawable d,
+            BridgeContext context) {
         // create a simple FrameLayout
         FrameLayout content = new FrameLayout(context);
 
         // get the actual Drawable object to draw
-        Drawable d = ResourceHelper.getDrawable(drawableResource, context);
         content.setBackground(d);
 
         // set the AttachInfo on the root view.
@@ -80,8 +112,27 @@
 
 
         // measure
-        int w = hardwareConfig.getScreenWidth();
-        int h = hardwareConfig.getScreenHeight();
+        int w = d.getIntrinsicWidth();
+        int h = d.getIntrinsicHeight();
+
+        final int screenWidth = hardwareConfig.getScreenWidth();
+        final int screenHeight = hardwareConfig.getScreenHeight();
+
+        if (w == -1 || h == -1) {
+            // Use screen size when either intrinsic width or height isn't available
+            w = screenWidth;
+            h = screenHeight;
+        } else if (w > screenWidth || h > screenHeight) {
+            // If image wouldn't fit to the screen, resize it to avoid cropping.
+
+            // We need to find scale such that scale * w <= screenWidth, scale * h <= screenHeight
+            double scale = Math.min((double) screenWidth / w, (double) screenHeight / h);
+
+            // scale * w / scale * h = w / h, so, proportions are preserved.
+            w = (int) Math.floor(scale * w);
+            h = (int) Math.floor(scale * h);
+        }
+
         int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
         int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
         content.measure(w_spec, h_spec);
@@ -105,8 +156,7 @@
 
         // and draw
         content.draw(canvas);
-
-        return Status.SUCCESS.createResult(image);
+        return image;
     }
 
     protected BufferedImage getImage(int w, int h) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 95576ef..f6e5ef1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -45,7 +45,7 @@
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
 import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.SessionParamsFlags;
+import com.android.layoutlib.bridge.android.RenderParamsFlags;
 import com.android.layoutlib.bridge.android.support.RecyclerViewUtil;
 import com.android.layoutlib.bridge.bars.AppCompatActionBar;
 import com.android.layoutlib.bridge.bars.BridgeActionBar;
@@ -403,7 +403,7 @@
             // it can instantiate the custom Fragment.
             Fragment_Delegate.setLayoutlibCallback(params.getLayoutlibCallback());
 
-            String rootTag = params.getFlag(SessionParamsFlags.FLAG_KEY_ROOT_TAG);
+            String rootTag = params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG);
             boolean isPreference = "PreferenceScreen".equals(rootTag);
             View view;
             if (isPreference) {
@@ -554,7 +554,14 @@
                 // draw the views
                 // create the BufferedImage into which the layout will be rendered.
                 boolean newImage = false;
-                if (newRenderSize || mCanvas == null) {
+
+                // When disableBitmapCaching is true, we do not reuse mImage and
+                // we create a new one in every render.
+                // This is useful when mImage is just a wrapper of Graphics2D so
+                // it doesn't get cached.
+                boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag(
+                    RenderParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING));
+                if (newRenderSize || mCanvas == null || disableBitmapCaching) {
                     if (params.getImageFactory() != null) {
                         mImage = params.getImageFactory().getImage(
                                 mMeasuredScreenWidth,
@@ -581,8 +588,12 @@
                     Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
                             true /*isMutable*/, hardwareConfig.getDensity());
 
-                    // create a Canvas around the Android bitmap
-                    mCanvas = new Canvas(bitmap);
+                    if (mCanvas == null) {
+                        // create a Canvas around the Android bitmap
+                        mCanvas = new Canvas(bitmap);
+                    } else {
+                        mCanvas.setBitmap(bitmap);
+                    }
                     mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
                 }
 
@@ -1064,7 +1075,7 @@
 
     private void findStatusBar(RenderResources resources, DisplayMetrics metrics) {
         boolean windowFullscreen = getBooleanThemeValue(resources,
-                "windowFullscreen", false, !isThemeAppCompat(resources));
+                "windowFullscreen", false, true);
 
         if (!windowFullscreen && !mWindowIsFloating) {
             // default value
@@ -1199,15 +1210,15 @@
           // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21).
             boolean isThemeAppCompat = false;
             for (int i = 0; i < 50; i++) {
+                if (defaultTheme == null) {
+                    break;
+                }
                 // for loop ensures that we don't run into cyclic theme inheritance.
                 if (defaultTheme.getName().startsWith("Theme.AppCompat")) {
                     isThemeAppCompat = true;
                     break;
                 }
                 defaultTheme = resources.getParent(defaultTheme);
-                if (defaultTheme == null) {
-                    break;
-                }
             }
             mIsThemeAppCompat = isThemeAppCompat;
         }
@@ -1631,7 +1642,7 @@
         return null;
     }
 
-    private void invalidateRenderingSize() {
+    public void invalidateRenderingSize() {
         mMeasuredScreenWidth = mMeasuredScreenHeight = -1;
     }
 
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
index d252462..8af93eb 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
index d109302..069f9f7 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
index 816ecc8..36e2688 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
index b034b75..ca438ad 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
index f86b1d3..a98abf5 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
index 8bbae90..7d8cc84 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
index 8af745d..7e6113b 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
new file mode 100644
index 0000000..c9b76be
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml
new file mode 100644
index 0000000..2da2cb9
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml
@@ -0,0 +1,393 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:ignore="HardcodedText,LabelFor,TextFields,ContentDescription,RtlHardcoded">
+
+    <FrameLayout
+        android:id="@id/frameLayout"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentEnd="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginEnd="311dp">
+
+        <TextView
+            android:id="@id/textView"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="left|top"
+            android:text="New Text" />
+    </FrameLayout>
+
+    <TextView
+        android:id="@id/textView2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="true"
+        android:layout_below="@id/frameLayout"
+        android:text="Large Text"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <TextView
+        android:id="@id/textView3"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_toEndOf="@id/textView2"
+        android:text="Medium Text"
+        android:textAppearance="?android:attr/textAppearanceMedium" />
+
+    <TextView
+        android:id="@id/textView4"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignTop="@id/textView2"
+        android:layout_toEndOf="@id/textView2"
+        android:text="Small Text"
+        android:textAppearance="?android:attr/textAppearanceSmall" />
+
+    <Button
+        android:id="@id/button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/textView3"
+        android:layout_toEndOf="@id/textView4"
+        android:text="New Button" />
+
+    <Button
+        android:id="@id/button2"
+        style="?android:attr/buttonStyleSmall"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_toEndOf="@id/button"
+        android:text="New Button" />
+
+    <CheckBox
+        android:id="@id/checkBox"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignEnd="@id/button"
+        android:layout_below="@id/button"
+        android:text="New CheckBox" />
+
+    <Switch
+        android:id="@id/switch1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="true"
+        android:layout_below="@id/textView2"
+        android:text="New Switch" />
+
+    <ImageButton
+        android:id="@id/imageButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/button"
+        android:layout_toEndOf="@id/switch1" />
+
+    <ImageView
+        android:id="@id/imageView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/ic_launcher"
+        android:layout_below="@id/button"
+        android:layout_toEndOf="@id/imageButton" />
+
+    <GridLayout
+        android:id="@id/gridLayout"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="true"
+        android:layout_below="@id/imageButton"
+        android:columnCount="2"
+        android:rowCount="2">
+
+        <ProgressBar
+            android:id="@id/progressBar"
+            style="?android:attr/progressBarStyleLarge"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_column="0"
+            android:layout_row="0" />
+
+        <ProgressBar
+            android:id="@id/progressBar2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_column="1"
+            android:layout_row="0" />
+
+        <ProgressBar
+            android:id="@id/progressBar3"
+            style="?android:attr/progressBarStyleSmall"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_column="0"
+            android:layout_row="1" />
+
+        <ProgressBar
+            android:id="@id/progressBar4"
+            style="?android:attr/progressBarStyleHorizontal"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_column="1"
+            android:layout_row="1" />
+    </GridLayout>
+
+    <SeekBar
+        android:id="@id/seekBar"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignTop="@id/gridLayout"
+        android:layout_toEndOf="@id/gridLayout" />
+
+    <RatingBar
+        android:id="@id/ratingBar"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/switch2"
+        android:layout_toEndOf="@id/gridLayout" />
+
+    <Switch
+        android:id="@id/switch2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/seekBar"
+        android:layout_toEndOf="@id/switch1"
+        android:checked="true" />
+
+    <EditText
+        android:id="@id/editText"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBottom="@id/ratingBar"
+        android:layout_alignParentStart="true"
+        android:text="plain text" />
+
+    <EditText
+        android:id="@id/editText2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="true"
+        android:layout_below="@id/ratingBar"
+        android:ems="3"
+        android:inputType="textPersonName"
+        android:text="Name" />
+
+    <EditText
+        android:id="@id/editText3"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerVertical="true"
+        android:layout_toEndOf="@id/editText2"
+        android:ems="2"
+        android:inputType="textPassword"
+        android:text="password" />
+
+    <EditText
+        android:id="@id/editText4"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignTop="@id/editText3"
+        android:layout_toEndOf="@id/editText3"
+        android:ems="3"
+        android:inputType="numberPassword"
+        android:text="numeric password" />
+
+    <EditText
+        android:id="@id/editText5"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/editText3"
+        android:layout_toStartOf="@id/editText6"
+        android:ems="7"
+        android:inputType="textEmailAddress"
+        android:text="email@domain.com" />
+
+    <EditText
+        android:id="@id/editText6"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentEnd="true"
+        android:layout_below="@id/editText4"
+        android:ems="7"
+        android:inputType="phone"
+        android:text="+11235554344" />
+
+    <EditText
+        android:id="@id/editText7"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/editText"
+        android:layout_toEndOf="@id/editText4"
+        android:ems="10"
+        android:inputType="textPostalAddress"
+        android:text="1600 Amphitheatre" />
+
+    <EditText
+        android:id="@id/editText9"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/editText5"
+        android:layout_alignParentStart="true"
+        android:ems="3"
+        android:inputType="time"
+        android:text="12:12" />
+
+    <RadioGroup
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/editText5"
+        android:layout_toEndOf="@id/editText9"
+        android:orientation="horizontal">
+
+        <RadioButton
+            android:id="@id/radioButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="New RadioButton" />
+
+        <RadioButton
+            android:id="@id/radioButton2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="New RadioButton" />
+
+    </RadioGroup>
+
+    <CheckedTextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="CheckedTextView"
+        android:id="@id/checkedTextView"
+        android:layout_below="@id/button2"
+        android:layout_alignParentEnd="true"
+        android:layout_alignStart="@id/button2" />
+
+    <DialerFilter
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/checkBox"
+        android:layout_toStartOf="@id/quickContactBadge"
+        android:id="@id/dialerFilter"
+        android:layout_above="@id/ratingBar"
+        android:layout_toEndOf="@id/seekBar">
+
+        <EditText
+            android:id="@android:id/hint"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Hint" />
+
+        <EditText
+            android:id="@android:id/primary"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@android:id/hint"
+            android:text="Primary" />
+    </DialerFilter>
+
+    <QuickContactBadge
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@id/quickContactBadge"
+        android:layout_below="@id/checkedTextView"
+        android:layout_alignParentEnd="true" />
+
+    <android.inputmethodservice.ExtractEditText
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="ExtractEditText"
+        android:id="@id/extractEditText"
+        android:layout_below="@id/editText9"
+        android:layout_alignParentEnd="true"
+        android:layout_alignStart="@id/checkedTextView" />
+
+    <ZoomControls
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@id/zoomControls"
+        android:layout_below="@id/editText9"
+        android:layout_alignParentStart="true" />
+
+    <TextureView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@id/textureView"
+        android:layout_below="@id/zoomControls"
+        android:layout_alignParentStart="true"
+        android:layout_alignBottom="@id/extractEditText"
+        android:layout_toStartOf="@id/editText3" />
+
+    <ListView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@id/listView"
+        android:layout_below="@id/textureView"
+        android:layout_alignParentStart="true"
+        android:layout_alignEnd="@id/textureView" />
+
+    <GridView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@id/gridView"
+        android:layout_below="@id/extractEditText"
+        android:layout_alignParentEnd="true"
+        android:layout_alignStart="@id/extractEditText" />
+
+    <ScrollView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@id/scrollView"
+        android:layout_below="@id/zoomControls"
+        android:layout_toRightOf="@id/listView"
+        android:layout_toLeftOf="@id/extractEditText">
+
+    <TabHost
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:id="@id/tabHost">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="vertical">
+
+            <TabWidget
+                android:id="@android:id/tabs"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
+
+            <FrameLayout
+                android:id="@android:id/tabcontent"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+
+                <LinearLayout
+                    android:id="@id/linearLayout"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:orientation="vertical"/>
+
+                <LinearLayout
+                    android:id="@id/linearLayout2"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:orientation="vertical"/>
+
+            </FrameLayout>
+        </LinearLayout>
+    </TabHost>
+</ScrollView>
+
+    <SearchView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@id/searchView"
+        android:layout_alignBottom="@id/zoomControls"
+        android:layout_toEndOf="@id/seekBar" />
+
+</RelativeLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml
new file mode 100644
index 0000000..1dc2fa0
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <item type="id" name="button" />
+    <item type="id" name="button2" />
+    <item type="id" name="checkBox" />
+    <item type="id" name="checkedTextView" />
+    <item type="id" name="dialerFilter" />
+    <item type="id" name="editText" />
+    <item type="id" name="editText2" />
+    <item type="id" name="editText3" />
+    <item type="id" name="editText4" />
+    <item type="id" name="editText5" />
+    <item type="id" name="editText6" />
+    <item type="id" name="editText7" />
+    <item type="id" name="editText8" />
+    <item type="id" name="editText9" />
+    <item type="id" name="extractEditText" />
+    <item type="id" name="frameLayout" />
+    <item type="id" name="gridLayout" />
+    <item type="id" name="gridView" />
+    <item type="id" name="imageButton" />
+    <item type="id" name="imageView" />
+    <item type="id" name="linearLayout" />
+    <item type="id" name="linearLayout2" />
+    <item type="id" name="listView" />
+    <item type="id" name="progressBar" />
+    <item type="id" name="progressBar2" />
+    <item type="id" name="progressBar3" />
+    <item type="id" name="progressBar4" />
+    <item type="id" name="quickContactBadge" />
+    <item type="id" name="radioButton" />
+    <item type="id" name="radioButton2" />
+    <item type="id" name="ratingBar" />
+    <item type="id" name="scrollView" />
+    <item type="id" name="searchView" />
+    <item type="id" name="seekBar" />
+    <item type="id" name="spinner" />
+    <item type="id" name="switch1" />
+    <item type="id" name="switch2" />
+    <item type="id" name="tabHost" />
+    <item type="id" name="textView" />
+    <item type="id" name="textView2" />
+    <item type="id" name="textView3" />
+    <item type="id" name="textView4" />
+    <item type="id" name="textureView" />
+    <item type="id" name="zoomControls" />
+</resources>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index ac23564..f2a039e 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -261,7 +261,7 @@
                 new ResourceRepository(new FolderWrapper(TEST_RES_DIR + APP_TEST_RES), false) {
             @NonNull
             @Override
-            protected ResourceItem createResourceItem(String name) {
+            protected ResourceItem createResourceItem(@NonNull String name) {
                 return new ResourceItem(name);
             }
         };
@@ -275,14 +275,27 @@
                 ConfigGenerator.getEnumMap(attrs), getLayoutLog());
     }
 
-    /**
-     * Create a new rendering session and test that rendering /layout/activity.xml on nexus 5
-     * doesn't throw any exceptions.
-     */
+    /** Text activity.xml */
     @Test
-    public void testRendering() throws ClassNotFoundException {
+    public void testActivity() throws ClassNotFoundException {
+        renderAndVerify("activity.xml", "activity.png");
+
+    }
+
+    /** Test allwidgets.xml */
+    @Test
+    public void testAllWidgets() throws ClassNotFoundException {
+        renderAndVerify("allwidgets.xml", "allwidgets.png");
+    }
+
+    /**
+     * Create a new rendering session and test that rendering given layout on nexus 5
+     * doesn't throw any exceptions and matches the provided image.
+     */
+    private void renderAndVerify(String layoutFileName, String goldenFileName)
+            throws ClassNotFoundException {
         // Create the layout pull parser.
-        LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/activity.xml");
+        LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/" + layoutFileName);
         // Create LayoutLibCallback.
         LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
         layoutLibCallback.initResources();
@@ -301,7 +314,7 @@
                     session.getResult().getErrorMessage());
         }
         try {
-            String goldenImagePath = APP_TEST_DIR + "/golden/activity.png";
+            String goldenImagePath = APP_TEST_DIR + "/golden/" + goldenFileName;
             ImageUtils.requireSimilar(goldenImagePath, session.getImage());
         } catch (IOException e) {
             getLogger().error(e, e.getMessage());
@@ -309,7 +322,7 @@
     }
 
     /**
-     * Uses Theme.Material and Target sdk version as 21.
+     * Uses Theme.Material and Target sdk version as 22.
      */
     private SessionParams getSessionParams(LayoutPullParser layoutParser,
             ConfigGenerator configGenerator, LayoutLibTestCallback layoutLibCallback) {
@@ -327,7 +340,7 @@
                 resourceResolver,
                 layoutLibCallback,
                 0,
-                21, // TODO: Make it more configurable to run tests for various versions.
+                22, // TODO: Make it more configurable to run tests for various versions.
                 getLayoutLog());
     }
 
@@ -381,17 +394,17 @@
                 }
 
                 @Override
-                public void warning(String msgFormat, Object... args) {
+                public void warning(@NonNull String msgFormat, Object... args) {
                     failWithMsg(msgFormat, args);
                 }
 
                 @Override
-                public void info(String msgFormat, Object... args) {
+                public void info(@NonNull String msgFormat, Object... args) {
                     // pass.
                 }
 
                 @Override
-                public void verbose(String msgFormat, Object... args) {
+                public void verbose(@NonNull String msgFormat, Object... args) {
                     // pass.
                 }
             };
@@ -399,7 +412,7 @@
         return mLogger;
     }
 
-    private static void failWithMsg(String msgFormat, Object... args) {
-        fail(msgFormat == null || args == null ? "" : String.format(msgFormat, args));
+    private static void failWithMsg(@NonNull String msgFormat, Object... args) {
+        fail(args == null ? "" : String.format(msgFormat, args));
     }
 }
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
index a5c3202..1191df6 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
@@ -21,12 +21,11 @@
 import com.android.ide.common.resources.configuration.DensityQualifier;
 import com.android.ide.common.resources.configuration.FolderConfiguration;
 import com.android.ide.common.resources.configuration.KeyboardStateQualifier;
-import com.android.ide.common.resources.configuration.LanguageQualifier;
 import com.android.ide.common.resources.configuration.LayoutDirectionQualifier;
+import com.android.ide.common.resources.configuration.LocaleQualifier;
 import com.android.ide.common.resources.configuration.NavigationMethodQualifier;
 import com.android.ide.common.resources.configuration.NetworkCodeQualifier;
 import com.android.ide.common.resources.configuration.NightModeQualifier;
-import com.android.ide.common.resources.configuration.RegionQualifier;
 import com.android.ide.common.resources.configuration.ScreenDimensionQualifier;
 import com.android.ide.common.resources.configuration.ScreenOrientationQualifier;
 import com.android.ide.common.resources.configuration.ScreenRatioQualifier;
@@ -158,10 +157,9 @@
         config.setUiModeQualifier(new UiModeQualifier(UiMode.NORMAL));
         config.setNightModeQualifier(new NightModeQualifier(NightMode.NOTNIGHT));
         config.setCountryCodeQualifier(new CountryCodeQualifier());
-        config.setLanguageQualifier(new LanguageQualifier());
         config.setLayoutDirectionQualifier(new LayoutDirectionQualifier());
         config.setNetworkCodeQualifier(new NetworkCodeQualifier());
-        config.setRegionQualifier(new RegionQualifier());
+        config.setLocaleQualifier(new LocaleQualifier());
         config.setVersionQualifier(new VersionQualifier());
         return config;
     }
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
index 0a5e798..5b648ef 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
@@ -23,8 +23,8 @@
 import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.ResourceReference;
 import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.resources.ResourceType;
 import com.android.ide.common.resources.IntArrayWrapper;
+import com.android.resources.ResourceType;
 import com.android.util.Pair;
 import com.android.utils.ILogger;
 
@@ -36,6 +36,8 @@
 
 import com.google.android.collect.Maps;
 
+import static org.junit.Assert.fail;
+
 @SuppressWarnings("deprecation") // For Pair
 public class LayoutLibTestCallback extends LayoutlibCallback {
 
@@ -121,7 +123,7 @@
 
     @Override
     public ILayoutPullParser getParser(String layoutName) {
-        org.junit.Assert.fail("This method shouldn't be called by this version of LayoutLib.");
+        fail("This method shouldn't be called by this version of LayoutLib.");
         return null;
     }
 
diff --git a/tools/obbtool/pbkdf2gen.cpp b/tools/obbtool/pbkdf2gen.cpp
index 98d67c0..f1d8d04 100644
--- a/tools/obbtool/pbkdf2gen.cpp
+++ b/tools/obbtool/pbkdf2gen.cpp
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>