Merge "Throw IllegalArgumentException on invalid hex-strings."
diff --git a/Android.mk b/Android.mk
index 7cd6635..5d9c5b3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -998,13 +998,9 @@
 	../../external/nist-sip/java \
 	../../external/apache-http/src \
 	../../external/tagsoup/src \
-	../../external/libphonenumber/java/src
 
 ext_src_files := $(call all-java-files-under,$(ext_dirs))
 
-ext_res_dirs := \
-	../../external/libphonenumber/java/src
-
 # ====  the library  =========================================
 include $(CLEAR_VARS)
 
@@ -1012,7 +1008,7 @@
 
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVA_LIBRARIES := core-libart
-LOCAL_JAVA_RESOURCE_DIRS := $(ext_res_dirs)
+LOCAL_STATIC_JAVA_LIBRARIES := libphonenumber-platform
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := ext
 
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index fbdbb25..c86fd53 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -146,8 +146,10 @@
     static const char kInstructionSet[] = "arm";
 #elif defined(__i386__)
     static const char kInstructionSet[] = "x86";
-#elif defined (__mips__)
+#elif defined (__mips__) && !defined(__LP64__)
     static const char kInstructionSet[] = "mips";
+#elif defined (__mips__) && defined(__LP64__)
+    static const char kInstructionSet[] = "mips64";
 #else
 #error "Unknown instruction set"
 #endif
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
index 7b25f73..bbe6eef2 100644
--- a/cmds/idmap/scan.cpp
+++ b/cmds/idmap/scan.cpp
@@ -146,13 +146,13 @@
         }
         char *buf = new char[uncompLen];
         if (NULL == buf) {
-            ALOGW("%s: failed to allocate %d byte\n", __FUNCTION__, uncompLen);
+            ALOGW("%s: failed to allocate %zd byte\n", __FUNCTION__, uncompLen);
             dataMap->release();
             return -1;
         }
         StreamingZipInflater inflater(dataMap, uncompLen);
         if (inflater.read(buf, uncompLen) < 0) {
-            ALOGW("%s: failed to inflate %d byte\n", __FUNCTION__, uncompLen);
+            ALOGW("%s: failed to inflate %zd byte\n", __FUNCTION__, uncompLen);
             delete[] buf;
             dataMap->release();
             return -1;
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 5e9d8f7..5249065 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -563,7 +563,10 @@
         if (res != 0) {
             Resources r = getResources(pii);
             if (r != null) {
-                return r.getString(res);
+                try {
+                    return r.getString(res);
+                } catch (Resources.NotFoundException e) {
+                }
             }
         }
         return null;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 17a31f3..6233676 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4161,22 +4161,24 @@
     final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
         boolean hasPkgInfo = false;
         if (packages != null) {
-            for (int i=packages.length-1; i>=0; i--) {
-                //Slog.i(TAG, "Cleaning old package: " + packages[i]);
-                if (!hasPkgInfo) {
-                    WeakReference<LoadedApk> ref;
-                    ref = mPackages.get(packages[i]);
-                    if (ref != null && ref.get() != null) {
-                        hasPkgInfo = true;
-                    } else {
-                        ref = mResourcePackages.get(packages[i]);
+            synchronized (mResourcesManager) {
+                for (int i=packages.length-1; i>=0; i--) {
+                    //Slog.i(TAG, "Cleaning old package: " + packages[i]);
+                    if (!hasPkgInfo) {
+                        WeakReference<LoadedApk> ref;
+                        ref = mPackages.get(packages[i]);
                         if (ref != null && ref.get() != null) {
                             hasPkgInfo = true;
+                        } else {
+                            ref = mResourcePackages.get(packages[i]);
+                            if (ref != null && ref.get() != null) {
+                                hasPkgInfo = true;
+                            }
                         }
                     }
+                    mPackages.remove(packages[i]);
+                    mResourcePackages.remove(packages[i]);
                 }
-                mPackages.remove(packages[i]);
-                mResourcePackages.remove(packages[i]);
             }
         }
         ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 87d785a..1b1e600 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -105,7 +105,7 @@
  */
 public abstract class BackupAgent extends ContextWrapper {
     private static final String TAG = "BackupAgent";
-    private static final boolean DEBUG = true;
+    private static final boolean DEBUG = false;
 
     /** @hide */
     public static final int TYPE_EOF = 0;
diff --git a/core/java/android/net/LocalServerSocket.java b/core/java/android/net/LocalServerSocket.java
index a36203b..9464222 100644
--- a/core/java/android/net/LocalServerSocket.java
+++ b/core/java/android/net/LocalServerSocket.java
@@ -20,12 +20,8 @@
 import java.io.FileDescriptor;
 
 /**
- * non-standard class for creating inbound UNIX-domain socket
- * on the Android platform, this is created in the Linux non-filesystem
- * namespace.
- *
- * On simulator platforms, this may be created in a temporary directory on
- * the filesystem
+ * Non-standard class for creating an inbound UNIX-domain socket
+ * in the Linux abstract namespace.
  */
 public class LocalServerSocket {
     private final LocalSocketImpl impl;
@@ -35,7 +31,7 @@
     private static final int LISTEN_BACKLOG = 50;
 
     /**
-     * Crewates a new server socket listening at specified name.
+     * Creates a new server socket listening at specified name.
      * On the Android platform, the name is created in the Linux
      * abstract namespace (instead of on the filesystem).
      * 
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 344dc91..9377def 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -104,7 +104,7 @@
 
     /**
      * This class is used to retrieved various statistics about the memory mappings for this
-     * process. The returns info broken down by dalvik, native, and other. All results are in kB.
+     * process. The returned info is broken down by dalvik, native, and other. All results are in kB.
      */
     public static class MemoryInfo implements Parcelable {
         /** The proportional set size for dalvik heap.  (Doesn't include other Dalvik overhead.) */
diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java
index c5aee7b..ae95854 100644
--- a/core/java/android/printservice/PrintService.java
+++ b/core/java/android/printservice/PrintService.java
@@ -386,7 +386,7 @@
 
             @Override
             public void setClient(IPrintServiceClient client) {
-                mHandler.obtainMessage(ServiceHandler.MSG_SET_CLEINT, client)
+                mHandler.obtainMessage(ServiceHandler.MSG_SET_CLIENT, client)
                         .sendToTarget();
             }
 
@@ -414,7 +414,7 @@
         public static final int MSG_STOP_PRINTER_STATE_TRACKING = 7;
         public static final int MSG_ON_PRINTJOB_QUEUED = 8;
         public static final int MSG_ON_REQUEST_CANCEL_PRINTJOB = 9;
-        public static final int MSG_SET_CLEINT = 10;
+        public static final int MSG_SET_CLIENT = 10;
 
         public ServiceHandler(Looper looper) {
             super(looper, null, true);
@@ -528,9 +528,9 @@
                     onPrintJobQueued(new PrintJob(printJobInfo, mClient));
                 } break;
 
-                case MSG_SET_CLEINT: {
+                case MSG_SET_CLIENT: {
                     if (DEBUG) {
-                        Log.i(LOG_TAG, "MSG_SET_CLEINT "
+                        Log.i(LOG_TAG, "MSG_SET_CLIENT "
                                 + getPackageName());
                     }
                     mClient = (IPrintServiceClient) message.obj;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 79e84d9..d08758b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6343,14 +6343,7 @@
         public static final String CALL_AUTO_RETRY = "call_auto_retry";
 
         /**
-         * The preferred network mode   7 = Global
-         *                              6 = EvDo only
-         *                              5 = CDMA w/o EvDo
-         *                              4 = CDMA / EvDo auto
-         *                              3 = GSM / WCDMA auto
-         *                              2 = WCDMA only
-         *                              1 = GSM only
-         *                              0 = GSM / WCDMA preferred
+         * See RIL_PreferredNetworkType in ril.h
          * @hide
          */
         public static final String PREFERRED_NETWORK_MODE =
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index 3301cbe..af821ba 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -62,7 +62,8 @@
             // wrapper that it directly forked).
             if (fdNum != 0) {
                 try {
-                    FileDescriptor fd = ZygoteInit.createFileDescriptor(fdNum);
+                    FileDescriptor fd = new FileDescriptor();
+                    fd.setInt$(fdNum);
                     DataOutputStream os = new DataOutputStream(new FileOutputStream(fd));
                     os.writeInt(Process.myPid());
                     os.close();
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 24820bc..c03938a 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -16,6 +16,11 @@
 
 package com.android.internal.os;
 
+import static android.system.OsConstants.O_CLOEXEC;
+import static android.system.OsConstants.STDERR_FILENO;
+import static android.system.OsConstants.STDIN_FILENO;
+import static android.system.OsConstants.STDOUT_FILENO;
+
 import android.net.Credentials;
 import android.net.LocalSocket;
 import android.os.Process;
@@ -186,10 +191,9 @@
             }
 
             if (parsedArgs.runtimeInit && parsedArgs.invokeWith != null) {
-                FileDescriptor[] pipeFds = Os.pipe();
+                FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                 childPipeFd = pipeFds[1];
                 serverPipeFd = pipeFds[0];
-                ZygoteInit.setCloseOnExec(serverPipeFd, true);
             }
 
             /**
@@ -224,8 +228,6 @@
                     parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                     parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                     parsedArgs.appDataDir);
-        } catch (IOException ex) {
-            logAndPrintError(newStderr, "Exception creating pipe", ex);
         } catch (ErrnoException ex) {
             logAndPrintError(newStderr, "Exception creating pipe", ex);
         } catch (IllegalArgumentException ex) {
@@ -857,14 +859,15 @@
 
         if (descriptors != null) {
             try {
-                ZygoteInit.reopenStdio(descriptors[0],
-                        descriptors[1], descriptors[2]);
+                Os.dup2(descriptors[0], STDIN_FILENO);
+                Os.dup2(descriptors[1], STDOUT_FILENO);
+                Os.dup2(descriptors[2], STDERR_FILENO);
 
                 for (FileDescriptor fd: descriptors) {
                     IoUtils.closeQuietly(fd);
                 }
                 newStderr = System.err;
-            } catch (IOException ex) {
+            } catch (ErrnoException ex) {
                 Log.e(TAG, "Error reopening stdio", ex);
             }
         }
@@ -990,8 +993,8 @@
     private void setChildPgid(int pid) {
         // Try to move the new child into the peer's process group.
         try {
-            ZygoteInit.setpgid(pid, ZygoteInit.getpgid(peer.getPid()));
-        } catch (IOException ex) {
+            Os.setpgid(pid, Os.getpgid(peer.getPid()));
+        } catch (ErrnoException ex) {
             // This exception is expected in the case where
             // the peer is not in our session
             // TODO get rid of this log message in the case where
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 62088fa..0fa9a97 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -16,6 +16,8 @@
 
 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;
 
@@ -32,6 +34,7 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
+import android.system.StructPollfd;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
@@ -165,8 +168,9 @@
             }
 
             try {
-                sServerSocket = new LocalServerSocket(
-                        createFileDescriptor(fileDesc));
+                FileDescriptor fd = new FileDescriptor();
+                fd.setInt$(fileDesc);
+                sServerSocket = new LocalServerSocket(fd);
             } catch (IOException ex) {
                 throw new RuntimeException(
                         "Error binding to local socket '" + fileDesc + "'", ex);
@@ -225,26 +229,6 @@
     private static final int ROOT_UID = 0;
     private static final int ROOT_GID = 0;
 
-    /**
-     * Sets effective user ID.
-     */
-    private static void setEffectiveUser(int uid) {
-        int errno = setreuid(ROOT_UID, uid);
-        if (errno != 0) {
-            Log.e(TAG, "setreuid() failed. errno: " + errno);
-        }
-    }
-
-    /**
-     * Sets effective group ID.
-     */
-    private static void setEffectiveGroup(int gid) {
-        int errno = setregid(ROOT_GID, gid);
-        if (errno != 0) {
-            Log.e(TAG, "setregid() failed. errno: " + errno);
-        }
-    }
-
     static void preload() {
         Log.d(TAG, "begin preload");
         preloadClasses();
@@ -292,8 +276,12 @@
         long startTime = SystemClock.uptimeMillis();
 
         // Drop root perms while running static initializers.
-        setEffectiveGroup(UNPRIVILEGED_GID);
-        setEffectiveUser(UNPRIVILEGED_UID);
+        try {
+            Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
+            Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
+        } catch (ErrnoException ex) {
+            throw new RuntimeException("Failed to drop root", ex);
+        }
 
         // Alter the target heap utilization.  With explicit GCs this
         // is not likely to have any effect.
@@ -348,8 +336,12 @@
             runtime.preloadDexCaches();
 
             // Bring back root. We'll need it later.
-            setEffectiveUser(ROOT_UID);
-            setEffectiveGroup(ROOT_GID);
+            try {
+                Os.setreuid(ROOT_UID, ROOT_UID);
+                Os.setregid(ROOT_GID, ROOT_GID);
+            } catch (ErrnoException ex) {
+                throw new RuntimeException("Failed to restore root", ex);
+            }
         }
     }
 
@@ -698,119 +690,42 @@
     private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
         ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
         ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
-        FileDescriptor[] fdArray = new FileDescriptor[4];
 
         fds.add(sServerSocket.getFileDescriptor());
         peers.add(null);
 
         while (true) {
-            int index;
-
-            try {
-                fdArray = fds.toArray(fdArray);
-                index = selectReadable(fdArray);
-            } catch (IOException ex) {
-                throw new RuntimeException("Error in select()", ex);
+            StructPollfd[] pollFds = new StructPollfd[fds.size()];
+            for (int i = 0; i < pollFds.length; ++i) {
+                pollFds[i] = new StructPollfd();
+                pollFds[i].fd = fds.get(i);
+                pollFds[i].events = (short) POLLIN;
             }
-
-            if (index < 0) {
-                throw new RuntimeException("Error in select()");
-            } else if (index == 0) {
-                ZygoteConnection newPeer = acceptCommandPeer(abiList);
-                peers.add(newPeer);
-                fds.add(newPeer.getFileDesciptor());
-            } else {
-                boolean done;
-                done = peers.get(index).runOnce();
-
-                if (done) {
-                    peers.remove(index);
-                    fds.remove(index);
+            try {
+                Os.poll(pollFds, -1);
+            } catch (ErrnoException ex) {
+                throw new RuntimeException("poll failed", ex);
+            }
+            for (int i = pollFds.length - 1; i >= 0; --i) {
+                if ((pollFds[i].revents & POLLIN) == 0) {
+                    continue;
+                }
+                if (i == 0) {
+                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
+                    peers.add(newPeer);
+                    fds.add(newPeer.getFileDesciptor());
+                } else {
+                    boolean done = peers.get(i).runOnce();
+                    if (done) {
+                        peers.remove(i);
+                        fds.remove(i);
+                    }
                 }
             }
         }
     }
 
     /**
-     * The Linux syscall "setreuid()"
-     * @param ruid real uid
-     * @param euid effective uid
-     * @return 0 on success, non-zero errno on fail
-     */
-    static native int setreuid(int ruid, int euid);
-
-    /**
-     * The Linux syscall "setregid()"
-     * @param rgid real gid
-     * @param egid effective gid
-     * @return 0 on success, non-zero errno on fail
-     */
-    static native int setregid(int rgid, int egid);
-
-    /**
-     * Invokes the linux syscall "setpgid"
-     *
-     * @param pid pid to change
-     * @param pgid new process group of pid
-     * @return 0 on success or non-zero errno on fail
-     */
-    static native int setpgid(int pid, int pgid);
-
-    /**
-     * Invokes the linux syscall "getpgid"
-     *
-     * @param pid pid to query
-     * @return pgid of pid in question
-     * @throws IOException on error
-     */
-    static native int getpgid(int pid) throws IOException;
-
-    /**
-     * Invokes the syscall dup2() to copy the specified descriptors into
-     * stdin, stdout, and stderr. The existing stdio descriptors will be
-     * closed and errors during close will be ignored. The specified
-     * descriptors will also remain open at their original descriptor numbers,
-     * so the caller may want to close the original descriptors.
-     *
-     * @param in new stdin
-     * @param out new stdout
-     * @param err new stderr
-     * @throws IOException
-     */
-    static native void reopenStdio(FileDescriptor in,
-            FileDescriptor out, FileDescriptor err) throws IOException;
-
-    /**
-     * Toggles the close-on-exec flag for the specified file descriptor.
-     *
-     * @param fd non-null; file descriptor
-     * @param flag desired close-on-exec flag state
-     * @throws IOException
-     */
-    static native void setCloseOnExec(FileDescriptor fd, boolean flag)
-            throws IOException;
-
-    /**
-     * Invokes select() on the provider array of file descriptors (selecting
-     * for readability only). Array elements of null are ignored.
-     *
-     * @param fds non-null; array of readable file descriptors
-     * @return index of descriptor that is now readable or -1 for empty array.
-     * @throws IOException if an error occurs
-     */
-    static native int selectReadable(FileDescriptor[] fds) throws IOException;
-
-    /**
-     * Creates a file descriptor from an int fd.
-     *
-     * @param fd integer OS file descriptor
-     * @return non-null; FileDescriptor instance
-     * @throws IOException if fd is invalid
-     */
-    static native FileDescriptor createFileDescriptor(int fd)
-            throws IOException;
-
-    /**
      * Class not instantiable.
      */
     private ZygoteInit() {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 97e0fd3..2d54742 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -156,7 +156,6 @@
     android_server_NetworkManagementSocketTagger.cpp \
     android_server_Watchdog.cpp \
     android_ddm_DdmHandleNativeHeap.cpp \
-    com_android_internal_os_ZygoteInit.cpp \
     android_backup_BackupDataInput.cpp \
     android_backup_BackupDataOutput.cpp \
     android_backup_FileBackupHelperBase.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 644f6a6..fb0d5d5 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -162,7 +162,6 @@
 extern int register_android_opengl_classes(JNIEnv *env);
 extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env);
 extern int register_android_server_NetworkManagementSocketTagger(JNIEnv* env);
-extern int register_com_android_internal_os_ZygoteInit(JNIEnv* env);
 extern int register_android_backup_BackupDataInput(JNIEnv *env);
 extern int register_android_backup_BackupDataOutput(JNIEnv *env);
 extern int register_android_backup_FileBackupHelperBase(JNIEnv *env);
@@ -526,8 +525,6 @@
     JavaVMInitArgs initArgs;
     char propBuf[PROPERTY_VALUE_MAX];
     char stackTraceFileBuf[sizeof("-Xstacktracefile:")-1 + PROPERTY_VALUE_MAX];
-    char dexoptFlagsBuf[PROPERTY_VALUE_MAX];
-    char enableAssertBuf[sizeof("-ea:")-1 + PROPERTY_VALUE_MAX];
     char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
     char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
     char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
@@ -537,8 +534,6 @@
     char gctypeOptsBuf[sizeof("-Xgc:")-1 + PROPERTY_VALUE_MAX];
     char backgroundgcOptsBuf[sizeof("-XX:BackgroundGC=")-1 + PROPERTY_VALUE_MAX];
     char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
-    char jitcodecachesizeOptsBuf[sizeof("-Xjitcodecachesize:")-1 + PROPERTY_VALUE_MAX];
-    char dalvikVmLibBuf[PROPERTY_VALUE_MAX];
     char dex2oatXmsImageFlagsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
     char dex2oatXmxImageFlagsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
     char dex2oatXmsFlagsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
@@ -567,8 +562,6 @@
     char langOption[sizeof("-Duser.language=") + 3];
     char regionOption[sizeof("-Duser.region=") + 3];
     char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX];
-    char jitOpBuf[sizeof("-Xjitop:")-1 + PROPERTY_VALUE_MAX];
-    char jitMethodBuf[sizeof("-Xjitmethod:")-1 + PROPERTY_VALUE_MAX];
     char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX];
 
     bool checkJni = false;
@@ -587,9 +580,6 @@
         /* extended JNI checking */
         addOption("-Xcheck:jni");
 
-        /* set a cap on JNI global references */
-        addOption("-Xjnigreflimit:2000");
-
         /* with -Xcheck:jni, this provides a JNI function call trace */
         //addOption("-verbose:jni");
     }
@@ -605,30 +595,6 @@
 
     parseRuntimeOption("dalvik.vm.stack-trace-file", stackTraceFileBuf, "-Xstacktracefile:");
 
-    property_get("dalvik.vm.check-dex-sum", propBuf, "");
-    if (strcmp(propBuf, "true") == 0) {
-        /* perform additional DEX checksum tests */
-        addOption("-Xcheckdexsum");
-    }
-
-    property_get("log.redirect-stdio", propBuf, "");
-    if (strcmp(propBuf, "true") == 0) {
-        /* convert stdout/stderr to log messages */
-        addOption("-Xlog-stdio");
-    }
-
-    strcpy(enableAssertBuf, "-ea:");
-    property_get("dalvik.vm.enableassertions", enableAssertBuf+sizeof("-ea:")-1, "");
-    if (enableAssertBuf[sizeof("-ea:")-1] != '\0') {
-        /* accept "all" to mean "all classes and packages" */
-        if (strcmp(enableAssertBuf+sizeof("-ea:")-1, "all") == 0)
-            enableAssertBuf[3] = '\0'; // truncate to "-ea"
-        ALOGI("Assertions enabled: '%s'\n", enableAssertBuf);
-        addOption(enableAssertBuf);
-    } else {
-        ALOGV("Assertions disabled\n");
-    }
-
     strcpy(jniOptsBuf, "-Xjniopts:");
     if (parseRuntimeOption("dalvik.vm.jniopts", jniOptsBuf, "-Xjniopts:")) {
         ALOGI("JNI options: '%s'\n", jniOptsBuf);
@@ -655,14 +621,6 @@
     parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");
     parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m");
 
-    // Increase the main thread's interpreter stack size for bug 6315322.
-    addOption("-XX:mainThreadStackSize=24K");
-
-    // Set the max jit code cache size.  Note: size of 0 will disable the JIT.
-    parseRuntimeOption("dalvik.vm.jit.codecachesize",
-                       jitcodecachesizeOptsBuf,
-                       "-Xjitcodecachesize:");
-
     parseRuntimeOption("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
     parseRuntimeOption("dalvik.vm.heapminfree", heapminfreeOptsBuf, "-XX:HeapMinFree=");
     parseRuntimeOption("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf, "-XX:HeapMaxFree=");
@@ -678,53 +636,6 @@
     parseRuntimeOption("dalvik.vm.gctype", gctypeOptsBuf, "-Xgc:");
     parseRuntimeOption("dalvik.vm.backgroundgctype", backgroundgcOptsBuf, "-XX:BackgroundGC=");
 
-    /*
-     * Enable or disable dexopt features, such as bytecode verification and
-     * calculation of register maps for precise GC.
-     */
-    property_get("dalvik.vm.dexopt-flags", dexoptFlagsBuf, "");
-    if (dexoptFlagsBuf[0] != '\0') {
-        const char* opc;
-        const char* val;
-
-        opc = strstr(dexoptFlagsBuf, "v=");     /* verification */
-        if (opc != NULL) {
-            switch (*(opc+2)) {
-            case 'n':   val = "-Xverify:none";      break;
-            case 'r':   val = "-Xverify:remote";    break;
-            case 'a':   val = "-Xverify:all";       break;
-            default:    val = NULL;                 break;
-            }
-
-            if (val != NULL) {
-                addOption(val);
-            }
-        }
-
-        opc = strstr(dexoptFlagsBuf, "o=");     /* optimization */
-        if (opc != NULL) {
-            switch (*(opc+2)) {
-            case 'n':   val = "-Xdexopt:none";      break;
-            case 'v':   val = "-Xdexopt:verified";  break;
-            case 'a':   val = "-Xdexopt:all";       break;
-            case 'f':   val = "-Xdexopt:full";      break;
-            default:    val = NULL;                 break;
-            }
-
-            if (val != NULL) {
-                addOption(val);
-            }
-        }
-
-        opc = strstr(dexoptFlagsBuf, "m=y");    /* register map */
-        if (opc != NULL) {
-            addOption("-Xgenregmap");
-
-            /* turn on precise GC while we're at it */
-            addOption("-Xgc:precise");
-        }
-    }
-
     /* enable debugging; set suspend=y to pause during VM init */
     /* use android ADB transport */
     addOption("-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y");
@@ -733,12 +644,6 @@
                        lockProfThresholdBuf,
                        "-Xlockprofthreshold:");
 
-    /* Force interpreter-only mode for selected opcodes. Eg "1-0a,3c,f1-ff" */
-    parseRuntimeOption("dalvik.vm.jit.op", jitOpBuf, "-Xjitop:");
-
-    /* Force interpreter-only mode for selected methods */
-    parseRuntimeOption("dalvik.vm.jit.method", jitMethodBuf, "-Xjitmethod:");
-
     if (executionMode == kEMIntPortable) {
         addOption("-Xint:portable");
     } else if (executionMode == kEMIntFast) {
@@ -747,64 +652,57 @@
         addOption("-Xint:jit");
     }
 
-    // libart tolerates libdvm flags, but not vice versa, so only pass some options if libart.
-    property_get("persist.sys.dalvik.vm.lib.2", dalvikVmLibBuf, "libart.so");
-    bool libart = (strncmp(dalvikVmLibBuf, "libart", 6) == 0);
+    // If we are booting without the real /data, don't spend time compiling.
+    property_get("vold.decrypt", voldDecryptBuf, "");
+    bool skip_compilation = ((strcmp(voldDecryptBuf, "trigger_restart_min_framework") == 0) ||
+                             (strcmp(voldDecryptBuf, "1") == 0));
 
-    if (libart) {
-        // If we booting without the real /data, don't spend time compiling.
-        property_get("vold.decrypt", voldDecryptBuf, "");
-        bool skip_compilation = ((strcmp(voldDecryptBuf, "trigger_restart_min_framework") == 0) ||
-                                 (strcmp(voldDecryptBuf, "1") == 0));
-
-        // Extra options for boot.art/boot.oat image generation.
-        parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xms", dex2oatXmsImageFlagsBuf,
-                                   "-Xms", "-Ximage-compiler-option");
-        parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xmx", dex2oatXmxImageFlagsBuf,
-                                   "-Xmx", "-Ximage-compiler-option");
-        if (skip_compilation) {
-            addOption("-Ximage-compiler-option");
-            addOption("--compiler-filter=verify-none");
-        } else {
-            parseCompilerOption("dalvik.vm.image-dex2oat-filter", dex2oatImageCompilerFilterBuf,
-                                "--compiler-filter=", "-Ximage-compiler-option");
-        }
-
-        // Make sure there is a preloaded-classes file.
-        if (!hasFile("/system/etc/preloaded-classes")) {
-            ALOGE("Missing preloaded-classes file, /system/etc/preloaded-classes not found: %s\n",
-                  strerror(errno));
-            goto bail;
-        }
+    // Extra options for boot.art/boot.oat image generation.
+    parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xms", dex2oatXmsImageFlagsBuf,
+                               "-Xms", "-Ximage-compiler-option");
+    parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xmx", dex2oatXmxImageFlagsBuf,
+                               "-Xmx", "-Ximage-compiler-option");
+    if (skip_compilation) {
         addOption("-Ximage-compiler-option");
-        addOption("--image-classes=/system/etc/preloaded-classes");
-
-        // If there is a compiled-classes file, push it.
-        if (hasFile("/system/etc/compiled-classes")) {
-            addOption("-Ximage-compiler-option");
-            addOption("--compiled-classes=/system/etc/compiled-classes");
-        }
-
-        property_get("dalvik.vm.image-dex2oat-flags", dex2oatImageFlagsBuf, "");
-        parseExtraOpts(dex2oatImageFlagsBuf, "-Ximage-compiler-option");
-
-        // Extra options for DexClassLoader.
-        parseCompilerRuntimeOption("dalvik.vm.dex2oat-Xms", dex2oatXmsFlagsBuf,
-                                   "-Xms", "-Xcompiler-option");
-        parseCompilerRuntimeOption("dalvik.vm.dex2oat-Xmx", dex2oatXmxFlagsBuf,
-                                   "-Xmx", "-Xcompiler-option");
-        if (skip_compilation) {
-            addOption("-Xcompiler-option");
-            addOption("--compiler-filter=verify-none");
-        } else {
-            parseCompilerOption("dalvik.vm.dex2oat-filter", dex2oatCompilerFilterBuf,
-                                "--compiler-filter=", "-Xcompiler-option");
-        }
-        property_get("dalvik.vm.dex2oat-flags", dex2oatFlagsBuf, "");
-        parseExtraOpts(dex2oatFlagsBuf, "-Xcompiler-option");
-
+        addOption("--compiler-filter=verify-none");
+    } else {
+        parseCompilerOption("dalvik.vm.image-dex2oat-filter", dex2oatImageCompilerFilterBuf,
+                            "--compiler-filter=", "-Ximage-compiler-option");
     }
 
+    // Make sure there is a preloaded-classes file.
+    if (!hasFile("/system/etc/preloaded-classes")) {
+        ALOGE("Missing preloaded-classes file, /system/etc/preloaded-classes not found: %s\n",
+              strerror(errno));
+        goto bail;
+    }
+    addOption("-Ximage-compiler-option");
+    addOption("--image-classes=/system/etc/preloaded-classes");
+
+    // If there is a compiled-classes file, push it.
+    if (hasFile("/system/etc/compiled-classes")) {
+        addOption("-Ximage-compiler-option");
+        addOption("--compiled-classes=/system/etc/compiled-classes");
+    }
+
+    property_get("dalvik.vm.image-dex2oat-flags", dex2oatImageFlagsBuf, "");
+    parseExtraOpts(dex2oatImageFlagsBuf, "-Ximage-compiler-option");
+
+    // Extra options for DexClassLoader.
+    parseCompilerRuntimeOption("dalvik.vm.dex2oat-Xms", dex2oatXmsFlagsBuf,
+                               "-Xms", "-Xcompiler-option");
+    parseCompilerRuntimeOption("dalvik.vm.dex2oat-Xmx", dex2oatXmxFlagsBuf,
+                               "-Xmx", "-Xcompiler-option");
+    if (skip_compilation) {
+        addOption("-Xcompiler-option");
+        addOption("--compiler-filter=verify-none");
+    } else {
+        parseCompilerOption("dalvik.vm.dex2oat-filter", dex2oatCompilerFilterBuf,
+                            "--compiler-filter=", "-Xcompiler-option");
+    }
+    property_get("dalvik.vm.dex2oat-flags", dex2oatFlagsBuf, "");
+    parseExtraOpts(dex2oatFlagsBuf, "-Xcompiler-option");
+
     /* extra options; parse this late so it overrides others */
     property_get("dalvik.vm.extra-opts", extraOptsBuf, "");
     parseExtraOpts(extraOptsBuf, NULL);
@@ -821,67 +719,65 @@
     /*
      * Set profiler options
      */
-    if (libart) {
-        // Whether or not the profiler should be enabled.
-        property_get("dalvik.vm.profiler", propBuf, "0");
-        if (propBuf[0] == '1') {
-            addOption("-Xenable-profiler");
-        }
+    // Whether or not the profiler should be enabled.
+    property_get("dalvik.vm.profiler", propBuf, "0");
+    if (propBuf[0] == '1') {
+        addOption("-Xenable-profiler");
+    }
 
-        // Whether the profile should start upon app startup or be delayed by some random offset
-        // (in seconds) that is bound between 0 and a fixed value.
-        property_get("dalvik.vm.profile.start-immed", propBuf, "0");
-        if (propBuf[0] == '1') {
-            addOption("-Xprofile-start-immediately");
-        }
+    // Whether the profile should start upon app startup or be delayed by some random offset
+    // (in seconds) that is bound between 0 and a fixed value.
+    property_get("dalvik.vm.profile.start-immed", propBuf, "0");
+    if (propBuf[0] == '1') {
+        addOption("-Xprofile-start-immediately");
+    }
 
-        // Number of seconds during profile runs.
-        parseRuntimeOption("dalvik.vm.profile.period-secs", profilePeriod, "-Xprofile-period:");
+    // Number of seconds during profile runs.
+    parseRuntimeOption("dalvik.vm.profile.period-secs", profilePeriod, "-Xprofile-period:");
 
-        // Length of each profile run (seconds).
-        parseRuntimeOption("dalvik.vm.profile.duration-secs",
-                           profileDuration,
-                           "-Xprofile-duration:");
+    // Length of each profile run (seconds).
+    parseRuntimeOption("dalvik.vm.profile.duration-secs",
+                       profileDuration,
+                       "-Xprofile-duration:");
 
-        // Polling interval during profile run (microseconds).
-        parseRuntimeOption("dalvik.vm.profile.interval-us", profileInterval, "-Xprofile-interval:");
+    // Polling interval during profile run (microseconds).
+    parseRuntimeOption("dalvik.vm.profile.interval-us", profileInterval, "-Xprofile-interval:");
 
-        // Coefficient for period backoff.  The the period is multiplied
-        // by this value after each profile run.
-        parseRuntimeOption("dalvik.vm.profile.backoff-coeff", profileBackoff, "-Xprofile-backoff:");
+    // Coefficient for period backoff.  The the period is multiplied
+    // by this value after each profile run.
+    parseRuntimeOption("dalvik.vm.profile.backoff-coeff", profileBackoff, "-Xprofile-backoff:");
 
-        // Top K% of samples that are considered relevant when
-        // deciding if the app should be recompiled.
-        parseRuntimeOption("dalvik.vm.profile.top-k-thr",
-                           profileTopKThreshold,
-                           "-Xprofile-top-k-threshold:");
+    // Top K% of samples that are considered relevant when
+    // deciding if the app should be recompiled.
+    parseRuntimeOption("dalvik.vm.profile.top-k-thr",
+                       profileTopKThreshold,
+                       "-Xprofile-top-k-threshold:");
 
-        // The threshold after which a change in the structure of the
-        // top K% profiled samples becomes significant and triggers
-        // recompilation. A change in profile is considered
-        // significant if X% (top-k-change-threshold) of the top K%
-        // (top-k-threshold property) samples has changed.
-        parseRuntimeOption("dalvik.vm.profile.top-k-ch-thr",
-                           profileTopKChangeThreshold,
-                           "-Xprofile-top-k-change-threshold:");
+    // The threshold after which a change in the structure of the
+    // top K% profiled samples becomes significant and triggers
+    // recompilation. A change in profile is considered
+    // significant if X% (top-k-change-threshold) of the top K%
+    // (top-k-threshold property) samples has changed.
+    parseRuntimeOption("dalvik.vm.profile.top-k-ch-thr",
+                       profileTopKChangeThreshold,
+                       "-Xprofile-top-k-change-threshold:");
 
-        // Type of profile data.
-        parseRuntimeOption("dalvik.vm.profiler.type", profileType, "-Xprofile-type:");
+    // Type of profile data.
+    parseRuntimeOption("dalvik.vm.profiler.type", profileType, "-Xprofile-type:");
 
-        // Depth of bounded stack data
-        parseRuntimeOption("dalvik.vm.profile.stack-depth",
-                           profileMaxStackDepth,
-                           "-Xprofile-max-stack-depth:");
+    // Depth of bounded stack data
+    parseRuntimeOption("dalvik.vm.profile.stack-depth",
+                       profileMaxStackDepth,
+                       "-Xprofile-max-stack-depth:");
 
-        // Native bridge library. "0" means that native bridge is disabled.
-        property_get("ro.dalvik.vm.native.bridge", propBuf, "");
-        if (propBuf[0] == '\0') {
-            ALOGW("ro.dalvik.vm.native.bridge is not expected to be empty");
-        } else if (strcmp(propBuf, "0") != 0) {
-            snprintf(nativeBridgeLibrary, sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX,
-                     "-XX:NativeBridge=%s", propBuf);
-            addOption(nativeBridgeLibrary);
-        }
+    // Native bridge library. "0" means that native bridge is disabled.
+    property_get("ro.dalvik.vm.native.bridge", propBuf, "");
+    if (propBuf[0] == '\0') {
+        ALOGW("ro.dalvik.vm.native.bridge is not expected to be empty");
+    } else if (strcmp(propBuf, "0") != 0) {
+        snprintf(nativeBridgeLibrary, sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX,
+                 "-XX:NativeBridge=%s", propBuf);
+        addOption(nativeBridgeLibrary);
     }
 
     initArgs.version = JNI_VERSION_1_4;
@@ -1321,7 +1217,6 @@
     REG_JNI(register_android_net_NetworkUtils),
     REG_JNI(register_android_net_TrafficStats),
     REG_JNI(register_android_os_MemoryFile),
-    REG_JNI(register_com_android_internal_os_ZygoteInit),
     REG_JNI(register_com_android_internal_os_Zygote),
     REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
     REG_JNI(register_android_hardware_Camera),
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 37f5062..43b8471 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -182,7 +182,7 @@
 
                 if (status == WOULD_BLOCK) {
                     if (kDebugDispatchCycle) {
-                        ALOGD("channel '%s' ~ Sent %u queued finish events; %u left.",
+                        ALOGD("channel '%s' ~ Sent %zu queued finish events; %zu left.",
                                 getInputChannelName(), i, mFinishQueue.size());
                     }
                     return 1; // keep the callback, try again later
@@ -201,7 +201,7 @@
             }
         }
         if (kDebugDispatchCycle) {
-            ALOGD("channel '%s' ~ Sent %u queued finish events; none left.",
+            ALOGD("channel '%s' ~ Sent %zu queued finish events; none left.",
                     getInputChannelName(), mFinishQueue.size());
         }
         mFinishQueue.clear();
@@ -218,7 +218,7 @@
         bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
     if (kDebugDispatchCycle) {
         ALOGD("channel '%s' ~ Consuming input events, consumeBatches=%s, frameTime=%lld.",
-                getInputChannelName(), consumeBatches ? "true" : "false", frameTime);
+                getInputChannelName(), consumeBatches ? "true" : "false", (long long)frameTime);
     }
 
     if (consumeBatches) {
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index e7388cf..265daeb 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -204,7 +204,7 @@
 
             if (kDebugDispatchCycle) {
                 ALOGD("channel '%s' ~ Received finished signal, seq=%u, handled=%s, "
-                        "pendingEvents=%u.",
+                        "pendingEvents=%zu.",
                         getInputChannelName(), seq, handled ? "true" : "false",
                         mPublishedSeqMap.size());
             }
diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp
deleted file mode 100644
index 496f569..0000000
--- a/core/jni/com_android_internal_os_ZygoteInit.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Zygote"
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <utils/misc.h>
-#include <errno.h>
-#include <sys/select.h>
-
-#include "jni.h"
-#include <JNIHelp.h>
-#include "core_jni_helpers.h"
-
-#include <sys/capability.h>
-#include <sys/prctl.h>
-
-namespace android {
-
-/*
- * In class com.android.internal.os.ZygoteInit:
- * private static native boolean setreuid(int ruid, int euid)
- */
-static jint com_android_internal_os_ZygoteInit_setreuid(
-    JNIEnv* env, jobject clazz, jint ruid, jint euid)
-{
-    if (setreuid(ruid, euid) < 0) {
-        return errno;
-    }
-    return 0;
-}
-
-/*
- * In class com.android.internal.os.ZygoteInit:
- * private static native int setregid(int rgid, int egid)
- */
-static jint com_android_internal_os_ZygoteInit_setregid(
-    JNIEnv* env, jobject clazz, jint rgid, jint egid)
-{
-    if (setregid(rgid, egid) < 0) {
-        return errno;
-    }
-    return 0;
-}
-
-/*
- * In class com.android.internal.os.ZygoteInit:
- * private static native int setpgid(int rgid, int egid)
- */
-static jint com_android_internal_os_ZygoteInit_setpgid(
-    JNIEnv* env, jobject clazz, jint pid, jint pgid)
-{
-    if (setpgid(pid, pgid) < 0) {
-        return errno;
-    }
-    return 0;
-}
-
-/*
- * In class com.android.internal.os.ZygoteInit:
- * private static native int getpgid(int pid)
- */
-static jint com_android_internal_os_ZygoteInit_getpgid(
-    JNIEnv* env, jobject clazz, jint pid)
-{
-    pid_t ret;
-    ret = getpgid(pid);
-
-    if (ret < 0) {
-        jniThrowIOException(env, errno);
-    }
-
-    return ret;
-}
-
-static void com_android_internal_os_ZygoteInit_reopenStdio(JNIEnv* env,
-        jobject clazz, jobject in, jobject out, jobject errfd)
-{
-    int fd;
-    int err;
-
-    fd = jniGetFDFromFileDescriptor(env, in);
-
-    if  (env->ExceptionCheck()) {
-        return;
-    }
-
-    do {
-        err = dup2(fd, STDIN_FILENO);
-    } while (err < 0 && errno == EINTR);
-
-    fd = jniGetFDFromFileDescriptor(env, out);
-
-    if  (env->ExceptionCheck()) {
-        return;
-    }
-
-    do {
-        err = dup2(fd, STDOUT_FILENO);
-    } while (err < 0 && errno == EINTR);
-
-    fd = jniGetFDFromFileDescriptor(env, errfd);
-
-    if  (env->ExceptionCheck()) {
-        return;
-    }
-
-    do {
-        err = dup2(fd, STDERR_FILENO);
-    } while (err < 0 && errno == EINTR);
-}
-
-static void com_android_internal_os_ZygoteInit_setCloseOnExec (JNIEnv *env,
-    jobject clazz, jobject descriptor, jboolean flag)
-{
-    int fd;
-    int err;
-    int fdFlags;
-
-    fd = jniGetFDFromFileDescriptor(env, descriptor);
-
-    if  (env->ExceptionCheck()) {
-        return;
-    }
-
-    fdFlags = fcntl(fd, F_GETFD);
-
-    if (fdFlags < 0) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-
-    if (flag) {
-        fdFlags |= FD_CLOEXEC;
-    } else {
-        fdFlags &= ~FD_CLOEXEC;
-    }
-
-    err = fcntl(fd, F_SETFD, fdFlags);
-
-    if (err < 0) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-}
-
-static jint com_android_internal_os_ZygoteInit_selectReadable (
-        JNIEnv *env, jobject clazz, jobjectArray fds)
-{
-    if (fds == NULL) {
-        jniThrowNullPointerException(env, "fds == null");
-        return -1;
-    }
-
-    jsize length = env->GetArrayLength(fds);
-    fd_set fdset;
-
-    if (env->ExceptionCheck()) {
-        return -1;
-    }
-
-    FD_ZERO(&fdset);
-
-    int nfds = 0;
-    for (jsize i = 0; i < length; i++) {
-        jobject fdObj = env->GetObjectArrayElement(fds, i);
-        if  (env->ExceptionCheck()) {
-            return -1;
-        }
-        if (fdObj == NULL) {
-            continue;
-        }
-        int fd = jniGetFDFromFileDescriptor(env, fdObj);
-        if  (env->ExceptionCheck()) {
-            return -1;
-        }
-
-        FD_SET(fd, &fdset);
-
-        if (fd >= nfds) {
-            nfds = fd + 1;
-        }
-    }
-
-    int err;
-    do {
-        err = select (nfds, &fdset, NULL, NULL, NULL);
-    } while (err < 0 && errno == EINTR);
-
-    if (err < 0) {
-        jniThrowIOException(env, errno);
-        return -1;
-    }
-
-    for (jsize i = 0; i < length; i++) {
-        jobject fdObj = env->GetObjectArrayElement(fds, i);
-        if  (env->ExceptionCheck()) {
-            return -1;
-        }
-        if (fdObj == NULL) {
-            continue;
-        }
-        int fd = jniGetFDFromFileDescriptor(env, fdObj);
-        if  (env->ExceptionCheck()) {
-            return -1;
-        }
-        if (FD_ISSET(fd, &fdset)) {
-            return (jint)i;
-        }
-    }
-    return -1;
-}
-
-static jobject com_android_internal_os_ZygoteInit_createFileDescriptor (
-        JNIEnv *env, jobject clazz, jint fd)
-{
-    return jniCreateFileDescriptor(env, fd);
-}
-
-/*
- * JNI registration.
- */
-static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    { "setreuid", "(II)I",
-      (void*) com_android_internal_os_ZygoteInit_setreuid },
-    { "setregid", "(II)I",
-      (void*) com_android_internal_os_ZygoteInit_setregid },
-    { "setpgid", "(II)I",
-      (void *) com_android_internal_os_ZygoteInit_setpgid },
-    { "getpgid", "(I)I",
-      (void *) com_android_internal_os_ZygoteInit_getpgid },
-    { "reopenStdio",
-        "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;"
-        "Ljava/io/FileDescriptor;)V",
-            (void *) com_android_internal_os_ZygoteInit_reopenStdio},
-    { "setCloseOnExec", "(Ljava/io/FileDescriptor;Z)V",
-        (void *)  com_android_internal_os_ZygoteInit_setCloseOnExec},
-    { "selectReadable", "([Ljava/io/FileDescriptor;)I",
-        (void *) com_android_internal_os_ZygoteInit_selectReadable },
-    { "createFileDescriptor", "(I)Ljava/io/FileDescriptor;",
-        (void *) com_android_internal_os_ZygoteInit_createFileDescriptor }
-};
-int register_com_android_internal_os_ZygoteInit(JNIEnv* env)
-{
-    return RegisterMethodsOrDie(env,
-            "com/android/internal/os/ZygoteInit", gMethods, NELEM(gMethods));
-}
-
-}; // namespace android
diff --git a/core/tests/coretests/src/android/os/SELinuxTest.java b/core/tests/coretests/src/android/os/SELinuxTest.java
deleted file mode 100644
index 9b63a6b..0000000
--- a/core/tests/coretests/src/android/os/SELinuxTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package android.os;
-
-import android.os.Process;
-import android.os.SELinux;
-import android.test.AndroidTestCase;
-import static junit.framework.Assert.assertEquals;
-
-public class SELinuxTest extends AndroidTestCase {
-
-    public void testgetFileCon() {
-        if(SELinux.isSELinuxEnabled() == false)
-            return;
-
-        String ctx = SELinux.getFileContext("/system/bin/toolbox");
-        assertEquals(ctx, "u:object_r:system_file:s0");
-    }
-
-    public void testgetCon() {
-        if(SELinux.isSELinuxEnabled() == false)
-            return;
-
-        String mycon = SELinux.getContext();
-        assertEquals(mycon, "u:r:untrusted_app:s0:c33");
-    }
-
-    public void testgetPidCon() {
-        if(SELinux.isSELinuxEnabled() == false)
-            return;
-
-        String mycon = SELinux.getPidContext(Process.myPid());
-        assertEquals(mycon, "u:r:untrusted_app:s0:c33");
-    }
-
-    public void testcheckSELinuxAccess() {
-        if(SELinux.isSELinuxEnabled() == false)
-            return;
-
-        String mycon = SELinux.getContext();
-        boolean ret;
-        ret = SELinux.checkSELinuxAccess(mycon, mycon, "process", "fork");
-        assertEquals(ret,"true");
-        ret = SELinux.checkSELinuxAccess(mycon, mycon, "memprotect", "mmap_zero");
-        assertEquals(ret,"true");
-    }
-}
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index 52e9910..c0795b6 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -93,7 +93,7 @@
         env->GetByteArrayRegion(byteArrayObj, 0, size, (jbyte*) buffer);
         env->DeleteLocalRef(byteArrayObj);
         if (env->ExceptionCheck()) {
-            ALOGW("Exception occurred while reading %zu at %lld", size, offset);
+            ALOGW("Exception occurred while reading %zu at %lld", size, (long long)offset);
             LOGW_EX(env);
             env->ExceptionClear();
             return -1;
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index dae6d3b..fc7931e 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -228,7 +228,7 @@
 
 static jobject android_media_MediaMetadataRetriever_getFrameAtTime(JNIEnv *env, jobject thiz, jlong timeUs, jint option)
 {
-    ALOGV("getFrameAtTime: %lld us option: %d", timeUs, option);
+    ALOGV("getFrameAtTime: %lld us option: %d", (long long)timeUs, option);
     MediaMetadataRetriever* retriever = getRetriever(env, thiz);
     if (retriever == 0) {
         jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp
index f234a1b..ecb2ac8 100644
--- a/media/jni/android_media_MediaMuxer.cpp
+++ b/media/jni/android_media_MediaMuxer.cpp
@@ -107,7 +107,7 @@
 
     if (dstSize < (offset + size)) {
         ALOGE("writeSampleData saw wrong dstSize %lld, size  %d, offset %d",
-              dstSize, size, offset);
+              (long long)dstSize, size, offset);
         if (byteArray != NULL) {
             env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0);
         }
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index ab8b4b8..914b8a6 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -305,7 +305,7 @@
 android_media_MediaRecorder_setMaxFileSize(
         JNIEnv *env, jobject thiz, jlong max_filesize_bytes)
 {
-    ALOGV("setMaxFileSize(%lld)", max_filesize_bytes);
+    ALOGV("setMaxFileSize(%lld)", (long long)max_filesize_bytes);
     sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
 
     char params[64];
diff --git a/media/mca/filterfw/Android.mk b/media/mca/filterfw/Android.mk
index a63d635..334f4e2 100644
--- a/media/mca/filterfw/Android.mk
+++ b/media/mca/filterfw/Android.mk
@@ -43,10 +43,4 @@
                           libjnigraphics \
                           libmedia
 
-# Don't prelink this library.  For more efficient code, you may want
-# to add this library to the prelink map and set this to true. However,
-# it's difficult to do this for applications that are not supplied as
-# part of a system image.
-LOCAL_PRELINK_MODULE := false
-
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/mca/filterfw/jni/Android.mk b/media/mca/filterfw/jni/Android.mk
index 4ae32ac..cba4e7e 100644
--- a/media/mca/filterfw/jni/Android.mk
+++ b/media/mca/filterfw/jni/Android.mk
@@ -41,13 +41,6 @@
     $(JNI_H_INCLUDE) \
     $(LOCAL_PATH)/..
 
-# Don't prelink this library.  For more efficient code, you may want
-# to add this library to the prelink map and set this to true. However,
-# it's difficult to do this for applications that are not supplied as
-# part of a system image.
-LOCAL_PRELINK_MODULE := false
-
 LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code -Wno-unused-parameter
 
 include $(BUILD_STATIC_LIBRARY)
-
diff --git a/media/mca/filterfw/native/core/shader_program.cpp b/media/mca/filterfw/native/core/shader_program.cpp
index f1ea7ed..1e573fb 100644
--- a/media/mca/filterfw/native/core/shader_program.cpp
+++ b/media/mca/filterfw/native/core/shader_program.cpp
@@ -315,7 +315,7 @@
       size_t next_pos = 0;
       size_t line_number = 1;
       while ( (next_pos = src.find_first_of('\n', cur_pos)) != std::string::npos) {
-        ALOGE("%03d : %s", line_number, src.substr(cur_pos, next_pos-cur_pos).c_str());
+        ALOGE("%03zd : %s", line_number, src.substr(cur_pos, next_pos-cur_pos).c_str());
         cur_pos = next_pos + 1;
         line_number++;
       }
@@ -435,7 +435,7 @@
     if (tex_var >= 0) {
       glUniform1i(tex_var, i);
     } else {
-      ALOGE("ShaderProgram: Shader does not seem to support %d number of "
+      ALOGE("ShaderProgram: Shader does not seem to support %zd number of "
            "inputs! Missing uniform 'tex_sampler_%d'!", textures.size(), i);
       return false;
     }
diff --git a/media/mca/filterpacks/Android.mk b/media/mca/filterpacks/Android.mk
index 7e8661f..0ff7658 100644
--- a/media/mca/filterpacks/Android.mk
+++ b/media/mca/filterpacks/Android.mk
@@ -48,8 +48,6 @@
 
 LOCAL_SHARED_LIBRARIES := liblog libutils libfilterfw
 
-LOCAL_PRELINK_MODULE := false
-
 LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index ccc700d..1502829 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -5797,6 +5797,7 @@
         if (denyTransientStatus || denyTransientNav) {
             // clear the clearable flags instead
             clearClearableFlagsLw();
+            vis &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
         }
 
         vis = mStatusBarController.updateVisibilityLw(transientStatusBarAllowed, oldVis, vis);
diff --git a/preloaded-classes b/preloaded-classes
index 7686431..dee84f0 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -2631,7 +2631,6 @@
 javax.microedition.khronos.opengles.GL11ExtensionPack
 javax.net.DefaultSocketFactory
 javax.net.SocketFactory
-javax.net.ssl.DefaultHostnameVerifier
 javax.net.ssl.DistinguishedNameParser
 javax.net.ssl.HostnameVerifier
 javax.net.ssl.HttpsURLConnection
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 2ee4ff2..114042d 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -1146,6 +1146,13 @@
             mApplicationContext = ctx.getApplicationContext();
         }
         mRWLock = new ReentrantReadWriteLock();
+        try {
+            registerNativeAllocation.invoke(sRuntime, 4 * 1024 * 1024); // 4MB for GC sake
+        } catch (Exception e) {
+            Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
+            throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
+        }
+
     }
 
     /**
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 8b524dd..0c555c5 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1587,7 +1587,7 @@
         if (mLastAlarmDeliveryTime <= 0) {
             return false;
         }
-        if (mPendingNonWakeupAlarms.size() > 0 && mNextNonWakeupDeliveryTime > nowELAPSED) {
+        if (mPendingNonWakeupAlarms.size() > 0 && mNextNonWakeupDeliveryTime < nowELAPSED) {
             // This is just a little paranoia, if somehow we have pending non-wakeup alarms
             // and the next delivery time is in the past, then just deliver them all.  This
             // avoids bugs where we get stuck in a loop trying to poll for alarms.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 79f2e7c..e3f7fb3 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4874,9 +4874,11 @@
             stats.noteProcessDiedLocked(app.info.uid, pid);
         }
 
-        Process.killProcessQuiet(pid);
-        Process.killProcessGroup(app.info.uid, pid);
-        app.killed = true;
+        if (!app.killed) {
+            Process.killProcessQuiet(pid);
+            Process.killProcessGroup(app.info.uid, pid);
+            app.killed = true;
+        }
 
         // Clean up already done if the process has been re-started.
         if (app.pid == pid && app.thread != null &&
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index df4bf28..c03dbc2 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1595,6 +1595,7 @@
         mStackSupervisor.mGoingToSleepActivities.remove(next);
         next.sleeping = false;
         mStackSupervisor.mWaitingVisibleActivities.remove(next);
+        next.waitingVisible = false;
 
         if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next);
 
@@ -2269,7 +2270,7 @@
                     // In this case, we want to finish this activity
                     // and everything above it, so be sneaky and pretend
                     // like these are all in the reply chain.
-                    end = numActivities - 1;
+                    end = activities.size() - 1;
                 } else if (replyChainEnd < 0) {
                     end = i;
                 } else {
@@ -2807,6 +2808,7 @@
         mStackSupervisor.mStoppingActivities.remove(r);
         mStackSupervisor.mGoingToSleepActivities.remove(r);
         mStackSupervisor.mWaitingVisibleActivities.remove(r);
+        r.waitingVisible = false;
         if (mResumedActivity == r) {
             mResumedActivity = null;
         }
@@ -3007,6 +3009,7 @@
         // down to the max limit while they are still waiting to finish.
         mStackSupervisor.mFinishingActivities.remove(r);
         mStackSupervisor.mWaitingVisibleActivities.remove(r);
+        r.waitingVisible = false;
 
         // Remove any pending results.
         if (r.finishing && r.pendingResults != null) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 03dd3c0..6f5866a 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1315,7 +1315,6 @@
                 }
             }
         }
-        ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
 
         final int launchFlags = intent.getFlags();
 
@@ -1392,6 +1391,8 @@
             }
         }
 
+        final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
+
         if (err != ActivityManager.START_SUCCESS) {
             if (resultRecord != null) {
                 resultStack.sendActivityResultLocked(-1,
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index bffb541..c5f63f1 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -445,14 +445,14 @@
         mAm.mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.PACKAGE_USAGE_STATS, null);
         Parcel current = Parcel.obtain();
+        synchronized (mAm) {
+            long now = SystemClock.uptimeMillis();
+            mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
+            mProcessStats.mTimePeriodEndUptime = now;
+            mProcessStats.writeToParcel(current, now, 0);
+        }
         mWriteLock.lock();
         try {
-            synchronized (mAm) {
-                long now = SystemClock.uptimeMillis();
-                mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
-                mProcessStats.mTimePeriodEndUptime = now;
-                mProcessStats.writeToParcel(current, now, 0);
-            }
             if (historic != null) {
                 ArrayList<String> files = getCommittedFiles(0, false, true);
                 if (files != null) {
@@ -476,18 +476,18 @@
     public ParcelFileDescriptor getStatsOverTime(long minTime) {
         mAm.mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.PACKAGE_USAGE_STATS, null);
+        Parcel current = Parcel.obtain();
+        long curTime;
+        synchronized (mAm) {
+            long now = SystemClock.uptimeMillis();
+            mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
+            mProcessStats.mTimePeriodEndUptime = now;
+            mProcessStats.writeToParcel(current, now, 0);
+            curTime = mProcessStats.mTimePeriodEndRealtime
+                    - mProcessStats.mTimePeriodStartRealtime;
+        }
         mWriteLock.lock();
         try {
-            Parcel current = Parcel.obtain();
-            long curTime;
-            synchronized (mAm) {
-                long now = SystemClock.uptimeMillis();
-                mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
-                mProcessStats.mTimePeriodEndUptime = now;
-                mProcessStats.writeToParcel(current, now, 0);
-                curTime = mProcessStats.mTimePeriodEndRealtime
-                        - mProcessStats.mTimePeriodStartRealtime;
-            }
             if (curTime < minTime) {
                 // Need to add in older stats to reach desired time.
                 ArrayList<String> files = getCommittedFiles(0, false, true);
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index 98f2997..95ed7bc 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -35,13 +35,22 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 /**
- * Centralized access to SELinux MMAC (middleware MAC) implementation.
+ * Centralized access to SELinux MMAC (middleware MAC) implementation. This
+ * class is responsible for loading the appropriate mac_permissions.xml file
+ * as well as providing an interface for assigning seinfo values to apks.
+ *
  * {@hide}
  */
 public final class SELinuxMMAC {
@@ -51,11 +60,9 @@
     private static final boolean DEBUG_POLICY = false;
     private static final boolean DEBUG_POLICY_INSTALL = DEBUG_POLICY || false;
 
-    // Signature seinfo values read from policy.
-    private static HashMap<Signature, Policy> sSigSeinfo = new HashMap<Signature, Policy>();
-
-    // Default seinfo read from policy.
-    private static String sDefaultSeinfo = null;
+    // All policy stanzas read from mac_permissions.xml. This is also the lock
+    // to synchronize access during policy load and access attempts.
+    private static final List<Policy> sPolicies = new ArrayList<Policy>();
 
     // Data policy override version file.
     private static final String DATA_VERSION_FILE =
@@ -94,293 +101,289 @@
     private static final String SEAPP_HASH_FILE =
             Environment.getDataDirectory().toString() + "/system/seapp_hash";
 
-
-    // Signature policy stanzas
-    static class Policy {
-        private String seinfo;
-        private final HashMap<String, String> pkgMap;
-
-        Policy() {
-            seinfo = null;
-            pkgMap = new HashMap<String, String>();
-        }
-
-        void putSeinfo(String seinfoValue) {
-            seinfo = seinfoValue;
-        }
-
-        void putPkg(String pkg, String seinfoValue) {
-            pkgMap.put(pkg, seinfoValue);
-        }
-
-        // Valid policy stanza means there exists a global
-        // seinfo value or at least one package policy.
-        boolean isValid() {
-            return (seinfo != null) || (!pkgMap.isEmpty());
-        }
-
-        String checkPolicy(String pkgName) {
-            // Check for package name seinfo value first.
-            String seinfoValue = pkgMap.get(pkgName);
-            if (seinfoValue != null) {
-                return seinfoValue;
-            }
-
-            // Return the global seinfo value.
-            return seinfo;
-        }
-    }
-
-    private static void flushInstallPolicy() {
-        sSigSeinfo.clear();
-        sDefaultSeinfo = null;
-    }
-
+    /**
+     * Load the mac_permissions.xml file containing all seinfo assignments used to
+     * label apps. The loaded mac_permissions.xml file is determined by the
+     * MAC_PERMISSIONS class variable which is set at class load time which itself
+     * is based on the USE_OVERRIDE_POLICY class variable. For further guidance on
+     * the proper structure of a mac_permissions.xml file consult the source code
+     * located at external/sepolicy/mac_permissions.xml.
+     *
+     * @return boolean indicating if policy was correctly loaded. A value of false
+     *         typically indicates a structural problem with the xml or incorrectly
+     *         constructed policy stanzas. A value of true means that all stanzas
+     *         were loaded successfully; no partial loading is possible.
+     */
     public static boolean readInstallPolicy() {
-        return readInstallPolicy(MAC_PERMISSIONS);
-    }
+        // Temp structure to hold the rules while we parse the xml file. We add
+        // all the rules once we know there's no problems.
+        List<Policy> policies = new ArrayList<>();
 
-    public static boolean readInstallPolicy(String macPermsPath) {
-        if (macPermsPath == null) {
-            throw new NullPointerException("mac_permissions.xml file path is null");
-        }
+        // A separate structure to hold the default stanza. We need to add this to
+        // the end of the policies list structure.
+        Policy defaultPolicy = null;
 
-        // Temp structures to hold the rules while we parse the xml file.
-        // We add all the rules together once we know there's no structural problems.
-        HashMap<Signature, Policy> sigSeinfo = new HashMap<Signature, Policy>();
-        String defaultSeinfo = null;
+        // Track sets of known policy certs so we can enforce rules across stanzas.
+        Set<Set<Signature>> knownCerts = new HashSet<>();
 
         FileReader policyFile = null;
+        XmlPullParser parser = Xml.newPullParser();
         try {
-            policyFile = new FileReader(macPermsPath);
-            Slog.d(TAG, "Using policy file " + macPermsPath);
+            policyFile = new FileReader(MAC_PERMISSIONS);
+            Slog.d(TAG, "Using policy file " + MAC_PERMISSIONS);
 
-            XmlPullParser parser = Xml.newPullParser();
             parser.setInput(policyFile);
+            parser.nextTag();
+            parser.require(XmlPullParser.START_TAG, null, "policy");
 
-            XmlUtils.beginDocument(parser, "policy");
-            while (true) {
-                XmlUtils.nextElement(parser);
-                if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
-                    break;
+            while (parser.next() != XmlPullParser.END_TAG) {
+                if (parser.getEventType() != XmlPullParser.START_TAG) {
+                    continue;
                 }
 
                 String tagName = parser.getName();
                 if ("signer".equals(tagName)) {
-                    String cert = parser.getAttributeValue(null, "signature");
-                    if (cert == null) {
-                        Slog.w(TAG, "<signer> without signature at "
-                               + parser.getPositionDescription());
-                        XmlUtils.skipCurrentTag(parser);
-                        continue;
+                    Policy signerPolicy = readSignerOrThrow(parser);
+                    // Return of a Policy instance ensures certain invariants have
+                    // passed, however, we still want to do some cross policy checking.
+                    // Thus, check that we haven't seen the certs in another stanza.
+                    Set<Signature> certs = signerPolicy.getSignatures();
+                    if (knownCerts.contains(certs)) {
+                        String msg = "Separate stanzas have identical certs";
+                        throw new IllegalStateException(msg);
                     }
-                    Signature signature;
-                    try {
-                        signature = new Signature(cert);
-                    } catch (IllegalArgumentException e) {
-                        Slog.w(TAG, "<signer> with bad signature at "
-                               + parser.getPositionDescription(), e);
-                        XmlUtils.skipCurrentTag(parser);
-                        continue;
-                    }
-                    Policy policy = readPolicyTags(parser);
-                    if (policy.isValid()) {
-                        sigSeinfo.put(signature, policy);
-                    }
+                    knownCerts.add(certs);
+                    policies.add(signerPolicy);
                 } else if ("default".equals(tagName)) {
-                    // Value is null if default tag is absent or seinfo tag is malformed.
-                    defaultSeinfo = readSeinfoTag(parser);
-                    if (DEBUG_POLICY_INSTALL)
-                        Slog.i(TAG, "<default> tag assigned seinfo=" + defaultSeinfo);
-
+                    Policy defPolicy = readDefaultOrThrow(parser);
+                    // Return of a Policy instance ensures certain invariants have
+                    // passed, however, we still want to do some cross policy checking.
+                    // Thus, check that we haven't already seen a default stanza.
+                    if (defaultPolicy != null) {
+                        String msg = "Multiple default stanzas identified";
+                        throw new IllegalStateException(msg);
+                    }
+                    defaultPolicy = defPolicy;
                 } else {
-                    XmlUtils.skipCurrentTag(parser);
+                    skip(parser);
                 }
             }
-        } catch (XmlPullParserException xpe) {
-            Slog.w(TAG, "Got exception parsing " + macPermsPath, xpe);
+        } catch (IllegalStateException | IllegalArgumentException |
+                XmlPullParserException ex) {
+            StringBuilder sb = new StringBuilder("Exception @");
+            sb.append(parser.getPositionDescription());
+            sb.append(" while parsing ");
+            sb.append(MAC_PERMISSIONS);
+            sb.append(":");
+            sb.append(ex);
+            Slog.w(TAG, sb.toString());
             return false;
         } catch (IOException ioe) {
-            Slog.w(TAG, "Got exception parsing " + macPermsPath, ioe);
+            Slog.w(TAG, "Exception parsing " + MAC_PERMISSIONS, ioe);
             return false;
         } finally {
             IoUtils.closeQuietly(policyFile);
         }
 
-        flushInstallPolicy();
-        sSigSeinfo = sigSeinfo;
-        sDefaultSeinfo = defaultSeinfo;
+        // Add the default policy to the end if there is one. This will ensure that
+        // the default stanza is consulted last when performing policy lookups.
+        if (defaultPolicy != null) {
+            policies.add(defaultPolicy);
+        }
+
+        synchronized (sPolicies) {
+            sPolicies.clear();
+            sPolicies.addAll(policies);
+        }
 
         return true;
     }
 
-    private static Policy readPolicyTags(XmlPullParser parser) throws
-            IOException, XmlPullParserException {
+    /**
+     * Loop over a signer tag looking for seinfo, package and cert tags. A {@link Policy}
+     * instance will be created and returned in the process. During the pass all other
+     * tag elements will be skipped.
+     *
+     * @param parser an XmlPullParser object representing a signer element.
+     * @return the constructed {@link Policy} instance
+     * @throws IOException
+     * @throws XmlPullParserException
+     * @throws IllegalArgumentException if any of the validation checks fail while
+     *         parsing tag values.
+     * @throws IllegalStateException if any of the invariants fail when constructing
+     *         the {@link Policy} instance.
+     */
+    private static Policy readSignerOrThrow(XmlPullParser parser) throws IOException,
+            XmlPullParserException {
 
-        int type;
-        int outerDepth = parser.getDepth();
-        Policy policy = new Policy();
-        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
-               && (type != XmlPullParser.END_TAG
-                   || parser.getDepth() > outerDepth)) {
-            if (type == XmlPullParser.END_TAG
-                || type == XmlPullParser.TEXT) {
+        parser.require(XmlPullParser.START_TAG, null, "signer");
+        Policy.PolicyBuilder pb = new Policy.PolicyBuilder();
+
+        // Check for a cert attached to the signer tag. We allow a signature
+        // to appear as an attribute as well as those attached to cert tags.
+        String cert = parser.getAttributeValue(null, "signature");
+        if (cert != null) {
+            pb.addSignature(cert);
+        }
+
+        while (parser.next() != XmlPullParser.END_TAG) {
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
                 continue;
             }
 
             String tagName = parser.getName();
             if ("seinfo".equals(tagName)) {
-                String seinfo = parseSeinfo(parser);
-                if (seinfo != null) {
-                    policy.putSeinfo(seinfo);
-                }
-                XmlUtils.skipCurrentTag(parser);
+                String seinfo = parser.getAttributeValue(null, "value");
+                pb.setGlobalSeinfoOrThrow(seinfo);
+                readSeinfo(parser);
             } else if ("package".equals(tagName)) {
-                String pkg = parser.getAttributeValue(null, "name");
-                if (!validatePackageName(pkg)) {
-                    Slog.w(TAG, "<package> without valid name at "
-                           + parser.getPositionDescription());
-                    XmlUtils.skipCurrentTag(parser);
-                    continue;
-                }
-
-                String seinfo = readSeinfoTag(parser);
-                if (seinfo != null) {
-                    policy.putPkg(pkg, seinfo);
-                }
+                readPackageOrThrow(parser, pb);
+            } else if ("cert".equals(tagName)) {
+                String sig = parser.getAttributeValue(null, "signature");
+                pb.addSignature(sig);
+                readCert(parser);
             } else {
-                XmlUtils.skipCurrentTag(parser);
+                skip(parser);
             }
         }
-        return policy;
+
+        return pb.build();
     }
 
-    private static String readSeinfoTag(XmlPullParser parser) throws
-            IOException, XmlPullParserException {
+    /**
+     * Loop over a default element looking for seinfo child tags. A {@link Policy}
+     * instance will be created and returned in the process. All other tags encountered
+     * will be skipped.
+     *
+     * @param parser an XmlPullParser object representing a default element.
+     * @return the constructed {@link Policy} instance
+     * @throws IOException
+     * @throws XmlPullParserException
+     * @throws IllegalArgumentException if any of the validation checks fail while
+     *         parsing tag values.
+     * @throws IllegalStateException if any of the invariants fail when constructing
+     *         the {@link Policy} instance.
+     */
+    private static Policy readDefaultOrThrow(XmlPullParser parser) throws IOException,
+            XmlPullParserException {
 
-        int type;
-        int outerDepth = parser.getDepth();
-        String seinfo = null;
-        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
-               && (type != XmlPullParser.END_TAG
-                   || parser.getDepth() > outerDepth)) {
-            if (type == XmlPullParser.END_TAG
-                || type == XmlPullParser.TEXT) {
+        parser.require(XmlPullParser.START_TAG, null, "default");
+        Policy.PolicyBuilder pb = new Policy.PolicyBuilder();
+        pb.setAsDefaultPolicy();
+
+        while (parser.next() != XmlPullParser.END_TAG) {
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
                 continue;
             }
 
             String tagName = parser.getName();
             if ("seinfo".equals(tagName)) {
-                seinfo = parseSeinfo(parser);
+                String seinfo = parser.getAttributeValue(null, "value");
+                pb.setGlobalSeinfoOrThrow(seinfo);
+                readSeinfo(parser);
+            } else {
+                skip(parser);
             }
-            XmlUtils.skipCurrentTag(parser);
         }
-        return seinfo;
-    }
 
-    private static String parseSeinfo(XmlPullParser parser) {
-
-        String seinfoValue = parser.getAttributeValue(null, "value");
-        if (!validateValue(seinfoValue)) {
-            Slog.w(TAG, "<seinfo> without valid value at "
-                   + parser.getPositionDescription());
-            seinfoValue = null;
-        }
-        return seinfoValue;
+        return pb.build();
     }
 
     /**
-     * General validation routine for package names.
-     * Returns a boolean indicating if the passed string
-     * is a valid android package name.
+     * Loop over a package element looking for seinfo child tags. If found return the
+     * value attribute of the seinfo tag, otherwise return null. All other tags encountered
+     * will be skipped.
+     *
+     * @param parser an XmlPullParser object representing a package element.
+     * @param pb a Policy.PolicyBuilder instance to build
+     * @throws IOException
+     * @throws XmlPullParserException
+     * @throws IllegalArgumentException if any of the validation checks fail while
+     *         parsing tag values.
+     * @throws IllegalStateException if there is a duplicate seinfo tag for the current
+     *         package tag.
      */
-    private static boolean validatePackageName(String name) {
-        if (name == null)
-            return false;
+    private static void readPackageOrThrow(XmlPullParser parser, Policy.PolicyBuilder pb) throws
+            IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, null, "package");
+        String pkgName = parser.getAttributeValue(null, "name");
 
-        final int N = name.length();
-        boolean hasSep = false;
-        boolean front = true;
-        for (int i=0; i<N; i++) {
-            final char c = name.charAt(i);
-            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
-                front = false;
+        while (parser.next() != XmlPullParser.END_TAG) {
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
                 continue;
             }
-            if (!front) {
-                if ((c >= '0' && c <= '9') || c == '_') {
-                    continue;
-                }
+
+            String tagName = parser.getName();
+            if ("seinfo".equals(tagName)) {
+                String seinfo = parser.getAttributeValue(null, "value");
+                pb.addInnerPackageMapOrThrow(pkgName, seinfo);
+                readSeinfo(parser);
+            } else {
+                skip(parser);
             }
-            if (c == '.') {
-                hasSep = true;
-                front = true;
-                continue;
-            }
-            return false;
         }
-        return hasSep;
+    }
+
+    private static void readCert(XmlPullParser parser) throws IOException,
+            XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, null, "cert");
+        parser.nextTag();
+    }
+
+    private static void readSeinfo(XmlPullParser parser) throws IOException,
+            XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, null, "seinfo");
+        parser.nextTag();
+    }
+
+    private static void skip(XmlPullParser p) throws IOException, XmlPullParserException {
+        if (p.getEventType() != XmlPullParser.START_TAG) {
+            throw new IllegalStateException();
+        }
+        int depth = 1;
+        while (depth != 0) {
+            switch (p.next()) {
+            case XmlPullParser.END_TAG:
+                depth--;
+                break;
+            case XmlPullParser.START_TAG:
+                depth++;
+                break;
+            }
+        }
     }
 
     /**
-     * General validation routine for tag values.
-     * Returns a boolean indicating if the passed string
-     * contains only letters or underscores.
-     */
-    private static boolean validateValue(String name) {
-        if (name == null)
-            return false;
-
-        final int N = name.length();
-        if (N == 0)
-            return false;
-
-        for (int i = 0; i < N; i++) {
-            final char c = name.charAt(i);
-            if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c != '_')) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Labels a package based on an seinfo tag from install policy.
-     * The label is attached to the ApplicationInfo instance of the package.
+     * Applies a security label to a package based on an seinfo tag taken from a matched
+     * policy. All signature based policy stanzas are consulted first and, if no match
+     * is found, the default policy stanza is then consulted. The security label is
+     * attached to the ApplicationInfo instance of the package in the event that a matching
+     * policy was found.
+     *
      * @param pkg object representing the package to be labeled.
-     * @return boolean which determines whether a non null seinfo label
-     *         was assigned to the package. A null value simply meaning that
-     *         no policy matched.
+     * @return boolean which determines whether a non null seinfo label was assigned
+     *         to the package. A null value simply represents that no policy matched.
      */
     public static boolean assignSeinfoValue(PackageParser.Package pkg) {
-
-        // We just want one of the signatures to match.
-        for (Signature s : pkg.mSignatures) {
-            if (s == null)
-                continue;
-
-            Policy policy = sSigSeinfo.get(s);
-            if (policy != null) {
-                String seinfo = policy.checkPolicy(pkg.packageName);
+        synchronized (sPolicies) {
+            for (Policy policy : sPolicies) {
+                String seinfo = policy.getMatchedSeinfo(pkg);
                 if (seinfo != null) {
                     pkg.applicationInfo.seinfo = seinfo;
-                    if (DEBUG_POLICY_INSTALL)
-                        Slog.i(TAG, "package (" + pkg.packageName +
-                               ") labeled with seinfo=" + seinfo);
-
+                    if (DEBUG_POLICY_INSTALL) {
+                        Slog.i(TAG, "package (" + pkg.packageName + ") labeled with " +
+                               "seinfo=" + seinfo);
+                    }
                     return true;
                 }
             }
         }
 
-        // If we have a default seinfo value then great, otherwise
-        // we set a null object and that is what we started with.
-        pkg.applicationInfo.seinfo = sDefaultSeinfo;
-        if (DEBUG_POLICY_INSTALL)
-            Slog.i(TAG, "package (" + pkg.packageName + ") labeled with seinfo="
-                   + (sDefaultSeinfo == null ? "null" : sDefaultSeinfo));
-
-        return (sDefaultSeinfo != null);
+        if (DEBUG_POLICY_INSTALL) {
+            Slog.i(TAG, "package (" + pkg.packageName + ") doesn't match any policy; " +
+                   "seinfo will remain null");
+        }
+        return false;
     }
 
     /**
@@ -485,3 +488,312 @@
         return false;
     }
 }
+
+/**
+ * Holds valid policy representations of individual stanzas from a mac_permissions.xml
+ * file. Each instance can further be used to assign seinfo values to apks using the
+ * {@link Policy#getMatchedSeinfo} method. To create an instance of this use the
+ * {@link PolicyBuilder} pattern class, where each instance is validated against a set
+ * of invariants before being built and returned. Each instance can be guaranteed to
+ * hold one valid policy stanza as outlined in the external/sepolicy/mac_permissions.xml
+ * file.
+ * </p>
+ * The following is an example of how to use {@link Policy.PolicyBuilder} to create a
+ * signer based Policy instance.
+ * </p>
+ * <pre>
+ * {@code
+ * Policy policy = new Policy.PolicyBuilder()
+ *         .addSignature("308204a8...")
+ *         .addSignature("483538c8...")
+ *         .setGlobalSeinfoOrThrow("paltform")
+ *         .addInnerPackageMapOrThrow("com.foo.", "bar")
+ *         .addInnerPackageMapOrThrow("com.foo.other", "bar")
+ *         .build();
+ * }
+ * </pre>
+ * <p>
+ * An example of how to use {@link Policy.PolicyBuilder} to create a default based Policy
+ * instance.
+ * </p>
+ * <pre>
+ * {@code
+ * Policy policy = new Policy.PolicyBuilder()
+ *         .setAsDefaultPolicy()
+ *         .setGlobalSeinfoOrThrow("defualt")
+ *         .build();
+ * }
+ * </pre>
+ */
+final class Policy {
+
+    private final String mSeinfo;
+    private final boolean mDefaultStanza;
+    private final Set<Signature> mCerts;
+    private final Map<String, String> mPkgMap;
+
+    // Use the PolicyBuilder pattern to instantiate
+    private Policy(PolicyBuilder builder) {
+        mSeinfo = builder.mSeinfo;
+        mDefaultStanza = builder.mDefaultStanza;
+        mCerts = Collections.unmodifiableSet(builder.mCerts);
+        mPkgMap = Collections.unmodifiableMap(builder.mPkgMap);
+    }
+
+    /**
+     * Return all the certs stored with this policy stanza.
+     *
+     * @return A set of Signature objects representing all the certs stored
+     *         with the policy.
+     */
+    public Set<Signature> getSignatures() {
+        return mCerts;
+    }
+
+    /**
+     * <p>
+     * Determine the seinfo value to assign to an apk. The appropriate seinfo value
+     * is determined using the following steps:
+     * </p>
+     * <ul>
+     *   <li> If this Policy instance is defined as a default stanza:
+     *       <ul><li>Return the global seinfo value</li></ul>
+     *   </li>
+     *   <li> If this Policy instance is defined as a signer stanza:
+     *     <ul>
+     *       <li> All certs used to sign the apk and all certs stored with this policy
+     *         instance are tested for set equality. If this fails then null is returned.
+     *       </li>
+     *       <li> If all certs match then an appropriate inner package stanza is
+     *         searched based on package name alone. If matched, the stored seinfo
+     *         value for that mapping is returned.
+     *       </li>
+     *       <li> If all certs matched and no inner package stanza matches then return
+     *         the global seinfo value. The returned value can be null in this case.
+     *       </li>
+     *     </ul>
+     *   </li>
+     * </ul>
+     * <p>
+     * In all cases, a return value of null should be interpreted as the apk failing
+     * to match this Policy instance; i.e. failing this policy stanza.
+     * </p>
+     * @param pkg the apk to check given as a PackageParser.Package object
+     * @return A string representing the seinfo matched during policy lookup.
+     *         A value of null can also be returned if no match occured.
+     */
+    public String getMatchedSeinfo(PackageParser.Package pkg) {
+        if (!mDefaultStanza) {
+            // Check for exact signature matches across all certs.
+            Signature[] certs = mCerts.toArray(new Signature[0]);
+            if (!Signature.areExactMatch(certs, pkg.mSignatures)) {
+                return null;
+            }
+
+            // Check for inner package name matches given that the
+            // signature checks already passed.
+            String seinfoValue = mPkgMap.get(pkg.packageName);
+            if (seinfoValue != null) {
+                return seinfoValue;
+            }
+        }
+
+        // Return the global seinfo value (even if it's null).
+        return mSeinfo;
+    }
+
+    /**
+     * A nested builder class to create {@link Policy} instances. A {@link Policy}
+     * class instance represents one valid policy stanza found in a mac_permissions.xml
+     * file. A valid policy stanza is defined to be either a signer or default stanza
+     * which obeys the rules outlined in external/sepolicy/mac_permissions.xml. The
+     * {@link #build} method ensures a set of invariants are upheld enforcing the correct
+     * stanza structure before returning a valid Policy object.
+     */
+    public static final class PolicyBuilder {
+
+        private String mSeinfo;
+        private boolean mDefaultStanza;
+        private final Set<Signature> mCerts;
+        private final Map<String, String> mPkgMap;
+
+        public PolicyBuilder() {
+            mCerts = new HashSet<Signature>(2);
+            mPkgMap = new HashMap<String, String>(2);
+        }
+
+        /**
+         * Sets this stanza as a defualt stanza. All policy stanzas are assumed to
+         * be signer stanzas unless this method is explicitly called. Default stanzas
+         * are treated differently with respect to allowable child tags, ordering and
+         * when and how policy decisions are enforced.
+         *
+         * @return The reference to this PolicyBuilder.
+         */
+        public PolicyBuilder setAsDefaultPolicy() {
+            mDefaultStanza = true;
+            return this;
+        }
+
+        /**
+         * Adds a signature to the set of certs used for validation checks. The purpose
+         * being that all contained certs will need to be matched against all certs
+         * contained with an apk.
+         *
+         * @param cert the signature to add given as a String.
+         * @return The reference to this PolicyBuilder.
+         * @throws IllegalArgumentException if the cert value fails validation;
+         *         null or is an invalid hex-encoded ASCII string.
+         */
+        public PolicyBuilder addSignature(String cert) {
+            if (cert == null) {
+                String err = "Invalid signature value " + cert;
+                throw new IllegalArgumentException(err);
+            }
+
+            mCerts.add(new Signature(cert));
+            return this;
+        }
+
+        /**
+         * Set the global seinfo tag for this policy stanza. The global seinfo tag
+         * represents the seinfo element that is used in one of two ways depending on
+         * its context. When attached to a signer tag the global seinfo represents an
+         * assignment when there isn't a further inner package refinement in policy.
+         * When used with a default tag, it represents the only allowable assignment
+         * value.
+         *
+         * @param seinfo the seinfo value given as a String.
+         * @return The reference to this PolicyBuilder.
+         * @throws IllegalArgumentException if the seinfo value fails validation;
+         *         null, zero length or contains non-valid characters [^a-zA-Z_\._0-9].
+         * @throws IllegalStateException if an seinfo value has already been found
+         */
+        public PolicyBuilder setGlobalSeinfoOrThrow(String seinfo) {
+            if (!validateValue(seinfo)) {
+                String err = "Invalid seinfo value " + seinfo;
+                throw new IllegalArgumentException(err);
+            }
+
+            if (mSeinfo != null && !mSeinfo.equals(seinfo)) {
+                String err = "Duplicate seinfo tag found";
+                throw new IllegalStateException(err);
+            }
+
+            mSeinfo = seinfo;
+            return this;
+        }
+
+        /**
+         * Create a package name to seinfo value mapping. Each mapping represents
+         * the seinfo value that will be assigned to the described package name.
+         * These localized mappings allow the global seinfo to be overriden. This
+         * mapping provides no value when used in conjunction with a default stanza;
+         * enforced through the {@link #build} method.
+         *
+         * @param pkgName the android package name given to the app
+         * @param seinfo the seinfo value that will be assigned to the passed pkgName
+         * @return The reference to this PolicyBuilder.
+         * @throws IllegalArgumentException if the seinfo value fails validation;
+         *         null, zero length or contains non-valid characters [^a-zA-Z_\.0-9].
+         *         Or, if the package name isn't a valid android package name.
+         * @throws IllegalStateException if trying to reset a package mapping with a
+         *         different seinfo value.
+         */
+        public PolicyBuilder addInnerPackageMapOrThrow(String pkgName, String seinfo) {
+            if (!validateValue(pkgName)) {
+                String err = "Invalid package name " + pkgName;
+                throw new IllegalArgumentException(err);
+            }
+            if (!validateValue(seinfo)) {
+                String err = "Invalid seinfo value " + seinfo;
+                throw new IllegalArgumentException(err);
+            }
+
+            String pkgValue = mPkgMap.get(pkgName);
+            if (pkgValue != null && !pkgValue.equals(seinfo)) {
+                String err = "Conflicting seinfo value found";
+                throw new IllegalStateException(err);
+            }
+
+            mPkgMap.put(pkgName, seinfo);
+            return this;
+        }
+
+        /**
+         * General validation routine for the attribute strings of an element. Checks
+         * if the string is non-null, positive length and only contains [a-zA-Z_\.0-9].
+         *
+         * @param name the string to validate.
+         * @return boolean indicating if the string was valid.
+         */
+        private boolean validateValue(String name) {
+            if (name == null)
+                return false;
+
+            // Want to match on [0-9a-zA-Z_.]
+            if (!name.matches("\\A[\\.\\w]+\\z")) {
+                return false;
+            }
+
+            return true;
+        }
+
+        /**
+         * <p>
+         * Create a {@link Policy} instance based on the current configuration. This
+         * method checks for certain policy invariants used to enforce certain guarantees
+         * about the expected structure of a policy stanza.
+         * Those invariants are:
+         * </p>
+         *    <ul>
+         *      <li> If a default stanza
+         *        <ul>
+         *          <li> an attached global seinfo tag must be present </li>
+         *          <li> no signatures and no package names can be present </li>
+         *        </ul>
+         *      </li>
+         *      <li> If a signer stanza
+         *        <ul>
+         *           <li> at least one cert must be found </li>
+         *           <li> either a global seinfo value is present OR at least one
+         *           inner package mapping must be present. </li>
+         *        </ul>
+         *      </li>
+         *    </ul>
+         *
+         * @return an instance of {@link Policy} with the options set from this builder
+         * @throws IllegalStateException if an invariant is violated.
+         */
+        public Policy build() {
+            Policy p = new Policy(this);
+
+            if (p.mDefaultStanza) {
+                if (p.mSeinfo == null) {
+                    String err = "Missing global seinfo tag with default stanza.";
+                    throw new IllegalStateException(err);
+                }
+                if (p.mCerts.size() != 0) {
+                    String err = "Certs not allowed with default stanza.";
+                    throw new IllegalStateException(err);
+                }
+                if (!p.mPkgMap.isEmpty()) {
+                    String err = "Inner package mappings not allowed with default stanza.";
+                    throw new IllegalStateException(err);
+                }
+            } else {
+                if (p.mCerts.size() == 0) {
+                    String err = "Missing certs with signer tag. Expecting at least one.";
+                    throw new IllegalStateException(err);
+                }
+                if ((p.mSeinfo == null) && (p.mPkgMap.isEmpty())) {
+                    String err = "Missing seinfo OR package tags with signer tag. At " +
+                            "least one must be present.";
+                    throw new IllegalStateException(err);
+                }
+            }
+
+            return p;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 30589b1..c6c2666 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -241,6 +241,7 @@
                 mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
             }
         }
+        mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
     }
 
     void switchUserStacks(int newUserId) {
diff --git a/services/core/java/com/android/server/wm/StackTapPointerEventListener.java b/services/core/java/com/android/server/wm/StackTapPointerEventListener.java
index 80eb453..1a85993 100644
--- a/services/core/java/com/android/server/wm/StackTapPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/StackTapPointerEventListener.java
@@ -31,7 +31,7 @@
     private float mDownX;
     private float mDownY;
     private int mPointerId;
-    final private Region mTouchExcludeRegion;
+    final private Region mTouchExcludeRegion = new Region();
     private final WindowManagerService mService;
     private final DisplayContent mDisplayContent;
 
@@ -39,7 +39,6 @@
             DisplayContent displayContent) {
         mService = service;
         mDisplayContent = displayContent;
-        mTouchExcludeRegion = displayContent.mTouchExcludeRegion;
         DisplayInfo info = displayContent.getDisplayInfo();
         mMotionSlop = (int)(info.logicalDensityDpi * TAP_MOTION_SLOP_INCHES);
     }
@@ -72,13 +71,15 @@
                 if (mPointerId == motionEvent.getPointerId(index)) {
                     final int x = (int)motionEvent.getX(index);
                     final int y = (int)motionEvent.getY(index);
-                    if ((motionEvent.getEventTime() - motionEvent.getDownTime())
-                            < TAP_TIMEOUT_MSEC
-                            && Math.abs(x - mDownX) < mMotionSlop
-                            && Math.abs(y - mDownY) < mMotionSlop
-                            && !mTouchExcludeRegion.contains(x, y)) {
-                        mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y,
-                                mDisplayContent).sendToTarget();
+                    synchronized(this) {
+                        if ((motionEvent.getEventTime() - motionEvent.getDownTime())
+                                < TAP_TIMEOUT_MSEC
+                                && Math.abs(x - mDownX) < mMotionSlop
+                                && Math.abs(y - mDownY) < mMotionSlop
+                                && !mTouchExcludeRegion.contains(x, y)) {
+                            mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y,
+                                    mDisplayContent).sendToTarget();
+                        }
                     }
                     mPointerId = -1;
                 }
@@ -86,4 +87,10 @@
             }
         }
     }
+
+    void setTouchExcludeRegion(Region newRegion) {
+        synchronized (this) {
+           mTouchExcludeRegion.set(newRegion);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 238c77e..802cf4b 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -191,7 +191,9 @@
         mTasks.add(stackNdx, task);
 
         task.mStack = this;
-        mDisplayContent.moveStack(this, true);
+        if (toTop) {
+            mDisplayContent.moveStack(this, true);
+        }
         EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.taskId, toTop ? 1 : 0, stackNdx);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1c03ced..c80d0e1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8796,7 +8796,8 @@
             if (!gone || !win.mHaveFrame || win.mLayoutNeeded
                     || ((win.isConfigChanged() || win.setInsetsChanged()) &&
                             ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
-                            win.mAppToken != null && win.mAppToken.layoutConfigChanges))
+                            (win.mHasSurface && win.mAppToken != null &&
+                            win.mAppToken.layoutConfigChanges)))
                     || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
                 if (!win.mLayoutAttached) {
                     if (initial) {
diff --git a/services/core/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp
index a58b00bce..3d981ab 100644
--- a/services/core/jni/com_android_server_AlarmManagerService.cpp
+++ b/services/core/jni/com_android_server_AlarmManagerService.cpp
@@ -290,7 +290,7 @@
 
     epollfd = epoll_create(N_ANDROID_TIMERFDS);
     if (epollfd < 0) {
-        ALOGV("epoll_create(%u) failed: %s", N_ANDROID_TIMERFDS,
+        ALOGV("epoll_create(%zu) failed: %s", N_ANDROID_TIMERFDS,
                 strerror(errno));
         return 0;
     }
diff --git a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
index d730b7e..b18b14d 100644
--- a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -214,7 +214,7 @@
 
     size_t status_size = agps_status->size;
     if (status_size == sizeof(AGpsStatus_v3)) {
-      ALOGV("AGpsStatus is V3: %d", status_size);
+      ALOGV("AGpsStatus is V3: %zd", status_size);
       switch (agps_status->addr.ss_family)
       {
       case AF_INET:
@@ -256,7 +256,7 @@
           break;
       }
     } else if (status_size >= sizeof(AGpsStatus_v2)) {
-      ALOGV("AGpsStatus is V2+: %d", status_size);
+      ALOGV("AGpsStatus is V2+: %zd", status_size);
       // for back-compatibility reasons we check in v2 that the data structure size is greater or
       // equal to the declared size in gps.h
       uint32_t ipaddr = agps_status->ipaddr;
@@ -266,12 +266,12 @@
           isSupported = true;
       }
     } else if (status_size >= sizeof(AGpsStatus_v1)) {
-        ALOGV("AGpsStatus is V1+: %d", status_size);
+        ALOGV("AGpsStatus is V1+: %zd", status_size);
         // because we have to check for >= with regards to v2, we also need to relax the check here
         // and only make sure that the size is at least what we expect
         isSupported = true;
     } else {
-        ALOGE("Invalid size of AGpsStatus found: %d.", status_size);
+        ALOGE("Invalid size of AGpsStatus found: %zd.", status_size);
     }
 
     if (isSupported) {
@@ -758,7 +758,7 @@
     } else if (interface_size == sizeof(AGpsInterface_v1)) {
         sAGpsInterface->data_conn_open(apnStr);
     } else {
-        ALOGE("Invalid size of AGpsInterface found: %d.", interface_size);
+        ALOGE("Invalid size of AGpsInterface found: %zd.", interface_size);
     }
 
     env->ReleaseStringUTFChars(apn, apnStr);
@@ -1260,7 +1260,7 @@
         env->DeleteLocalRef(gpsMeasurementsEventClass);
         env->DeleteLocalRef(gpsMeasurementsEvent);
     } else {
-        ALOGE("Invalid GpsData size found in gps_measurement_callback, size=%d", data->size);
+        ALOGE("Invalid GpsData size found in gps_measurement_callback, size=%zd", data->size);
     }
 }
 
@@ -1311,7 +1311,7 @@
     size_t dataLength = message->data_length;
     uint8_t* data = message->data;
     if (dataLength == 0 || data == NULL) {
-        ALOGE("Invalid Navigation Message found: data=%p, length=%d", data, dataLength);
+        ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, dataLength);
         return NULL;
     }
 
@@ -1370,7 +1370,7 @@
         env->DeleteLocalRef(navigationMessageEventClass);
         env->DeleteLocalRef(navigationMessageEvent);
     } else {
-        ALOGE("Invalid GpsNavigationMessage size found: %d", message->size);
+        ALOGE("Invalid GpsNavigationMessage size found: %zd", message->size);
     }
 }
 
diff --git a/tests/CoreTests/android/core/InetAddrTest.java b/tests/CoreTests/android/core/InetAddrTest.java
deleted file mode 100644
index c7b89e1..0000000
--- a/tests/CoreTests/android/core/InetAddrTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.core;
-
-import junit.framework.TestCase;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Random;
-
-import android.test.suitebuilder.annotation.Suppress;
-
-/**
- * Tests InetAddr class by checking methods to resolve domains to IP addresses
- * and by checking if the class returns correct addresses for local host address
- * and host name.
- */
-@Suppress
-public class InetAddrTest extends TestCase {
-    private static final String[] HOSTS = {
-            "localhost", "www.google.com", "www.slashdot.org", "www.wikipedia.org",
-            "www.paypal.com", "www.cnn.com", "www.yahoo.com", "www.amazon.com",
-            "www.ebay.com", "www.android.com"
-    };
-
-    public void testInetAddr() throws Exception {
-        byte[] raw;
-
-        InetAddress ia = InetAddress.getByName("localhost");
-
-        raw = ia.getAddress();
-
-        assertEquals(127, raw[0]);
-        assertEquals(0, raw[1]);
-        assertEquals(0, raw[2]);
-        assertEquals(1, raw[3]);
-
-        ia = InetAddress.getByName("127.0.0.1");
-
-        raw = ia.getAddress();
-
-        assertEquals(127, raw[0]);
-        assertEquals(0, raw[1]);
-        assertEquals(0, raw[2]);
-        assertEquals(1, raw[3]);
-
-        ia = InetAddress.getByName(null);
-
-        try {
-            InetAddress.getByName(".0.0.1");
-            fail("expected ex");
-        } catch (UnknownHostException ex) {
-            // expected
-        }
-
-        try {
-            InetAddress.getByName("thereisagoodchancethisdomaindoesnotexist.weirdtld");
-            fail("expected ex");
-        } catch (UnknownHostException ex) {
-            // expected
-        }
-
-        try {
-            InetAddress.getByName("127.0.0.");
-            fail("expected ex");
-        } catch (UnknownHostException ex) {
-            // expected
-        }
-
-        Random random = new Random();
-        int count = 0;
-        for (int i = 0; i < 100; i++) {
-            int index = random.nextInt(HOSTS.length);
-            try {
-                InetAddress.getByName(HOSTS[index]);
-                count++;
-                try {
-                    Thread.sleep(50);
-                } catch (InterruptedException ex) {
-                }
-            } catch (UnknownHostException ex) {
-            }
-        }
-        assertEquals("Not all host lookups succeeded", 100, count);
-    }
-}
diff --git a/tests/CoreTests/android/core/SSLSocketTest.java b/tests/CoreTests/android/core/SSLSocketTest.java
deleted file mode 100644
index 65062c2..0000000
--- a/tests/CoreTests/android/core/SSLSocketTest.java
+++ /dev/null
@@ -1,1094 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.core;
-
-import junit.framework.TestCase;
-
-import com.android.org.conscrypt.FileClientSessionCache;
-import com.android.org.conscrypt.OpenSSLContextImpl;
-import com.android.org.conscrypt.SSLClientSessionCache;
-import org.apache.commons.codec.binary.Base64;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.security.KeyStore;
-import java.security.KeyManagementException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-/**
- * SSL integration tests that hit real servers.
- */
-public class SSLSocketTest extends TestCase {
-
-    private static SSLSocketFactory clientFactory =
-            (SSLSocketFactory) SSLSocketFactory.getDefault();
-
-    /**
-     * Does a number of HTTPS requests on some host and consumes the response.
-     * We don't use the HttpsUrlConnection class, but do this on our own
-     * with the SSLSocket class. This gives us a chance to test the basic
-     * behavior of SSL.
-     *
-     * @param host      The host name the request is being sent to.
-     * @param port      The port the request is being sent to.
-     * @param path      The path being requested (e.g. "/index.html").
-     * @param outerLoop The number of times we reconnect and do the request.
-     * @param innerLoop The number of times we do the request for each
-     *                  connection (using HTTP keep-alive).
-     * @param delay     The delay after each request (in seconds).
-     * @throws IOException When a problem occurs.
-     */
-    private void fetch(SSLSocketFactory socketFactory, String host, int port,
-            boolean secure, String path, int outerLoop, int innerLoop,
-            int delay, int timeout) throws IOException {
-        InetSocketAddress address = new InetSocketAddress(host, port);
-
-        for (int i = 0; i < outerLoop; i++) {
-            // Connect to the remote host
-            Socket socket = secure ? socketFactory.createSocket()
-                    : new Socket();
-            if (timeout >= 0) {
-                socket.setKeepAlive(true);
-                socket.setSoTimeout(timeout * 1000);
-            }
-            socket.connect(address);
-
-            // Get the streams
-            OutputStream output = socket.getOutputStream();
-            PrintWriter writer = new PrintWriter(output);
-
-            try {
-                DataInputStream input = new DataInputStream(socket.getInputStream());
-                try {
-                    for (int j = 0; j < innerLoop; j++) {
-                        android.util.Log.d("SSLSocketTest",
-                                "GET https://" + host + path + " HTTP/1.1");
-
-                        // Send a request
-                        writer.println("GET https://" + host + path + " HTTP/1.1\r");
-                        writer.println("Host: " + host + "\r");
-                        writer.println("Connection: " +
-                                (j == innerLoop - 1 ? "Close" : "Keep-Alive")
-                                + "\r");
-                        writer.println("\r");
-                        writer.flush();
-
-                        int length = -1;
-                        boolean chunked = false;
-
-                        String line = input.readLine();
-
-                        if (line == null) {
-                            throw new IOException("No response from server");
-                            // android.util.Log.d("SSLSocketTest", "No response from server");
-                        }
-
-                        // Consume the headers, check content length and encoding type
-                        while (line != null && line.length() != 0) {
-//                    System.out.println(line);
-                            int dot = line.indexOf(':');
-                            if (dot != -1) {
-                                String key = line.substring(0, dot).trim();
-                                String value = line.substring(dot + 1).trim();
-
-                                if ("Content-Length".equalsIgnoreCase(key)) {
-                                    length = Integer.valueOf(value);
-                                } else if ("Transfer-Encoding".equalsIgnoreCase(key)) {
-                                    chunked = "Chunked".equalsIgnoreCase(value);
-                                }
-
-                            }
-                            line = input.readLine();
-                        }
-
-                        assertTrue("Need either content length or chunked encoding", length != -1
-                                || chunked);
-
-                        // Consume the content itself
-                        if (chunked) {
-                            length = Integer.parseInt(input.readLine(), 16);
-                            while (length != 0) {
-                                byte[] buffer = new byte[length];
-                                input.readFully(buffer);
-                                input.readLine();
-                                length = Integer.parseInt(input.readLine(), 16);
-                            }
-                            input.readLine();
-                        } else {
-                            byte[] buffer = new byte[length];
-                            input.readFully(buffer);
-                        }
-
-                        // Sleep for the given number of seconds
-                        try {
-                            Thread.sleep(delay * 1000);
-                        } catch (InterruptedException ex) {
-                            // Shut up!
-                        }
-                    }
-                } finally {
-                    input.close();
-                }
-            } finally {
-                writer.close();
-            }
-            // Close the connection
-            socket.close();
-        }
-    }
-
-    /**
-     * Invokes fetch() with the default socket factory.
-     */
-    private void fetch(String host, int port, boolean secure, String path,
-            int outerLoop, int innerLoop,
-            int delay, int timeout) throws IOException {
-        fetch(clientFactory, host, port, secure, path, outerLoop, innerLoop,
-                delay, timeout);
-    }
-
-    /**
-     * Does a single request for each of the hosts. Consumes the response.
-     *
-     * @throws IOException If a problem occurs.
-     */
-    public void testSimple() throws IOException {
-        fetch("www.fortify.net", 443, true, "/sslcheck.html", 1, 1, 0, 60);
-        fetch("mail.google.com", 443, true, "/mail/", 1, 1, 0, 60);
-        fetch("www.paypal.com", 443, true, "/", 1, 1, 0, 60);
-        fetch("www.yellownet.ch", 443, true, "/", 1, 1, 0, 60);
-    }
-
-    /**
-     * Does repeated requests for each of the hosts, with the connection being
-     * closed in between.
-     *
-     * @throws IOException If a problem occurs.
-     */
-    public void testRepeatedClose() throws IOException {
-        fetch("www.fortify.net", 443, true, "/sslcheck.html", 10, 1, 0, 60);
-        fetch("mail.google.com", 443, true, "/mail/", 10, 1, 0, 60);
-        fetch("www.paypal.com", 443, true, "/", 10, 1, 0, 60);
-        fetch("www.yellownet.ch", 443, true, "/", 10, 1, 0, 60);
-    }
-
-    /**
-     * Does repeated requests for each of the hosts, with the connection being
-     * kept alive in between.
-     *
-     * @throws IOException If a problem occurs.
-     */
-    public void testRepeatedKeepAlive() throws IOException {
-        fetch("www.fortify.net", 443, true, "/sslcheck.html", 1, 10, 0, 60);
-        fetch("mail.google.com", 443, true, "/mail/", 1, 10, 0, 60);
-
-        // These two don't accept keep-alive
-        // fetch("www.paypal.com", 443, "/", 1, 10);
-        // fetch("www.yellownet.ch", 443, "/", 1, 10);
-    }
-
-    /**
-     * Does repeated requests for each of the hosts, with the connection being
-     * closed in between. Waits a couple of seconds after each request, but
-     * stays within a reasonable timeout. Expectation is that the connection
-     * stays open.
-     *
-     * @throws IOException If a problem occurs.
-     */
-    public void testShortTimeout() throws IOException {
-        fetch("www.fortify.net", 443, true, "/sslcheck.html", 1, 10, 5, 60);
-        fetch("mail.google.com", 443, true, "/mail/", 1, 10, 5, 60);
-
-        // These two don't accept keep-alive
-        // fetch("www.paypal.com", 443, "/", 1, 10);
-        // fetch("www.yellownet.ch", 443, "/", 1, 10);
-    }
-
-    /**
-     * Does repeated requests for each of the hosts, with the connection being
-     * kept alive in between. Waits a longer time after each request.
-     * Expectation is that the host closes the connection.
-     */
-    public void testLongTimeout() {
-        // Seems to have a veeeery long timeout.
-        // fetch("www.fortify.net", 443, "/sslcheck.html", 1, 2, 60);
-
-        // Google has a 60s timeout, so 90s of waiting should trigger it.
-        try {
-            fetch("mail.google.com", 443, true, "/mail/", 1, 2, 90, 180);
-            fail("Oops - timeout expected.");
-        } catch (IOException ex) {
-            // Expected.
-        }
-
-        // These two don't accept keep-alive
-        // fetch("www.paypal.com", 443, "/", 1, 10);
-        // fetch("www.yellownet.ch", 443, "/", 1, 10);
-    }
-
-    /**
-     * Does repeated requests for each of the hosts, with the connection being
-     * closed in between. Waits a longer time after each request. Expectation is
-     * that the host closes the connection.
-     */
-    // These two need manual interaction to reproduce...
-    public void xxtestBrokenConnection() {
-        try {
-            fetch("www.fortify.net", 443, true, "/sslcheck.html", 1, 2, 60, 60);
-            fail("Oops - timeout expected.");
-        } catch (IOException ex) {
-            android.util.Log.d("SSLSocketTest", "Exception", ex);
-            // Expected.
-        }
-
-        // These two don't accept keep-alive
-        // fetch("www.paypal.com", 443, "/", 1, 10);
-        // fetch("www.yellownet.ch", 443, "/", 1, 10);
-    }
-
-    /**
-     * Does repeated requests for each of the hosts, with the connection being
-     * closed in between. Waits a longer time after each request. Expectation is
-     * that the host closes the connection.
-     */
-    // These two need manual interaction to reproduce...
-    public void xxtestBrokenConnection2() {
-        try {
-            fetch("www.heise.de", 80, false, "/index.html", 1, 2, 60, 60);
-            fail("Oops - timeout expected.");
-        } catch (IOException ex) {
-            android.util.Log.d("SSLSocketTest", "Exception", ex);
-            // Expected.
-        }
-
-        // These two don't accept keep-alive
-        // fetch("www.paypal.com", 443, "/", 1, 10);
-        // fetch("www.yellownet.ch", 443, "/", 1, 10);
-    }
-
-    /**
-     * Regression test for 865926: SSLContext.init() should
-     * use default values for null arguments.
-     */
-    public void testContextInitNullArgs() throws Exception {
-            SSLContext ctx = SSLContext.getInstance("TLS");
-            ctx.init(null, null, null);
-    }
-
-    /**
-     * Regression test for 963650: javax.net.ssl.KeyManager has no implemented
-     * (documented?) algorithms.
-     */
-    public void testDefaultAlgorithms() throws Exception {
-            SSLContext ctx = SSLContext.getInstance("TLS");
-            KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
-            KeyStore ks = KeyStore.getInstance("BKS");
-
-            assertEquals("X509", kmf.getAlgorithm());
-            assertEquals("X509", KeyManagerFactory.getDefaultAlgorithm());
-
-            assertEquals("BKS", ks.getType());
-            assertEquals("BKS", KeyStore.getDefaultType());
-    }
-
-    /**
-     * Regression test for problem where close() resulted in a hand if
-     * a different thread was sitting in a blocking read or write.
-     */
-    public void testMultithreadedClose() throws Exception {
-            InetSocketAddress address = new InetSocketAddress("www.fortify.net", 443);
-            final Socket socket = clientFactory.createSocket();
-            socket.connect(address);
-
-            Thread reader = new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        byte[] buffer = new byte[512];
-                        InputStream stream = socket.getInputStream();
-                        socket.getInputStream().read(buffer);
-                    } catch (Exception ex) {
-                        android.util.Log.d("SSLSocketTest",
-                                "testMultithreadedClose() reader got " + ex.toString());
-                    }
-                }
-            };
-
-            Thread closer = new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        Thread.sleep(5000);
-                        socket.close();
-                    } catch (Exception ex) {
-                        android.util.Log.d("SSLSocketTest",
-                                "testMultithreadedClose() closer got " + ex.toString());
-                    }
-                }
-            };
-
-            android.util.Log.d("SSLSocketTest", "testMultithreadedClose() starting reader...");
-            reader.start();
-            android.util.Log.d("SSLSocketTest", "testMultithreadedClose() starting closer...");
-            closer.start();
-
-            long t1 = System.currentTimeMillis();
-            android.util.Log.d("SSLSocketTest", "testMultithreadedClose() joining reader...");
-            reader.join(30000);
-            android.util.Log.d("SSLSocketTest", "testMultithreadedClose() joining closer...");
-            closer.join(30000);
-            long t2 = System.currentTimeMillis();
-
-            assertTrue("Concurrent close() hangs", t2 - t1 < 30000);
-    }
-
-    private int multithreadedFetchRuns;
-
-    private int multithreadedFetchWins;
-
-    private Random multithreadedFetchRandom = new Random();
-
-    /**
-     * Regression test for problem where multiple threads with multiple SSL
-     * connection would cause problems due to either missing native locking
-     * or the slowness of the SSL connections.
-     */
-    public void testMultithreadedFetch() {
-        Thread[] threads = new Thread[10];
-
-        for (int i = 0; i < threads.length; i++) {
-            threads[i] = new Thread() {
-                @Override
-                public void run() {
-                    for (int i = 0; i < 10; i++) {
-                        try {
-                            multithreadedFetchRuns++;
-                            switch (multithreadedFetchRandom.nextInt(4)) {
-                                case 0: {
-                                    fetch("www.fortify.net", 443,
-                                            true, "/sslcheck.html", 1, 1, 0, 60);
-                                    break;
-                                }
-
-                                case 1: {
-                                    fetch("mail.google.com", 443, true, "/mail/", 1, 1, 0, 60);
-                                    break;
-                                }
-
-                                case 2: {
-                                    fetch("www.paypal.com", 443, true, "/", 1, 1, 0, 60);
-                                    break;
-                                }
-
-                                case 3: {
-                                    fetch("www.yellownet.ch", 443, true, "/", 1, 1, 0, 60);
-                                    break;
-                                }
-                            }
-                            multithreadedFetchWins++;
-                        } catch (Exception ex) {
-                            android.util.Log.d("SSLSocketTest",
-                                    "testMultithreadedFetch() got Exception", ex);
-                        }
-                    }
-                }
-            };
-            threads[i].start();
-
-            android.util.Log.d("SSLSocketTest", "testMultithreadedFetch() started thread #" + i);
-        }
-
-        for (int i = 0; i < threads.length; i++) {
-            try {
-                threads[i].join();
-                android.util.Log.d("SSLSocketTest", "testMultithreadedFetch() joined thread #" + i);
-            } catch (InterruptedException ex) {
-                // Not interested.
-            }
-        }
-
-        assertTrue("At least 95% of multithreaded SSL connections must succeed",
-                multithreadedFetchWins >= (multithreadedFetchRuns * 95) / 100);
-    }
-
-    // -------------------------------------------------------------------------
-    // Regression test for #1204316: Missing client cert unit test. Passes on
-    // both Android and the RI. To use on the RI, install Apache Commons and
-    // replace the references to the base64-encoded keys by the JKS versions.
-    // -------------------------------------------------------------------------
-    
-    /** 
-     * Defines the keystore contents for the server, JKS version. Holds just a
-     * single self-generated key. The subject name is "Test Server".
-     */
-    private static final String SERVER_KEYS_JKS = 
-        "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";
-
-    /** 
-     * Defines the keystore contents for the server, BKS version. Holds just a
-     * single self-generated key. The subject name is "Test Server".
-     */
-    private static final String SERVER_KEYS_BKS = 
-        "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";
-    
-    /** 
-     * Defines the keystore contents for the client, JKS version. Holds just a
-     * single self-generated key. The subject name is "Test Client".
-     */
-    private static final String CLIENT_KEYS_JKS = 
-        "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";
-
-    /** 
-     * Defines the keystore contents for the client, BKS version. Holds just a
-     * single self-generated key. The subject name is "Test Client".
-     */
-    private static final String CLIENT_KEYS_BKS = 
-        "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";    
-    /** 
-     * Defines the password for the keystore.
-     */
-    private static final String PASSWORD = "android";
-            
-    /** 
-     * Implements basically a dummy TrustManager. It stores the certificate
-     * chain it sees, so it can later be queried.
-     */
-    class TestTrustManager implements X509TrustManager {
-        
-        private X509Certificate[] chain;
-        
-        private String authType;
-        
-        public void checkClientTrusted(X509Certificate[] chain, String authType) {
-            this.chain = chain;
-            this.authType = authType;
-        }
-
-        public void checkServerTrusted(X509Certificate[] chain, String authType) {
-            this.chain = chain;
-            this.authType = authType;
-        }
-
-        public X509Certificate[] getAcceptedIssuers() {
-            return new X509Certificate[0];
-        }
-
-        public X509Certificate[] getChain() {
-            return chain;
-        }
-        
-        public String getAuthType() {
-            return authType;
-        }
-        
-    }
-    
-    /** 
-     * Implements a test SSL socket server. It wait for a connection on a given
-     * port, requests client authentication (if specified), and read 256 bytes
-     * from the socket. 
-     */
-    class TestServer implements Runnable {
-
-        public static final int CLIENT_AUTH_NONE = 0;
-
-        public static final int CLIENT_AUTH_WANTED = 1;
-
-        public static final int CLIENT_AUTH_NEEDED = 2;
-        
-        private TestTrustManager trustManager;
-
-        private Exception exception;
-
-        private int port;
-        
-        private int clientAuth;
-        
-        private boolean provideKeys;
-
-        public TestServer(int port, boolean provideKeys, int clientAuth) {
-            this.port = port;
-            this.clientAuth = clientAuth;
-            this.provideKeys = provideKeys;
-            
-            trustManager = new TestTrustManager(); 
-        }
-        
-        public void run() {
-            try {
-                KeyManager[] keyManagers = provideKeys
-                        ? getKeyManagers(SERVER_KEYS_BKS) : null;
-                TrustManager[] trustManagers = new TrustManager[] {
-                        trustManager };
-
-                SSLContext sslContext = SSLContext.getInstance("TLS");
-                sslContext.init(keyManagers, trustManagers, null);
-                
-                SSLServerSocket serverSocket
-                        = (SSLServerSocket) sslContext.getServerSocketFactory()
-                        .createServerSocket();
-                
-                if (clientAuth == CLIENT_AUTH_WANTED) {
-                    serverSocket.setWantClientAuth(true);
-                } else if (clientAuth == CLIENT_AUTH_NEEDED) {
-                    serverSocket.setNeedClientAuth(true);
-                } else {
-                    serverSocket.setWantClientAuth(false);
-                }
-                
-                serverSocket.bind(new InetSocketAddress(port));
-                
-                SSLSocket clientSocket = (SSLSocket) serverSocket.accept();
-
-                InputStream stream = clientSocket.getInputStream();
-
-                for (int i = 0; i < 256; i++) {
-                    int j = stream.read();
-                    if (i != j) {
-                        throw new RuntimeException("Error reading socket,"
-                                + " expected " + i + ", got " + j);
-                    }
-                }
-                
-                stream.close();
-                clientSocket.close();
-                serverSocket.close();
-                
-            } catch (Exception ex) {
-                exception = ex;
-            }
-        }
-
-        public Exception getException() {
-            return exception;
-        }
-        
-        public X509Certificate[] getChain() {
-            return trustManager.getChain();
-        }
-        
-    }
-
-    /** 
-     * Implements a test SSL socket client. It open a connection to localhost on
-     * a given port and writes 256 bytes to the socket. 
-     */
-    class TestClient implements Runnable {
-        
-        private TestTrustManager trustManager;
-
-        private Exception exception;
-        
-        private int port;
-        
-        private boolean provideKeys;
-        
-        public TestClient(int port, boolean provideKeys) {
-            this.port = port;
-            this.provideKeys = provideKeys;
-            
-            trustManager = new TestTrustManager(); 
-        }
-        
-        public void run() {
-            try {
-                KeyManager[] keyManagers = provideKeys
-                        ? getKeyManagers(CLIENT_KEYS_BKS) : null;
-                TrustManager[] trustManagers = new TrustManager[] {
-                        trustManager };
-
-                SSLContext sslContext = SSLContext.getInstance("TLS");
-                sslContext.init(keyManagers, trustManagers, null);
-                
-                SSLSocket socket = (SSLSocket) sslContext.getSocketFactory()
-                        .createSocket();
-
-                socket.connect(new InetSocketAddress(port));
-                socket.startHandshake();
-
-                OutputStream stream = socket.getOutputStream();
-                
-                for (int i = 0; i < 256; i++) {
-                    stream.write(i);
-                }
-                
-                stream.flush();
-                stream.close();
-                socket.close();
-                
-            } catch (Exception ex) {
-                exception = ex;
-            }
-        }
-
-        public Exception getException() {
-            return exception;
-        }
-
-        public X509Certificate[] getChain() {
-            return trustManager.getChain();
-        }
-        
-    }
-    
-    /**
-     * Loads a keystore from a base64-encoded String. Returns the KeyManager[]
-     * for the result.
-     */
-    private KeyManager[] getKeyManagers(String keys) throws Exception {
-        byte[] bytes = new Base64().decode(keys.getBytes());                    
-        InputStream inputStream = new ByteArrayInputStream(bytes);
-        
-        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
-        keyStore.load(inputStream, PASSWORD.toCharArray());
-        inputStream.close();
-        
-        String algorithm = KeyManagerFactory.getDefaultAlgorithm();
-        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm);
-        keyManagerFactory.init(keyStore, PASSWORD.toCharArray());
-        
-        return keyManagerFactory.getKeyManagers();
-    }
-
-    /**
-     * Implements the actual test case. Launches a server and a client, requires
-     * client authentication and checks the certificates afterwards (not in the
-     * usual sense, we just make sure that we got the expected certificates,
-     * because our self-signed test certificates are not valid.)
-     */
-    public void testClientAuth() {
-        try {
-            TestServer server = new TestServer(8088, true, TestServer.CLIENT_AUTH_WANTED);
-            TestClient client = new TestClient(8088, true);
-            
-            Thread serverThread = new Thread(server);
-            Thread clientThread = new Thread(client);
-            
-            serverThread.start();
-            clientThread.start();
-            
-            serverThread.join();
-            clientThread.join();
-            
-            // The server must have completed without an exception.
-            if (server.getException() != null) {
-                throw new RuntimeException(server.getException());
-            }
-
-            // The client must have completed without an exception.
-            if (client.getException() != null) {
-                throw new RuntimeException(client.getException());
-            }
-            
-            // Caution: The clientChain is the certificate chain from our
-            // client object. It contains the server certificates, of course!
-            X509Certificate[] clientChain = client.getChain();
-            assertTrue("Client cert chain must not be null", clientChain != null);
-            assertTrue("Client cert chain must not be empty", clientChain.length != 0);
-            assertEquals("CN=Test Server, OU=Android, O=Google, L=MTV, ST=California, C=US", clientChain[0].getSubjectDN().toString());
-            // Important part ------^
-            
-            // Caution: The serverChain is the certificate chain from our
-            // server object. It contains the client certificates, of course!
-            X509Certificate[] serverChain = server.getChain();
-            assertTrue("Server cert chain must not be null", serverChain != null);
-            assertTrue("Server cert chain must not be empty", serverChain.length != 0);
-            assertEquals("CN=Test Client, OU=Android, O=Google, L=MTV, ST=California, C=US", serverChain[0].getSubjectDN().toString());
-            // Important part ------^
-            
-        } catch (Exception ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    // -------------------------------------------------------------------------
-    private SSLSocket handshakeSocket;
-
-    private Exception handshakeException;
-
-    
-    public void testSSLHandshakeHangTimeout() {
-        
-        Thread thread = new Thread() {
-            @Override
-            public void run() {
-                try {
-                    SSLSocket socket = (SSLSocket)clientFactory.createSocket(
-                            "www.heise.de", 80);
-                    socket.setSoTimeout(5000);
-                    socket.startHandshake();
-                    socket.close();
-                } catch (Exception ex) {
-                    handshakeException = ex;
-                }
-            }
-        };
-        
-        thread.start();
-        
-        try {
-            thread.join(10000);
-        } catch (InterruptedException ex) {
-            // Ignore.
-        }
-        
-        if (handshakeException == null) {
-            fail("SSL handshake should have failed.");
-        }
-    }
-
-    public void testSSLHandshakeHangClose() {
-        
-        Thread thread = new Thread() {
-            @Override
-            public void run() {
-                try {
-                    handshakeSocket = (SSLSocket)clientFactory.createSocket(
-                            "www.heise.de", 80);
-                    handshakeSocket.startHandshake();
-                } catch (Exception ex) {
-                    handshakeException = ex;
-                }
-            }
-        };
-        
-        thread.start();
-
-        
-        try {
-            Thread.sleep(5000);
-            try {
-                handshakeSocket.close();
-            } catch (Exception ex) {
-                throw new RuntimeException(ex);
-            }
-
-            thread.join(5000);
-        } catch (InterruptedException ex) {
-            // Ignore.
-        }
-        
-        if (handshakeException == null) {
-            fail("SSL handshake should have failed.");
-        }
-    }
-
-    /**
-     * Tests our in-memory and persistent caching support.
-     */
-    public void testClientSessionCaching() throws IOException,
-            KeyManagementException {
-        OpenSSLContextImpl context = OpenSSLContextImpl.getPreferred();
-
-        // Cache size = 2.
-        FakeClientSessionCache fakeCache = new FakeClientSessionCache();
-        context.engineInit(null, null, null);
-        context.engineGetClientSessionContext().setPersistentCache(fakeCache);
-        SSLSocketFactory socketFactory = context.engineGetSocketFactory();
-        context.engineGetClientSessionContext().setSessionCacheSize(2);
-        makeRequests(socketFactory);
-        List<String> smallCacheOps = Arrays.asList(
-                "get www.fortify.net",
-                "put www.fortify.net",
-                "get www.paypal.com",
-                "put www.paypal.com",
-                "get www.yellownet.ch",
-                "put www.yellownet.ch",
-
-                // At this point, all in-memory cache requests should miss,
-                // but the sessions will still be in the persistent cache.
-                "get www.fortify.net",
-                "get www.paypal.com",
-                "get www.yellownet.ch"
-        );
-        assertEquals(smallCacheOps, fakeCache.ops);
-
-        // Cache size = 3.
-        fakeCache = new FakeClientSessionCache();
-        context.engineInit(null, null, null);
-        context.engineGetClientSessionContext().setPersistentCache(fakeCache);
-        socketFactory = context.engineGetSocketFactory();
-        context.engineGetClientSessionContext().setSessionCacheSize(3);
-        makeRequests(socketFactory);
-        List<String> bigCacheOps = Arrays.asList(
-                "get www.fortify.net",
-                "put www.fortify.net",
-                "get www.paypal.com",
-                "put www.paypal.com",
-                "get www.yellownet.ch",
-                "put www.yellownet.ch"
-
-                // At this point, all results should be in the in-memory
-                // cache, and the persistent cache shouldn't be hit anymore.
-        );
-        assertEquals(bigCacheOps, fakeCache.ops);
-
-        // Cache size = 4.
-        fakeCache = new FakeClientSessionCache();
-        context.engineInit(null, null, null);
-        context.engineGetClientSessionContext().setPersistentCache(fakeCache);
-        socketFactory = context.engineGetSocketFactory();
-        context.engineGetClientSessionContext().setSessionCacheSize(4);
-        makeRequests(socketFactory);
-        assertEquals(bigCacheOps, fakeCache.ops);
-    }
-
-    /**
-     * Executes sequence of requests twice using given socket factory.
-     */
-    private void makeRequests(SSLSocketFactory socketFactory)
-            throws IOException {
-        for (int i = 0; i < 2; i++) {
-            fetch(socketFactory, "www.fortify.net", 443, true, "/sslcheck.html",
-                    1, 1, 0, 60);
-            fetch(socketFactory, "www.paypal.com", 443, true, "/",
-                    1, 1, 0, 60);
-            fetch(socketFactory, "www.yellownet.ch", 443, true, "/",
-                    1, 1, 0, 60);
-        }
-    }
-
-    /**
-     * Fake in the sense that it doesn't actually persist anything.
-     */
-    static class FakeClientSessionCache implements SSLClientSessionCache {
-
-        List<String> ops = new ArrayList<String>();
-        Map<String, byte[]> sessions = new HashMap<String, byte[]>();
-
-        public byte[] getSessionData(String host, int port) {
-            ops.add("get " + host);
-            return sessions.get(host);
-        }
-
-        public void putSessionData(SSLSession session, byte[] sessionData) {
-            String host = session.getPeerHost();
-            System.err.println("length: " + sessionData.length);
-            ops.add("put " + host);
-            sessions.put(host, sessionData);
-        }
-    }
-
-    public void testFileBasedClientSessionCache() throws IOException,
-            KeyManagementException {
-        OpenSSLContextImpl context = OpenSSLContextImpl.getPreferred();
-        String tmpDir = System.getProperty("java.io.tmpdir");
-        if (tmpDir == null) {
-            fail("Please set 'java.io.tmpdir' system property.");
-        }
-        File cacheDir = new File(tmpDir
-                + "/" + SSLSocketTest.class.getName() + "/cache");
-        deleteDir(cacheDir);
-        SSLClientSessionCache fileCache
-                = FileClientSessionCache.usingDirectory(cacheDir);
-        try {
-            ClientSessionCacheProxy cacheProxy
-                    = new ClientSessionCacheProxy(fileCache);
-            context.engineInit(null, null, null);
-            context.engineGetClientSessionContext().setPersistentCache(cacheProxy);
-            SSLSocketFactory socketFactory = context.engineGetSocketFactory();
-            context.engineGetClientSessionContext().setSessionCacheSize(1);
-            makeRequests(socketFactory);
-            List<String> expected = Arrays.asList(
-                    "unsuccessful get www.fortify.net",
-                    "put www.fortify.net",
-                    "unsuccessful get www.paypal.com",
-                    "put www.paypal.com",
-                    "unsuccessful get www.yellownet.ch",
-                    "put www.yellownet.ch",
-
-                    // At this point, all in-memory cache requests should miss,
-                    // but the sessions will still be in the persistent cache.
-                    "successful get www.fortify.net",
-                    "successful get www.paypal.com",
-                    "successful get www.yellownet.ch"
-            );
-            assertEquals(expected, cacheProxy.ops);
-
-            // Try again now that file-based cache is populated.
-            fileCache = FileClientSessionCache.usingDirectory(cacheDir);
-            cacheProxy = new ClientSessionCacheProxy(fileCache);
-            context.engineInit(null, null, null);
-            context.engineGetClientSessionContext().setPersistentCache(cacheProxy);
-            socketFactory = context.engineGetSocketFactory();
-            context.engineGetClientSessionContext().setSessionCacheSize(1);
-            makeRequests(socketFactory);
-            expected = Arrays.asList(
-                    "successful get www.fortify.net",
-                    "successful get www.paypal.com",
-                    "successful get www.yellownet.ch",
-                    "successful get www.fortify.net",
-                    "successful get www.paypal.com",
-                    "successful get www.yellownet.ch"
-            );
-            assertEquals(expected, cacheProxy.ops);
-        } finally {
-            deleteDir(cacheDir);
-        }
-    }
-
-    private static void deleteDir(File directory) {
-        if (!directory.exists()) {
-            return;
-        }
-        for (File file : directory.listFiles()) {
-            file.delete();
-        }
-        directory.delete();
-    }
-
-    static class ClientSessionCacheProxy implements SSLClientSessionCache {
-
-        final SSLClientSessionCache delegate;
-        final List<String> ops = new ArrayList<String>();
-
-        ClientSessionCacheProxy(SSLClientSessionCache delegate) {
-            this.delegate = delegate;
-        }
-
-        public byte[] getSessionData(String host, int port) {
-            byte[] sessionData = delegate.getSessionData(host, port);
-            ops.add((sessionData == null ? "unsuccessful" : "successful")
-                    + " get " + host);
-            return sessionData;
-        }
-
-        public void putSessionData(SSLSession session, byte[] sessionData) {
-            delegate.putSessionData(session, sessionData);
-            ops.add("put " + session.getPeerHost());
-        }
-    }
-
-    public static void main(String[] args) throws KeyManagementException, IOException {
-        new SSLSocketTest().testFileBasedClientSessionCache();
-    }
-}
diff --git a/tests/CoreTests/android/core/SocketTest.java b/tests/CoreTests/android/core/SocketTest.java
deleted file mode 100644
index 9db6077..0000000
--- a/tests/CoreTests/android/core/SocketTest.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.core;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.Semaphore;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
-
-/**
- * Regression tests for various socket related problems. And a few general
- * socket tests.
- */
-public class SocketTest extends TestCase {
-
-    private static final String NON_EXISTING_ADDRESS = "123.123.123.123";
-
-    private static final String KNOW_GOOD_ADDRESS = "209.85.129.147";
-
-    private static final String PACKAGE_DROPPING_ADDRESS = "191.167.0.1";
-    
-    // Test for basic bind/connect/accept behavior.
-    @SmallTest
-    public void testSocketSimple() throws Exception {
-        ServerSocket ss;
-        Socket s, s1;
-        int port;
-
-        IOException lastEx = null;
-
-        ss = new ServerSocket();
-
-        for (port = 9900; port < 9999; port++) {
-            try {
-                ss.bind(new InetSocketAddress("127.0.0.1", port));
-                lastEx = null;
-                break;
-            } catch (IOException ex) {
-                lastEx = ex;
-            }
-        }
-
-        if (lastEx != null) {
-            throw lastEx;
-        }
-
-        s = new Socket("127.0.0.1", port);
-
-        s1 = ss.accept();
-
-        s.getOutputStream().write(0xa5);
-
-        assertEquals(0xa5, s1.getInputStream().read());
-
-        s1.getOutputStream().write(0x5a);
-        assertEquals(0x5a, s.getInputStream().read());
-    }
-    
-    // Regression test for #820068: Wildcard address
-    @SmallTest
-    public void testWildcardAddress() throws Exception {
-        Socket s2 = new Socket();
-        s2.bind(new InetSocketAddress((InetAddress) null, 12345));
-        byte[] addr = s2.getLocalAddress().getAddress();
-        for (int i = 0; i < 4; i++) {
-            assertEquals("Not the wildcard address", 0, addr[i]);
-        }
-    }
-    
-    // Regression test for #865753: server sockets not closing properly
-    @SmallTest
-    public void testServerSocketClose() throws Exception {
-        ServerSocket s3 = new ServerSocket(23456);
-        s3.close();
-        ServerSocket s4 = new ServerSocket(23456);
-        s4.close();
-    }
-    
-    // Regression test for #876985: SO_REUSEADDR not working properly
-    
-    private Exception serverError = null;
-    
-    @LargeTest
-    public void testSetReuseAddress() throws IOException {
-        InetSocketAddress addr = new InetSocketAddress(8383);
-
-        final ServerSocket serverSock = new ServerSocket();
-        serverSock.setReuseAddress(true);
-        serverSock.bind(addr);
-
-        final Semaphore semThreadEnd = new Semaphore(0);
-        new Thread() {
-            @Override
-            public void run() {
-                try {
-                    Socket sock = serverSock.accept();
-                    sock.getInputStream().read();
-                    sock.close();
-                } catch (IOException e) {
-                    serverError = e;
-                }
-                semThreadEnd.release();
-            }
-        }.start();
-
-        // Give the server a bit of time for startup
-        try {
-            Thread.sleep(2000);
-        } catch (InterruptedException ex) {
-            // Ignored.
-        }
-        
-        Socket client = new Socket("localhost", 8383);
-        client.getOutputStream().write(1);
-        // Just leave this connection open from the client side. It will be
-        // closed from the server side so the server stays in the TIME_WAIT
-        // state for a while. setReuseAddress() should be able to handle this.
-
-        try {
-            semThreadEnd.acquire();
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        serverSock.close();
-
-        ServerSocket serverSock2 = new ServerSocket();
-        serverSock2.setReuseAddress(true);
-        serverSock2.bind(addr);
-        serverSock2.close();
-        
-        if (serverError != null) {
-            throw new RuntimeException("Server must complete without error", serverError);
-        }
-    }
-
-    // Regression for 916701, a wrong exception was thrown after timeout of
-    // a ServerSocket.
-    @LargeTest
-    public void testTimeoutException() throws IOException {
-        ServerSocket s = new ServerSocket(9800);
-        s.setSoTimeout(2000);
-        try {
-            s.accept();
-        } catch (SocketTimeoutException e) {
-            // this is ok.
-        }
-    }
-
-    // Regression for issue 1001980, openening a SocketChannel threw an Exception
-    @SmallTest
-    public void testNativeSocketChannelOpen() throws IOException {
-        SocketChannel.open();
-    }
-
-// Regression test for issue 1018016, connecting ignored a set timeout.
-//
-// Disabled because test behaves differently depending on networking
-// environment. It works fine in the emulator and one the device with
-// WLAN, but when 3G comes into play, the possible existence of a
-// proxy makes it fail.
-//
-//    @LargeTest
-//    public void testSocketSetSOTimeout() throws IOException {
-//        Socket sock = new Socket();
-//        int timeout = 5000;
-//        long start = System.currentTimeMillis();
-//        try {
-//            sock.connect(new InetSocketAddress(NON_EXISTING_ADDRESS, 80), timeout);
-//        } catch (SocketTimeoutException e) {
-//            // expected
-//            long delay = System.currentTimeMillis() - start;
-//            if (Math.abs(delay - timeout) > 1000) {
-//                fail("timeout was not accurate. expected: " + timeout
-//                        + " actual: " + delay + " miliseconds.");
-//            }
-//        } finally {
-//            try {
-//                sock.close();
-//            } catch (IOException ioe) {
-//                // ignore
-//            }
-//        }
-//    }
-    
-    /**
-     * Regression test for 1062928: Dotted IP addresses (e.g., 192.168.100.1)
-     * appear to be broken in the M5 SDK.
-     * 
-     * Tests that a connection given a ip-addressv4 such as 192.168.100.100 does
-     * not fail - sdk m5 seems only to accept dns names instead of ip numbers.
-     * ip 209.85.129.147 (one address of www.google.com) on port 80 (http) is
-     * used to test the connection.
-     */
-
-// Commenting out this test since it is flaky, even at the best of times.  See
-// #1191317 for Info.
-    @Suppress
-    public void disable_testConnectWithIP4IPAddr() {
-        // call a Google Web server
-        InetSocketAddress scktAddrss = new InetSocketAddress(KNOW_GOOD_ADDRESS,
-                80);
-        Socket clntSckt = new Socket();
-        try {
-            clntSckt.connect(scktAddrss, 5000);
-        } catch (Throwable e) {
-            fail("connection problem:" + e.getClass().getName() + ": "
-                    + e.getMessage());
-        } finally {
-            try {
-                clntSckt.close();
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-    }
-
-    
-    // Regression test for #1058962: Socket.close() does not cause
-    // socket.connect() to return immediately.
-    private Socket client;
-    
-    private Exception error;
-    
-    private boolean connected;
-
-// This test isn't working now, but really should work.
-// TODO Enable this test again.
-
-    @Suppress
-    public void disable_testSocketConnectClose() {
-        try {
-            client = new Socket();
-            
-            new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        client.connect(new InetSocketAddress(PACKAGE_DROPPING_ADDRESS, 1357));
-                    } catch (Exception ex) {
-                        error = ex;
-                    }
-                    
-                    connected = true;
-                }
-            }.start();
-            
-            Thread.sleep(1000);
-            
-            Assert.assertNull("Connect must not fail immediately. Maybe try different address.", error);
-            Assert.assertFalse("Connect must not succeed. Maybe try different address.", connected);
-            
-            client.close();
-            
-            Thread.sleep(1000);
-
-            if (error == null) {
-                fail("Socket connect still ongoing");
-            } else if (!(error instanceof SocketException)) {
-                fail("Socket connect interrupted with wrong error: " + error.toString());
-            }
-            
-        } catch (Exception ex) {
-            throw new RuntimeException(ex);
-        }
-            
-    }
-    
-}