Fixing up the formatting code which is already merged

I just apply google coding guide like space.

Uploading the same code about + handling just apply the Google Coding Guide.
The previous code is "https://android-review.googlesource.com/#/c/122770/"

This code is about + plus number converting logic for international NANP.

Change-Id: I23e4709294c603b387b28b3c2a56c932d838c666
diff --git a/Android.mk b/Android.mk
index 5d9c5b3..15afe90 100644
--- a/Android.mk
+++ b/Android.mk
@@ -202,6 +202,7 @@
 	core/java/android/os/IUpdateLock.aidl \
 	core/java/android/os/IUserManager.aidl \
 	core/java/android/os/IVibratorService.aidl \
+	core/java/android/security/IKeystoreService.aidl \
 	core/java/android/service/notification/INotificationListener.aidl \
 	core/java/android/service/notification/IStatusBarNotificationHolder.aidl \
 	core/java/android/service/notification/IConditionListener.aidl \
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 4e2ff0b..09d6c29 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -466,8 +466,9 @@
             String resultData = data.readString();
             Bundle resultExtras = data.readBundle();
             boolean resultAbort = data.readInt() != 0;
+            int intentFlags = data.readInt();
             if (who != null) {
-                finishReceiver(who, resultCode, resultData, resultExtras, resultAbort);
+                finishReceiver(who, resultCode, resultData, resultExtras, resultAbort, intentFlags);
             }
             reply.writeNoException();
             return true;
@@ -2329,6 +2330,15 @@
             reply.writeNoException();
             return true;
         }
+
+        case NOTIFY_CLEARTEXT_NETWORK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final int uid = data.readInt();
+            final byte[] firstPacket = data.createByteArray();
+            notifyCleartextNetwork(uid, firstPacket);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -2807,7 +2817,8 @@
         data.recycle();
         reply.recycle();
     }
-    public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException
+    public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
+            boolean abortBroadcast, int flags) throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -2817,6 +2828,7 @@
         data.writeString(resultData);
         data.writeBundle(map);
         data.writeInt(abortBroadcast ? 1 : 0);
+        data.writeInt(flags);
         mRemote.transact(FINISH_RECEIVER_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
         reply.readException();
         data.recycle();
@@ -5378,5 +5390,18 @@
         reply.recycle();
     }
 
+    @Override
+    public void notifyCleartextNetwork(int uid, byte[] firstPacket) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(uid);
+        data.writeByteArray(firstPacket);
+        mRemote.transact(NOTIFY_CLEARTEXT_NETWORK_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 978366e..9d821e1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -359,7 +359,7 @@
         public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
                 boolean ordered, boolean sticky, IBinder token, int sendingUser) {
             super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
-                    token, sendingUser);
+                    token, sendingUser, intent.getFlags());
             this.intent = intent;
         }
 
@@ -1061,8 +1061,7 @@
             WindowManagerGlobal.getInstance().dumpGfxInfo(fd);
         }
 
-        @Override
-        public void dumpDbInfo(FileDescriptor fd, String[] args) {
+        private void dumpDatabaseInfo(FileDescriptor fd, String[] args) {
             PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd));
             PrintWriterPrinter printer = new PrintWriterPrinter(pw);
             SQLiteDebug.dump(printer, args);
@@ -1070,6 +1069,22 @@
         }
 
         @Override
+        public void dumpDbInfo(final FileDescriptor fd, final String[] args) {
+            if (mSystemThread) {
+                // Ensure this invocation is asynchronous to prevent
+                // writer waiting due to buffer cannot be consumed.
+                AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        dumpDatabaseInfo(fd, args);
+                    }
+                });
+            } else {
+                dumpDatabaseInfo(fd, args);
+            }
+        }
+
+        @Override
         public void unstableProviderDied(IBinder provider) {
             sendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
         }
@@ -1153,9 +1168,17 @@
             sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0);
         }
 
+        @Override
         public void scheduleEnterAnimationComplete(IBinder token) {
             sendMessage(H.ENTER_ANIMATION_COMPLETE, token);
         }
+
+        @Override
+        public void notifyCleartextNetwork(byte[] firstPacket) {
+            if (StrictMode.vmCleartextNetworkEnabled()) {
+                StrictMode.onCleartextNetworkDetected(firstPacket);
+            }
+        }
     }
 
     private class H extends Handler {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 0123e16..b2bfc13 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -667,6 +667,15 @@
             reply.writeNoException();
             return true;
         }
+
+        case NOTIFY_CLEARTEXT_NETWORK_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            final byte[] firstPacket = data.createByteArray();
+            notifyCleartextNetwork(firstPacket);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -1346,4 +1355,13 @@
         mRemote.transact(ENTER_ANIMATION_COMPLETE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
         data.recycle();
     }
+
+    @Override
+    public void notifyCleartextNetwork(byte[] firstPacket) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeByteArray(firstPacket);
+        mRemote.transact(NOTIFY_CLEARTEXT_NETWORK_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
 }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index be26f30..de47147 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -106,7 +106,8 @@
             String resultData, Bundle map, String requiredPermission,
             int appOp, boolean serialized, boolean sticky, int userId) throws RemoteException;
     public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException;
-    public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException;
+    public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
+            boolean abortBroadcast, int flags) throws RemoteException;
     public void attachApplication(IApplicationThread app) throws RemoteException;
     public void activityResumed(IBinder token) throws RemoteException;
     public void activityIdle(IBinder token, Configuration config,
@@ -463,6 +464,8 @@
     public void notifyLaunchTaskBehindComplete(IBinder token) throws RemoteException;
     public void notifyEnterAnimationComplete(IBinder token) throws RemoteException;
 
+    public void notifyCleartextNetwork(int uid, byte[] firstPacket) throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -781,4 +784,7 @@
     int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237;
     int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
     int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239;
+
+    // Start of M transactions
+    int NOTIFY_CLEARTEXT_NETWORK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+280;
 }
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index f53075c..7ff207f 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -146,6 +146,7 @@
     void scheduleCancelVisibleBehind(IBinder token) throws RemoteException;
     void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled) throws RemoteException;
     void scheduleEnterAnimationComplete(IBinder token) throws RemoteException;
+    void notifyCleartextNetwork(byte[] firstPacket) throws RemoteException;
 
     String descriptor = "android.app.IApplicationThread";
 
@@ -203,4 +204,5 @@
     int CANCEL_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+52;
     int BACKGROUND_VISIBLE_BEHIND_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+53;
     int ENTER_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+54;
+    int NOTIFY_CLEARTEXT_NETWORK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+55;
 }
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index aa98e97..973196c 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -796,7 +796,7 @@
                         if (extras != null) {
                             extras.setAllowFds(false);
                         }
-                        mgr.finishReceiver(this, resultCode, data, extras, false);
+                        mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
                     } catch (RemoteException e) {
                         Slog.w(ActivityThread.TAG, "Couldn't finish broadcast to unregistered receiver");
                     }
@@ -821,8 +821,8 @@
             public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
                     boolean ordered, boolean sticky, int sendingUser) {
                 super(resultCode, resultData, resultExtras,
-                        mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED,
-                        ordered, sticky, mIIntentReceiver.asBinder(), sendingUser);
+                        mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
+                        sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
                 mCurIntent = intent;
                 mOrdered = ordered;
             }
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index 9a32fdf..af74e73 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -238,6 +238,7 @@
         final boolean mInitialStickyHint;
         final IBinder mToken;
         final int mSendingUser;
+        final int mFlags;
         
         int mResultCode;
         String mResultData;
@@ -246,8 +247,8 @@
         boolean mFinished;
 
         /** @hide */
-        public PendingResult(int resultCode, String resultData, Bundle resultExtras,
-                int type, boolean ordered, boolean sticky, IBinder token, int userId) {
+        public PendingResult(int resultCode, String resultData, Bundle resultExtras, int type,
+                boolean ordered, boolean sticky, IBinder token, int userId, int flags) {
             mResultCode = resultCode;
             mResultData = resultData;
             mResultExtras = resultExtras;
@@ -256,6 +257,7 @@
             mInitialStickyHint = sticky;
             mToken = token;
             mSendingUser = userId;
+            mFlags = flags;
         }
         
         /**
@@ -417,11 +419,11 @@
                     }
                     if (mOrderedHint) {
                         am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
-                                mAbortBroadcast);
+                                mAbortBroadcast, mFlags);
                     } else {
                         // This broadcast was sent to a component; it is not ordered,
                         // but we still need to tell the activity manager we are done.
-                        am.finishReceiver(mToken, 0, null, null, false);
+                        am.finishReceiver(mToken, 0, null, null, false, mFlags);
                     }
                 } catch (RemoteException ex) {
                 }
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 58f0fc0..ddb8e94 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -16,7 +16,6 @@
 
 package android.net;
 
-import android.net.NetworkUtils;
 import android.os.Parcelable;
 import android.os.Parcel;
 import android.system.ErrnoException;
@@ -31,15 +30,14 @@
 import java.net.UnknownHostException;
 import java.net.URL;
 import java.net.URLConnection;
-import java.net.URLStreamHandler;
-import java.util.concurrent.atomic.AtomicReference;
 import javax.net.SocketFactory;
 
 import com.android.okhttp.ConnectionPool;
-import com.android.okhttp.HostResolver;
 import com.android.okhttp.HttpHandler;
 import com.android.okhttp.HttpsHandler;
 import com.android.okhttp.OkHttpClient;
+import com.android.okhttp.OkUrlFactory;
+import com.android.okhttp.internal.Internal;
 
 /**
  * Identifies a {@code Network}.  This is supplied to applications via
@@ -60,10 +58,10 @@
     // Objects used to perform per-network operations such as getSocketFactory
     // and openConnection, and a lock to protect access to them.
     private volatile NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;
-    // mLock should be used to control write access to mConnectionPool and mHostResolver.
+    // mLock should be used to control write access to mConnectionPool and mNetwork.
     // maybeInitHttpClient() must be called prior to reading either variable.
     private volatile ConnectionPool mConnectionPool = null;
-    private volatile HostResolver mHostResolver = null;
+    private volatile com.android.okhttp.internal.Network mNetwork = null;
     private Object mLock = new Object();
 
     // Default connection pool values. These are evaluated at startup, just
@@ -217,10 +215,10 @@
     // out) ConnectionPools.
     private void maybeInitHttpClient() {
         synchronized (mLock) {
-            if (mHostResolver == null) {
-                mHostResolver = new HostResolver() {
+            if (mNetwork == null) {
+                mNetwork = new com.android.okhttp.internal.Network() {
                     @Override
-                    public InetAddress[] getAllByName(String host) throws UnknownHostException {
+                    public InetAddress[] resolveInetAddresses(String host) throws UnknownHostException {
                         return Network.this.getAllByName(host);
                     }
                 };
@@ -244,23 +242,26 @@
     public URLConnection openConnection(URL url) throws IOException {
         maybeInitHttpClient();
         String protocol = url.getProtocol();
-        OkHttpClient client;
-        // TODO: HttpHandler creates OkHttpClients that share the default ResponseCache.
+        OkUrlFactory okUrlFactory;
+        // TODO: HttpHandler creates OkUrlFactory instances that share the default ResponseCache.
         // Could this cause unexpected behavior?
         // TODO: Should the network's proxy be specified?
         if (protocol.equals("http")) {
-            client = HttpHandler.createHttpOkHttpClient(null /* proxy */);
+            okUrlFactory = HttpHandler.createHttpOkUrlFactory(null /* proxy */);
         } else if (protocol.equals("https")) {
-            client = HttpsHandler.createHttpsOkHttpClient(null /* proxy */);
+            okUrlFactory = HttpsHandler.createHttpsOkUrlFactory(null /* proxy */);
         } else {
-            // OkHttpClient only supports HTTP and HTTPS and returns a null URLStreamHandler if
+            // OkHttp only supports HTTP and HTTPS and returns a null URLStreamHandler if
             // passed another protocol.
             throw new MalformedURLException("Invalid URL or unrecognized protocol " + protocol);
         }
-        return client.setSocketFactory(getSocketFactory())
-                .setHostResolver(mHostResolver)
-                .setConnectionPool(mConnectionPool)
-                .open(url);
+        OkHttpClient client = okUrlFactory.client();
+        client.setSocketFactory(getSocketFactory()).setConnectionPool(mConnectionPool);
+
+        // Use internal APIs to change the Network.
+        Internal.instance.setNetwork(client, mNetwork);
+
+        return okUrlFactory.open(url);
     }
 
     /**
diff --git a/core/java/android/net/http/HttpResponseCache.java b/core/java/android/net/http/HttpResponseCache.java
index 2785a15..c6c22e7 100644
--- a/core/java/android/net/http/HttpResponseCache.java
+++ b/core/java/android/net/http/HttpResponseCache.java
@@ -16,32 +16,33 @@
 
 package android.net.http;
 
-import android.content.Context;
+import com.android.okhttp.Cache;
+import com.android.okhttp.AndroidShimResponseCache;
+import com.android.okhttp.OkCacheContainer;
+
 import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
 import java.net.CacheRequest;
 import java.net.CacheResponse;
-import java.net.HttpURLConnection;
 import java.net.ResponseCache;
 import java.net.URI;
 import java.net.URLConnection;
 import java.util.List;
 import java.util.Map;
-import javax.net.ssl.HttpsURLConnection;
-import org.apache.http.impl.client.DefaultHttpClient;
 
 /**
  * Caches HTTP and HTTPS responses to the filesystem so they may be reused,
- * saving time and bandwidth. This class supports {@link HttpURLConnection} and
- * {@link HttpsURLConnection}; there is no platform-provided cache for {@link
- * DefaultHttpClient} or {@link AndroidHttpClient}.
+ * saving time and bandwidth. This class supports {@link
+ * java.net.HttpURLConnection} and {@link javax.net.ssl.HttpsURLConnection};
+ * there is no platform-provided cache for {@link
+ * org.apache.http.impl.client.DefaultHttpClient} or {@link AndroidHttpClient}.
  *
  * <h3>Installing an HTTP response cache</h3>
  * Enable caching of all of your application's HTTP requests by installing the
  * cache at application startup. For example, this code installs a 10 MiB cache
- * in the {@link Context#getCacheDir() application-specific cache directory} of
- * the filesystem}: <pre>   {@code
+ * in the {@link android.content.Context#getCacheDir() application-specific
+ * cache directory} of the filesystem}: <pre>   {@code
  *   protected void onCreate(Bundle savedInstanceState) {
  *       ...
  *
@@ -73,10 +74,10 @@
  * contain private data.</strong> Although it often has more free space,
  * external storage is optional and&#8212;even if available&#8212;can disappear
  * during use. Retrieve the external cache directory using {@link
- * Context#getExternalCacheDir()}. If this method returns null, your application
- * should fall back to either not caching or caching on non-external storage. If
- * the external storage is removed during use, the cache hit rate will drop to
- * zero and ongoing cache reads will fail.
+ * android.content.Context#getExternalCacheDir()}. If this method returns null,
+ * your application should fall back to either not caching or caching on
+ * non-external storage. If the external storage is removed during use, the
+ * cache hit rate will drop to zero and ongoing cache reads will fail.
  *
  * <p>Flushing the cache forces its data to the filesystem. This ensures that
  * all responses written to the cache will be readable the next time the
@@ -147,11 +148,11 @@
  *       } catch (Exception httpResponseCacheNotAvailable) {
  *       }}</pre>
  */
-public final class HttpResponseCache extends ResponseCache implements Closeable {
+public final class HttpResponseCache extends ResponseCache implements Closeable, OkCacheContainer {
 
-    private final com.android.okhttp.HttpResponseCache delegate;
+    private final AndroidShimResponseCache delegate;
 
-    private HttpResponseCache(com.android.okhttp.HttpResponseCache delegate) {
+    private HttpResponseCache(AndroidShimResponseCache delegate) {
         this.delegate = delegate;
     }
 
@@ -161,17 +162,14 @@
      */
     public static HttpResponseCache getInstalled() {
         ResponseCache installed = ResponseCache.getDefault();
-        if (installed instanceof com.android.okhttp.HttpResponseCache) {
-            return new HttpResponseCache(
-                    (com.android.okhttp.HttpResponseCache) installed);
+        if (installed instanceof HttpResponseCache) {
+            return (HttpResponseCache) installed;
         }
-
         return null;
     }
 
     /**
-     * Creates a new HTTP response cache and {@link ResponseCache#setDefault
-     * sets it} as the system default cache.
+     * Creates a new HTTP response cache and sets it as the system default cache.
      *
      * @param directory the directory to hold cache data.
      * @param maxSize the maximum size of the cache in bytes.
@@ -180,26 +178,26 @@
      *     Most applications should respond to this exception by logging a
      *     warning.
      */
-    public static HttpResponseCache install(File directory, long maxSize) throws IOException {
+    public static synchronized HttpResponseCache install(File directory, long maxSize)
+            throws IOException {
         ResponseCache installed = ResponseCache.getDefault();
-        if (installed instanceof com.android.okhttp.HttpResponseCache) {
-            com.android.okhttp.HttpResponseCache installedCache =
-                    (com.android.okhttp.HttpResponseCache) installed;
+        if (installed instanceof HttpResponseCache) {
+            HttpResponseCache installedResponseCache = (HttpResponseCache) installed;
             // don't close and reopen if an equivalent cache is already installed
-            if (installedCache.getDirectory().equals(directory)
-                    && installedCache.getMaxSize() == maxSize
-                    && !installedCache.isClosed()) {
-                return new HttpResponseCache(installedCache);
+            AndroidShimResponseCache trueResponseCache = installedResponseCache.delegate;
+            if (trueResponseCache.isEquivalent(directory, maxSize)) {
+                return installedResponseCache;
             } else {
                 // The HttpResponseCache that owns this object is about to be replaced.
-                installedCache.close();
+                trueResponseCache.close();
             }
         }
 
-        com.android.okhttp.HttpResponseCache responseCache =
-                new com.android.okhttp.HttpResponseCache(directory, maxSize);
-        ResponseCache.setDefault(responseCache);
-        return new HttpResponseCache(responseCache);
+        AndroidShimResponseCache trueResponseCache =
+                AndroidShimResponseCache.create(directory, maxSize);
+        HttpResponseCache newResponseCache = new HttpResponseCache(trueResponseCache);
+        ResponseCache.setDefault(newResponseCache);
+        return newResponseCache;
     }
 
     @Override public CacheResponse get(URI uri, String requestMethod,
@@ -214,10 +212,15 @@
     /**
      * Returns the number of bytes currently being used to store the values in
      * this cache. This may be greater than the {@link #maxSize} if a background
-     * deletion is pending.
+     * deletion is pending. {@code -1} is returned if the size cannot be determined.
      */
     public long size() {
-        return delegate.getSize();
+        try {
+            return delegate.size();
+        } catch (IOException e) {
+            // This can occur if the cache failed to lazily initialize.
+            return -1;
+        }
     }
 
     /**
@@ -225,7 +228,7 @@
      * its data.
      */
     public long maxSize() {
-        return delegate.getMaxSize();
+        return delegate.maxSize();
     }
 
     /**
@@ -271,7 +274,7 @@
      * will remain on the filesystem.
      */
     @Override public void close() throws IOException {
-        if (ResponseCache.getDefault() == this.delegate) {
+        if (ResponseCache.getDefault() == this) {
             ResponseCache.setDefault(null);
         }
         delegate.close();
@@ -281,9 +284,16 @@
      * Uninstalls the cache and deletes all of its stored contents.
      */
     public void delete() throws IOException {
-        if (ResponseCache.getDefault() == this.delegate) {
+        if (ResponseCache.getDefault() == this) {
             ResponseCache.setDefault(null);
         }
         delegate.delete();
     }
+
+    /** @hide Needed for OkHttp integration. */
+    @Override
+    public Cache getCache() {
+        return delegate.getCache();
+    }
+
 }
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 16250c7..07649e7 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -284,6 +284,8 @@
      */
     void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces);
 
+    void setUidCleartextNetworkPolicy(int uid, int policy);
+
     /**
      * Return status of bandwidth control module.
      */
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 21a9904..4834f97 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -614,9 +614,9 @@
         synchronized(Process.class) {
             ArrayList<String> argsForZygote = new ArrayList<String>();
 
-            // --runtime-init, --setuid=, --setgid=,
+            // --runtime-args, --setuid=, --setgid=,
             // and --setgroups= must go first
-            argsForZygote.add("--runtime-init");
+            argsForZygote.add("--runtime-args");
             argsForZygote.add("--setuid=" + uid);
             argsForZygote.add("--setgid=" + gid);
             if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 6db5f67..5018711 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -32,14 +32,17 @@
 import android.view.IWindowManager;
 
 import com.android.internal.os.RuntimeInit;
-
 import com.android.internal.util.FastPrintWriter;
+import com.android.internal.util.HexDump;
+
 import dalvik.system.BlockGuard;
 import dalvik.system.CloseGuard;
 import dalvik.system.VMDebug;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -137,6 +140,13 @@
      */
     public static final String VISUAL_PROPERTY = "persist.sys.strictmode.visual";
 
+    /**
+     * Temporary property used to include {@link #DETECT_VM_CLEARTEXT_NETWORK}
+     * in {@link VmPolicy.Builder#detectAll()}. Apps can still always opt-into
+     * detection using {@link VmPolicy.Builder#detectCleartextNetwork()}.
+     */
+    private static final String CLEARTEXT_PROPERTY = "persist.sys.strictmode.nonssl";
+
     // Only log a duplicate stack trace to the logs every second.
     private static final long MIN_LOG_INTERVAL_MS = 1000;
 
@@ -150,7 +160,7 @@
     // of the Looper.
     private static final int MAX_OFFENSES_PER_LOOP = 10;
 
-    // Thread-policy:
+    // Byte 1: Thread-policy
 
     /**
      * @hide
@@ -177,83 +187,91 @@
     private static final int ALL_THREAD_DETECT_BITS =
             DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK | DETECT_CUSTOM;
 
-    // Process-policy:
+    // Byte 2: Process-policy
 
     /**
      * Note, a "VM_" bit, not thread.
      * @hide
      */
-    public static final int DETECT_VM_CURSOR_LEAKS = 0x200;  // for VmPolicy
+    public static final int DETECT_VM_CURSOR_LEAKS = 0x01 << 8;  // for VmPolicy
 
     /**
      * Note, a "VM_" bit, not thread.
      * @hide
      */
-    public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400;  // for VmPolicy
+    public static final int DETECT_VM_CLOSABLE_LEAKS = 0x02 << 8;  // for VmPolicy
 
     /**
      * Note, a "VM_" bit, not thread.
      * @hide
      */
-    public static final int DETECT_VM_ACTIVITY_LEAKS = 0x800;  // for VmPolicy
+    public static final int DETECT_VM_ACTIVITY_LEAKS = 0x04 << 8;  // for VmPolicy
 
     /**
      * @hide
      */
-    private static final int DETECT_VM_INSTANCE_LEAKS = 0x1000;  // for VmPolicy
+    private static final int DETECT_VM_INSTANCE_LEAKS = 0x08 << 8;  // for VmPolicy
 
     /**
      * @hide
      */
-    public static final int DETECT_VM_REGISTRATION_LEAKS = 0x2000;  // for VmPolicy
+    public static final int DETECT_VM_REGISTRATION_LEAKS = 0x10 << 8;  // for VmPolicy
 
     /**
      * @hide
      */
-    private static final int DETECT_VM_FILE_URI_EXPOSURE = 0x4000;  // for VmPolicy
+    private static final int DETECT_VM_FILE_URI_EXPOSURE = 0x20 << 8;  // for VmPolicy
+
+    /**
+     * @hide
+     */
+    private static final int DETECT_VM_CLEARTEXT_NETWORK = 0x40 << 8;  // for VmPolicy
 
     private static final int ALL_VM_DETECT_BITS =
             DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS |
             DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_INSTANCE_LEAKS |
-            DETECT_VM_REGISTRATION_LEAKS | DETECT_VM_FILE_URI_EXPOSURE;
+            DETECT_VM_REGISTRATION_LEAKS | DETECT_VM_FILE_URI_EXPOSURE |
+            DETECT_VM_CLEARTEXT_NETWORK;
+
+    // Byte 3: Penalty
 
     /**
      * @hide
      */
-    public static final int PENALTY_LOG = 0x10;  // normal android.util.Log
+    public static final int PENALTY_LOG = 0x01 << 16;  // normal android.util.Log
 
     // Used for both process and thread policy:
 
     /**
      * @hide
      */
-    public static final int PENALTY_DIALOG = 0x20;
+    public static final int PENALTY_DIALOG = 0x02 << 16;
 
     /**
      * Death on any detected violation.
      *
      * @hide
      */
-    public static final int PENALTY_DEATH = 0x40;
+    public static final int PENALTY_DEATH = 0x04 << 16;
 
     /**
      * Death just for detected network usage.
      *
      * @hide
      */
-    public static final int PENALTY_DEATH_ON_NETWORK = 0x200;
+    public static final int PENALTY_DEATH_ON_NETWORK = 0x08 << 16;
 
     /**
      * Flash the screen during violations.
      *
      * @hide
      */
-    public static final int PENALTY_FLASH = 0x800;
+    public static final int PENALTY_FLASH = 0x10 << 16;
 
     /**
      * @hide
      */
-    public static final int PENALTY_DROPBOX = 0x80;
+    public static final int PENALTY_DROPBOX = 0x20 << 16;
 
     /**
      * Non-public penalty mode which overrides all the other penalty
@@ -266,7 +284,14 @@
      *
      * @hide
      */
-    public static final int PENALTY_GATHER = 0x100;
+    public static final int PENALTY_GATHER = 0x40 << 16;
+
+    /**
+     * Death when cleartext network traffic is detected.
+     *
+     * @hide
+     */
+    public static final int PENALTY_DEATH_ON_CLEARTEXT_NETWORK = 0x80 << 16;
 
     /**
      * Mask of all the penalty bits valid for thread policies.
@@ -275,13 +300,18 @@
             PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER |
             PENALTY_DEATH_ON_NETWORK | PENALTY_FLASH;
 
-
     /**
      * Mask of all the penalty bits valid for VM policies.
      */
-    private static final int VM_PENALTY_MASK =
-            PENALTY_LOG | PENALTY_DEATH | PENALTY_DROPBOX;
+    private static final int VM_PENALTY_MASK = PENALTY_LOG | PENALTY_DEATH | PENALTY_DROPBOX
+            | PENALTY_DEATH_ON_CLEARTEXT_NETWORK;
 
+    /** {@hide} */
+    public static final int NETWORK_POLICY_ACCEPT = 0;
+    /** {@hide} */
+    public static final int NETWORK_POLICY_LOG = 1;
+    /** {@hide} */
+    public static final int NETWORK_POLICY_REJECT = 2;
 
     // TODO: wrap in some ImmutableHashMap thing.
     // Note: must be before static initialization of sVmPolicy.
@@ -636,9 +666,17 @@
              * but will likely expand in future releases.
              */
             public Builder detectAll() {
-                return enable(DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_CURSOR_LEAKS
+                int flags = DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_CURSOR_LEAKS
                         | DETECT_VM_CLOSABLE_LEAKS | DETECT_VM_REGISTRATION_LEAKS
-                        | DETECT_VM_FILE_URI_EXPOSURE);
+                        | DETECT_VM_FILE_URI_EXPOSURE;
+
+                // TODO: always add DETECT_VM_CLEARTEXT_NETWORK once we have facility
+                // for apps to mark sockets that should be ignored
+                if (SystemProperties.getBoolean(CLEARTEXT_PROPERTY, false)) {
+                    flags |= DETECT_VM_CLEARTEXT_NETWORK;
+                }
+
+                return enable(flags);
             }
 
             /**
@@ -686,15 +724,49 @@
             }
 
             /**
-             * Crashes the whole process on violation.  This penalty runs at
-             * the end of all enabled penalties so yo you'll still get
-             * your logging or other violations before the process dies.
+             * Detect any network traffic from the calling app which is not
+             * wrapped in SSL/TLS. This can help you detect places that your app
+             * is inadvertently sending cleartext data across the network.
+             * <p>
+             * Using {@link #penaltyDeath()} or
+             * {@link #penaltyDeathOnCleartextNetwork()} will block further
+             * traffic on that socket to prevent accidental data leakage, in
+             * addition to crashing your process.
+             * <p>
+             * Using {@link #penaltyDropBox()} will log the raw contents of the
+             * packet that triggered the violation.
+             * <p>
+             * This inspects both IPv4/IPv6 and TCP/UDP network traffic, but it
+             * may be subject to false positives, such as when STARTTLS
+             * protocols or HTTP proxies are used.
+             *
+             * @hide
+             */
+            public Builder detectCleartextNetwork() {
+                return enable(DETECT_VM_CLEARTEXT_NETWORK);
+            }
+
+            /**
+             * Crashes the whole process on violation. This penalty runs at the
+             * end of all enabled penalties so you'll still get your logging or
+             * other violations before the process dies.
              */
             public Builder penaltyDeath() {
                 return enable(PENALTY_DEATH);
             }
 
             /**
+             * Crashes the whole process when cleartext network traffic is
+             * detected.
+             *
+             * @see #detectCleartextNetwork()
+             * @hide
+             */
+            public Builder penaltyDeathOnCleartextNetwork() {
+                return enable(PENALTY_DEATH_ON_CLEARTEXT_NETWORK);
+            }
+
+            /**
              * Log detected violations to the system log.
              */
             public Builder penaltyLog() {
@@ -1422,7 +1494,7 @@
     }
 
     private static class AndroidCloseGuardReporter implements CloseGuard.Reporter {
-        public void report (String message, Throwable allocationSite) {
+        public void report(String message, Throwable allocationSite) {
             onVmPolicyViolation(message, allocationSite);
         }
     }
@@ -1508,6 +1580,27 @@
                     sIsIdlerRegistered = true;
                 }
             }
+
+            int networkPolicy = NETWORK_POLICY_ACCEPT;
+            if ((sVmPolicyMask & DETECT_VM_CLEARTEXT_NETWORK) != 0) {
+                if ((sVmPolicyMask & PENALTY_DEATH) != 0
+                        || (sVmPolicyMask & PENALTY_DEATH_ON_CLEARTEXT_NETWORK) != 0) {
+                    networkPolicy = NETWORK_POLICY_REJECT;
+                } else {
+                    networkPolicy = NETWORK_POLICY_LOG;
+                }
+            }
+
+            final INetworkManagementService netd = INetworkManagementService.Stub.asInterface(
+                    ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
+            if (netd != null) {
+                try {
+                    netd.setUidCleartextNetworkPolicy(android.os.Process.myUid(), networkPolicy);
+                } catch (RemoteException ignored) {
+                }
+            } else if (networkPolicy != NETWORK_POLICY_ACCEPT) {
+                Log.w(TAG, "Dropping requested network policy due to missing service!");
+            }
         }
     }
 
@@ -1570,6 +1663,13 @@
     /**
      * @hide
      */
+    public static boolean vmCleartextNetworkEnabled() {
+        return (sVmPolicyMask & DETECT_VM_CLEARTEXT_NETWORK) != 0;
+    }
+
+    /**
+     * @hide
+     */
     public static void onSqliteObjectLeaked(String message, Throwable originStack) {
         onVmPolicyViolation(message, originStack);
     }
@@ -1600,7 +1700,39 @@
      */
     public static void onFileUriExposed(String location) {
         final String message = "file:// Uri exposed through " + location;
-        onVmPolicyViolation(message, new Throwable(message));
+        onVmPolicyViolation(null, new Throwable(message));
+    }
+
+    /**
+     * @hide
+     */
+    public static void onCleartextNetworkDetected(byte[] firstPacket) {
+        byte[] rawAddr = null;
+        if (firstPacket != null) {
+            if (firstPacket.length >= 20 && (firstPacket[0] & 0xf0) == 0x40) {
+                // IPv4
+                rawAddr = new byte[4];
+                System.arraycopy(firstPacket, 16, rawAddr, 0, 4);
+            } else if (firstPacket.length >= 40 && (firstPacket[0] & 0xf0) == 0x60) {
+                // IPv6
+                rawAddr = new byte[16];
+                System.arraycopy(firstPacket, 24, rawAddr, 0, 16);
+            }
+        }
+
+        final int uid = android.os.Process.myUid();
+        String msg = "Detected cleartext network traffic from UID " + uid;
+        if (rawAddr != null) {
+            try {
+                msg = "Detected cleartext network traffic from UID " + uid + " to "
+                        + InetAddress.getByAddress(rawAddr);
+            } catch (UnknownHostException ignored) {
+            }
+        }
+
+        final boolean forceDeath = (sVmPolicyMask & PENALTY_DEATH_ON_CLEARTEXT_NETWORK) != 0;
+        onVmPolicyViolation(HexDump.dumpHexString(firstPacket).trim(), new Throwable(msg),
+                forceDeath);
     }
 
     // Map from VM violation fingerprint to uptime millis.
@@ -1610,10 +1742,18 @@
      * @hide
      */
     public static void onVmPolicyViolation(String message, Throwable originStack) {
+        onVmPolicyViolation(message, originStack, false);
+    }
+
+    /**
+     * @hide
+     */
+    public static void onVmPolicyViolation(String message, Throwable originStack,
+            boolean forceDeath) {
         final boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0;
-        final boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0;
+        final boolean penaltyDeath = ((sVmPolicyMask & PENALTY_DEATH) != 0) || forceDeath;
         final boolean penaltyLog = (sVmPolicyMask & PENALTY_LOG) != 0;
-        final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+        final ViolationInfo info = new ViolationInfo(message, originStack, sVmPolicyMask);
 
         // Erase stuff not relevant for process-wide violations
         info.numAnimationsRunning = 0;
@@ -2057,6 +2197,8 @@
      * @hide
      */
     public static class ViolationInfo {
+        public String message;
+
         /**
          * Stack and other stuff info.
          */
@@ -2118,10 +2260,15 @@
             policy = 0;
         }
 
+        public ViolationInfo(Throwable tr, int policy) {
+            this(null, tr, policy);
+        }
+
         /**
          * Create an instance of ViolationInfo initialized from an exception.
          */
-        public ViolationInfo(Throwable tr, int policy) {
+        public ViolationInfo(String message, Throwable tr, int policy) {
+            this.message = message;
             crashInfo = new ApplicationErrorReport.CrashInfo(tr);
             violationUptimeMillis = SystemClock.uptimeMillis();
             this.policy = policy;
@@ -2184,6 +2331,7 @@
          *   and the gathering penalty should be removed.
          */
         public ViolationInfo(Parcel in, boolean unsetGatheringBit) {
+            message = in.readString();
             crashInfo = new ApplicationErrorReport.CrashInfo(in);
             int rawPolicy = in.readInt();
             if (unsetGatheringBit) {
@@ -2204,6 +2352,7 @@
          * Save a ViolationInfo instance to a parcel.
          */
         public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(message);
             crashInfo.writeToParcel(dest, flags);
             int start = dest.dataPosition();
             dest.writeInt(policy);
diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl
new file mode 100644
index 0000000..bf51ed1
--- /dev/null
+++ b/core/java/android/security/IKeystoreService.aidl
@@ -0,0 +1,55 @@
+/**
+ * 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;
+
+import android.security.KeystoreArguments;
+
+/**
+ * This must be kept manually in sync with system/security/keystore until AIDL
+ * can generate both Java and C++ bindings.
+ *
+ * @hide
+ */
+interface IKeystoreService {
+    int test();
+    byte[] get(String name);
+    int insert(String name, in byte[] item, int uid, int flags);
+    int del(String name, int uid);
+    int exist(String name, int uid);
+    String[] saw(String namePrefix, int uid);
+    int reset();
+    int password(String password);
+    int lock();
+    int unlock(String password);
+    int zero();
+    int generate(String name, int uid, int keyType, int keySize, int flags,
+        in KeystoreArguments args);
+    int import_key(String name, in byte[] data, int uid, int flags);
+    byte[] sign(String name, in byte[] data);
+    int verify(String name, in byte[] data, in byte[] signature);
+    byte[] get_pubkey(String name);
+    int del_key(String name, int uid);
+    int grant(String name, int granteeUid);
+    int ungrant(String name, int granteeUid);
+    long getmtime(String name);
+    int duplicate(String srcKey, int srcUid, String destKey, int destUid);
+    int is_hardware_backed(String string);
+    int clear_uid(long uid);
+    int reset_uid(int uid);
+    int sync_uid(int sourceUid, int targetUid);
+    int password_uid(String password, int uid);
+}
diff --git a/core/java/android/security/IKeystoreService.java b/core/java/android/security/IKeystoreService.java
deleted file mode 100644
index 7e9aba0..0000000
--- a/core/java/android/security/IKeystoreService.java
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security;
-
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.RemoteException;
-
-/**
- * This must be kept manually in sync with system/security/keystore until AIDL
- * can generate both Java and C++ bindings.
- *
- * @hide
- */
-public interface IKeystoreService extends IInterface {
-    public static abstract class Stub extends Binder implements IKeystoreService {
-        private static class Proxy implements IKeystoreService {
-            private final IBinder mRemote;
-
-            Proxy(IBinder remote) {
-                mRemote = remote;
-            }
-
-            public IBinder asBinder() {
-                return mRemote;
-            }
-
-            public String getInterfaceDescriptor() {
-                return DESCRIPTOR;
-            }
-
-            public int test() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_test, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public byte[] get(String name) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                byte[] _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    mRemote.transact(Stub.TRANSACTION_get, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.createByteArray();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int insert(String name, byte[] item, int uid, int flags) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    _data.writeByteArray(item);
-                    _data.writeInt(uid);
-                    _data.writeInt(flags);
-                    mRemote.transact(Stub.TRANSACTION_insert, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int del(String name, int uid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    _data.writeInt(uid);
-                    mRemote.transact(Stub.TRANSACTION_del, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int exist(String name, int uid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    _data.writeInt(uid);
-                    mRemote.transact(Stub.TRANSACTION_exist, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public String[] saw(String name, int uid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                String[] _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    _data.writeInt(uid);
-                    mRemote.transact(Stub.TRANSACTION_saw, _data, _reply, 0);
-                    _reply.readException();
-                    int size = _reply.readInt();
-                    _result = new String[size];
-                    for (int i = 0; i < size; i++) {
-                        _result[i] = _reply.readString();
-                    }
-                    int _ret = _reply.readInt();
-                    if (_ret != 1) {
-                        return null;
-                    }
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public int reset() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_reset, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int password(String password) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(password);
-                    mRemote.transact(Stub.TRANSACTION_password, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int lock() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_lock, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int unlock(String password) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(password);
-                    mRemote.transact(Stub.TRANSACTION_unlock, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public int zero() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_zero, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int generate(String name, int uid, int keyType, int keySize, int flags,
-                    byte[][] args) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    _data.writeInt(uid);
-                    _data.writeInt(keyType);
-                    _data.writeInt(keySize);
-                    _data.writeInt(flags);
-                    if (args == null) {
-                        _data.writeInt(0);
-                    } else {
-                        _data.writeInt(args.length);
-                        for (int i = 0; i < args.length; i++) {
-                            _data.writeByteArray(args[i]);
-                        }
-                    }
-                    mRemote.transact(Stub.TRANSACTION_generate, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int import_key(String name, byte[] data, int uid, int flags)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    _data.writeByteArray(data);
-                    _data.writeInt(uid);
-                    _data.writeInt(flags);
-                    mRemote.transact(Stub.TRANSACTION_import, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public byte[] sign(String name, byte[] data) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                byte[] _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    _data.writeByteArray(data);
-                    mRemote.transact(Stub.TRANSACTION_sign, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.createByteArray();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int verify(String name, byte[] data, byte[] signature) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    _data.writeByteArray(data);
-                    _data.writeByteArray(signature);
-                    mRemote.transact(Stub.TRANSACTION_verify, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public byte[] get_pubkey(String name) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                byte[] _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    mRemote.transact(Stub.TRANSACTION_get_pubkey, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.createByteArray();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int del_key(String name, int uid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    _data.writeInt(uid);
-                    mRemote.transact(Stub.TRANSACTION_del_key, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int grant(String name, int granteeUid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    _data.writeInt(granteeUid);
-                    mRemote.transact(Stub.TRANSACTION_grant, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int ungrant(String name, int granteeUid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    _data.writeInt(granteeUid);
-                    mRemote.transact(Stub.TRANSACTION_ungrant, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public long getmtime(String name) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                long _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    mRemote.transact(Stub.TRANSACTION_getmtime, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readLong();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public int duplicate(String srcKey, int srcUid, String destKey, int destUid)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(srcKey);
-                    _data.writeInt(srcUid);
-                    _data.writeString(destKey);
-                    _data.writeInt(destUid);
-                    mRemote.transact(Stub.TRANSACTION_duplicate, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public int is_hardware_backed(String keyType) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(keyType);
-                    mRemote.transact(Stub.TRANSACTION_is_hardware_backed, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public int clear_uid(long uid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeLong(uid);
-                    mRemote.transact(Stub.TRANSACTION_clear_uid, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int reset_uid(int uid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(uid);
-                    mRemote.transact(Stub.TRANSACTION_reset_uid, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int sync_uid(int srcUid, int dstUid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(srcUid);
-                    _data.writeInt(dstUid);
-                    mRemote.transact(Stub.TRANSACTION_sync_uid, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int password_uid(String password, int uid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(password);
-                    _data.writeInt(uid);
-                    mRemote.transact(Stub.TRANSACTION_password_uid, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-        }
-
-        private static final String DESCRIPTOR = "android.security.keystore";
-
-        static final int TRANSACTION_test = IBinder.FIRST_CALL_TRANSACTION + 0;
-        static final int TRANSACTION_get = IBinder.FIRST_CALL_TRANSACTION + 1;
-        static final int TRANSACTION_insert = IBinder.FIRST_CALL_TRANSACTION + 2;
-        static final int TRANSACTION_del = IBinder.FIRST_CALL_TRANSACTION + 3;
-        static final int TRANSACTION_exist = IBinder.FIRST_CALL_TRANSACTION + 4;
-        static final int TRANSACTION_saw = IBinder.FIRST_CALL_TRANSACTION + 5;
-        static final int TRANSACTION_reset = IBinder.FIRST_CALL_TRANSACTION + 6;
-        static final int TRANSACTION_password = IBinder.FIRST_CALL_TRANSACTION + 7;
-        static final int TRANSACTION_lock = IBinder.FIRST_CALL_TRANSACTION + 8;
-        static final int TRANSACTION_unlock = IBinder.FIRST_CALL_TRANSACTION + 9;
-        static final int TRANSACTION_zero = IBinder.FIRST_CALL_TRANSACTION + 10;
-        static final int TRANSACTION_generate = IBinder.FIRST_CALL_TRANSACTION + 11;
-        static final int TRANSACTION_import = IBinder.FIRST_CALL_TRANSACTION + 12;
-        static final int TRANSACTION_sign = IBinder.FIRST_CALL_TRANSACTION + 13;
-        static final int TRANSACTION_verify = IBinder.FIRST_CALL_TRANSACTION + 14;
-        static final int TRANSACTION_get_pubkey = IBinder.FIRST_CALL_TRANSACTION + 15;
-        static final int TRANSACTION_del_key = IBinder.FIRST_CALL_TRANSACTION + 16;
-        static final int TRANSACTION_grant = IBinder.FIRST_CALL_TRANSACTION + 17;
-        static final int TRANSACTION_ungrant = IBinder.FIRST_CALL_TRANSACTION + 18;
-        static final int TRANSACTION_getmtime = IBinder.FIRST_CALL_TRANSACTION + 19;
-        static final int TRANSACTION_duplicate = IBinder.FIRST_CALL_TRANSACTION + 20;
-        static final int TRANSACTION_is_hardware_backed = IBinder.FIRST_CALL_TRANSACTION + 21;
-        static final int TRANSACTION_clear_uid = IBinder.FIRST_CALL_TRANSACTION + 22;
-        static final int TRANSACTION_reset_uid = IBinder.FIRST_CALL_TRANSACTION + 23;
-        static final int TRANSACTION_sync_uid = IBinder.FIRST_CALL_TRANSACTION + 24;
-        static final int TRANSACTION_password_uid = IBinder.FIRST_CALL_TRANSACTION + 25;
-
-        /**
-         * Cast an IBinder object into an IKeystoreService interface, generating
-         * a proxy if needed.
-         */
-        public static IKeystoreService asInterface(IBinder obj) {
-            if (obj == null) {
-                return null;
-            }
-            IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
-            if (iin != null && iin instanceof IKeystoreService) {
-                return (IKeystoreService) iin;
-            }
-            return new IKeystoreService.Stub.Proxy(obj);
-        }
-
-        /** Construct the stub at attach it to the interface. */
-        public Stub() {
-            attachInterface(this, DESCRIPTOR);
-        }
-
-        public IBinder asBinder() {
-            return this;
-        }
-
-        @Override
-        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-                throws RemoteException {
-            switch (code) {
-                case INTERFACE_TRANSACTION: {
-                    reply.writeString(DESCRIPTOR);
-                    return true;
-                }
-                case TRANSACTION_test: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int resultCode = test();
-                    reply.writeNoException();
-                    reply.writeInt(resultCode);
-                    return true;
-                }
-            }
-            return super.onTransact(code, data, reply, flags);
-        }
-    }
-
-    public int test() throws RemoteException;
-
-    public byte[] get(String name) throws RemoteException;
-
-    public int insert(String name, byte[] item, int uid, int flags) throws RemoteException;
-
-    public int del(String name, int uid) throws RemoteException;
-
-    public int exist(String name, int uid) throws RemoteException;
-
-    public String[] saw(String name, int uid) throws RemoteException;
-
-    public int reset() throws RemoteException;
-
-    public int password(String password) throws RemoteException;
-
-    public int lock() throws RemoteException;
-
-    public int unlock(String password) throws RemoteException;
-
-    public int zero() throws RemoteException;
-
-    public int generate(String name, int uid, int keyType, int keySize, int flags, byte[][] args)
-            throws RemoteException;
-
-    public int import_key(String name, byte[] data, int uid, int flags) throws RemoteException;
-
-    public byte[] sign(String name, byte[] data) throws RemoteException;
-
-    public int verify(String name, byte[] data, byte[] signature) throws RemoteException;
-
-    public byte[] get_pubkey(String name) throws RemoteException;
-
-    public int del_key(String name, int uid) throws RemoteException;
-
-    public int grant(String name, int granteeUid) throws RemoteException;
-
-    public int ungrant(String name, int granteeUid) throws RemoteException;
-
-    public long getmtime(String name) throws RemoteException;
-
-    public int duplicate(String srcKey, int srcUid, String destKey, int destUid)
-            throws RemoteException;
-
-    public int is_hardware_backed(String string) throws RemoteException;
-
-    public int clear_uid(long uid) throws RemoteException;
-
-    public int reset_uid(int uid) throws RemoteException;
-
-    public int sync_uid(int sourceUid, int targetUid) throws RemoteException;
-
-    public int password_uid(String password, int uid) throws RemoteException;
-}
diff --git a/core/java/android/security/KeystoreArguments.aidl b/core/java/android/security/KeystoreArguments.aidl
new file mode 100644
index 0000000..d636414
--- /dev/null
+++ b/core/java/android/security/KeystoreArguments.aidl
@@ -0,0 +1,20 @@
+/**
+ * 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;
+
+/* @hide */
+parcelable KeystoreArguments;
diff --git a/core/java/android/security/KeystoreArguments.java b/core/java/android/security/KeystoreArguments.java
new file mode 100644
index 0000000..16054e5
--- /dev/null
+++ b/core/java/android/security/KeystoreArguments.java
@@ -0,0 +1,76 @@
+/**
+ * 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;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Class for handling the additional arguments to some keystore binder calls.
+ * This must be kept in sync with the deserialization code in system/security/keystore.
+ * @hide
+ */
+public class KeystoreArguments implements Parcelable {
+    public byte[][] args;
+
+    public static final Parcelable.Creator<KeystoreArguments> CREATOR = new
+            Parcelable.Creator<KeystoreArguments>() {
+                public KeystoreArguments createFromParcel(Parcel in) {
+                    return new KeystoreArguments(in);
+                }
+                public KeystoreArguments[] newArray(int size) {
+                    return new KeystoreArguments[size];
+                }
+            };
+
+    public KeystoreArguments() {
+        args = null;
+    }
+
+    public KeystoreArguments(byte[][] args) {
+        this.args = args;
+    }
+
+    private KeystoreArguments(Parcel in) {
+        readFromParcel(in);
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        if (args == null) {
+            out.writeInt(0);
+        } else {
+            out.writeInt(args.length);
+            for (byte[] arg : args) {
+                out.writeByteArray(arg);
+            }
+        }
+    }
+
+    private void readFromParcel(Parcel in) {
+        int length = in.readInt();
+        args = new byte[length][];
+        for (int i = 0; i < length; i++) {
+            args[i] = in.createByteArray();
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index af821ba..34ae58a 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -19,6 +19,7 @@
 import android.os.Process;
 import android.util.Slog;
 
+import dalvik.system.VMRuntime;
 import java.io.DataOutputStream;
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
@@ -96,9 +97,20 @@
      * @param args Arguments for {@link RuntimeInit#main}.
      */
     public static void execApplication(String invokeWith, String niceName,
-            int targetSdkVersion, FileDescriptor pipeFd, String[] args) {
+            int targetSdkVersion, String instructionSet, FileDescriptor pipeFd,
+            String[] args) {
         StringBuilder command = new StringBuilder(invokeWith);
-        command.append(" /system/bin/app_process /system/bin --application");
+
+        final String appProcess;
+        if (VMRuntime.is64BitInstructionSet(instructionSet)) {
+            appProcess = "/system/bin/app_process64";
+        } else {
+            appProcess = "/system/bin/app_process32";
+        }
+        command.append(' ');
+        command.append(appProcess);
+
+        command.append(" /system/bin --application");
         if (niceName != null) {
             command.append(" '--nice-name=").append(niceName).append("'");
         }
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index c03938a..aba4bd0 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.os;
 
+import static android.system.OsConstants.F_SETFD;
 import static android.system.OsConstants.O_CLOEXEC;
 import static android.system.OsConstants.STDERR_FILENO;
 import static android.system.OsConstants.STDIN_FILENO;
@@ -30,6 +31,7 @@
 import android.system.Os;
 import android.util.Log;
 import dalvik.system.PathClassLoader;
+import dalvik.system.VMRuntime;
 import java.io.BufferedReader;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
@@ -190,10 +192,11 @@
                 rlimits = parsedArgs.rlimits.toArray(intArray2d);
             }
 
-            if (parsedArgs.runtimeInit && parsedArgs.invokeWith != null) {
+            if (parsedArgs.invokeWith != null) {
                 FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                 childPipeFd = pipeFds[1];
                 serverPipeFd = pipeFds[0];
+                Os.fcntlInt(childPipeFd, F_SETFD, 0);
             }
 
             /**
@@ -301,20 +304,13 @@
      *   <li> --rlimit=r,c,m<i>tuple of values for setrlimit() call.
      *    <code>r</code> is the resource, <code>c</code> and <code>m</code>
      *    are the settings for current and max value.</i>
-     *   <li> --classpath=<i>colon-separated classpath</i> indicates
-     * that the specified class (which must b first non-flag argument) should
-     * be loaded from jar files in the specified classpath. Incompatible with
-     * --runtime-init
-     *   <li> --runtime-init indicates that the remaining arg list should
-     * be handed off to com.android.internal.os.RuntimeInit, rather than
-     * processed directly
-     * Android runtime startup (eg, Binder initialization) is also eschewed.
-     *   <li> --nice-name=<i>nice name to appear in ps</i>
-     *   <li> If <code>--runtime-init</code> is present:
-     *      [--] &lt;args for RuntimeInit &gt;
-     *   <li> If <code>--runtime-init</code> is absent:
-     *      [--] &lt;classname&gt; [args...]
      *   <li> --instruction-set=<i>instruction-set-string</i> which instruction set to use/emulate.
+     *   <li> --nice-name=<i>nice name to appear in ps</i>
+     *   <li> --runtime-args indicates that the remaining arg list should
+     * be handed off to com.android.internal.os.RuntimeInit, rather than
+     * processed directly.
+     * Android runtime startup (eg, Binder initialization) is also eschewed.
+     *   <li> [--] &lt;args for RuntimeInit &gt;
      * </ul>
      */
     static class Arguments {
@@ -342,12 +338,6 @@
         int targetSdkVersion;
         boolean targetSdkVersionSpecified;
 
-        /** from --classpath */
-        String classpath;
-
-        /** from --runtime-init */
-        boolean runtimeInit;
-
         /** from --nice-name */
         String niceName;
 
@@ -409,6 +399,8 @@
                 throws IllegalArgumentException {
             int curArg = 0;
 
+            boolean seenRuntimeArgs = true;
+
             for ( /* curArg */ ; curArg < args.length; curArg++) {
                 String arg = args[curArg];
 
@@ -449,8 +441,8 @@
                     debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
                 } else if (arg.equals("--enable-assert")) {
                     debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
-                } else if (arg.equals("--runtime-init")) {
-                    runtimeInit = true;
+                } else if (arg.equals("--runtime-args")) {
+                    seenRuntimeArgs = true;
                 } else if (arg.startsWith("--seinfo=")) {
                     if (seInfoSpecified) {
                         throw new IllegalArgumentException(
@@ -495,17 +487,6 @@
                     }
 
                     rlimits.add(rlimitTuple);
-                } else if (arg.equals("-classpath")) {
-                    if (classpath != null) {
-                        throw new IllegalArgumentException(
-                                "Duplicate arg specified");
-                    }
-                    try {
-                        classpath = args[++curArg];
-                    } catch (IndexOutOfBoundsException ex) {
-                        throw new IllegalArgumentException(
-                                "-classpath requires argument");
-                    }
                 } else if (arg.startsWith("--setgroups=")) {
                     if (gids != null) {
                         throw new IllegalArgumentException(
@@ -552,9 +533,8 @@
                 }
             }
 
-            if (runtimeInit && classpath != null) {
-                throw new IllegalArgumentException(
-                        "--runtime-init and -classpath are incompatible");
+            if (!seenRuntimeArgs) {
+                throw new IllegalArgumentException("Unexpected argument : " + args[curArg]);
             }
 
             remainingArgs = new String[args.length - curArg];
@@ -876,47 +856,14 @@
             Process.setArgV0(parsedArgs.niceName);
         }
 
-        if (parsedArgs.runtimeInit) {
-            if (parsedArgs.invokeWith != null) {
-                WrapperInit.execApplication(parsedArgs.invokeWith,
-                        parsedArgs.niceName, parsedArgs.targetSdkVersion,
-                        pipeFd, parsedArgs.remainingArgs);
-            } else {
-                RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
-                        parsedArgs.remainingArgs, null /* classLoader */);
-            }
+        if (parsedArgs.invokeWith != null) {
+            WrapperInit.execApplication(parsedArgs.invokeWith,
+                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
+                    VMRuntime.getCurrentInstructionSet(),
+                    pipeFd, parsedArgs.remainingArgs);
         } else {
-            String className;
-            try {
-                className = parsedArgs.remainingArgs[0];
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                logAndPrintError(newStderr,
-                        "Missing required class name argument", null);
-                return;
-            }
-
-            String[] mainArgs = new String[parsedArgs.remainingArgs.length - 1];
-            System.arraycopy(parsedArgs.remainingArgs, 1,
-                    mainArgs, 0, mainArgs.length);
-
-            if (parsedArgs.invokeWith != null) {
-                WrapperInit.execStandalone(parsedArgs.invokeWith,
-                        parsedArgs.classpath, className, mainArgs);
-            } else {
-                ClassLoader cloader;
-                if (parsedArgs.classpath != null) {
-                    cloader = new PathClassLoader(parsedArgs.classpath,
-                            ClassLoader.getSystemClassLoader());
-                } else {
-                    cloader = ClassLoader.getSystemClassLoader();
-                }
-
-                try {
-                    ZygoteInit.invokeStaticMain(cloader, className, mainArgs);
-                } catch (RuntimeException ex) {
-                    logAndPrintError(newStderr, "Error starting.", ex);
-                }
-            }
+            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
+                    parsedArgs.remainingArgs, null /* classLoader */);
         }
     }
 
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 0fa9a97..8107985 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -17,7 +17,6 @@
 package com.android.internal.os;
 
 import static android.system.OsConstants.POLLIN;
-import static android.system.OsConstants.POLLOUT;
 import static android.system.OsConstants.S_IRWXG;
 import static android.system.OsConstants.S_IRWXO;
 
@@ -104,54 +103,6 @@
     private static final boolean PRELOAD_RESOURCES = true;
 
     /**
-     * Invokes a static "main(argv[]) method on class "className".
-     * Converts various failing exceptions into RuntimeExceptions, with
-     * the assumption that they will then cause the VM instance to exit.
-     *
-     * @param loader class loader to use
-     * @param className Fully-qualified class name
-     * @param argv Argument vector for main()
-     */
-    static void invokeStaticMain(ClassLoader loader,
-            String className, String[] argv)
-            throws ZygoteInit.MethodAndArgsCaller {
-        Class<?> cl;
-
-        try {
-            cl = loader.loadClass(className);
-        } catch (ClassNotFoundException ex) {
-            throw new RuntimeException(
-                    "Missing class when invoking static main " + className,
-                    ex);
-        }
-
-        Method m;
-        try {
-            m = cl.getMethod("main", new Class[] { String[].class });
-        } catch (NoSuchMethodException ex) {
-            throw new RuntimeException(
-                    "Missing static main on " + className, ex);
-        } catch (SecurityException ex) {
-            throw new RuntimeException(
-                    "Problem getting static main on " + className, ex);
-        }
-
-        int modifiers = m.getModifiers();
-        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
-            throw new RuntimeException(
-                    "Main method is not public and static on " + className);
-        }
-
-        /*
-         * This throw gets caught in ZygoteInit.main(), which responds
-         * by invoking the exception's run() method. This arrangement
-         * clears up all the stack frames that were required in setting
-         * up the process.
-         */
-        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
-    }
-
-    /**
      * Registers a server socket for zygote command connections
      *
      * @throws RuntimeException when open fails
@@ -276,11 +227,22 @@
         long startTime = SystemClock.uptimeMillis();
 
         // Drop root perms while running static initializers.
-        try {
-            Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
-            Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
-        } catch (ErrnoException ex) {
-            throw new RuntimeException("Failed to drop root", ex);
+        final int reuid = Os.getuid();
+        final int regid = Os.getgid();
+
+        // We need to drop root perms only if we're already root. In the case of "wrapped"
+        // processes (see WrapperInit), this function is called from an unprivileged uid
+        // and gid.
+        boolean droppedPriviliges = false;
+        if (reuid == ROOT_UID && regid == ROOT_GID) {
+            try {
+                Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
+                Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
+            } catch (ErrnoException ex) {
+                throw new RuntimeException("Failed to drop root", ex);
+            }
+
+            droppedPriviliges = true;
         }
 
         // Alter the target heap utilization.  With explicit GCs this
@@ -335,12 +297,14 @@
             // Fill in dex caches with classes, fields, and methods brought in by preloading.
             runtime.preloadDexCaches();
 
-            // Bring back root. We'll need it later.
-            try {
-                Os.setreuid(ROOT_UID, ROOT_UID);
-                Os.setregid(ROOT_GID, ROOT_GID);
-            } catch (ErrnoException ex) {
-                throw new RuntimeException("Failed to restore root", ex);
+            // Bring back root. We'll need it later if we're in the zygote.
+            if (droppedPriviliges) {
+                try {
+                    Os.setreuid(ROOT_UID, ROOT_UID);
+                    Os.setregid(ROOT_GID, ROOT_GID);
+                } catch (ErrnoException ex) {
+                    throw new RuntimeException("Failed to restore root", ex);
+                }
             }
         }
     }
@@ -473,7 +437,7 @@
 
             WrapperInit.execApplication(parsedArgs.invokeWith,
                     parsedArgs.niceName, parsedArgs.targetSdkVersion,
-                    null, args);
+                    VMRuntime.getCurrentInstructionSet(), null, args);
         } else {
             ClassLoader cl = null;
             if (systemServerClasspath != null) {
diff --git a/core/tests/coretests/apks/install_bad_dex/Android.mk b/core/tests/coretests/apks/install_bad_dex/Android.mk
index 769a1b0..05983aa 100644
--- a/core/tests/coretests/apks/install_bad_dex/Android.mk
+++ b/core/tests/coretests/apks/install_bad_dex/Android.mk
@@ -5,6 +5,7 @@
 
 LOCAL_PACKAGE_NAME := install_bad_dex
 
-LOCAL_JAVA_RESOURCE_FILES := $(LOCAL_PATH)/classes.dex
-
 include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+# Override target specific variable PRIVATE_DEX_FILE to inject bad classes.dex file.
+$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(LOCAL_PATH)/classes.dex
diff --git a/core/tests/coretests/src/android/net/http/HttpResponseCacheTest.java b/core/tests/coretests/src/android/net/http/HttpResponseCacheTest.java
deleted file mode 100644
index 9015a6f..0000000
--- a/core/tests/coretests/src/android/net/http/HttpResponseCacheTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2011 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.net.http;
-
-import com.google.mockwebserver.MockResponse;
-import com.google.mockwebserver.MockWebServer;
-import java.io.File;
-import java.net.CacheRequest;
-import java.net.CacheResponse;
-import java.net.ResponseCache;
-import java.net.URI;
-import java.net.URLConnection;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import junit.framework.TestCase;
-
-public final class HttpResponseCacheTest extends TestCase {
-
-    private File cacheDir;
-    private MockWebServer server = new MockWebServer();
-
-    @Override public void setUp() throws Exception {
-        super.setUp();
-        String tmp = System.getProperty("java.io.tmpdir");
-        cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID());
-    }
-
-    @Override protected void tearDown() throws Exception {
-        ResponseCache.setDefault(null);
-        server.shutdown();
-        super.tearDown();
-    }
-
-    public void testInstall() throws Exception {
-        HttpResponseCache installed = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        assertNotNull(installed);
-        assertSame(installed, ResponseCache.getDefault());
-        assertSame(installed, HttpResponseCache.getDefault());
-    }
-
-    public void testSecondEquivalentInstallDoesNothing() throws Exception {
-        HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        HttpResponseCache another = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        assertSame(first, another);
-    }
-
-    public void testInstallClosesPreviouslyInstalled() throws Exception {
-        HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        HttpResponseCache another = HttpResponseCache.install(cacheDir, 8 * 1024 * 1024);
-        assertNotSame(first, another);
-        try {
-            first.flush();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testGetInstalledWithWrongTypeInstalled() {
-        ResponseCache.setDefault(new ResponseCache() {
-            @Override public CacheResponse get(URI uri, String requestMethod,
-                    Map<String, List<String>> requestHeaders) {
-                return null;
-            }
-            @Override public CacheRequest put(URI uri, URLConnection connection) {
-                return null;
-            }
-        });
-        assertNull(HttpResponseCache.getInstalled());
-    }
-
-    public void testCloseCloses() throws Exception {
-        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        cache.close();
-        try {
-            cache.flush();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testCloseUninstalls() throws Exception {
-        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        cache.close();
-        assertNull(ResponseCache.getDefault());
-    }
-
-    public void testDeleteUninstalls() throws Exception {
-        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        cache.delete();
-        assertNull(ResponseCache.getDefault());
-    }
-
-    /**
-     * Make sure that statistics tracking are wired all the way through the
-     * wrapper class. http://code.google.com/p/android/issues/detail?id=25418
-     */
-    public void testStatisticsTracking() throws Exception {
-        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-
-        server.enqueue(new MockResponse()
-                .addHeader("Cache-Control: max-age=60")
-                .setBody("A"));
-        server.play();
-
-        URLConnection c1 = server.getUrl("/").openConnection();
-        assertEquals('A', c1.getInputStream().read());
-        assertEquals(1, cache.getRequestCount());
-        assertEquals(1, cache.getNetworkCount());
-        assertEquals(0, cache.getHitCount());
-
-        URLConnection c2 = server.getUrl("/").openConnection();
-        assertEquals('A', c2.getInputStream().read());
-
-        URLConnection c3 = server.getUrl("/").openConnection();
-        assertEquals('A', c3.getInputStream().read());
-        assertEquals(3, cache.getRequestCount());
-        assertEquals(1, cache.getNetworkCount());
-        assertEquals(2, cache.getHitCount());
-    }
-}
diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java
index a0ffb5f..9d9a173 100644
--- a/keystore/java/android/security/AndroidKeyPairGenerator.java
+++ b/keystore/java/android/security/AndroidKeyPairGenerator.java
@@ -50,10 +50,50 @@
  *
  * {@hide}
  */
-public class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
+public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
+
+    public static class RSA extends AndroidKeyPairGenerator {
+        public RSA() {
+            super("RSA");
+        }
+    }
+
+    public static class EC extends AndroidKeyPairGenerator {
+        public EC() {
+            super("EC");
+        }
+    }
+
+    /*
+     * These must be kept in sync with system/security/keystore/defaults.h
+     */
+
+    /* EC */
+    private static final int EC_DEFAULT_KEY_SIZE = 256;
+    private static final int EC_MIN_KEY_SIZE = 192;
+    private static final int EC_MAX_KEY_SIZE = 521;
+
+    /* RSA */
+    private static final int RSA_DEFAULT_KEY_SIZE = 2048;
+    private static final int RSA_MIN_KEY_SIZE = 512;
+    private static final int RSA_MAX_KEY_SIZE = 8192;
+
+    private final String mAlgorithm;
+
     private android.security.KeyStore mKeyStore;
 
     private KeyPairGeneratorSpec mSpec;
+    private String mKeyAlgorithm;
+    private int mKeyType;
+    private int mKeySize;
+
+    protected AndroidKeyPairGenerator(String algorithm) {
+        mAlgorithm = algorithm;
+    }
+
+    public String getAlgorithm() {
+        return mAlgorithm;
+    }
 
     /**
      * Generate a KeyPair which is backed by the Android keystore service. You
@@ -88,12 +128,11 @@
 
         Credentials.deleteAllTypesForAlias(mKeyStore, alias);
 
-        final int keyType = KeyStore.getKeyTypeForAlgorithm(mSpec.getKeyType());
-        byte[][] args = getArgsForKeyType(keyType, mSpec.getAlgorithmParameterSpec());
+        byte[][] args = getArgsForKeyType(mKeyType, mSpec.getAlgorithmParameterSpec());
 
         final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
-        if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, keyType,
-                mSpec.getKeySize(), mSpec.getFlags(), args)) {
+        if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, mKeyType, mKeySize,
+                mSpec.getFlags(), args)) {
             throw new IllegalStateException("could not generate key in keystore");
         }
 
@@ -109,7 +148,7 @@
 
         final PublicKey pubKey;
         try {
-            final KeyFactory keyFact = KeyFactory.getInstance(mSpec.getKeyType());
+            final KeyFactory keyFact = KeyFactory.getInstance(mKeyAlgorithm);
             pubKey = keyFact.generatePublic(new X509EncodedKeySpec(pubKeyBytes));
         } catch (NoSuchAlgorithmException e) {
             throw new IllegalStateException("Can't instantiate key generator", e);
@@ -117,18 +156,9 @@
             throw new IllegalStateException("keystore returned invalid key encoding", e);
         }
 
-        final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
-        certGen.setPublicKey(pubKey);
-        certGen.setSerialNumber(mSpec.getSerialNumber());
-        certGen.setSubjectDN(mSpec.getSubjectDN());
-        certGen.setIssuerDN(mSpec.getSubjectDN());
-        certGen.setNotBefore(mSpec.getStartDate());
-        certGen.setNotAfter(mSpec.getEndDate());
-        certGen.setSignatureAlgorithm(getDefaultSignatureAlgorithmForKeyType(mSpec.getKeyType()));
-
         final X509Certificate cert;
         try {
-            cert = certGen.generate(privKey);
+            cert = generateCertificate(privKey, pubKey);
         } catch (Exception e) {
             Credentials.deleteAllTypesForAlias(mKeyStore, alias);
             throw new IllegalStateException("Can't generate certificate", e);
@@ -151,13 +181,78 @@
         return new KeyPair(pubKey, privKey);
     }
 
-    private static String getDefaultSignatureAlgorithmForKeyType(String keyType) {
-        if ("RSA".equalsIgnoreCase(keyType)) {
+    @SuppressWarnings("deprecation")
+    private X509Certificate generateCertificate(PrivateKey privateKey, PublicKey publicKey)
+            throws Exception {
+        final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
+        certGen.setPublicKey(publicKey);
+        certGen.setSerialNumber(mSpec.getSerialNumber());
+        certGen.setSubjectDN(mSpec.getSubjectDN());
+        certGen.setIssuerDN(mSpec.getSubjectDN());
+        certGen.setNotBefore(mSpec.getStartDate());
+        certGen.setNotAfter(mSpec.getEndDate());
+        certGen.setSignatureAlgorithm(getDefaultSignatureAlgorithmForKeyAlgorithm(mKeyAlgorithm));
+        return certGen.generate(privateKey);
+    }
+
+    private String getKeyAlgorithm(KeyPairGeneratorSpec spec) {
+        String result = spec.getKeyType();
+        if (result != null) {
+            return result;
+        }
+        return getAlgorithm();
+    }
+
+    private static int getDefaultKeySize(int keyType) {
+        if (keyType == NativeCrypto.EVP_PKEY_EC) {
+            return EC_DEFAULT_KEY_SIZE;
+        } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
+            return RSA_DEFAULT_KEY_SIZE;
+        }
+        return -1;
+    }
+
+    private static void checkValidKeySize(String keyAlgorithm, int keyType, int keySize)
+            throws InvalidAlgorithmParameterException {
+        if (keyType == NativeCrypto.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) {
+            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);
+            }
+        } else {
+            throw new InvalidAlgorithmParameterException(
+                "Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    private static void checkCorrectParametersSpec(int keyType, int keySize,
+            AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException {
+        if (keyType == NativeCrypto.EVP_PKEY_RSA && spec != null) {
+            if (spec instanceof RSAKeyGenParameterSpec) {
+                RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
+                if (keySize != -1 && keySize != rsaSpec.getKeysize()) {
+                    throw new InvalidAlgorithmParameterException("RSA key size must match: "
+                            + keySize + " vs " + rsaSpec.getKeysize());
+                }
+            } else {
+                throw new InvalidAlgorithmParameterException(
+                    "RSA may only use RSAKeyGenParameterSpec");
+            }
+        }
+    }
+
+    private static String getDefaultSignatureAlgorithmForKeyAlgorithm(String algorithm) {
+        if ("RSA".equalsIgnoreCase(algorithm)) {
             return "sha256WithRSA";
-        } else if ("EC".equalsIgnoreCase(keyType)) {
+        } else if ("EC".equalsIgnoreCase(algorithm)) {
             return "sha256WithECDSA";
         } else {
-            throw new IllegalArgumentException("Unsupported key type " + keyType);
+            throw new IllegalArgumentException("Unsupported key type " + algorithm);
         }
     }
 
@@ -190,7 +285,26 @@
         }
 
         KeyPairGeneratorSpec spec = (KeyPairGeneratorSpec) params;
+        String keyAlgorithm = getKeyAlgorithm(spec);
+        int keyType = KeyStore.getKeyTypeForAlgorithm(keyAlgorithm);
+        if (keyType == -1) {
+            throw new InvalidAlgorithmParameterException(
+                    "Unsupported key algorithm: " + keyAlgorithm);
+        }
+        int keySize = spec.getKeySize();
+        if (keySize == -1) {
+            keySize = getDefaultKeySize(keyType);
+            if (keySize == -1) {
+                throw new InvalidAlgorithmParameterException(
+                    "Unsupported key algorithm: " + keyAlgorithm);
+            }
+        }
+        checkCorrectParametersSpec(keyType, keySize, spec.getAlgorithmParameterSpec());
+        checkValidKeySize(keyAlgorithm, keyType, keySize);
 
+        mKeyAlgorithm = keyAlgorithm;
+        mKeyType = keyType;
+        mKeySize = keySize;
         mSpec = spec;
         mKeyStore = android.security.KeyStore.getInstance();
     }
diff --git a/keystore/java/android/security/AndroidKeyStoreProvider.java b/keystore/java/android/security/AndroidKeyStoreProvider.java
index b17e450..9081e92 100644
--- a/keystore/java/android/security/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/AndroidKeyStoreProvider.java
@@ -33,6 +33,7 @@
         put("KeyStore." + AndroidKeyStore.NAME, AndroidKeyStore.class.getName());
 
         // java.security.KeyPairGenerator
-        put("KeyPairGenerator.RSA", AndroidKeyPairGenerator.class.getName());
+        put("KeyPairGenerator.EC", AndroidKeyPairGenerator.EC.class.getName());
+        put("KeyPairGenerator.RSA", AndroidKeyPairGenerator.RSA.class.getName());
     }
 }
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 607817a..dfa41e8 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -242,7 +242,7 @@
      * @param response Callback to invoke when the request completes;
      *     must not be null
      * @param keyTypes The acceptable types of asymmetric keys such as
-     *     "RSA" or "DSA", or a null array.
+     *     "EC" or "RSA", or a null array.
      * @param issuers The acceptable certificate issuers for the
      *     certificate matching the private key, or null.
      * @param host The host name of the server requesting the
@@ -263,7 +263,7 @@
          *
          * keyTypes would allow the list to be filtered and typically
          * will be set correctly by the server. In practice today,
-         * most all users will want only RSA, rarely DSA, and usually
+         * most all users will want only RSA or EC, and usually
          * only a small number of certs will be available.
          *
          * issuers is typically not useful. Some servers historically
diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
index 6b67f43..cc097aa 100644
--- a/keystore/java/android/security/KeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -16,8 +16,6 @@
 
 package android.security;
 
-import com.android.org.conscrypt.NativeCrypto;
-
 import android.content.Context;
 import android.text.TextUtils;
 
@@ -26,7 +24,6 @@
 import java.security.PrivateKey;
 import java.security.cert.Certificate;
 import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.RSAKeyGenParameterSpec;
 import java.util.Date;
 
 import javax.security.auth.x500.X500Principal;
@@ -54,19 +51,6 @@
  * certificate signed by a real Certificate Authority.
  */
 public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
-    /*
-     * These must be kept in sync with system/security/keystore/defaults.h
-     */
-
-    /* EC */
-    private static final int EC_DEFAULT_KEY_SIZE = 256;
-    private static final int EC_MIN_KEY_SIZE = 192;
-    private static final int EC_MAX_KEY_SIZE = 521;
-
-    /* RSA */
-    private static final int RSA_DEFAULT_KEY_SIZE = 2048;
-    private static final int RSA_MIN_KEY_SIZE = 512;
-    private static final int RSA_MAX_KEY_SIZE = 8192;
 
     private final Context mContext;
 
@@ -108,7 +92,7 @@
      * @param context Android context for the activity
      * @param keyStoreAlias name to use for the generated key in the Android
      *            keystore
-     * @param keyType key algorithm to use (RSA, DSA, EC)
+     * @param keyType key algorithm to use (EC, RSA)
      * @param keySize size of key to generate
      * @param spec the underlying key type parameters
      * @param subjectDN X.509 v3 Subject Distinguished Name
@@ -139,13 +123,6 @@
             throw new IllegalArgumentException("endDate < startDate");
         }
 
-        final int keyTypeInt = KeyStore.getKeyTypeForAlgorithm(keyType);
-        if (keySize == -1) {
-            keySize = getDefaultKeySizeForType(keyTypeInt);
-        }
-        checkCorrectParametersSpec(keyTypeInt, keySize, spec);
-        checkValidKeySize(keyTypeInt, keySize);
-
         mContext = context;
         mKeystoreAlias = keyStoreAlias;
         mKeyType = keyType;
@@ -158,46 +135,6 @@
         mFlags = flags;
     }
 
-    private static int getDefaultKeySizeForType(int keyType) {
-        if (keyType == NativeCrypto.EVP_PKEY_EC) {
-            return EC_DEFAULT_KEY_SIZE;
-        } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
-            return RSA_DEFAULT_KEY_SIZE;
-        }
-        throw new IllegalArgumentException("Invalid key type " + keyType);
-    }
-
-    private static void checkValidKeySize(int keyType, int keySize) {
-        if (keyType == NativeCrypto.EVP_PKEY_EC) {
-            if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
-                throw new IllegalArgumentException("EC keys must be >= " + EC_MIN_KEY_SIZE
-                        + " and <= " + EC_MAX_KEY_SIZE);
-            }
-        } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
-            if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
-                throw new IllegalArgumentException("RSA keys must be >= " + RSA_MIN_KEY_SIZE
-                        + " and <= " + RSA_MAX_KEY_SIZE);
-            }
-        } else {
-            throw new IllegalArgumentException("Invalid key type " + keyType);
-        }
-    }
-
-    private static void checkCorrectParametersSpec(int keyType, int keySize,
-            AlgorithmParameterSpec spec) {
-        if (keyType == NativeCrypto.EVP_PKEY_RSA && spec != null) {
-            if (spec instanceof RSAKeyGenParameterSpec) {
-                RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
-                if (keySize != -1 && keySize != rsaSpec.getKeysize()) {
-                    throw new IllegalArgumentException("RSA key size must match: " + keySize
-                            + " vs " + rsaSpec.getKeysize());
-                }
-            } else {
-                throw new IllegalArgumentException("RSA may only use RSAKeyGenParameterSpec");
-            }
-        }
-    }
-
     /**
      * Gets the Android context used for operations with this instance.
      */
@@ -214,8 +151,7 @@
     }
 
     /**
-     * Returns the key type (e.g., "RSA", "DSA", "EC") specified by this
-     * parameter.
+     * Returns the key type (e.g., "EC", "RSA") specified by this parameter.
      */
     public String getKeyType() {
         return mKeyType;
@@ -311,7 +247,7 @@
 
         private String mKeystoreAlias;
 
-        private String mKeyType = "RSA";
+        private String mKeyType;
 
         private int mKeySize = -1;
 
@@ -354,15 +290,13 @@
         }
 
         /**
-         * Sets the key type (e.g., RSA, DSA, EC) of the keypair to be created.
+         * Sets the key type (e.g., EC, RSA) of the keypair to be created.
          */
         public Builder setKeyType(String keyType) throws NoSuchAlgorithmException {
             if (keyType == null) {
                 throw new NullPointerException("keyType == null");
             } else {
-                try {
-                    KeyStore.getKeyTypeForAlgorithm(keyType);
-                } catch (IllegalArgumentException e) {
+                if (KeyStore.getKeyTypeForAlgorithm(keyType) == -1) {
                     throw new NoSuchAlgorithmException("Unsupported key type: " + keyType);
                 }
             }
@@ -384,9 +318,8 @@
         }
 
         /**
-         * Sets the underlying key type's parameters. This is required for DSA
-         * where you must set this to an instance of
-         * {@link java.security.spec.DSAParameterSpec}.
+         * Sets the algorithm-specific key generation parameters. For example, for RSA keys
+         * this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}.
          */
         public Builder setAlgorithmParameterSpec(AlgorithmParameterSpec spec) {
             if (spec == null) {
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 1dbdbfb..e753a7c 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -68,13 +68,13 @@
         return new KeyStore(keystore);
     }
 
-    static int getKeyTypeForAlgorithm(String keyType) throws IllegalArgumentException {
+    static int getKeyTypeForAlgorithm(String keyType) {
         if ("RSA".equalsIgnoreCase(keyType)) {
             return NativeCrypto.EVP_PKEY_RSA;
         } else if ("EC".equalsIgnoreCase(keyType)) {
             return NativeCrypto.EVP_PKEY_EC;
         } else {
-            throw new IllegalArgumentException("Unsupported key type: " + keyType);
+            return -1;
         }
     }
 
@@ -205,7 +205,8 @@
     public boolean generate(String key, int uid, int keyType, int keySize, int flags,
             byte[][] args) {
         try {
-            return mBinder.generate(key, uid, keyType, keySize, flags, args) == NO_ERROR;
+            return mBinder.generate(key, uid, keyType, keySize, flags,
+                    new KeystoreArguments(args)) == NO_ERROR;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return false;
diff --git a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
index ea6c43d..95d14b7 100644
--- a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
@@ -27,12 +27,9 @@
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPublicKey;
 import java.security.interfaces.ECPublicKey;
 import java.security.interfaces.RSAPublicKey;
 import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.DSAParameterSpec;
 import java.security.spec.RSAKeyGenParameterSpec;
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -155,167 +152,6 @@
                 NOW_PLUS_10_YEARS);
     }
 
-    public void testKeyPairGenerator_GenerateKeyPair_DSA_Unencrypted_Success() throws Exception {
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeyType("DSA")
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 1024, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success()
-            throws Exception {
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeyType("DSA")
-                .setKeySize(2048)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_DSA_SpecifiedParams_Unencrypted_Success()
-            throws Exception {
-        /*
-         * generated using: openssl dsaparam -C 2048
-         */
-        BigInteger p = new BigInteger(1, new byte[] {
-                (byte) 0xC0, (byte) 0x3D, (byte) 0x86, (byte) 0x09, (byte) 0xCA, (byte) 0x8C,
-                (byte) 0x37, (byte) 0xCA, (byte) 0xCC, (byte) 0x4A, (byte) 0x81, (byte) 0xBD,
-                (byte) 0xD8, (byte) 0x50, (byte) 0x77, (byte) 0xCD, (byte) 0xDD, (byte) 0x32,
-                (byte) 0x0B, (byte) 0x43, (byte) 0xBF, (byte) 0x42, (byte) 0x06, (byte) 0x5A,
-                (byte) 0x3D, (byte) 0x18, (byte) 0x50, (byte) 0x47, (byte) 0x79, (byte) 0xE1,
-                (byte) 0x5B, (byte) 0x86, (byte) 0x03, (byte) 0xB9, (byte) 0x28, (byte) 0x9C,
-                (byte) 0x18, (byte) 0xA9, (byte) 0xF5, (byte) 0xD6, (byte) 0xF4, (byte) 0x94,
-                (byte) 0x5B, (byte) 0x87, (byte) 0x58, (byte) 0xCA, (byte) 0xB2, (byte) 0x1E,
-                (byte) 0xFC, (byte) 0xED, (byte) 0x37, (byte) 0xC3, (byte) 0x49, (byte) 0xAC,
-                (byte) 0xFA, (byte) 0x46, (byte) 0xDB, (byte) 0x7A, (byte) 0x50, (byte) 0x96,
-                (byte) 0xCF, (byte) 0x52, (byte) 0xD7, (byte) 0x4E, (byte) 0xEB, (byte) 0x26,
-                (byte) 0x41, (byte) 0xA2, (byte) 0x6F, (byte) 0x99, (byte) 0x80, (byte) 0x9F,
-                (byte) 0x0F, (byte) 0x0A, (byte) 0xA8, (byte) 0x0D, (byte) 0xAC, (byte) 0xAB,
-                (byte) 0xEF, (byte) 0x7D, (byte) 0xE7, (byte) 0x4C, (byte) 0xF1, (byte) 0x88,
-                (byte) 0x44, (byte) 0xC9, (byte) 0x17, (byte) 0xD0, (byte) 0xBB, (byte) 0xE2,
-                (byte) 0x01, (byte) 0x8C, (byte) 0xC1, (byte) 0x02, (byte) 0x1D, (byte) 0x3C,
-                (byte) 0x15, (byte) 0xB7, (byte) 0x41, (byte) 0x30, (byte) 0xD8, (byte) 0x11,
-                (byte) 0xBD, (byte) 0x6A, (byte) 0x2A, (byte) 0x0D, (byte) 0x36, (byte) 0x44,
-                (byte) 0x9C, (byte) 0x3F, (byte) 0x32, (byte) 0xE2, (byte) 0x1C, (byte) 0xFB,
-                (byte) 0xE3, (byte) 0xFF, (byte) 0xCC, (byte) 0x1A, (byte) 0x72, (byte) 0x38,
-                (byte) 0x37, (byte) 0x69, (byte) 0x5E, (byte) 0x35, (byte) 0x73, (byte) 0xE1,
-                (byte) 0x1E, (byte) 0x74, (byte) 0x35, (byte) 0x44, (byte) 0x07, (byte) 0xB5,
-                (byte) 0x2F, (byte) 0x0B, (byte) 0x60, (byte) 0xF4, (byte) 0xA9, (byte) 0xE0,
-                (byte) 0x81, (byte) 0xB2, (byte) 0xCD, (byte) 0x8B, (byte) 0x82, (byte) 0x76,
-                (byte) 0x7F, (byte) 0xD4, (byte) 0x17, (byte) 0x32, (byte) 0x86, (byte) 0x98,
-                (byte) 0x7C, (byte) 0x85, (byte) 0x66, (byte) 0xF6, (byte) 0x77, (byte) 0xED,
-                (byte) 0x8B, (byte) 0x1A, (byte) 0x52, (byte) 0x16, (byte) 0xDA, (byte) 0x1C,
-                (byte) 0xA7, (byte) 0x16, (byte) 0x79, (byte) 0x20, (byte) 0x1C, (byte) 0x99,
-                (byte) 0x5F, (byte) 0x12, (byte) 0x66, (byte) 0x15, (byte) 0x9F, (byte) 0xE5,
-                (byte) 0x73, (byte) 0xA9, (byte) 0x61, (byte) 0xBA, (byte) 0xA7, (byte) 0x23,
-                (byte) 0x93, (byte) 0x77, (byte) 0xB5, (byte) 0xF6, (byte) 0xEC, (byte) 0x13,
-                (byte) 0xBF, (byte) 0x95, (byte) 0x60, (byte) 0x78, (byte) 0x84, (byte) 0xE3,
-                (byte) 0x44, (byte) 0xEC, (byte) 0x74, (byte) 0xC2, (byte) 0xCB, (byte) 0xD4,
-                (byte) 0x70, (byte) 0xC5, (byte) 0x7B, (byte) 0xF8, (byte) 0x07, (byte) 0x3B,
-                (byte) 0xEB, (byte) 0x9F, (byte) 0xC9, (byte) 0x7D, (byte) 0xE0, (byte) 0xA5,
-                (byte) 0xBA, (byte) 0x68, (byte) 0x7B, (byte) 0xF4, (byte) 0x70, (byte) 0x40,
-                (byte) 0xAE, (byte) 0xE9, (byte) 0x65, (byte) 0xEE, (byte) 0x5B, (byte) 0x71,
-                (byte) 0x36, (byte) 0x0B, (byte) 0xB0, (byte) 0xA2, (byte) 0x98, (byte) 0x7D,
-                (byte) 0xE3, (byte) 0x24, (byte) 0x95, (byte) 0x2B, (byte) 0xC2, (byte) 0x0A,
-                (byte) 0x78, (byte) 0x3D, (byte) 0xCC, (byte) 0x3A, (byte) 0xEE, (byte) 0xED,
-                (byte) 0x48, (byte) 0xEB, (byte) 0xA3, (byte) 0x78, (byte) 0xA8, (byte) 0x9D,
-                (byte) 0x0A, (byte) 0x8F, (byte) 0x9E, (byte) 0x59, (byte) 0x2C, (byte) 0x44,
-                (byte) 0xB5, (byte) 0xF9, (byte) 0x53, (byte) 0x43,
-        });
-
-        BigInteger q = new BigInteger(1, new byte[] {
-                (byte) 0xA1, (byte) 0x9B, (byte) 0x1D, (byte) 0xC0, (byte) 0xE3, (byte) 0xF6,
-                (byte) 0x4A, (byte) 0x35, (byte) 0xE1, (byte) 0x8A, (byte) 0x43, (byte) 0xC2,
-                (byte) 0x9C, (byte) 0xF9, (byte) 0x52, (byte) 0x8F, (byte) 0x94, (byte) 0xA1,
-                (byte) 0x12, (byte) 0x11, (byte) 0xDB, (byte) 0x9A, (byte) 0xB6, (byte) 0x35,
-                (byte) 0x56, (byte) 0x26, (byte) 0x60, (byte) 0x89, (byte) 0x11, (byte) 0xAC,
-                (byte) 0xA8, (byte) 0xE5,
-        });
-
-        BigInteger g = new BigInteger(1, new byte[] {
-                (byte) 0xA1, (byte) 0x5C, (byte) 0x57, (byte) 0x15, (byte) 0xC3, (byte) 0xD9,
-                (byte) 0xD7, (byte) 0x41, (byte) 0x89, (byte) 0xD6, (byte) 0xB8, (byte) 0x7B,
-                (byte) 0xF3, (byte) 0xE0, (byte) 0xB3, (byte) 0xC5, (byte) 0xD1, (byte) 0xAA,
-                (byte) 0xF9, (byte) 0x55, (byte) 0x48, (byte) 0xF1, (byte) 0xDA, (byte) 0xE8,
-                (byte) 0x6F, (byte) 0x51, (byte) 0x05, (byte) 0xB2, (byte) 0xC9, (byte) 0x64,
-                (byte) 0xDA, (byte) 0x5F, (byte) 0xD4, (byte) 0xAA, (byte) 0xFD, (byte) 0x67,
-                (byte) 0xE0, (byte) 0x10, (byte) 0x2C, (byte) 0x1F, (byte) 0x03, (byte) 0x10,
-                (byte) 0xD4, (byte) 0x4B, (byte) 0x20, (byte) 0x82, (byte) 0x2B, (byte) 0x04,
-                (byte) 0xF9, (byte) 0x09, (byte) 0xAE, (byte) 0x28, (byte) 0x3D, (byte) 0x9B,
-                (byte) 0xFF, (byte) 0x87, (byte) 0x76, (byte) 0xCD, (byte) 0xF0, (byte) 0x11,
-                (byte) 0xB7, (byte) 0xEA, (byte) 0xE6, (byte) 0xCD, (byte) 0x60, (byte) 0xD3,
-                (byte) 0x8C, (byte) 0x74, (byte) 0xD3, (byte) 0x45, (byte) 0x63, (byte) 0x69,
-                (byte) 0x3F, (byte) 0x1D, (byte) 0x31, (byte) 0x25, (byte) 0x49, (byte) 0x97,
-                (byte) 0x4B, (byte) 0x73, (byte) 0x34, (byte) 0x12, (byte) 0x73, (byte) 0x27,
-                (byte) 0x4C, (byte) 0xDA, (byte) 0xF3, (byte) 0x08, (byte) 0xA8, (byte) 0xA9,
-                (byte) 0x27, (byte) 0xE4, (byte) 0xB8, (byte) 0xD6, (byte) 0xB5, (byte) 0xC4,
-                (byte) 0x18, (byte) 0xED, (byte) 0xBD, (byte) 0x6F, (byte) 0xA2, (byte) 0x36,
-                (byte) 0xA2, (byte) 0x9C, (byte) 0x27, (byte) 0x62, (byte) 0x7F, (byte) 0x93,
-                (byte) 0xD7, (byte) 0x52, (byte) 0xA9, (byte) 0x76, (byte) 0x55, (byte) 0x99,
-                (byte) 0x00, (byte) 0x5B, (byte) 0xC2, (byte) 0xB9, (byte) 0x18, (byte) 0xAC,
-                (byte) 0x6B, (byte) 0x83, (byte) 0x0D, (byte) 0xA1, (byte) 0xC5, (byte) 0x01,
-                (byte) 0x1A, (byte) 0xE5, (byte) 0x4D, (byte) 0x2F, (byte) 0xCF, (byte) 0x5D,
-                (byte) 0xB2, (byte) 0xE7, (byte) 0xC7, (byte) 0xCB, (byte) 0x2C, (byte) 0xFF,
-                (byte) 0x51, (byte) 0x1B, (byte) 0x9D, (byte) 0xA4, (byte) 0x05, (byte) 0xEB,
-                (byte) 0x17, (byte) 0xD8, (byte) 0x97, (byte) 0x9D, (byte) 0x0C, (byte) 0x59,
-                (byte) 0x92, (byte) 0x8A, (byte) 0x03, (byte) 0x34, (byte) 0xFD, (byte) 0x16,
-                (byte) 0x0F, (byte) 0x2A, (byte) 0xF9, (byte) 0x7D, (byte) 0xC3, (byte) 0x41,
-                (byte) 0x0D, (byte) 0x06, (byte) 0x5A, (byte) 0x4B, (byte) 0x34, (byte) 0xD5,
-                (byte) 0xF5, (byte) 0x09, (byte) 0x1C, (byte) 0xCE, (byte) 0xA7, (byte) 0x19,
-                (byte) 0x6D, (byte) 0x04, (byte) 0x53, (byte) 0x71, (byte) 0xCC, (byte) 0x84,
-                (byte) 0xA0, (byte) 0xB2, (byte) 0xA0, (byte) 0x68, (byte) 0xA3, (byte) 0x40,
-                (byte) 0xC0, (byte) 0x67, (byte) 0x38, (byte) 0x96, (byte) 0x73, (byte) 0x2E,
-                (byte) 0x8E, (byte) 0x2A, (byte) 0x9D, (byte) 0x56, (byte) 0xE9, (byte) 0xAC,
-                (byte) 0xC7, (byte) 0xEC, (byte) 0x84, (byte) 0x7F, (byte) 0xFC, (byte) 0xE0,
-                (byte) 0x69, (byte) 0x03, (byte) 0x8B, (byte) 0x48, (byte) 0x64, (byte) 0x76,
-                (byte) 0x85, (byte) 0xA5, (byte) 0x10, (byte) 0xD9, (byte) 0x31, (byte) 0xC3,
-                (byte) 0x8B, (byte) 0x07, (byte) 0x48, (byte) 0x62, (byte) 0xF6, (byte) 0x68,
-                (byte) 0xF2, (byte) 0x96, (byte) 0xB2, (byte) 0x18, (byte) 0x5B, (byte) 0xFF,
-                (byte) 0x6D, (byte) 0xD1, (byte) 0x6B, (byte) 0xF5, (byte) 0xFD, (byte) 0x81,
-                (byte) 0xF1, (byte) 0xFD, (byte) 0x04, (byte) 0xF0, (byte) 0x9F, (byte) 0xB7,
-                (byte) 0x08, (byte) 0x95, (byte) 0x57, (byte) 0x48, (byte) 0x07, (byte) 0x00,
-                (byte) 0x52, (byte) 0xEC, (byte) 0x75, (byte) 0x91, (byte) 0x02, (byte) 0x11,
-                (byte) 0xA3, (byte) 0x64, (byte) 0x26, (byte) 0xCA,
-        });
-
-        AlgorithmParameterSpec spec = new DSAParameterSpec(p, q, g);
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeyType("DSA")
-                .setKeySize(2048)
-                .setAlgorithmParameterSpec(spec)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, spec, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
     public void testKeyPairGenerator_GenerateKeyPair_EC_Unencrypted_Success() throws Exception {
         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
                 .setAlias(TEST_ALIAS_1)
@@ -469,17 +305,7 @@
         assertNotNull("The PublicKey for the KeyPair should be not null", pubKey);
         assertEquals(keyType, pubKey.getAlgorithm());
 
-        if ("DSA".equalsIgnoreCase(keyType)) {
-            DSAPublicKey dsaPubKey = (DSAPublicKey) pubKey;
-            DSAParams actualParams = dsaPubKey.getParams();
-            assertEquals(keySize, (actualParams.getP().bitLength() + 7) & ~7);
-            if (spec != null) {
-                DSAParameterSpec expectedParams = (DSAParameterSpec) spec;
-                assertEquals(expectedParams.getP(), actualParams.getP());
-                assertEquals(expectedParams.getQ(), actualParams.getQ());
-                assertEquals(expectedParams.getG(), actualParams.getG());
-            }
-        } else if ("EC".equalsIgnoreCase(keyType)) {
+        if ("EC".equalsIgnoreCase(keyType)) {
             assertEquals("Curve should be what was specified during initialization", keySize,
                     ((ECPublicKey) pubKey).getParams().getCurve().getField().getFieldSize());
         } else if ("RSA".equalsIgnoreCase(keyType)) {
diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
index 6597d3f..9775e64 100644
--- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
@@ -20,7 +20,6 @@
 
 import com.android.org.conscrypt.NativeCrypto;
 import com.android.org.conscrypt.OpenSSLEngine;
-import com.android.org.conscrypt.OpenSSLKeyHolder;
 
 import android.test.AndroidTestCase;
 
@@ -41,8 +40,6 @@
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
 import java.security.interfaces.ECPrivateKey;
 import java.security.interfaces.ECPublicKey;
 import java.security.interfaces.RSAPrivateKey;
@@ -722,368 +719,6 @@
             (byte) 0x7e, (byte) 0xde, (byte) 0xb2
     };
 
-    /*
-     * The keys and certificates below are generated with:
-     *
-     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
-     * openssl dsaparam -out dsaparam.pem 1024
-     * openssl req -newkey dsa:dsaparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req
-     * mkdir -p demoCA/newcerts
-     * touch demoCA/index.txt
-     * echo "01" > demoCA/serial
-     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
-     */
-
-    /**
-     * Generated from above and converted with:
-     *
-     * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_DSA_CA_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x8a, (byte) 0x30, (byte) 0x82,
-            (byte) 0x01, (byte) 0xf3, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-            (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0x87, (byte) 0xc0,
-            (byte) 0x68, (byte) 0x7f, (byte) 0x42, (byte) 0x92, (byte) 0x0b, (byte) 0x7a,
-            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x5e, (byte) 0x31,
-            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55,
-            (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53,
-            (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74,
-            (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30,
-            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
-            (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57,
-            (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73,
-            (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c,
-            (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x17, (byte) 0x30, (byte) 0x15,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c,
-            (byte) 0x0e, (byte) 0x63, (byte) 0x61, (byte) 0x2e, (byte) 0x65, (byte) 0x78,
-            (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e,
-            (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17,
-            (byte) 0x0d, (byte) 0x31, (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32,
-            (byte) 0x37, (byte) 0x32, (byte) 0x33, (byte) 0x33, (byte) 0x31, (byte) 0x32,
-            (byte) 0x39, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x33,
-            (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x35, (byte) 0x32, (byte) 0x33,
-            (byte) 0x33, (byte) 0x31, (byte) 0x32, (byte) 0x39, (byte) 0x5a, (byte) 0x30,
-            (byte) 0x5e, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02,
-            (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c,
-            (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d,
-            (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31,
-            (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e,
-            (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74,
-            (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69,
-            (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79,
-            (byte) 0x20, (byte) 0x4c, (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x17,
-            (byte) 0x30, (byte) 0x15, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x03, (byte) 0x0c, (byte) 0x0e, (byte) 0x63, (byte) 0x61, (byte) 0x2e,
-            (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c,
-            (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30,
-            (byte) 0x81, (byte) 0x9f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
-            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
-            (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03,
-            (byte) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
-            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa4, (byte) 0xc7,
-            (byte) 0x06, (byte) 0xba, (byte) 0xdf, (byte) 0x2b, (byte) 0xee, (byte) 0xd2,
-            (byte) 0xb9, (byte) 0xe4, (byte) 0x52, (byte) 0x21, (byte) 0x68, (byte) 0x2b,
-            (byte) 0x83, (byte) 0xdf, (byte) 0xe3, (byte) 0x9c, (byte) 0x08, (byte) 0x73,
-            (byte) 0xdd, (byte) 0x90, (byte) 0xea, (byte) 0x97, (byte) 0x0c, (byte) 0x96,
-            (byte) 0x20, (byte) 0xb1, (byte) 0xee, (byte) 0x11, (byte) 0xd5, (byte) 0xd4,
-            (byte) 0x7c, (byte) 0x44, (byte) 0x96, (byte) 0x2e, (byte) 0x6e, (byte) 0xa2,
-            (byte) 0xb2, (byte) 0xa3, (byte) 0x4b, (byte) 0x0f, (byte) 0x32, (byte) 0x90,
-            (byte) 0xaf, (byte) 0x5c, (byte) 0x6f, (byte) 0x00, (byte) 0x88, (byte) 0x45,
-            (byte) 0x4e, (byte) 0x9b, (byte) 0x26, (byte) 0xc1, (byte) 0x94, (byte) 0x3c,
-            (byte) 0xfe, (byte) 0x10, (byte) 0xbd, (byte) 0xda, (byte) 0xf2, (byte) 0x8d,
-            (byte) 0x03, (byte) 0x52, (byte) 0x32, (byte) 0x11, (byte) 0xff, (byte) 0xf6,
-            (byte) 0xf9, (byte) 0x6e, (byte) 0x8f, (byte) 0x0f, (byte) 0xc8, (byte) 0x0a,
-            (byte) 0x48, (byte) 0x39, (byte) 0x33, (byte) 0xb9, (byte) 0x0c, (byte) 0xb3,
-            (byte) 0x2b, (byte) 0xab, (byte) 0x7d, (byte) 0x79, (byte) 0x6f, (byte) 0x57,
-            (byte) 0x5b, (byte) 0xb8, (byte) 0x84, (byte) 0xb6, (byte) 0xcc, (byte) 0xe8,
-            (byte) 0x30, (byte) 0x78, (byte) 0xff, (byte) 0x92, (byte) 0xe5, (byte) 0x43,
-            (byte) 0x2e, (byte) 0xef, (byte) 0x66, (byte) 0x98, (byte) 0xb4, (byte) 0xfe,
-            (byte) 0xa2, (byte) 0x40, (byte) 0xf2, (byte) 0x1f, (byte) 0xd0, (byte) 0x86,
-            (byte) 0x16, (byte) 0xc8, (byte) 0x45, (byte) 0xc4, (byte) 0x52, (byte) 0xcb,
-            (byte) 0x31, (byte) 0x5c, (byte) 0x9f, (byte) 0x32, (byte) 0x3b, (byte) 0xf7,
-            (byte) 0x19, (byte) 0x08, (byte) 0xc7, (byte) 0x00, (byte) 0x21, (byte) 0x7d,
-            (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
-            (byte) 0x50, (byte) 0x30, (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16,
-            (byte) 0x04, (byte) 0x14, (byte) 0x47, (byte) 0x82, (byte) 0xa3, (byte) 0xf1,
-            (byte) 0xc2, (byte) 0x7e, (byte) 0x3a, (byte) 0xde, (byte) 0x4f, (byte) 0x30,
-            (byte) 0x4c, (byte) 0x7f, (byte) 0x72, (byte) 0x81, (byte) 0x15, (byte) 0x32,
-            (byte) 0xda, (byte) 0x7f, (byte) 0x58, (byte) 0x18, (byte) 0x30, (byte) 0x1f,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04,
-            (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x47,
-            (byte) 0x82, (byte) 0xa3, (byte) 0xf1, (byte) 0xc2, (byte) 0x7e, (byte) 0x3a,
-            (byte) 0xde, (byte) 0x4f, (byte) 0x30, (byte) 0x4c, (byte) 0x7f, (byte) 0x72,
-            (byte) 0x81, (byte) 0x15, (byte) 0x32, (byte) 0xda, (byte) 0x7f, (byte) 0x58,
-            (byte) 0x18, (byte) 0x30, (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03,
-            (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
-            (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
-            (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00,
-            (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x08, (byte) 0x7f,
-            (byte) 0x6a, (byte) 0x48, (byte) 0x90, (byte) 0x7b, (byte) 0x9b, (byte) 0x72,
-            (byte) 0x13, (byte) 0xa7, (byte) 0xef, (byte) 0x6b, (byte) 0x0b, (byte) 0x59,
-            (byte) 0xe5, (byte) 0x49, (byte) 0x72, (byte) 0x3a, (byte) 0xc8, (byte) 0x84,
-            (byte) 0xcc, (byte) 0x23, (byte) 0x18, (byte) 0x4c, (byte) 0xec, (byte) 0xc7,
-            (byte) 0xef, (byte) 0xcb, (byte) 0xa7, (byte) 0xbe, (byte) 0xe4, (byte) 0xef,
-            (byte) 0x8f, (byte) 0xc6, (byte) 0x06, (byte) 0x8c, (byte) 0xc0, (byte) 0xe4,
-            (byte) 0x2f, (byte) 0x2a, (byte) 0xc0, (byte) 0x35, (byte) 0x7d, (byte) 0x5e,
-            (byte) 0x19, (byte) 0x29, (byte) 0x8c, (byte) 0xb9, (byte) 0xf1, (byte) 0x1e,
-            (byte) 0xaf, (byte) 0x82, (byte) 0xd8, (byte) 0xe3, (byte) 0x88, (byte) 0xe1,
-            (byte) 0x31, (byte) 0xc8, (byte) 0x82, (byte) 0x1f, (byte) 0x83, (byte) 0xa9,
-            (byte) 0xde, (byte) 0xfe, (byte) 0x4b, (byte) 0xe2, (byte) 0x78, (byte) 0x64,
-            (byte) 0xed, (byte) 0xa4, (byte) 0x7b, (byte) 0xee, (byte) 0x8d, (byte) 0x71,
-            (byte) 0x1b, (byte) 0x44, (byte) 0xe6, (byte) 0xb7, (byte) 0xe8, (byte) 0xc5,
-            (byte) 0x9a, (byte) 0x93, (byte) 0x92, (byte) 0x6f, (byte) 0x6f, (byte) 0xdb,
-            (byte) 0xbd, (byte) 0xd7, (byte) 0x03, (byte) 0x85, (byte) 0xa9, (byte) 0x5f,
-            (byte) 0x53, (byte) 0x5f, (byte) 0x5d, (byte) 0x30, (byte) 0xc6, (byte) 0xd9,
-            (byte) 0xce, (byte) 0x34, (byte) 0xa8, (byte) 0xbe, (byte) 0x31, (byte) 0x47,
-            (byte) 0x1c, (byte) 0xa4, (byte) 0x7f, (byte) 0xc0, (byte) 0x2c, (byte) 0xbc,
-            (byte) 0xfe, (byte) 0x1a, (byte) 0x31, (byte) 0xd8, (byte) 0x77, (byte) 0x4d,
-            (byte) 0xfc, (byte) 0x45, (byte) 0x84, (byte) 0xfc, (byte) 0x45, (byte) 0x12,
-            (byte) 0xab, (byte) 0x50, (byte) 0xe4, (byte) 0x45, (byte) 0xe5, (byte) 0x11
-    };
-
-    /**
-     * Generated from above and converted with: openssl pkcs8 -topk8 -outform d
-     * -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_DSA_KEY_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x4c, (byte) 0x02, (byte) 0x01,
-            (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x2c, (byte) 0x06,
-            (byte) 0x07, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38,
-            (byte) 0x04, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1f,
-            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xb3, (byte) 0x23,
-            (byte) 0xf7, (byte) 0x86, (byte) 0xbd, (byte) 0x3b, (byte) 0x86, (byte) 0xcc,
-            (byte) 0xc3, (byte) 0x91, (byte) 0xc0, (byte) 0x30, (byte) 0x32, (byte) 0x02,
-            (byte) 0x47, (byte) 0x35, (byte) 0x01, (byte) 0xef, (byte) 0xee, (byte) 0x98,
-            (byte) 0x13, (byte) 0x56, (byte) 0x49, (byte) 0x47, (byte) 0xb5, (byte) 0x20,
-            (byte) 0xa8, (byte) 0x60, (byte) 0xcb, (byte) 0xc0, (byte) 0xd5, (byte) 0x77,
-            (byte) 0xc1, (byte) 0x69, (byte) 0xcd, (byte) 0x18, (byte) 0x34, (byte) 0x92,
-            (byte) 0xf2, (byte) 0x6a, (byte) 0x2a, (byte) 0x10, (byte) 0x59, (byte) 0x1c,
-            (byte) 0x91, (byte) 0x20, (byte) 0x51, (byte) 0xca, (byte) 0x37, (byte) 0xb2,
-            (byte) 0x87, (byte) 0xa6, (byte) 0x8a, (byte) 0x02, (byte) 0xfd, (byte) 0x45,
-            (byte) 0x46, (byte) 0xf9, (byte) 0x76, (byte) 0xb1, (byte) 0x35, (byte) 0x38,
-            (byte) 0x8d, (byte) 0xff, (byte) 0x4c, (byte) 0x5d, (byte) 0x75, (byte) 0x8f,
-            (byte) 0x66, (byte) 0x15, (byte) 0x7d, (byte) 0x7b, (byte) 0xda, (byte) 0xdb,
-            (byte) 0x57, (byte) 0x39, (byte) 0xff, (byte) 0x91, (byte) 0x3f, (byte) 0xdd,
-            (byte) 0xe2, (byte) 0xb4, (byte) 0x22, (byte) 0x60, (byte) 0x4c, (byte) 0x32,
-            (byte) 0x3b, (byte) 0x9d, (byte) 0x34, (byte) 0x9f, (byte) 0xb9, (byte) 0x5d,
-            (byte) 0x75, (byte) 0xb9, (byte) 0xd3, (byte) 0x7f, (byte) 0x11, (byte) 0xba,
-            (byte) 0xb7, (byte) 0xc8, (byte) 0x32, (byte) 0xc6, (byte) 0xce, (byte) 0x71,
-            (byte) 0x91, (byte) 0xd3, (byte) 0x32, (byte) 0xaf, (byte) 0x4d, (byte) 0x7e,
-            (byte) 0x7c, (byte) 0x15, (byte) 0xf7, (byte) 0x71, (byte) 0x2c, (byte) 0x52,
-            (byte) 0x65, (byte) 0x4d, (byte) 0xa9, (byte) 0x81, (byte) 0x25, (byte) 0x35,
-            (byte) 0xce, (byte) 0x0b, (byte) 0x5b, (byte) 0x56, (byte) 0xfe, (byte) 0xf1,
-            (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xeb, (byte) 0x4e, (byte) 0x7f,
-            (byte) 0x7a, (byte) 0x31, (byte) 0xb3, (byte) 0x7d, (byte) 0x8d, (byte) 0xb2,
-            (byte) 0xf7, (byte) 0xaf, (byte) 0xad, (byte) 0xb1, (byte) 0x42, (byte) 0x92,
-            (byte) 0xf3, (byte) 0x6c, (byte) 0xe4, (byte) 0xed, (byte) 0x8b, (byte) 0x02,
-            (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x81, (byte) 0xc8, (byte) 0x36,
-            (byte) 0x48, (byte) 0xdb, (byte) 0x71, (byte) 0x2b, (byte) 0x91, (byte) 0xce,
-            (byte) 0x6d, (byte) 0xbc, (byte) 0xb8, (byte) 0xf9, (byte) 0xcb, (byte) 0x50,
-            (byte) 0x91, (byte) 0x10, (byte) 0x8a, (byte) 0xf8, (byte) 0x37, (byte) 0x50,
-            (byte) 0xda, (byte) 0x4f, (byte) 0xc8, (byte) 0x4d, (byte) 0x73, (byte) 0xcb,
-            (byte) 0x4d, (byte) 0xb0, (byte) 0x19, (byte) 0x54, (byte) 0x5a, (byte) 0xf3,
-            (byte) 0x6c, (byte) 0xc9, (byte) 0xd8, (byte) 0x96, (byte) 0xd9, (byte) 0xb0,
-            (byte) 0x54, (byte) 0x7e, (byte) 0x7d, (byte) 0xe2, (byte) 0x58, (byte) 0x0e,
-            (byte) 0x5f, (byte) 0xc0, (byte) 0xce, (byte) 0xb9, (byte) 0x5c, (byte) 0xe3,
-            (byte) 0xd3, (byte) 0xdf, (byte) 0xcf, (byte) 0x45, (byte) 0x74, (byte) 0xfb,
-            (byte) 0xe6, (byte) 0x20, (byte) 0xe7, (byte) 0xfc, (byte) 0x0f, (byte) 0xca,
-            (byte) 0xdb, (byte) 0xc0, (byte) 0x0b, (byte) 0xe1, (byte) 0x5a, (byte) 0x16,
-            (byte) 0x1d, (byte) 0xb3, (byte) 0x2e, (byte) 0xe5, (byte) 0x5f, (byte) 0x89,
-            (byte) 0x17, (byte) 0x73, (byte) 0x50, (byte) 0xd1, (byte) 0x4a, (byte) 0x60,
-            (byte) 0xb7, (byte) 0xaa, (byte) 0xf0, (byte) 0xc7, (byte) 0xc5, (byte) 0x03,
-            (byte) 0x4e, (byte) 0x36, (byte) 0x51, (byte) 0x9e, (byte) 0x2f, (byte) 0xfa,
-            (byte) 0xf3, (byte) 0xd6, (byte) 0x58, (byte) 0x14, (byte) 0x02, (byte) 0xb4,
-            (byte) 0x41, (byte) 0xd6, (byte) 0x72, (byte) 0x6f, (byte) 0x58, (byte) 0x5b,
-            (byte) 0x2d, (byte) 0x23, (byte) 0xc0, (byte) 0x75, (byte) 0x4f, (byte) 0x39,
-            (byte) 0xa8, (byte) 0x6a, (byte) 0xdf, (byte) 0x79, (byte) 0x21, (byte) 0xf2,
-            (byte) 0x77, (byte) 0x91, (byte) 0x3f, (byte) 0x1c, (byte) 0x4d, (byte) 0x48,
-            (byte) 0x78, (byte) 0xcd, (byte) 0xed, (byte) 0x79, (byte) 0x23, (byte) 0x04,
-            (byte) 0x17, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xc7, (byte) 0xe7,
-            (byte) 0xe2, (byte) 0x6b, (byte) 0x14, (byte) 0xe6, (byte) 0x31, (byte) 0x12,
-            (byte) 0xb2, (byte) 0x1e, (byte) 0xd4, (byte) 0xf2, (byte) 0x9b, (byte) 0x2c,
-            (byte) 0xf6, (byte) 0x54, (byte) 0x4c, (byte) 0x12, (byte) 0xe8, (byte) 0x22
-    };
-
-    /**
-     * Generated from above and converted with: openssl x509 -outform d -in
-     * usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_DSA_USER_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x03, (byte) 0xca, (byte) 0x30, (byte) 0x82,
-            (byte) 0x03, (byte) 0x33, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-            (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
-            (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
-            (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05,
-            (byte) 0x00, (byte) 0x30, (byte) 0x5e, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
-            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
-            (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13,
-            (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
-            (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74,
-            (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x18,
-            (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6e,
-            (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64,
-            (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50,
-            (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c, (byte) 0x74, (byte) 0x64,
-            (byte) 0x31, (byte) 0x17, (byte) 0x30, (byte) 0x15, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x0e, (byte) 0x63,
-            (byte) 0x61, (byte) 0x2e, (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d,
-            (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f,
-            (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31,
-            (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x37, (byte) 0x32,
-            (byte) 0x33, (byte) 0x33, (byte) 0x34, (byte) 0x32, (byte) 0x32, (byte) 0x5a,
-            (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x33, (byte) 0x30, (byte) 0x38,
-            (byte) 0x32, (byte) 0x35, (byte) 0x32, (byte) 0x33, (byte) 0x33, (byte) 0x34,
-            (byte) 0x32, (byte) 0x32, (byte) 0x5a, (byte) 0x30, (byte) 0x62, (byte) 0x31,
-            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55,
-            (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53,
-            (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74,
-            (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30,
-            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
-            (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57,
-            (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73,
-            (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c,
-            (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c,
-            (byte) 0x12, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76, (byte) 0x65,
-            (byte) 0x72, (byte) 0x2e, (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d,
-            (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f,
-            (byte) 0x6d, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0xb7, (byte) 0x30,
-            (byte) 0x82, (byte) 0x01, (byte) 0x2c, (byte) 0x06, (byte) 0x07, (byte) 0x2a,
-            (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38, (byte) 0x04, (byte) 0x01,
-            (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1f, (byte) 0x02, (byte) 0x81,
-            (byte) 0x81, (byte) 0x00, (byte) 0xb3, (byte) 0x23, (byte) 0xf7, (byte) 0x86,
-            (byte) 0xbd, (byte) 0x3b, (byte) 0x86, (byte) 0xcc, (byte) 0xc3, (byte) 0x91,
-            (byte) 0xc0, (byte) 0x30, (byte) 0x32, (byte) 0x02, (byte) 0x47, (byte) 0x35,
-            (byte) 0x01, (byte) 0xef, (byte) 0xee, (byte) 0x98, (byte) 0x13, (byte) 0x56,
-            (byte) 0x49, (byte) 0x47, (byte) 0xb5, (byte) 0x20, (byte) 0xa8, (byte) 0x60,
-            (byte) 0xcb, (byte) 0xc0, (byte) 0xd5, (byte) 0x77, (byte) 0xc1, (byte) 0x69,
-            (byte) 0xcd, (byte) 0x18, (byte) 0x34, (byte) 0x92, (byte) 0xf2, (byte) 0x6a,
-            (byte) 0x2a, (byte) 0x10, (byte) 0x59, (byte) 0x1c, (byte) 0x91, (byte) 0x20,
-            (byte) 0x51, (byte) 0xca, (byte) 0x37, (byte) 0xb2, (byte) 0x87, (byte) 0xa6,
-            (byte) 0x8a, (byte) 0x02, (byte) 0xfd, (byte) 0x45, (byte) 0x46, (byte) 0xf9,
-            (byte) 0x76, (byte) 0xb1, (byte) 0x35, (byte) 0x38, (byte) 0x8d, (byte) 0xff,
-            (byte) 0x4c, (byte) 0x5d, (byte) 0x75, (byte) 0x8f, (byte) 0x66, (byte) 0x15,
-            (byte) 0x7d, (byte) 0x7b, (byte) 0xda, (byte) 0xdb, (byte) 0x57, (byte) 0x39,
-            (byte) 0xff, (byte) 0x91, (byte) 0x3f, (byte) 0xdd, (byte) 0xe2, (byte) 0xb4,
-            (byte) 0x22, (byte) 0x60, (byte) 0x4c, (byte) 0x32, (byte) 0x3b, (byte) 0x9d,
-            (byte) 0x34, (byte) 0x9f, (byte) 0xb9, (byte) 0x5d, (byte) 0x75, (byte) 0xb9,
-            (byte) 0xd3, (byte) 0x7f, (byte) 0x11, (byte) 0xba, (byte) 0xb7, (byte) 0xc8,
-            (byte) 0x32, (byte) 0xc6, (byte) 0xce, (byte) 0x71, (byte) 0x91, (byte) 0xd3,
-            (byte) 0x32, (byte) 0xaf, (byte) 0x4d, (byte) 0x7e, (byte) 0x7c, (byte) 0x15,
-            (byte) 0xf7, (byte) 0x71, (byte) 0x2c, (byte) 0x52, (byte) 0x65, (byte) 0x4d,
-            (byte) 0xa9, (byte) 0x81, (byte) 0x25, (byte) 0x35, (byte) 0xce, (byte) 0x0b,
-            (byte) 0x5b, (byte) 0x56, (byte) 0xfe, (byte) 0xf1, (byte) 0x02, (byte) 0x15,
-            (byte) 0x00, (byte) 0xeb, (byte) 0x4e, (byte) 0x7f, (byte) 0x7a, (byte) 0x31,
-            (byte) 0xb3, (byte) 0x7d, (byte) 0x8d, (byte) 0xb2, (byte) 0xf7, (byte) 0xaf,
-            (byte) 0xad, (byte) 0xb1, (byte) 0x42, (byte) 0x92, (byte) 0xf3, (byte) 0x6c,
-            (byte) 0xe4, (byte) 0xed, (byte) 0x8b, (byte) 0x02, (byte) 0x81, (byte) 0x81,
-            (byte) 0x00, (byte) 0x81, (byte) 0xc8, (byte) 0x36, (byte) 0x48, (byte) 0xdb,
-            (byte) 0x71, (byte) 0x2b, (byte) 0x91, (byte) 0xce, (byte) 0x6d, (byte) 0xbc,
-            (byte) 0xb8, (byte) 0xf9, (byte) 0xcb, (byte) 0x50, (byte) 0x91, (byte) 0x10,
-            (byte) 0x8a, (byte) 0xf8, (byte) 0x37, (byte) 0x50, (byte) 0xda, (byte) 0x4f,
-            (byte) 0xc8, (byte) 0x4d, (byte) 0x73, (byte) 0xcb, (byte) 0x4d, (byte) 0xb0,
-            (byte) 0x19, (byte) 0x54, (byte) 0x5a, (byte) 0xf3, (byte) 0x6c, (byte) 0xc9,
-            (byte) 0xd8, (byte) 0x96, (byte) 0xd9, (byte) 0xb0, (byte) 0x54, (byte) 0x7e,
-            (byte) 0x7d, (byte) 0xe2, (byte) 0x58, (byte) 0x0e, (byte) 0x5f, (byte) 0xc0,
-            (byte) 0xce, (byte) 0xb9, (byte) 0x5c, (byte) 0xe3, (byte) 0xd3, (byte) 0xdf,
-            (byte) 0xcf, (byte) 0x45, (byte) 0x74, (byte) 0xfb, (byte) 0xe6, (byte) 0x20,
-            (byte) 0xe7, (byte) 0xfc, (byte) 0x0f, (byte) 0xca, (byte) 0xdb, (byte) 0xc0,
-            (byte) 0x0b, (byte) 0xe1, (byte) 0x5a, (byte) 0x16, (byte) 0x1d, (byte) 0xb3,
-            (byte) 0x2e, (byte) 0xe5, (byte) 0x5f, (byte) 0x89, (byte) 0x17, (byte) 0x73,
-            (byte) 0x50, (byte) 0xd1, (byte) 0x4a, (byte) 0x60, (byte) 0xb7, (byte) 0xaa,
-            (byte) 0xf0, (byte) 0xc7, (byte) 0xc5, (byte) 0x03, (byte) 0x4e, (byte) 0x36,
-            (byte) 0x51, (byte) 0x9e, (byte) 0x2f, (byte) 0xfa, (byte) 0xf3, (byte) 0xd6,
-            (byte) 0x58, (byte) 0x14, (byte) 0x02, (byte) 0xb4, (byte) 0x41, (byte) 0xd6,
-            (byte) 0x72, (byte) 0x6f, (byte) 0x58, (byte) 0x5b, (byte) 0x2d, (byte) 0x23,
-            (byte) 0xc0, (byte) 0x75, (byte) 0x4f, (byte) 0x39, (byte) 0xa8, (byte) 0x6a,
-            (byte) 0xdf, (byte) 0x79, (byte) 0x21, (byte) 0xf2, (byte) 0x77, (byte) 0x91,
-            (byte) 0x3f, (byte) 0x1c, (byte) 0x4d, (byte) 0x48, (byte) 0x78, (byte) 0xcd,
-            (byte) 0xed, (byte) 0x79, (byte) 0x23, (byte) 0x03, (byte) 0x81, (byte) 0x84,
-            (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x1a, (byte) 0x50,
-            (byte) 0x9d, (byte) 0x3e, (byte) 0xa1, (byte) 0x6c, (byte) 0x99, (byte) 0x35,
-            (byte) 0x36, (byte) 0x26, (byte) 0x22, (byte) 0x6b, (byte) 0x47, (byte) 0x45,
-            (byte) 0x80, (byte) 0x5b, (byte) 0xd5, (byte) 0xc1, (byte) 0xc5, (byte) 0x70,
-            (byte) 0x75, (byte) 0x55, (byte) 0x66, (byte) 0x33, (byte) 0x1d, (byte) 0xae,
-            (byte) 0xd0, (byte) 0x01, (byte) 0x64, (byte) 0x8b, (byte) 0xae, (byte) 0x9d,
-            (byte) 0x66, (byte) 0x58, (byte) 0xf9, (byte) 0x42, (byte) 0x74, (byte) 0x3a,
-            (byte) 0x32, (byte) 0xc7, (byte) 0x7f, (byte) 0x25, (byte) 0x64, (byte) 0x7d,
-            (byte) 0x08, (byte) 0x26, (byte) 0xbf, (byte) 0x21, (byte) 0x3a, (byte) 0x84,
-            (byte) 0xcc, (byte) 0x2c, (byte) 0x66, (byte) 0x7d, (byte) 0xc7, (byte) 0xd6,
-            (byte) 0xb1, (byte) 0x69, (byte) 0x57, (byte) 0x67, (byte) 0x52, (byte) 0x73,
-            (byte) 0x3f, (byte) 0x79, (byte) 0x60, (byte) 0xaa, (byte) 0xf4, (byte) 0x8a,
-            (byte) 0x48, (byte) 0x42, (byte) 0x46, (byte) 0x41, (byte) 0xd0, (byte) 0x50,
-            (byte) 0x9b, (byte) 0xa2, (byte) 0x4e, (byte) 0xa5, (byte) 0x88, (byte) 0x10,
-            (byte) 0xf7, (byte) 0x61, (byte) 0xa2, (byte) 0xfa, (byte) 0x8d, (byte) 0xa6,
-            (byte) 0x13, (byte) 0x9e, (byte) 0x36, (byte) 0x86, (byte) 0x62, (byte) 0xf0,
-            (byte) 0x97, (byte) 0xef, (byte) 0x11, (byte) 0xc6, (byte) 0x35, (byte) 0xd3,
-            (byte) 0x79, (byte) 0x30, (byte) 0xde, (byte) 0xf2, (byte) 0x7f, (byte) 0x7a,
-            (byte) 0x3c, (byte) 0x03, (byte) 0xa3, (byte) 0xc5, (byte) 0xbc, (byte) 0xb1,
-            (byte) 0xbc, (byte) 0x2f, (byte) 0x10, (byte) 0xf4, (byte) 0x51, (byte) 0x89,
-            (byte) 0xe2, (byte) 0xaf, (byte) 0xf7, (byte) 0x61, (byte) 0x1a, (byte) 0xf0,
-            (byte) 0x87, (byte) 0x5e, (byte) 0xa5, (byte) 0x02, (byte) 0xd2, (byte) 0xe4,
-            (byte) 0xa3, (byte) 0x7b, (byte) 0x30, (byte) 0x79, (byte) 0x30, (byte) 0x09,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x04,
-            (byte) 0x02, (byte) 0x30, (byte) 0x00, (byte) 0x30, (byte) 0x2c, (byte) 0x06,
-            (byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48, (byte) 0x01, (byte) 0x86,
-            (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x0d, (byte) 0x04, (byte) 0x1f,
-            (byte) 0x16, (byte) 0x1d, (byte) 0x4f, (byte) 0x70, (byte) 0x65, (byte) 0x6e,
-            (byte) 0x53, (byte) 0x53, (byte) 0x4c, (byte) 0x20, (byte) 0x47, (byte) 0x65,
-            (byte) 0x6e, (byte) 0x65, (byte) 0x72, (byte) 0x61, (byte) 0x74, (byte) 0x65,
-            (byte) 0x64, (byte) 0x20, (byte) 0x43, (byte) 0x65, (byte) 0x72, (byte) 0x74,
-            (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x63, (byte) 0x61, (byte) 0x74,
-            (byte) 0x65, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14,
-            (byte) 0xd1, (byte) 0x6c, (byte) 0x36, (byte) 0x36, (byte) 0x61, (byte) 0x6c,
-            (byte) 0xf6, (byte) 0x90, (byte) 0x82, (byte) 0x82, (byte) 0x87, (byte) 0x93,
-            (byte) 0xbe, (byte) 0x99, (byte) 0x60, (byte) 0x1b, (byte) 0x03, (byte) 0x58,
-            (byte) 0x36, (byte) 0x63, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30,
-            (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x47, (byte) 0x82, (byte) 0xa3,
-            (byte) 0xf1, (byte) 0xc2, (byte) 0x7e, (byte) 0x3a, (byte) 0xde, (byte) 0x4f,
-            (byte) 0x30, (byte) 0x4c, (byte) 0x7f, (byte) 0x72, (byte) 0x81, (byte) 0x15,
-            (byte) 0x32, (byte) 0xda, (byte) 0x7f, (byte) 0x58, (byte) 0x18, (byte) 0x30,
-            (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
-            (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05,
-            (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00,
-            (byte) 0x81, (byte) 0xde, (byte) 0x20, (byte) 0xa1, (byte) 0xb2, (byte) 0x50,
-            (byte) 0x03, (byte) 0xcd, (byte) 0x90, (byte) 0x4f, (byte) 0x2b, (byte) 0x47,
-            (byte) 0x1d, (byte) 0xac, (byte) 0x6e, (byte) 0xb4, (byte) 0xc7, (byte) 0x14,
-            (byte) 0xc6, (byte) 0x4f, (byte) 0x45, (byte) 0xaf, (byte) 0x81, (byte) 0x5d,
-            (byte) 0x5a, (byte) 0x31, (byte) 0xff, (byte) 0x9c, (byte) 0x4d, (byte) 0xdc,
-            (byte) 0x9e, (byte) 0x36, (byte) 0x9f, (byte) 0x9b, (byte) 0xb1, (byte) 0xc9,
-            (byte) 0x50, (byte) 0xa3, (byte) 0xf6, (byte) 0x9c, (byte) 0x68, (byte) 0x6f,
-            (byte) 0x68, (byte) 0xd9, (byte) 0x56, (byte) 0x1b, (byte) 0xe5, (byte) 0x1b,
-            (byte) 0x41, (byte) 0xd4, (byte) 0xcc, (byte) 0xb6, (byte) 0x37, (byte) 0xd5,
-            (byte) 0x69, (byte) 0x6b, (byte) 0x39, (byte) 0xaf, (byte) 0xc6, (byte) 0xb8,
-            (byte) 0x39, (byte) 0x76, (byte) 0xe3, (byte) 0xf7, (byte) 0x97, (byte) 0x74,
-            (byte) 0x31, (byte) 0xc4, (byte) 0x2d, (byte) 0xb7, (byte) 0x9a, (byte) 0xa4,
-            (byte) 0xfa, (byte) 0x9f, (byte) 0xa8, (byte) 0xe3, (byte) 0x41, (byte) 0xda,
-            (byte) 0x2f, (byte) 0x0c, (byte) 0x9d, (byte) 0x83, (byte) 0xdc, (byte) 0x86,
-            (byte) 0x1f, (byte) 0x5c, (byte) 0x0f, (byte) 0x87, (byte) 0x05, (byte) 0xc9,
-            (byte) 0xb0, (byte) 0x63, (byte) 0xca, (byte) 0x9b, (byte) 0xdb, (byte) 0xe6,
-            (byte) 0x3c, (byte) 0xe9, (byte) 0x23, (byte) 0x9e, (byte) 0x23, (byte) 0x44,
-            (byte) 0x1d, (byte) 0x5b, (byte) 0x60, (byte) 0x66, (byte) 0xb6, (byte) 0x72,
-            (byte) 0x8c, (byte) 0x87, (byte) 0x86, (byte) 0xe8, (byte) 0xdb, (byte) 0x29,
-            (byte) 0x67, (byte) 0x9c, (byte) 0x33, (byte) 0x5c, (byte) 0x39, (byte) 0xf1,
-            (byte) 0xb5, (byte) 0x9b, (byte) 0xb8, (byte) 0xe1, (byte) 0x42, (byte) 0x51,
-            (byte) 0xed, (byte) 0x2c
-    };
-
     /**
      * The amount of time to allow before and after expected time for variance
      * in timing tests.
@@ -1500,26 +1135,6 @@
                 FAKE_RSA_CA_1);
     }
 
-    public void testKeyStore_GetEntry_DSA_NullParams_Unencrypted_Success() throws Exception {
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_DSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
-                FAKE_DSA_USER_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_DSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-
-        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-        assertNotNull("Entry should exist", entry);
-
-        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
-
-        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
-
-        assertPrivateKeyEntryEquals(keyEntry, "DSA", FAKE_DSA_KEY_1, FAKE_DSA_USER_1, FAKE_DSA_CA_1);
-    }
-
     public void testKeyStore_GetEntry_EC_NullParams_Unencrypted_Success() throws Exception {
         mKeyStore.load(null, null);
 
@@ -1583,11 +1198,7 @@
 
     private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, PrivateKey expectedKey,
             Certificate expectedCert, Collection<Certificate> expectedChain) throws Exception {
-        if (expectedKey instanceof DSAPrivateKey) {
-            assertEquals("Returned PrivateKey should be what we inserted",
-                    ((DSAPrivateKey) expectedKey).getParams(),
-                    ((DSAPublicKey) keyEntry.getCertificate().getPublicKey()).getParams());
-        } else if (expectedKey instanceof ECPrivateKey) {
+        if (expectedKey instanceof ECPrivateKey) {
             assertEquals("Returned PrivateKey should be what we inserted",
                     ((ECPrivateKey) expectedKey).getParams().getCurve(),
                     ((ECPublicKey) keyEntry.getCertificate().getPublicKey()).getParams().getCurve());
@@ -1871,33 +1482,6 @@
         assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
     }
 
-    public void testKeyStore_SetEntry_PrivateKeyEntry_DSA_Unencrypted_Success() throws Exception {
-        mKeyStore.load(null, null);
-
-        KeyFactory keyFact = KeyFactory.getInstance("DSA");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_DSA_KEY_1));
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        final Certificate[] expectedChain = new Certificate[2];
-        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_DSA_USER_1));
-        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_DSA_CA_1));
-
-        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
-
-        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
-
-        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-        assertNotNull("Retrieved entry should exist", actualEntry);
-
-        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                actualEntry instanceof PrivateKeyEntry);
-
-        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
-
-        assertPrivateKeyEntryEquals(actual, "DSA", FAKE_DSA_KEY_1, FAKE_DSA_USER_1, FAKE_DSA_CA_1);
-    }
-
     public void testKeyStore_SetEntry_PrivateKeyEntry_EC_Unencrypted_Success() throws Exception {
         mKeyStore.load(null, null);
 
diff --git a/libs/androidfw/misc.cpp b/libs/androidfw/misc.cpp
index 29686ef..a9b46d2 100644
--- a/libs/androidfw/misc.cpp
+++ b/libs/androidfw/misc.cpp
@@ -56,9 +56,11 @@
             return kFileTypeBlockDev;
         else if (S_ISFIFO(sb.st_mode))
             return kFileTypeFifo;
-#ifdef HAVE_SYMLINKS
+#if defined(S_ISLNK)
         else if (S_ISLNK(sb.st_mode))
             return kFileTypeSymlink;
+#endif
+#if defined(S_ISSOCK)
         else if (S_ISSOCK(sb.st_mode))
             return kFileTypeSocket;
 #endif
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 9f2014f..061d26a 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -203,6 +203,34 @@
 }
 
 void Matrix4::loadInverse(const Matrix4& v) {
+    // Fast case for common translation matrices
+    if (v.isPureTranslate()) {
+        // Reset the matrix
+        // Unnamed fields are never written to except by
+        // loadIdentity(), they don't need to be reset
+        data[kScaleX]       = 1.0f;
+        data[kSkewX]        = 0.0f;
+
+        data[kScaleY]       = 1.0f;
+        data[kSkewY]        = 0.0f;
+
+        data[kScaleZ]       = 1.0f;
+
+        data[kPerspective0] = 0.0f;
+        data[kPerspective1] = 0.0f;
+        data[kPerspective2] = 1.0f;
+
+        // No need to deal with kTranslateZ because isPureTranslate()
+        // only returns true when the kTranslateZ component is 0
+        data[kTranslateX]   = -v.data[kTranslateX];
+        data[kTranslateY]   = -v.data[kTranslateY];
+        data[kTranslateZ]   = 0.0f;
+
+        // A "pure translate" matrix can be identity or translation
+        mType = v.getType();
+        return;
+    }
+
     double scale = 1.0 /
             (v.data[kScaleX] * ((double) v.data[kScaleY]  * v.data[kPerspective2] -
                     (double) v.data[kTranslateY] * v.data[kPerspective1]) +
@@ -212,18 +240,18 @@
                      (double) v.data[kScaleY] * v.data[kPerspective0]));
 
     data[kScaleX] = (v.data[kScaleY] * v.data[kPerspective2] -
-            v.data[kTranslateY] * v.data[kPerspective1])  * scale;
+            v.data[kTranslateY] * v.data[kPerspective1]) * scale;
     data[kSkewX] = (v.data[kTranslateX] * v.data[kPerspective1] -
             v.data[kSkewX]  * v.data[kPerspective2]) * scale;
     data[kTranslateX] = (v.data[kSkewX] * v.data[kTranslateY] -
-            v.data[kTranslateX] * v.data[kScaleY])  * scale;
+            v.data[kTranslateX] * v.data[kScaleY]) * scale;
 
     data[kSkewY] = (v.data[kTranslateY] * v.data[kPerspective0] -
             v.data[kSkewY]  * v.data[kPerspective2]) * scale;
     data[kScaleY] = (v.data[kScaleX] * v.data[kPerspective2] -
-            v.data[kTranslateX] * v.data[kPerspective0])  * scale;
+            v.data[kTranslateX] * v.data[kPerspective0]) * scale;
     data[kTranslateY] = (v.data[kTranslateX] * v.data[kSkewY] -
-            v.data[kScaleX]  * v.data[kTranslateY]) * scale;
+            v.data[kScaleX] * v.data[kTranslateY]) * scale;
 
     data[kPerspective0] = (v.data[kSkewY] * v.data[kPerspective1] -
             v.data[kScaleY] * v.data[kPerspective0]) * scale;
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index b0bf4a1..8a78a8f 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -508,6 +508,7 @@
 
     // Reference to BluetoothA2dp to query for AbsoluteVolume.
     private BluetoothA2dp mA2dp;
+    // lock always taken synchronized on mConnectedDevices
     private final Object mA2dpAvrcpLock = new Object();
     // If absolute volume is supported in AVRCP device
     private boolean mAvrcpAbsVolSupported = false;
@@ -2731,12 +2732,12 @@
             List<BluetoothDevice> deviceList;
             switch(profile) {
             case BluetoothProfile.A2DP:
-                synchronized (mA2dpAvrcpLock) {
-                    mA2dp = (BluetoothA2dp) proxy;
-                    deviceList = mA2dp.getConnectedDevices();
-                    if (deviceList.size() > 0) {
-                        btDevice = deviceList.get(0);
-                        synchronized (mConnectedDevices) {
+                synchronized (mConnectedDevices) {
+                    synchronized (mA2dpAvrcpLock) {
+                        mA2dp = (BluetoothA2dp) proxy;
+                        deviceList = mA2dp.getConnectedDevices();
+                        if (deviceList.size() > 0) {
+                            btDevice = deviceList.get(0);
                             int state = mA2dp.getConnectionState(btDevice);
                             int delay = checkSendBecomingNoisyIntent(
                                                 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
@@ -2831,9 +2832,9 @@
         public void onServiceDisconnected(int profile) {
             switch(profile) {
             case BluetoothProfile.A2DP:
-                synchronized (mA2dpAvrcpLock) {
-                    mA2dp = null;
-                    synchronized (mConnectedDevices) {
+                synchronized (mConnectedDevices) {
+                    synchronized (mA2dpAvrcpLock) {
+                        mA2dp = null;
                         if (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)) {
                             makeA2dpDeviceUnavailableNow(
                                     mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP));
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 114042d..fb8ae5d 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -302,6 +302,46 @@
         rsnContextResume(mContext);
     }
 
+    native long rsnClosureCreate(long con, long kernelID, long returnValue,
+        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
+        long[] depFieldIDs);
+    synchronized long nClosureCreate(long kernelID, long returnValue,
+        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
+        long[] depFieldIDs) {
+      validate();
+      return rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values,
+          sizes, depClosures, depFieldIDs);
+    }
+
+    native void rsnClosureSetArg(long con, long closureID, int index,
+      long value, int size);
+    synchronized void nClosureSetArg(long closureID, int index, long value,
+        int size) {
+      validate();
+      rsnClosureSetArg(mContext, closureID, index, value, size);
+    }
+
+    native void rsnClosureSetGlobal(long con, long closureID, long fieldID,
+        long value, int size);
+    // Does this have to be synchronized?
+    synchronized void nClosureSetGlobal(long closureID, long fieldID,
+        long value, int size) {
+      validate(); // TODO: is this necessary?
+      rsnClosureSetGlobal(mContext, closureID, fieldID, value, size);
+    }
+
+    native long rsnScriptGroup2Create(long con, long[] closures);
+    synchronized long nScriptGroup2Create(long[] closures) {
+      validate();
+      return rsnScriptGroup2Create(mContext, closures);
+    }
+
+    native void rsnScriptGroup2Execute(long con, long groupID);
+    synchronized void nScriptGroup2Execute(long groupID) {
+      validate();
+      rsnScriptGroup2Execute(mContext, groupID);
+    }
+
     native void rsnAssignName(long con, long obj, byte[] name);
     synchronized void nAssignName(long obj, byte[] name) {
         validate();
diff --git a/rs/java/android/renderscript/ScriptGroup2.java b/rs/java/android/renderscript/ScriptGroup2.java
new file mode 100644
index 0000000..dcad787
--- /dev/null
+++ b/rs/java/android/renderscript/ScriptGroup2.java
@@ -0,0 +1,319 @@
+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;
+
+/**
+   @hide Pending Android public API approval.
+ */
+/**
+
+******************************
+You have tried to change the API from what has been previously approved.
+
+To make these errors go away, you have two choices:
+   1) You can add "@hide" javadoc comments to the methods, etc. listed in the
+      errors above.
+
+   2) You can update current.txt by executing the following command:
+         make update-api
+
+To submit the revised current.txt to the main Android repository,
+you will need approval.
+******************************
+
+   @hide Pending Android public API approval.
+ */
+public class ScriptGroup2 extends BaseObj {
+
+  public static class Closure extends BaseObj {
+    private Allocation mReturnValue;
+    private Map<Script.FieldID, Object> mBindings;
+
+    private Future mReturnFuture;
+    private Map<Script.FieldID, Future> mGlobalFuture;
+
+    private static final String TAG = "Closure";
+
+    public Closure(long id, RenderScript rs) {
+      super(id, rs);
+    }
+
+    public Closure(RenderScript rs, Script.KernelID kernelID, Type returnType,
+        Object[] args, Map<Script.FieldID, Object> globals) {
+      super(0, rs);
+
+      mReturnValue = Allocation.createTyped(rs, returnType);
+      mBindings = new HashMap<Script.FieldID, Object>();
+      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 UnboundValue) {
+          UnboundValue unbound = (UnboundValue)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 UnboundValue) {
+          UnboundValue unbound = (UnboundValue)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);
+    }
+
+    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;
+      } else {
+        depClosures[index] = 0;
+        depFieldIDs[index] = 0;
+      }
+
+      ValueAndSize vs = new ValueAndSize(rs, obj);
+      values[index] = vs.value;
+      sizes[index] = vs.size;
+    }
+
+    public Future getReturn() {
+      if (mReturnFuture == null) {
+        mReturnFuture = new Future(this, null, mReturnValue);
+      }
+
+      return mReturnFuture;
+    }
+
+    public Future getGlobal(Script.FieldID field) {
+      Future f = mGlobalFuture.get(field);
+
+      if (f == null) {
+        f = new Future(this, field, mBindings.get(field));
+        mGlobalFuture.put(field, f);
+      }
+
+      return f;
+    }
+
+    void setArg(int index, Object obj) {
+      ValueAndSize vs = new ValueAndSize(mRS, obj);
+      mRS.nClosureSetArg(getID(mRS), index, vs.value, vs.size);
+    }
+
+    void setGlobal(Script.FieldID fieldID, Object 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;
+    }
+  }
+
+  public static 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; }
+  }
+
+  public static class UnboundValue {
+    // 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;
+
+    UnboundValue() {
+      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);
+      }
+    }
+  }
+
+  List<Closure> mClosures;
+  List<UnboundValue> mInputs;
+  Future[] mOutputs;
+
+  private static final String TAG = "ScriptGroup2";
+
+  public ScriptGroup2(long id, RenderScript rs) {
+    super(id, rs);
+  }
+
+  ScriptGroup2(RenderScript rs, List<Closure> closures,
+      List<UnboundValue> inputs, Future[] outputs) {
+    super(0, rs);
+    mClosures = closures;
+    mInputs = inputs;
+    mOutputs = 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(closureIDs);
+    setID(id);
+  }
+
+  // TODO: If this was reflected method, we could enforce the number of
+  // arguments.
+  public Object[] execute(Object... inputs) {
+    if (inputs.length < mInputs.size()) {
+      Log.e(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
+          "less than expected " + mInputs.size());
+      return null;
+    }
+
+    if (inputs.length > mInputs.size()) {
+      Log.i(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
+          "more than expected " + mInputs.size());
+    }
+
+    for (int i = 0; i < mInputs.size(); i++) {
+      Object obj = inputs[i];
+      if (obj instanceof Future || obj instanceof UnboundValue) {
+        Log.e(TAG, this.toString() + ": input " + i +
+            " is a future or unbound value");
+        return null;
+      }
+      UnboundValue unbound = mInputs.get(i);
+      unbound.set(obj);
+    }
+
+    mRS.nScriptGroup2Execute(getID(mRS));
+
+    Object[] outputObjs = new Object[mOutputs.length];
+    int i = 0;
+    for (Future f : mOutputs) {
+      outputObjs[i++] = f.getValue();
+    }
+    return outputObjs;
+  }
+
+  /**
+     @hide Pending Android public API approval.
+   */
+  public static final class Builder {
+    RenderScript mRS;
+    List<Closure> mClosures;
+    List<UnboundValue> mInputs;
+
+    private static final String TAG = "ScriptGroup2.Builder";
+
+    public Builder(RenderScript rs) {
+      mRS = rs;
+      mClosures = new ArrayList<Closure>();
+      mInputs = new ArrayList<UnboundValue>();
+    }
+
+    public Closure addKernel(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;
+    }
+
+    public UnboundValue addInput() {
+      UnboundValue unbound = new UnboundValue();
+      mInputs.add(unbound);
+      return unbound;
+    }
+
+    public ScriptGroup2 create(Future... outputs) {
+      // TODO: Save all script groups that have been created and return one that was
+      // saved and matches the outputs.
+      ScriptGroup2 ret = new ScriptGroup2(mRS, mClosures, mInputs, outputs);
+      return ret;
+    }
+
+  }
+}
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 68a0b83..dced99a 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -193,6 +193,88 @@
     rsContextFinish((RsContext)con);
 }
 
+static jlong
+nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID,
+               jlong returnValue, jlongArray fieldIDArray,
+               jlongArray valueArray, jintArray sizeArray,
+               jlongArray depClosureArray, jlongArray depFieldIDArray) {
+  jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
+  jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
+  RsScriptFieldID* fieldIDs =
+      (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * fieldIDs_length);
+  for (int i = 0; i< fieldIDs_length; i++) {
+    fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
+  }
+
+  jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
+  jsize values_length = _env->GetArrayLength(valueArray);
+  uintptr_t* values = (uintptr_t*)alloca(sizeof(uintptr_t) * values_length);
+  for (int i = 0; i < values_length; i++) {
+    values[i] = (uintptr_t)jValues[i];
+  }
+
+  jint* sizes = _env->GetIntArrayElements(sizeArray, nullptr);
+  jsize sizes_length = _env->GetArrayLength(sizeArray);
+
+  jlong* jDepClosures =
+      _env->GetLongArrayElements(depClosureArray, nullptr);
+  jsize depClosures_length = _env->GetArrayLength(depClosureArray);
+  RsClosure* depClosures =
+      (RsClosure*)alloca(sizeof(RsClosure) * depClosures_length);
+  for (int i = 0; i < depClosures_length; i++) {
+    depClosures[i] = (RsClosure)jDepClosures[i];
+  }
+
+  jlong* jDepFieldIDs =
+      _env->GetLongArrayElements(depFieldIDArray, nullptr);
+  jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray);
+  RsScriptFieldID* depFieldIDs =
+      (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * depFieldIDs_length);
+  for (int i = 0; i < depClosures_length; i++) {
+    depFieldIDs[i] = (RsClosure)jDepFieldIDs[i];
+  }
+
+  return (jlong)(uintptr_t)rsClosureCreate(
+      (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue,
+      fieldIDs, (size_t)fieldIDs_length, values, (size_t)values_length,
+      (size_t*)sizes, (size_t)sizes_length,
+      depClosures, (size_t)depClosures_length,
+      depFieldIDs, (size_t)depFieldIDs_length);
+}
+
+static void
+nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
+               jint index, jlong value, jint size) {
+  rsClosureSetArg((RsContext)con, (RsClosure)closureID, (uint32_t)index,
+                  (uintptr_t)value, (size_t)size);
+}
+
+static void
+nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
+                  jlong fieldID, jlong value, jint size) {
+  rsClosureSetGlobal((RsContext)con, (RsClosure)closureID,
+                     (RsScriptFieldID)fieldID, (uintptr_t)value, (size_t)size);
+}
+
+static long
+nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con,
+                    jlongArray closureArray) {
+  jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr);
+  jsize numClosures = _env->GetArrayLength(closureArray);
+  RsClosure* closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures);
+  for (int i = 0; i < numClosures; i++) {
+    closures[i] = (RsClosure)jClosures[i];
+  }
+
+  return (jlong)(uintptr_t)rsScriptGroup2Create((RsContext)con, closures,
+                                                numClosures);
+}
+
+static void
+nScriptGroup2Execute(JNIEnv *_env, jobject _this, jlong con, jlong groupID) {
+  rsScriptGroupExecute((RsContext)con, (RsScriptGroup2)groupID);
+}
+
 static void
 nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str)
 {
@@ -1841,6 +1923,9 @@
 {"rsnContextPause",                  "(J)V",                                  (void*)nContextPause },
 {"rsnContextResume",                 "(J)V",                                  (void*)nContextResume },
 {"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
+{"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
+{"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
+{"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
 {"rsnAssignName",                    "(JJ[B)V",                               (void*)nAssignName },
 {"rsnGetName",                       "(JJ)Ljava/lang/String;",                (void*)nGetName },
 {"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
@@ -1915,9 +2000,11 @@
 {"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
 {"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
 {"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
+{"rsnScriptGroup2Create",            "(J[J)J",                                (void*)nScriptGroup2Create },
 {"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
 {"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
 {"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
+{"rsnScriptGroup2Execute",           "(JJ)V",                                 (void*)nScriptGroup2Execute },
 
 {"rsnProgramStoreCreate",            "(JZZZZZZIII)J",                         (void*)nProgramStoreCreate },
 
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 020c951..967ee31 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -24,9 +24,6 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.TrafficStats.UID_TETHERING;
-import static android.net.RouteInfo.RTN_THROW;
-import static android.net.RouteInfo.RTN_UNICAST;
-import static android.net.RouteInfo.RTN_UNREACHABLE;
 import static com.android.server.NetworkManagementService.NetdResponseCode.ClatdStatusResult;
 import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceGetCfgResult;
 import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceListResult;
@@ -38,6 +35,7 @@
 import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
 
+import android.app.ActivityManagerNative;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.INetworkManagementEventObserver;
@@ -61,6 +59,7 @@
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.StrictMode;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.telephony.DataConnectionRealTimeInfo;
@@ -70,9 +69,12 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.net.NetworkStatsFactory;
+import com.android.internal.util.HexDump;
 import com.android.internal.util.Preconditions;
 import com.android.server.NativeDaemonConnector.Command;
 import com.android.server.NativeDaemonConnector.SensitiveArg;
@@ -87,8 +89,6 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InterfaceAddress;
 import java.net.NetworkInterface;
@@ -145,6 +145,7 @@
         public static final int InterfaceAddressChange    = 614;
         public static final int InterfaceDnsServerInfo    = 615;
         public static final int RouteChange               = 616;
+        public static final int StrictCleartext           = 617;
     }
 
     static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1;
@@ -174,12 +175,19 @@
     private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory();
 
     private Object mQuotaLock = new Object();
+
     /** Set of interfaces with active quotas. */
+    @GuardedBy("mQuotaLock")
     private HashMap<String, Long> mActiveQuotas = Maps.newHashMap();
     /** Set of interfaces with active alerts. */
+    @GuardedBy("mQuotaLock")
     private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
     /** Set of UIDs with active reject rules. */
+    @GuardedBy("mQuotaLock")
     private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();
+    /** Set of UIDs with cleartext penalties. */
+    @GuardedBy("mQuotaLock")
+    private SparseIntArray mUidCleartextPolicy = new SparseIntArray();
 
     private Object mIdleTimerLock = new Object();
     /** Set of interfaces with active idle timers. */
@@ -198,6 +206,7 @@
 
     private volatile boolean mBandwidthControlEnabled;
     private volatile boolean mFirewallEnabled;
+    private volatile boolean mStrictEnabled;
 
     private boolean mMobileActivityFromRadio = false;
     private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
@@ -495,11 +504,18 @@
             }
         }
 
+        try {
+            mConnector.execute("strict", "enable");
+            mStrictEnabled = true;
+        } catch (NativeDaemonConnectorException e) {
+            Log.wtf(TAG, "Failed strict enable", e);
+        }
+
         // push any existing quota or UID rules
         synchronized (mQuotaLock) {
             int size = mActiveQuotas.size();
             if (size > 0) {
-                Slog.d(TAG, "pushing " + size + " active quota rules");
+                Slog.d(TAG, "Pushing " + size + " active quota rules");
                 final HashMap<String, Long> activeQuotas = mActiveQuotas;
                 mActiveQuotas = Maps.newHashMap();
                 for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) {
@@ -509,7 +525,7 @@
 
             size = mActiveAlerts.size();
             if (size > 0) {
-                Slog.d(TAG, "pushing " + size + " active alert rules");
+                Slog.d(TAG, "Pushing " + size + " active alert rules");
                 final HashMap<String, Long> activeAlerts = mActiveAlerts;
                 mActiveAlerts = Maps.newHashMap();
                 for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) {
@@ -519,13 +535,23 @@
 
             size = mUidRejectOnQuota.size();
             if (size > 0) {
-                Slog.d(TAG, "pushing " + size + " active uid rules");
+                Slog.d(TAG, "Pushing " + size + " active UID rules");
                 final SparseBooleanArray uidRejectOnQuota = mUidRejectOnQuota;
                 mUidRejectOnQuota = new SparseBooleanArray();
                 for (int i = 0; i < uidRejectOnQuota.size(); i++) {
                     setUidNetworkRules(uidRejectOnQuota.keyAt(i), uidRejectOnQuota.valueAt(i));
                 }
             }
+
+            size = mUidCleartextPolicy.size();
+            if (size > 0) {
+                Slog.d(TAG, "Pushing " + size + " active UID cleartext policies");
+                final SparseIntArray local = mUidCleartextPolicy;
+                mUidCleartextPolicy = new SparseIntArray();
+                for (int i = 0; i < local.size(); i++) {
+                    setUidCleartextNetworkPolicy(local.keyAt(i), local.valueAt(i));
+                }
+            }
         }
 
         // TODO: Push any existing firewall state
@@ -792,6 +818,14 @@
                     }
                     throw new IllegalStateException(errorMessage);
                     // break;
+            case NetdResponseCode.StrictCleartext:
+                final int uid = Integer.parseInt(cooked[1]);
+                final byte[] firstPacket = HexDump.hexStringToByteArray(cooked[2]);
+                try {
+                    ActivityManagerNative.getDefault().notifyCleartextNetwork(uid, firstPacket);
+                } catch (RemoteException ignored) {
+                }
+                break;
             default: break;
             }
             return false;
@@ -1641,6 +1675,49 @@
     }
 
     @Override
+    public void setUidCleartextNetworkPolicy(int uid, int policy) {
+        if (Binder.getCallingUid() != uid) {
+            mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        }
+
+        synchronized (mQuotaLock) {
+            final int oldPolicy = mUidCleartextPolicy.get(uid, StrictMode.NETWORK_POLICY_ACCEPT);
+            if (oldPolicy == policy) {
+                return;
+            }
+
+            if (!mStrictEnabled) {
+                // Module isn't enabled yet; stash the requested policy away to
+                // apply later once the daemon is connected.
+                mUidCleartextPolicy.put(uid, policy);
+                return;
+            }
+
+            final String policyString;
+            switch (policy) {
+                case StrictMode.NETWORK_POLICY_ACCEPT:
+                    policyString = "accept";
+                    break;
+                case StrictMode.NETWORK_POLICY_LOG:
+                    policyString = "log";
+                    break;
+                case StrictMode.NETWORK_POLICY_REJECT:
+                    policyString = "reject";
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown policy " + policy);
+            }
+
+            try {
+                mConnector.execute("strict", "set_uid_cleartext_policy", uid, policyString);
+                mUidCleartextPolicy.put(uid, policy);
+            } catch (NativeDaemonConnectorException e) {
+                throw e.rethrowAsParcelableException();
+            }
+        }
+    }
+
+    @Override
     public boolean isBandwidthControlEnabled() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         return mBandwidthControlEnabled;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index f02a815..0540326 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1322,6 +1322,7 @@
         // We are now bringing the service up, so no longer in the
         // restarting state.
         if (mRestartingServices.remove(r)) {
+            r.resetRestartCounter();
             clearRestartingIfNeededLocked(r);
         }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
old mode 100755
new mode 100644
index e3f7fb3..668d62b
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -399,16 +399,6 @@
         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
     }
 
-    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
-        for (BroadcastQueue queue : mBroadcastQueues) {
-            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
-            if (r != null) {
-                return r;
-            }
-        }
-        return null;
-    }
-
     /**
      * Activity we have told the window manager to have key focus.
      */
@@ -1207,6 +1197,7 @@
     static final int FINISH_BOOTING_MSG = 45;
     static final int START_USER_SWITCH_MSG = 46;
     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
+    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1912,6 +1903,23 @@
                 }
                 break;
             }
+            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
+                final int uid = msg.arg1;
+                final byte[] firstPacket = (byte[]) msg.obj;
+
+                synchronized (mPidsSelfLocked) {
+                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
+                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
+                        if (p.uid == uid) {
+                            try {
+                                p.thread.notifyCleartextNetwork(firstPacket);
+                            } catch (RemoteException ignored) {
+                            }
+                        }
+                    }
+                }
+                break;
+            }
             }
         }
     };
@@ -2313,7 +2321,7 @@
             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
 
         mConfiguration.setToDefaults();
-        mConfiguration.setLocale(Locale.getDefault());
+        mConfiguration.locale = Locale.getDefault();
 
         mConfigurationSeq = mConfiguration.seq = 1;
         mProcessCpuTracker.init();
@@ -6018,6 +6026,7 @@
             // Take care of any services that are waiting for the process.
             mServices.processStartTimedOutLocked(app);
             app.kill("start timeout", true);
+            removeLruProcessLocked(app);
             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
                 Slog.w(TAG, "Unattached app died before backup, skipping");
                 try {
@@ -10115,6 +10124,11 @@
     }
 
     @Override
+    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
+        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
+    }
+
+    @Override
     public boolean shutdown(int timeout) {
         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
                 != PackageManager.PERMISSION_GRANTED) {
@@ -11736,8 +11750,12 @@
             sb.append("\n");
             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
                 sb.append(info.crashInfo.stackTrace);
+                sb.append("\n");
             }
-            sb.append("\n");
+            if (info.message != null) {
+                sb.append(info.message);
+                sb.append("\n");
+            }
 
             // Only buffer up to ~64k.  Various logging bits truncate
             // things at 128k.
@@ -15313,11 +15331,11 @@
             synchronized(this) {
                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
                 if (rl != null) {
-                    if (rl.curBroadcast != null) {
-                        BroadcastRecord r = rl.curBroadcast;
-                        final boolean doNext = finishReceiverLocked(
-                                receiver.asBinder(), r.resultCode, r.resultData,
-                                r.resultExtras, r.resultAbort);
+                    final BroadcastRecord r = rl.curBroadcast;
+                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
+                        final boolean doNext = r.queue.finishReceiverLocked(
+                                r, r.resultCode, r.resultData, r.resultExtras,
+                                r.resultAbort, false);
                         if (doNext) {
                             doTrim = true;
                             r.queue.processNextBroadcast(false);
@@ -15990,17 +16008,6 @@
         }
     }
 
-    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
-            String resultData, Bundle resultExtras, boolean resultAbort) {
-        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
-        if (r == null) {
-            Slog.w(TAG, "finishReceiver called but not found on queue");
-            return false;
-        }
-
-        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
-    }
-
     void backgroundServicesFinishedLocked(int userId) {
         for (BroadcastQueue queue : mBroadcastQueues) {
             queue.backgroundServicesFinishedLocked(userId);
@@ -16008,7 +16015,7 @@
     }
 
     public void finishReceiver(IBinder who, int resultCode, String resultData,
-            Bundle resultExtras, boolean resultAbort) {
+            Bundle resultExtras, boolean resultAbort, int flags) {
         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
 
         // Refuse possible leaked file descriptors
@@ -16022,7 +16029,9 @@
             BroadcastRecord r;
 
             synchronized(this) {
-                r = broadcastRecordForReceiverLocked(who);
+                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
+                        ? mFgBroadcastQueue : mBgBroadcastQueue;
+                r = queue.getMatchingOrderedReceiver(who);
                 if (r != null) {
                     doNext = r.queue.finishReceiverLocked(r, resultCode,
                         resultData, resultExtras, resultAbort, true);
@@ -16215,6 +16224,7 @@
         Configuration ci;
         synchronized(this) {
             ci = new Configuration(mConfiguration);
+            ci.userSetLocale = false;
         }
         return ci;
     }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index c03dbc2..152f8d7 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1553,14 +1553,14 @@
                 // Now the task above it has to return to the home task instead.
                 final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
                 mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
-            } else {
-                if (DEBUG_STATES && isOnHomeDisplay()) Slog.d(TAG,
+            } else if (!isOnHomeDisplay()) {
+                return false;
+            } else if (!isHomeStack()){
+                if (DEBUG_STATES) Slog.d(TAG,
                         "resumeTopActivityLocked: Launching home next");
-                // Only resume home if on home display
                 final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
                         HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
-                return isOnHomeDisplay() &&
-                        mStackSupervisor.resumeHomeStackTask(returnTaskType, prev);
+                return mStackSupervisor.resumeHomeStackTask(returnTaskType, prev);
             }
         }
 
diff --git a/services/core/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp
index 3d981ab..3fd0f84 100644
--- a/services/core/jni/com_android_server_AlarmManagerService.cpp
+++ b/services/core/jni/com_android_server_AlarmManagerService.cpp
@@ -21,7 +21,9 @@
 #include "jni.h"
 #include <utils/Log.h>
 #include <utils/misc.h>
+#include <utils/String8.h>
 
+#include <dirent.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <string.h>
@@ -80,8 +82,8 @@
 class AlarmImplTimerFd : public AlarmImpl
 {
 public:
-    AlarmImplTimerFd(int fds[N_ANDROID_TIMERFDS], int epollfd) :
-        AlarmImpl(fds, N_ANDROID_TIMERFDS), epollfd(epollfd) { }
+    AlarmImplTimerFd(int fds[N_ANDROID_TIMERFDS], int epollfd, int rtc_id) :
+        AlarmImpl(fds, N_ANDROID_TIMERFDS), epollfd(epollfd), rtc_id(rtc_id) { }
     ~AlarmImplTimerFd();
 
     int set(int type, struct timespec *ts);
@@ -90,6 +92,7 @@
 
 private:
     int epollfd;
+    int rtc_id;
 };
 
 AlarmImpl::AlarmImpl(int *fds_, size_t n_fds) : fds(new int[n_fds]),
@@ -170,9 +173,16 @@
         return -1;
     }
 
-    fd = open("/dev/rtc0", O_RDWR);
+    if (rtc_id < 0) {
+        ALOGV("Not setting RTC because wall clock RTC was not found");
+        errno = ENODEV;
+        return -1;
+    }
+
+    android::String8 rtc_dev = String8::format("/dev/rtc%d", rtc_id);
+    fd = open(rtc_dev.string(), O_RDWR);
     if (fd < 0) {
-        ALOGV("Unable to open RTC driver: %s\n", strerror(errno));
+        ALOGV("Unable to open %s: %s\n", rtc_dev.string(), strerror(errno));
         return res;
     }
 
@@ -283,6 +293,66 @@
     return reinterpret_cast<jlong>(ret);
 }
 
+static const char rtc_sysfs[] = "/sys/class/rtc";
+
+static bool rtc_is_hctosys(unsigned int rtc_id)
+{
+    android::String8 hctosys_path = String8::format("%s/rtc%u/hctosys",
+            rtc_sysfs, rtc_id);
+
+    FILE *file = fopen(hctosys_path.string(), "re");
+    if (!file) {
+        ALOGE("failed to open %s: %s", hctosys_path.string(), strerror(errno));
+        return false;
+    }
+
+    unsigned int hctosys;
+    bool ret = false;
+    int err = fscanf(file, "%u", &hctosys);
+    if (err == EOF)
+        ALOGE("failed to read from %s: %s", hctosys_path.string(),
+                strerror(errno));
+    else if (err == 0)
+        ALOGE("%s did not have expected contents", hctosys_path.string());
+    else
+        ret = hctosys;
+
+    fclose(file);
+    return ret;
+}
+
+static int wall_clock_rtc()
+{
+    DIR *dir = opendir(rtc_sysfs);
+    if (!dir) {
+        ALOGE("failed to open %s: %s", rtc_sysfs, strerror(errno));
+        return -1;
+    }
+
+    struct dirent *dirent;
+    while (errno = 0, dirent = readdir(dir)) {
+        unsigned int rtc_id;
+        int matched = sscanf(dirent->d_name, "rtc%u", &rtc_id);
+
+        if (matched < 0)
+            break;
+        else if (matched != 1)
+            continue;
+
+        if (rtc_is_hctosys(rtc_id)) {
+            ALOGV("found wall clock RTC %u", rtc_id);
+            return rtc_id;
+        }
+    }
+
+    if (errno == 0)
+        ALOGW("no wall clock RTC found");
+    else
+        ALOGE("failed to enumerate RTCs: %s", strerror(errno));
+
+    return -1;
+}
+
 static jlong init_timerfd()
 {
     int epollfd;
@@ -308,7 +378,7 @@
         }
     }
 
-    AlarmImpl *ret = new AlarmImplTimerFd(fds, epollfd);
+    AlarmImpl *ret = new AlarmImplTimerFd(fds, epollfd, wall_clock_rtc());
 
     for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) {
         epoll_event event;
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 86015fc..d002d9b 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -2286,11 +2286,11 @@
 
     private static String getCurrentIdp(boolean useNanp) {
         String ps = null;
-        if(useNanp)
+        if (useNanp) {
             ps = NANP_IDP_STRING;
-        else{
+        } else {
             // in case, there is no IDD is found, we shouldn't convert it.
-            ps = SystemProperties.get(PROPERTY_OPERATOR_IDP_STRING, PLUS_SIGN_STRING);                
+            ps = SystemProperties.get(PROPERTY_OPERATOR_IDP_STRING, PLUS_SIGN_STRING);
         }
         return ps;
     }