am 4997cd36: am 9e30e202: am 2af5010a: am 36a75d6a: Merge "Fixed a crash in the notification group manager" into mnc-dev

* commit '4997cd364deeeb03edfe19e9c3959bd694970ec7':
  Fixed a crash in the notification group manager
diff --git a/Android.mk b/Android.mk
index 9ddb777..ed8d38d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -713,6 +713,7 @@
 	bouncycastle \
 	okhttp \
 	ext \
+	icu4j \
 	framework \
 	telephony-common \
 	voip-common
@@ -766,7 +767,8 @@
 	$(foreach lib,$(FRAMEWORKS_SUPPORT_JAVA_LIBRARIES),$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib)-res,,COMMON))
 
 framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES := \
-    frameworks/base/docs/knowntags.txt
+    frameworks/base/docs/knowntags.txt \
+    libcore/Docs.mk
 
 samples_dir := development/samples/browseable
 
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 96c0dbd..d64e270 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -106,7 +106,7 @@
                 "usage: am [subcommand] [options]\n" +
                 "usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" +
                 "               [--sampling INTERVAL] [-R COUNT] [-S] [--opengl-trace]\n" +
-                "               [--user <USER_ID> | current] <INTENT>\n" +
+                "               [--track-allocation] [--user <USER_ID> | current] <INTENT>\n" +
                 "       am startservice [--user <USER_ID> | current] <INTENT>\n" +
                 "       am stopservice [--user <USER_ID> | current] <INTENT>\n" +
                 "       am force-stop [--user <USER_ID> | all | current] <PACKAGE>\n" +
@@ -162,6 +162,7 @@
                 "        the top activity will be finished.\n" +
                 "    -S: force stop the target app before starting the activity\n" +
                 "    --opengl-trace: enable tracing of OpenGL functions\n" +
+                "    --track-allocation: enable tracking of object allocations\n" +
                 "    --user <USER_ID> | current: Specify which user to run as; if not\n" +
                 "        specified then run as the current user.\n" +
                 "\n" +
@@ -691,6 +692,8 @@
                 mStopOption = true;
             } else if (opt.equals("--opengl-trace")) {
                 mStartFlags |= ActivityManager.START_FLAG_OPENGL_TRACES;
+            } else if (opt.equals("--track-allocation")) {
+                mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION;
             } else if (opt.equals("--user")) {
                 mUserId = parseUserArg(nextArgRequired());
             } else if (opt.equals("--receiver-permission")) {
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index 7ce0846..51bbb81 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -65,7 +65,7 @@
 LOCAL_MODULE_STEM_32 := app_process32
 LOCAL_MODULE_STEM_64 := app_process64
 
-LOCAL_ADDRESS_SANITIZER := true
+LOCAL_SANITIZE := address
 LOCAL_CLANG := true
 LOCAL_MODULE_PATH := $(TARGET_OUT_EXECUTABLES)/asan
 
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index 2ee586f..7c8842c 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -27,6 +27,8 @@
 
 LOCAL_MODULE:= bootanimation
 
+LOCAL_INIT_RC := bootanim.rc
+
 ifdef TARGET_32_BIT_SURFACEFLINGER
 LOCAL_32_BIT_ONLY := true
 endif
diff --git a/cmds/bootanimation/bootanim.rc b/cmds/bootanimation/bootanim.rc
new file mode 100644
index 0000000..ee0d0b8
--- /dev/null
+++ b/cmds/bootanimation/bootanim.rc
@@ -0,0 +1,6 @@
+service bootanim /system/bin/bootanimation
+    class core
+    user graphics
+    group graphics audio
+    disabled
+    oneshot
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index 2a7c79b..754d3f5 100644
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -234,6 +234,18 @@
                 InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
     }
 
+    private int getInputDeviceId(int inputSource) {
+        final int DEFAULT_DEVICE_ID = 0;
+        int[] devIds = InputDevice.getDeviceIds();
+        for (int devId : devIds) {
+            InputDevice inputDev = InputDevice.getDevice(devId);
+            if (inputDev.supportsSource(inputSource)) {
+                return devId;
+            }
+        }
+        return DEFAULT_DEVICE_ID;
+    }
+
     /**
      * Builds a MotionEvent and injects it into the event stream.
      *
@@ -249,11 +261,10 @@
         final int DEFAULT_META_STATE = 0;
         final float DEFAULT_PRECISION_X = 1.0f;
         final float DEFAULT_PRECISION_Y = 1.0f;
-        final int DEFAULT_DEVICE_ID = 0;
         final int DEFAULT_EDGE_FLAGS = 0;
         MotionEvent event = MotionEvent.obtain(when, when, action, x, y, pressure, DEFAULT_SIZE,
-                DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, DEFAULT_DEVICE_ID,
-                DEFAULT_EDGE_FLAGS);
+                DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y,
+                getInputDeviceId(inputSource), DEFAULT_EDGE_FLAGS);
         event.setSource(inputSource);
         Log.i(TAG, "injectMotionEvent: " + event);
         InputManager.getInstance().injectInputEvent(event,
diff --git a/cmds/svc/src/com/android/commands/svc/PowerCommand.java b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
index 2754f2d..6ce29cb 100644
--- a/cmds/svc/src/com/android/commands/svc/PowerCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
@@ -93,7 +93,7 @@
                 } else if ("shutdown".equals(args[1])) {
                     try {
                         // no confirm, wait till device is off
-                        pm.shutdown(false, true);
+                        pm.shutdown(false, null, true);
                     } catch (RemoteException e) {
                         System.err.println("Failed to shutdown.");
                     }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 87c9efc2..ec262e5 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -210,6 +210,13 @@
     public static final int START_FLAG_OPENGL_TRACES = 1<<2;
 
     /**
+     * Flag for IActivityManaqer.startActivity: launch the app for
+     * allocation tracking.
+     * @hide
+     */
+    public static final int START_FLAG_TRACK_ALLOCATION = 1<<3;
+
+    /**
      * Result for IActivityManaqer.broadcastIntent: success!
      * @hide
      */
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index da21eaf..890b754 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -132,6 +132,7 @@
 import dalvik.system.CloseGuard;
 import dalvik.system.VMDebug;
 import dalvik.system.VMRuntime;
+import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
 
 final class RemoteServiceException extends AndroidRuntimeException {
     public RemoteServiceException(String msg) {
@@ -445,6 +446,7 @@
         IUiAutomationConnection instrumentationUiAutomationConnection;
         int debugMode;
         boolean enableOpenGlTrace;
+        boolean trackAllocation;
         boolean restrictedBackupMode;
         boolean persistent;
         Configuration config;
@@ -769,9 +771,9 @@
                 ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                 IInstrumentationWatcher instrumentationWatcher,
                 IUiAutomationConnection instrumentationUiConnection, int debugMode,
-                boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
-                Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
-                Bundle coreSettings) {
+                boolean enableOpenGlTrace, boolean trackAllocation, boolean isRestrictedBackupMode,
+                boolean persistent, Configuration config, CompatibilityInfo compatInfo,
+                Map<String, IBinder> services, Bundle coreSettings) {
 
             if (services != null) {
                 // Setup the service cache in the ServiceManager
@@ -827,6 +829,7 @@
             data.instrumentationUiAutomationConnection = instrumentationUiConnection;
             data.debugMode = debugMode;
             data.enableOpenGlTrace = enableOpenGlTrace;
+            data.trackAllocation = trackAllocation;
             data.restrictedBackupMode = isRestrictedBackupMode;
             data.persistent = persistent;
             data.config = config;
@@ -988,7 +991,7 @@
             long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
 
             Runtime runtime = Runtime.getRuntime();
-
+            runtime.gc();  // Do GC since countInstancesOfClass counts unreachable objects.
             long dalvikMax = runtime.totalMemory() / 1024;
             long dalvikFree = runtime.freeMemory() / 1024;
             long dalvikAllocated = dalvikMax - dalvikFree;
@@ -4428,6 +4431,10 @@
     }
 
     private void handleBindApplication(AppBindData data) {
+        if (data.trackAllocation) {
+            DdmVmInternal.enableRecentAllocations(true);
+        }
+
         mBoundApplication = data;
         mConfiguration = new Configuration(data.config);
         mCompatConfiguration = new Configuration(data.config);
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index 330d730..fb03b62 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -823,7 +823,7 @@
         }
 
         /**
-         * Returns an intent intent that can be used to show or edit details of the alarm clock in
+         * Returns an intent that can be used to show or edit details of the alarm clock in
          * the application that scheduled it.
          *
          * <p class="note">Beware that any application can retrieve and send this intent, 
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index e178087..b9ebd9f 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -292,6 +292,7 @@
                     IUiAutomationConnection.Stub.asInterface(binder);
             int testMode = data.readInt();
             boolean openGlTrace = data.readInt() != 0;
+            boolean trackAllocation = data.readInt() != 0;
             boolean restrictedBackupMode = (data.readInt() != 0);
             boolean persistent = (data.readInt() != 0);
             Configuration config = Configuration.CREATOR.createFromParcel(data);
@@ -299,7 +300,7 @@
             HashMap<String, IBinder> services = data.readHashMap(null);
             Bundle coreSettings = data.readBundle();
             bindApplication(packageName, info, providers, testName, profilerInfo, testArgs,
-                    testWatcher, uiAutomationConnection, testMode, openGlTrace,
+                    testWatcher, uiAutomationConnection, testMode, openGlTrace, trackAllocation,
                     restrictedBackupMode, persistent, config, compatInfo, services, coreSettings);
             return true;
         }
@@ -987,13 +988,14 @@
         data.recycle();
     }
 
+    @Override
     public final void bindApplication(String packageName, ApplicationInfo info,
             List<ProviderInfo> providers, ComponentName testName, ProfilerInfo profilerInfo,
             Bundle testArgs, IInstrumentationWatcher testWatcher,
             IUiAutomationConnection uiAutomationConnection, int debugMode,
-            boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
-            Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
-            Bundle coreSettings) throws RemoteException {
+            boolean openGlTrace, boolean trackAllocation, boolean restrictedBackupMode,
+            boolean persistent, Configuration config, CompatibilityInfo compatInfo,
+            Map<String, IBinder> services, Bundle coreSettings) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeString(packageName);
@@ -1016,6 +1018,7 @@
         data.writeStrongInterface(uiAutomationConnection);
         data.writeInt(debugMode);
         data.writeInt(openGlTrace ? 1 : 0);
+        data.writeInt(trackAllocation ? 1 : 0);
         data.writeInt(restrictedBackupMode ? 1 : 0);
         data.writeInt(persistent ? 1 : 0);
         config.writeToParcel(data, 0);
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 185578f..e204d50 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -95,8 +95,9 @@
     void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers,
             ComponentName testName, ProfilerInfo profilerInfo, Bundle testArguments,
             IInstrumentationWatcher testWatcher, IUiAutomationConnection uiAutomationConnection,
-            int debugMode, boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
-            Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
+            int debugMode, boolean openGlTrace, boolean trackAllocation,
+            boolean restrictedBackupMode, boolean persistent, Configuration config,
+            CompatibilityInfo compatInfo, Map<String, IBinder> services,
             Bundle coreSettings) throws RemoteException;
     void scheduleExit() throws RemoteException;
     void scheduleSuicide() throws RemoteException;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 87d52e4..cba257c 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2191,7 +2191,9 @@
     /**
      * Activity Action:  Start this activity to request system shutdown.
      * The optional boolean extra field {@link #EXTRA_KEY_CONFIRM} can be set to true
-     * to request confirmation from the user before shutting down.
+     * to request confirmation from the user before shutting down. The optional boolean
+     * extra field {@link #EXTRA_USER_REQUESTED_SHUTDOWN} can be set to true to
+     * indicate that the shutdown is requested by the user.
      *
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
@@ -3505,6 +3507,15 @@
     public static final String EXTRA_KEY_CONFIRM = "android.intent.extra.KEY_CONFIRM";
 
     /**
+     * Set to true in {@link #ACTION_REQUEST_SHUTDOWN} to indicate that the shutdown is
+     * requested by the user.
+     *
+     * {@hide}
+     */
+    public static final String EXTRA_USER_REQUESTED_SHUTDOWN =
+            "android.intent.extra.USER_REQUESTED_SHUTDOWN";
+
+    /**
      * Used as a boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED} or
      * {@link android.content.Intent#ACTION_PACKAGE_CHANGED} intents to override the default action
      * of restarting the application.
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 6feb860..914945b 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -531,12 +531,14 @@
 
     /**
      * String retrieved from the seinfo tag found in selinux policy. This value
-     * is useful in setting an SELinux security context on the process as well
-     * as its data directory.
+     * can be overridden with a value set through the mac_permissions.xml policy
+     * construct. This value is useful in setting an SELinux security context on
+     * the process as well as its data directory. The String default is being used
+     * here to represent a catchall label when no policy matches.
      *
      * {@hide}
      */
-    public String seinfo;
+    public String seinfo = "default";
 
     /**
      * Paths to all shared libraries this application is linked against.  This
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 731903c..788aee9 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -20,6 +20,7 @@
 import android.annotation.ColorInt;
 import android.annotation.StyleRes;
 import android.annotation.StyleableRes;
+import android.icu.text.PluralRules;
 import com.android.internal.util.GrowingArrayUtils;
 import com.android.internal.util.XmlUtils;
 
@@ -68,8 +69,6 @@
 import java.lang.ref.WeakReference;
 import java.util.Locale;
 
-import libcore.icu.NativePluralRules;
-
 /**
  * Class for accessing an application's resources.  This sits on top of the
  * asset manager of the application (accessible through {@link #getAssets}) and
@@ -154,7 +153,7 @@
     final DisplayMetrics mMetrics = new DisplayMetrics();
 
     private final Configuration mConfiguration = new Configuration();
-    private NativePluralRules mPluralRule;
+    private PluralRules mPluralRule;
 
     private CompatibilityInfo mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
 
@@ -335,9 +334,9 @@
      */
     public CharSequence getQuantityText(@PluralsRes int id, int quantity)
             throws NotFoundException {
-        NativePluralRules rule = getPluralRule();
+        PluralRules rule = getPluralRule();
         CharSequence res = mAssets.getResourceBagText(id,
-                attrForQuantityCode(rule.quantityForInt(quantity)));
+                attrForQuantityCode(rule.select(quantity)));
         if (res != null) {
             return res;
         }
@@ -347,40 +346,29 @@
         }
         throw new NotFoundException("Plural resource ID #0x" + Integer.toHexString(id)
                 + " quantity=" + quantity
-                + " item=" + stringForQuantityCode(rule.quantityForInt(quantity)));
+                + " item=" + rule.select(quantity));
     }
 
-    private NativePluralRules getPluralRule() {
+    private PluralRules getPluralRule() {
         synchronized (sSync) {
             if (mPluralRule == null) {
-                mPluralRule = NativePluralRules.forLocale(mConfiguration.locale);
+                mPluralRule = PluralRules.forLocale(mConfiguration.locale);
             }
             return mPluralRule;
         }
     }
 
-    private static int attrForQuantityCode(int quantityCode) {
+    private static int attrForQuantityCode(String quantityCode) {
         switch (quantityCode) {
-            case NativePluralRules.ZERO: return 0x01000005;
-            case NativePluralRules.ONE:  return 0x01000006;
-            case NativePluralRules.TWO:  return 0x01000007;
-            case NativePluralRules.FEW:  return 0x01000008;
-            case NativePluralRules.MANY: return 0x01000009;
+            case PluralRules.KEYWORD_ZERO: return 0x01000005;
+            case PluralRules.KEYWORD_ONE:  return 0x01000006;
+            case PluralRules.KEYWORD_TWO:  return 0x01000007;
+            case PluralRules.KEYWORD_FEW:  return 0x01000008;
+            case PluralRules.KEYWORD_MANY: return 0x01000009;
             default:                     return ID_OTHER;
         }
     }
 
-    private static String stringForQuantityCode(int quantityCode) {
-        switch (quantityCode) {
-            case NativePluralRules.ZERO: return "zero";
-            case NativePluralRules.ONE:  return "one";
-            case NativePluralRules.TWO:  return "two";
-            case NativePluralRules.FEW:  return "few";
-            case NativePluralRules.MANY: return "many";
-            default:                     return "other";
-        }
-    }
-
     /**
      * Return the string value associated with a particular resource ID.  It
      * will be stripped of any styled text information.
@@ -2059,7 +2047,7 @@
         }
         synchronized (sSync) {
             if (mPluralRule != null) {
-                mPluralRule = NativePluralRules.forLocale(config.locale);
+                mPluralRule = PluralRules.forLocale(config.locale);
             }
         }
     }
diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java
index fa9f479..b83fb26 100644
--- a/core/java/android/net/LocalSocketImpl.java
+++ b/core/java/android/net/LocalSocketImpl.java
@@ -25,6 +25,9 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
+import android.system.StructLinger;
+import android.system.StructTimeval;
+import android.util.MutableInt;
 
 /**
  * Socket implementation used for android.net.LocalSocket and
@@ -59,7 +62,13 @@
             FileDescriptor myFd = fd;
             if (myFd == null) throw new IOException("socket closed");
 
-            return available_native(myFd);
+            MutableInt avail = new MutableInt(0);
+            try {
+                Os.ioctlInt(myFd, OsConstants.FIONREAD, avail);
+            } catch (ErrnoException e) {
+                throw e.rethrowAsIOException();
+            }
+            return avail.value;
         }
 
         /** {@inheritDoc} */
@@ -156,18 +165,31 @@
         public void flush() throws IOException {
             FileDescriptor myFd = fd;
             if (myFd == null) throw new IOException("socket closed");
-            while(pending_native(myFd) > 0) {
+
+            // Loop until the output buffer is empty.
+            MutableInt pending = new MutableInt(0);
+            while (true) {
+                try {
+                    // See linux/net/unix/af_unix.c
+                    Os.ioctlInt(myFd, OsConstants.TIOCOUTQ, pending);
+                } catch (ErrnoException e) {
+                    throw e.rethrowAsIOException();
+                }
+
+                if (pending.value <= 0) {
+                    // The output buffer is empty.
+                    break;
+                }
+
                 try {
                     Thread.sleep(10);
                 } catch (InterruptedException ie) {
-                    return;
+                    break;
                 }
             }
         }
     }
 
-    private native int pending_native(FileDescriptor fd) throws IOException;
-    private native int available_native(FileDescriptor fd) throws IOException;
     private native int read_native(FileDescriptor fd) throws IOException;
     private native int readba_native(byte[] b, int off, int len,
             FileDescriptor fd) throws IOException;
@@ -179,28 +201,8 @@
             int namespace) throws IOException;
     private native void bindLocal(FileDescriptor fd, String name, int namespace)
             throws IOException;
-    private native void listen_native(FileDescriptor fd, int backlog)
-            throws IOException;
-    private native void shutdown(FileDescriptor fd, boolean shutdownInput);
     private native Credentials getPeerCredentials_native(
             FileDescriptor fd) throws IOException;
-    private native int getOption_native(FileDescriptor fd, int optID)
-            throws IOException;
-    private native void setOption_native(FileDescriptor fd, int optID,
-            int b, int value) throws IOException;
-
-//    private native LocalSocketAddress getSockName_native
-//            (FileDescriptor fd) throws IOException;
-
-    /**
-     * Accepts a connection on a server socket.
-     *
-     * @param fd file descriptor of server socket
-     * @param s socket implementation that will become the new socket
-     * @return file descriptor of new socket
-     */
-    private native FileDescriptor accept
-            (FileDescriptor fd, LocalSocketImpl s) throws IOException;
 
     /**
      * Create a new instance.
@@ -232,7 +234,7 @@
      * or {@link LocalSocket#SOCKET_SEQPACKET}
      * @throws IOException
      */
-    public void create (int sockType) throws IOException {
+    public void create(int sockType) throws IOException {
         // no error if socket already created
         // need this for LocalServerSocket.accept()
         if (fd == null) {
@@ -311,8 +313,11 @@
         if (fd == null) {
             throw new IOException("socket not created");
         }
-
-        listen_native(fd, backlog);
+        try {
+            Os.listen(fd, backlog);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
     }
 
     /**
@@ -322,14 +327,17 @@
      * @param s a socket that will be used to represent the new connection.
      * @throws IOException
      */
-    protected void accept(LocalSocketImpl s) throws IOException
-    {
+    protected void accept(LocalSocketImpl s) throws IOException {
         if (fd == null) {
             throw new IOException("socket not created");
         }
 
-        s.fd = accept(fd, s);
-        s.mFdCreatedInternally = true;
+        try {
+            s.fd = Os.accept(fd, null /* address */);
+            s.mFdCreatedInternally = true;
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
     }
 
     /**
@@ -396,7 +404,11 @@
             throw new IOException("socket not created");
         }
 
-        shutdown(fd, true);
+        try {
+            Os.shutdown(fd, OsConstants.SHUT_RD);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
     }
 
     /**
@@ -410,7 +422,11 @@
             throw new IOException("socket not created");
         }
 
-        shutdown(fd, false);
+        try {
+            Os.shutdown(fd, OsConstants.SHUT_WR);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
     }
 
     protected FileDescriptor getFileDescriptor()
@@ -434,24 +450,49 @@
             throw new IOException("socket not created");
         }
 
-        if (optID == SocketOptions.SO_TIMEOUT) {
-            return 0;
-        }
-        
-        int value = getOption_native(fd, optID);
-        switch (optID)
-        {
-            case SocketOptions.SO_RCVBUF:
-            case SocketOptions.SO_SNDBUF:
-                return value;
-            case SocketOptions.SO_REUSEADDR:
-            default:
-                return value;
+        try {
+            Object toReturn;
+            switch (optID) {
+                case SocketOptions.SO_TIMEOUT:
+                    StructTimeval timeval = Os.getsockoptTimeval(fd, OsConstants.SOL_SOCKET,
+                            OsConstants.SO_SNDTIMEO);
+                    toReturn = (int) timeval.toMillis();
+                    break;
+                case SocketOptions.SO_RCVBUF:
+                case SocketOptions.SO_SNDBUF:
+                case SocketOptions.SO_REUSEADDR:
+                    int osOpt = javaSoToOsOpt(optID);
+                    toReturn = Os.getsockoptInt(fd, OsConstants.SOL_SOCKET, osOpt);
+                    break;
+                case SocketOptions.SO_LINGER:
+                    StructLinger linger=
+                            Os.getsockoptLinger(fd, OsConstants.SOL_SOCKET, OsConstants.SO_LINGER);
+                    if (!linger.isOn()) {
+                        toReturn = -1;
+                    } else {
+                        toReturn = linger.l_linger;
+                    }
+                    break;
+                case SocketOptions.TCP_NODELAY:
+                    toReturn = Os.getsockoptInt(fd, OsConstants.IPPROTO_TCP,
+                            OsConstants.TCP_NODELAY);
+                    break;
+                default:
+                    throw new IOException("Unknown option: " + optID);
+            }
+            return toReturn;
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
         }
     }
 
     public void setOption(int optID, Object value)
             throws IOException {
+
+        if (fd == null) {
+            throw new IOException("socket not created");
+        }
+
         /*
          * Boolean.FALSE is used to disable some options, so it
          * is important to distinguish between FALSE and unset.
@@ -460,11 +501,6 @@
          */
         int boolValue = -1;
         int intValue = 0;
-
-        if (fd == null) {
-            throw new IOException("socket not created");
-        }
-
         if (value instanceof Integer) {
             intValue = (Integer)value;
         } else if (value instanceof Boolean) {
@@ -473,7 +509,39 @@
             throw new IOException("bad value: " + value);
         }
 
-        setOption_native(fd, optID, boolValue, intValue);
+        try {
+            switch (optID) {
+                case SocketOptions.SO_LINGER:
+                    StructLinger linger = new StructLinger(boolValue, intValue);
+                    Os.setsockoptLinger(fd, OsConstants.SOL_SOCKET, OsConstants.SO_LINGER, linger);
+                    break;
+                case SocketOptions.SO_TIMEOUT:
+                    /*
+                     * SO_TIMEOUT from the core library gets converted to
+                     * SO_SNDTIMEO, but the option is supposed to set both
+                     * send and receive timeouts. Note: The incoming timeout
+                     * value is in milliseconds.
+                     */
+                    StructTimeval timeval = StructTimeval.fromMillis(intValue);
+                    Os.setsockoptTimeval(fd, OsConstants.SOL_SOCKET, OsConstants.SO_SNDTIMEO,
+                            timeval);
+                    break;
+                case SocketOptions.SO_RCVBUF:
+                case SocketOptions.SO_SNDBUF:
+                case SocketOptions.SO_REUSEADDR:
+                    int osOpt = javaSoToOsOpt(optID);
+                    Os.setsockoptInt(fd, OsConstants.SOL_SOCKET, osOpt, intValue);
+                    break;
+                case SocketOptions.TCP_NODELAY:
+                    Os.setsockoptInt(fd, OsConstants.IPPROTO_TCP, OsConstants.TCP_NODELAY,
+                            intValue);
+                    break;
+                default:
+                    throw new IOException("Unknown option: " + optID);
+            }
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
     }
 
     /**
@@ -517,8 +585,7 @@
      * @return non-null; peer credentials
      * @throws IOException
      */
-    public Credentials getPeerCredentials() throws IOException
-    {
+    public Credentials getPeerCredentials() throws IOException {
         return getPeerCredentials_native(fd);
     }
 
@@ -528,15 +595,26 @@
      * @return non-null; socket name
      * @throws IOException on failure
      */
-    public LocalSocketAddress getSockAddress() throws IOException
-    {
+    public LocalSocketAddress getSockAddress() throws IOException {
+        // This method has never been implemented.
         return null;
-        //TODO implement this
-        //return getSockName_native(fd);
     }
 
     @Override
     protected void finalize() throws IOException {
         close();
     }
+
+    private static int javaSoToOsOpt(int optID) {
+        switch (optID) {
+            case SocketOptions.SO_SNDBUF:
+                return OsConstants.SO_SNDBUF;
+            case SocketOptions.SO_RCVBUF:
+                return OsConstants.SO_RCVBUF;
+            case SocketOptions.SO_REUSEADDR:
+                return OsConstants.SO_REUSEADDR;
+            default:
+                throw new UnsupportedOperationException("Unknown option: " + optID);
+        }
+    }
 }
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 0f37ac7..c4f62ba 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -46,7 +46,7 @@
     boolean isDeviceIdleMode();
 
     void reboot(boolean confirm, String reason, boolean wait);
-    void shutdown(boolean confirm, boolean wait);
+    void shutdown(boolean confirm, String reason, boolean wait);
     void crash(String message);
 
     void setStayOnSetting(int val);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 9a1a03e..69974fa 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -387,7 +387,13 @@
      * @hide
      */
     public static final String REBOOT_RECOVERY = "recovery";
-    
+
+    /**
+     * The value to pass as the 'reason' argument to android_reboot().
+     * @hide
+     */
+    public static final String SHUTDOWN_USER_REQUESTED = "userrequested";
+
     final Context mContext;
     final IPowerManager mService;
     final Handler mHandler;
@@ -926,13 +932,14 @@
      * Turn off the device.
      *
      * @param confirm If true, shows a shutdown confirmation dialog.
+     * @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
      * @param wait If true, this call waits for the shutdown to complete and does not return.
      *
      * @hide
      */
-    public void shutdown(boolean confirm, boolean wait) {
+    public void shutdown(boolean confirm, String reason, boolean wait) {
         try {
-            mService.shutdown(confirm, wait);
+            mService.shutdown(confirm, reason, wait);
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 0c79094..8c544f4 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -68,7 +68,7 @@
     /** Send progress to listeners no more often than this (in ms). */
     private static final long PUBLISH_PROGRESS_INTERVAL_MS = 500;
 
-    /** Used to communicate with recovery.  See bootable/recovery/recovery.c. */
+    /** Used to communicate with recovery.  See bootable/recovery/recovery.cpp. */
     private static File RECOVERY_DIR = new File("/cache/recovery");
     private static File COMMAND_FILE = new File(RECOVERY_DIR, "command");
     private static File UNCRYPT_FILE = new File(RECOVERY_DIR, "uncrypt_file");
@@ -506,18 +506,32 @@
         String[] names = RECOVERY_DIR.list();
         for (int i = 0; names != null && i < names.length; i++) {
             if (names[i].startsWith(LAST_PREFIX)) continue;
-            File f = new File(RECOVERY_DIR, names[i]);
-            if (!f.delete()) {
-                Log.e(TAG, "Can't delete: " + f);
-            } else {
-                Log.i(TAG, "Deleted: " + f);
-            }
+            recursiveDelete(new File(RECOVERY_DIR, names[i]));
         }
 
         return log;
     }
 
     /**
+     * Internally, delete a given file or directory recursively.
+     */
+    private static void recursiveDelete(File name) {
+        if (name.isDirectory()) {
+            String[] files = name.list();
+            for (int i = 0; files != null && i < files.length; i++) {
+                File f = new File(name, files[i]);
+                recursiveDelete(f);
+            }
+        }
+
+        if (!name.delete()) {
+            Log.e(TAG, "Can't delete: " + name);
+        } else {
+            Log.i(TAG, "Deleted: " + name);
+        }
+    }
+
+    /**
      * Internally, recovery treats each line of the command file as a separate
      * argv, so we only need to protect against newlines and nulls.
      */
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index f10b982..87ce12c 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -1574,7 +1574,8 @@
      */
     public static void conditionallyCheckInstanceCounts() {
         VmPolicy policy = getVmPolicy();
-        if (policy.classInstanceLimit.size() == 0) {
+        int policySize = policy.classInstanceLimit.size();
+        if (policySize == 0) {
             return;
         }
 
@@ -1583,15 +1584,17 @@
         System.gc();
 
         // Note: classInstanceLimit is immutable, so this is lock-free
-        for (Map.Entry<Class, Integer> entry : policy.classInstanceLimit.entrySet()) {
-            Class klass = entry.getKey();
-            int limit = entry.getValue();
-            long instances = VMDebug.countInstancesOfClass(klass, false);
-            if (instances <= limit) {
-                continue;
+        // Create the classes array.
+        Class[] classes = policy.classInstanceLimit.keySet().toArray(new Class[policySize]);
+        long[] instanceCounts = VMDebug.countInstancesOfClasses(classes, false);
+        for (int i = 0; i < classes.length; ++i) {
+            Class klass = classes[i];
+            int limit = policy.classInstanceLimit.get(klass);
+            long instances = instanceCounts[i];
+            if (instances > limit) {
+                Throwable tr = new InstanceCountViolation(klass, instances, limit);
+                onVmPolicyViolation(tr.getMessage(), tr);
             }
-            Throwable tr = new InstanceCountViolation(klass, instances, limit);
-            onVmPolicyViolation(tr.getMessage(), tr);
         }
     }
 
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 31b5849..7529c52 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -75,6 +75,10 @@
     public static final long TRACE_TAG_BIONIC = 1L << 16;
     /** @hide */
     public static final long TRACE_TAG_POWER = 1L << 17;
+    /** @hide */
+    public static final long TRACE_TAG_PACKAGE_MANAGER = 1L << 18;
+    /** @hide */
+    public static final long TRACE_TAG_SYSTEM_SERVER = 1L << 19;
 
     private static final long TRACE_TAG_NOT_READY = 1L << 63;
     private static final int MAX_SECTION_NAME_LEN = 127;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3b7f6aa..b3e3ecb 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -19006,7 +19006,7 @@
 
     /**
      * Returns the suggested minimum width that the view should use. This
-     * returns the maximum of the view's minimum width)
+     * returns the maximum of the view's minimum width
      * and the background's minimum width
      *  ({@link android.graphics.drawable.Drawable#getMinimumWidth()}).
      * <p>
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index a04c4f1..2cde03d 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -372,7 +372,6 @@
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
  *   <li>{@link #getEventTime()}  - The event time.</li>
- *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #getParcelableData()} - The posted {@link android.app.Notification}.</li>
  *   <li>{@link #getText()} - Text for providing more context.</li>
  * </ul>
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index de8ccc1..f2bb55a 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -415,7 +415,7 @@
      * Notify the host application that the scale applied to the WebView has
      * changed.
      *
-     * @param view he WebView that is initiating the callback.
+     * @param view The WebView that is initiating the callback.
      * @param oldScale The old scale factor
      * @param newScale The new scale factor
      */
diff --git a/core/java/android/widget/Adapter.java b/core/java/android/widget/Adapter.java
index 88b54bf..518718f 100644
--- a/core/java/android/widget/Adapter.java
+++ b/core/java/android/widget/Adapter.java
@@ -130,8 +130,7 @@
      * type of View for all items, this method should return 1.
      * </p>
      * <p>
-     * This method will only be called when when the adapter is set on the
-     * the {@link AdapterView}.
+     * This method will only be called when the adapter is set on the {@link AdapterView}.
      * </p>
      * 
      * @return The number of types of Views that will be created by this adapter
@@ -148,4 +147,3 @@
       */
      boolean isEmpty();
 }
-
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index 27aec4e..17ca904d 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -3366,10 +3366,11 @@
                             + pkgList.keyAt(index) + "/" + proc.mUid
                             + " for multi-proc " + proc.mName + " version " + proc.mVersion);
                 }
+                String savedName = proc.mName;
                 proc = pkg.mProcesses.get(proc.mName);
                 if (proc == null) {
                     throw new IllegalStateException("Didn't create per-package process "
-                            + proc.mName + " in pkg " + pkg.mPackageName + "/" + pkg.mUid);
+                            + savedName + " in pkg " + pkg.mPackageName + "/" + pkg.mUid);
                 }
                 holder.state = proc;
             }
diff --git a/core/java/com/android/internal/app/ShutdownActivity.java b/core/java/com/android/internal/app/ShutdownActivity.java
index 97521cf..745d28f 100644
--- a/core/java/com/android/internal/app/ShutdownActivity.java
+++ b/core/java/com/android/internal/app/ShutdownActivity.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.IPowerManager;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Slog;
@@ -30,6 +31,7 @@
     private static final String TAG = "ShutdownActivity";
     private boolean mReboot;
     private boolean mConfirm;
+    private boolean mUserRequested;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -38,6 +40,7 @@
         Intent intent = getIntent();
         mReboot = Intent.ACTION_REBOOT.equals(intent.getAction());
         mConfirm = intent.getBooleanExtra(Intent.EXTRA_KEY_CONFIRM, false);
+        mUserRequested = intent.getBooleanExtra(Intent.EXTRA_USER_REQUESTED_SHUTDOWN, false);
         Slog.i(TAG, "onCreate(): confirm=" + mConfirm);
 
         Thread thr = new Thread("ShutdownActivity") {
@@ -49,7 +52,9 @@
                     if (mReboot) {
                         pm.reboot(mConfirm, null, false);
                     } else {
-                        pm.shutdown(mConfirm, false);
+                        pm.shutdown(mConfirm,
+                                    mUserRequested ? PowerManager.SHUTDOWN_USER_REQUESTED : null,
+                                    false);
                     }
                 } catch (RemoteException e) {
                 }
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 06919e1..cbdb754 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -179,8 +179,18 @@
 
     static void preload() {
         Log.d(TAG, "begin preload");
-        preloadClasses();
-        preloadResources();
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClasses");
+            preloadClasses();
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+        }
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources");
+            preloadResources();
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+        }
         preloadOpenGL();
         preloadSharedLibraries();
         preloadTextResources();
@@ -266,6 +276,7 @@
                 }
 
                 try {
+                    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClass " + line);
                     if (false) {
                         Log.v(TAG, "Preloading " + line + "...");
                     }
@@ -289,6 +300,8 @@
                         throw (RuntimeException) t;
                     }
                     throw new RuntimeException(t);
+                } finally {
+                    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
                 }
             }
 
@@ -302,7 +315,9 @@
             runtime.setTargetHeapUtilization(defaultUtilization);
 
             // Fill in dex caches with classes, fields, and methods brought in by preloading.
+            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
             runtime.preloadDexCaches();
+            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
 
             // Bring back root. We'll need it later if we're in the zygote.
             if (droppedPriviliges) {
@@ -564,42 +579,57 @@
 
     public static void main(String argv[]) {
         try {
-            RuntimeInit.enableDdms();
-            // Start profiling the zygote initialization.
-            SamplingProfilerIntegration.start();
-
             boolean startSystemServer = false;
             String socketName = "zygote";
             String abiList = null;
-            for (int i = 1; i < argv.length; i++) {
-                if ("start-system-server".equals(argv[i])) {
-                    startSystemServer = true;
-                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
-                    abiList = argv[i].substring(ABI_LIST_ARG.length());
-                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
-                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
-                } else {
-                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
+            try {
+                Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
+                RuntimeInit.enableDdms();
+                // Start profiling the zygote initialization.
+                SamplingProfilerIntegration.start();
+
+                for (int i = 1; i < argv.length; i++) {
+                    if ("start-system-server".equals(argv[i])) {
+                        startSystemServer = true;
+                    } else if (argv[i].startsWith(ABI_LIST_ARG)) {
+                        abiList = argv[i].substring(ABI_LIST_ARG.length());
+                    } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
+                        socketName = argv[i].substring(SOCKET_NAME_ARG.length());
+                    } else {
+                        throw new RuntimeException("Unknown command line argument: " + argv[i]);
+                    }
                 }
+
+                if (abiList == null) {
+                    throw new RuntimeException("No ABI list supplied.");
+                }
+
+                registerZygoteSocket(socketName);
+                try {
+                    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
+                    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
+                            SystemClock.uptimeMillis());
+                    preload();
+                    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
+                            SystemClock.uptimeMillis());
+                } finally {
+                    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+                }
+
+                // Finish profiling the zygote initialization.
+                SamplingProfilerIntegration.writeZygoteSnapshot();
+
+                // Do an initial gc to clean up after startup
+                try {
+                    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
+                    gcAndFinalize();
+                } finally {
+                    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+                }
+            } finally {
+                Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
             }
 
-            if (abiList == null) {
-                throw new RuntimeException("No ABI list supplied.");
-            }
-
-            registerZygoteSocket(socketName);
-            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
-                SystemClock.uptimeMillis());
-            preload();
-            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
-                SystemClock.uptimeMillis());
-
-            // Finish profiling the zygote initialization.
-            SamplingProfilerIntegration.writeZygoteSnapshot();
-
-            // Do an initial gc to clean up after startup
-            gcAndFinalize();
-
             // Disable tracing so that forked processes do not inherit stale tracing tags from
             // Zygote.
             Trace.setTracingEnabled(false);
diff --git a/core/java/com/android/internal/util/WithFramework.java b/core/java/com/android/internal/util/WithFramework.java
deleted file mode 100644
index 7d8596f..0000000
--- a/core/java/com/android/internal/util/WithFramework.java
+++ /dev/null
@@ -1,58 +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 com.android.internal.util;
-
-import java.lang.reflect.Method;
-
-/**
- * Binds native framework methods and then invokes a main class with the
- * remaining arguments.
- */
-class WithFramework {
-
-    /**
-     * Invokes main(String[]) method on class in args[0] with args[1..n].
-     */
-    public static void main(String[] args) throws Exception {
-        if (args.length == 0) {
-            printUsage();
-            return;
-        }
-
-        Class<?> mainClass = Class.forName(args[0]);
-
-        System.loadLibrary("android_runtime");
-        if (registerNatives() < 0) {
-            throw new RuntimeException("Error registering natives.");
-        }
-
-        String[] newArgs = new String[args.length - 1];
-        System.arraycopy(args, 1, newArgs, 0, newArgs.length);
-        Method mainMethod = mainClass.getMethod("main", String[].class);
-        mainMethod.invoke(null, new Object[] { newArgs });
-    }
-
-    private static void printUsage() {
-        System.err.println("Usage: dalvikvm " + WithFramework.class.getName()
-                + " [main class] [args]");
-    }
-
-    /**
-     * Registers native functions. See AndroidRuntime.cpp.
-     */
-    static native int registerNatives();
-}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 2fad2f6..df2334f 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#define ATRACE_TAG ATRACE_TAG_DALVIK
 #define LOG_TAG "AndroidRuntime"
 //#define LOG_NDEBUG 0
 
@@ -23,6 +24,7 @@
 #include <binder/IServiceManager.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
+#include <utils/Trace.h>
 #include <binder/Parcel.h>
 #include <utils/threads.h>
 #include <cutils/properties.h>
@@ -1439,6 +1441,7 @@
  */
 /*static*/ int AndroidRuntime::startReg(JNIEnv* env)
 {
+    ATRACE_NAME("RegisterAndroidNatives");
     /*
      * This hook causes all future threads created in this process to be
      * attached to the JavaVM.  (This needs to go away in favor of JNI
@@ -1473,20 +1476,10 @@
 }
 
 /**
- * Used by WithFramework to register native functions.
+ * Used by surface flinger's DdmConnection to register native methods from
+ * the framework.
  */
-extern "C"
-jint Java_com_android_internal_util_WithFramework_registerNatives(
-        JNIEnv* env, jclass clazz) {
+extern "C" jint registerFrameworkNatives(JNIEnv* env) {
     return register_jni_procs(gRegJNI, NELEM(gRegJNI), env);
 }
-
-/**
- * Used by LoadClass to register native functions.
- */
-extern "C"
-jint Java_LoadClass_registerNatives(JNIEnv* env, jclass clazz) {
-    return register_jni_procs(gRegJNI, NELEM(gRegJNI), env);
-}
-
 }   // namespace android
diff --git a/core/jni/android_net_LocalSocketImpl.cpp b/core/jni/android_net_LocalSocketImpl.cpp
index 97abe6b..c137b17 100644
--- a/core/jni/android_net_LocalSocketImpl.cpp
+++ b/core/jni/android_net_LocalSocketImpl.cpp
@@ -112,317 +112,6 @@
     }
 }
 
-/* private native void listen_native(int fd, int backlog) throws IOException; */
-static void
-socket_listen (JNIEnv *env, jobject object, jobject fileDescriptor, jint backlog)
-{
-    int ret;
-    int fd;
-
-    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
-    if (env->ExceptionCheck()) {
-        return;
-    }
-
-    ret = listen(fd, backlog);
-
-    if (ret < 0) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-}
-
-/*    private native FileDescriptor
-**    accept (FileDescriptor fd, LocalSocketImpl s)
-**                                   throws IOException;
-*/
-static jobject
-socket_accept (JNIEnv *env, jobject object, jobject fileDescriptor, jobject s)
-{
-    union {
-        struct sockaddr address;
-        struct sockaddr_un un_address;
-    } sa;
-
-    int ret;
-    int retFD;
-    int fd;
-    socklen_t addrlen;
-
-    if (s == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return NULL;
-    }
-
-    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
-    if (env->ExceptionCheck()) {
-        return NULL;
-    }
-
-    do {
-        addrlen = sizeof(sa);
-        ret = accept(fd, &(sa.address), &addrlen);
-    } while (ret < 0 && errno == EINTR);
-
-    if (ret < 0) {
-        jniThrowIOException(env, errno);
-        return NULL;
-    }
-
-    retFD = ret;
-
-    return jniCreateFileDescriptor(env, retFD);
-}
-
-/* private native void shutdown(FileDescriptor fd, boolean shutdownInput) */
-
-static void
-socket_shutdown (JNIEnv *env, jobject object, jobject fileDescriptor,
-                    jboolean shutdownInput)
-{
-    int ret;
-    int fd;
-
-    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
-    if (env->ExceptionCheck()) {
-        return;
-    }
-
-    ret = shutdown(fd, shutdownInput ? SHUT_RD : SHUT_WR);
-
-    if (ret < 0) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-}
-
-static bool
-java_opt_to_real(int optID, int* opt, int* level)
-{
-    switch (optID)
-    {
-        case 4098:
-            *opt = SO_RCVBUF;
-            *level = SOL_SOCKET;
-            return true;
-        case 4097:
-            *opt = SO_SNDBUF;
-            *level = SOL_SOCKET;
-            return true;
-        case 4102:
-            *opt = SO_SNDTIMEO;
-            *level = SOL_SOCKET;
-            return true;
-        case 128:
-            *opt = SO_LINGER;
-            *level = SOL_SOCKET;
-            return true;
-        case 1:
-            *opt = TCP_NODELAY;
-            *level = IPPROTO_TCP;
-            return true;
-        case 4:
-            *opt = SO_REUSEADDR;
-            *level = SOL_SOCKET;
-            return true;
-
-    }
-    return false;
-}
-
-static jint
-socket_getOption(JNIEnv *env, jobject object, jobject fileDescriptor, jint optID)
-{
-    int ret, value;
-    int opt, level;
-    int fd;
-
-    socklen_t size = sizeof(int);
-
-    if (!java_opt_to_real(optID, &opt, &level)) {
-        jniThrowIOException(env, -1);
-        return 0;
-    }
-
-    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
-    if (env->ExceptionCheck()) {
-        return 0;
-    }
-
-    switch (opt)
-    {
-        case SO_LINGER:
-        {
-            struct linger lingr;
-            size = sizeof(lingr);
-            ret = getsockopt(fd, level, opt, &lingr, &size);
-            if (!lingr.l_onoff) {
-                value = -1;
-            } else {
-                value = lingr.l_linger;
-            }
-            break;
-        }
-        default:
-            ret = getsockopt(fd, level, opt, &value, &size);
-            break;
-    }
-
-
-    if (ret != 0) {
-        jniThrowIOException(env, errno);
-        return 0;
-    }
-
-    return value;
-}
-
-static void socket_setOption(
-        JNIEnv *env, jobject object, jobject fileDescriptor, jint optID,
-        jint boolValue, jint intValue) {
-    int ret;
-    int optname;
-    int level;
-    int fd;
-
-    if (!java_opt_to_real(optID, &optname, &level)) {
-        jniThrowIOException(env, -1);
-        return;
-    }
-
-    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
-    if (env->ExceptionCheck()) {
-        return;
-    }
-
-    switch (optname) {
-        case SO_LINGER: {
-            /*
-             * SO_LINGER is special because it needs to use a special
-             * "linger" struct as well as use the incoming boolean
-             * argument specially.
-             */
-            struct linger lingr;
-            lingr.l_onoff = boolValue ? 1 : 0; // Force it to be 0 or 1.
-            lingr.l_linger = intValue;
-            ret = setsockopt(fd, level, optname, &lingr, sizeof(lingr));
-            break;
-        }
-        case SO_SNDTIMEO: {
-            /*
-             * SO_TIMEOUT from the core library gets converted to
-             * SO_SNDTIMEO, but the option is supposed to set both
-             * send and receive timeouts. Note: The incoming timeout
-             * value is in milliseconds.
-             */
-            struct timeval timeout;
-            timeout.tv_sec = intValue / 1000;
-            timeout.tv_usec = (intValue % 1000) * 1000;
-
-            ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,
-                    (void *)&timeout, sizeof(timeout));
-
-            if (ret == 0) {
-                ret = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO,
-                        (void *)&timeout, sizeof(timeout));
-            }
-
-            break;
-        }
-        default: {
-            /*
-             * In all other cases, the translated option level and
-             * optname may be used directly for a call to setsockopt().
-             */
-            ret = setsockopt(fd, level, optname, &intValue, sizeof(intValue));
-            break;
-        }
-    }
-
-    if (ret != 0) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-}
-static jint socket_pending (JNIEnv *env, jobject object,
-        jobject fileDescriptor)
-{
-    int fd;
-
-    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
-    if (env->ExceptionCheck()) {
-        return (jint)-1;
-    }
-
-    int pending;
-    int ret = ioctl(fd, TIOCOUTQ, &pending);
-
-    // If this were a non-socket fd, there would be other cases to worry
-    // about...
-
-    //ALOGD("socket_pending, ioctl ret:%d, pending:%d", ret, pending);
-    if (ret < 0) {
-        jniThrowIOException(env, errno);
-        return (jint) 0;
-    }
-
-    return (jint)pending;
-}
-static jint socket_available (JNIEnv *env, jobject object,
-        jobject fileDescriptor)
-{
-    int fd;
-
-    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
-    if (env->ExceptionCheck()) {
-        return (jint)-1;
-    }
-
-#if 1
-    int avail;
-    int ret = ioctl(fd, FIONREAD, &avail);
-
-    // If this were a non-socket fd, there would be other cases to worry
-    // about...
-
-    if (ret < 0) {
-        jniThrowIOException(env, errno);
-        return (jint) 0;
-    }
-
-    return (jint)avail;
-#else
-// there appears to be a bionic bug that prevents this version from working.
-
-    ssize_t ret;
-    struct msghdr msg;
-
-    memset(&msg, 0, sizeof(msg));
-
-    do {
-        ret = recvmsg(fd, &msg, MSG_PEEK | MSG_DONTWAIT | MSG_NOSIGNAL);
-    } while (ret < 0 && errno == EINTR);
-
-
-    // MSG_PEEK returns 0 on EOF and EWOULDBLOCK on none available
-    if (ret < 0 && errno == EWOULDBLOCK) {
-        return 0;
-    } if (ret < 0) {
-        jniThrowIOException(env, errno);
-        return -1;
-    }
-
-    return (jint)ret;
-#endif
-}
-
 /**
  * Processes ancillary data, handling only
  * SCM_RIGHTS. Creates appropriate objects and sets appropriate
@@ -803,72 +492,14 @@
             creds.pid, creds.uid, creds.gid);
 }
 
-#if 0
-//TODO change this to return an instance of LocalSocketAddress
-static jobject socket_getSockName(JNIEnv *env,
-        jobject object, jobject fileDescriptor)
-{
-    int err;
-    int fd;
-
-    if (fileDescriptor == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return NULL;
-    }
-
-    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
-    if (env->ExceptionCheck()) {
-        return NULL;
-    }
-
-    union {
-        struct sockaddr address;
-        struct sockaddr_un un_address;
-    } sa;
-
-    memset(&sa, 0, sizeof(sa));
-
-    socklen_t namelen = sizeof(sa);
-    err = getsockname(fd, &(sa.address), &namelen);
-
-    if (err < 0) {
-        jniThrowIOException(env, errno);
-        return NULL;
-    }
-
-    if (sa.address.sa_family != AF_UNIX) {
-        // We think we're an impl only for AF_UNIX, so this should never happen.
-
-        jniThrowIOException(env, EINVAL);
-        return NULL;
-    }
-
-    if (sa.un_address.sun_path[0] == '\0') {
-    } else {
-    }
-
-
-
-
-}
-#endif
-
 /*
  * JNI registration.
  */
 static JNINativeMethod gMethods[] = {
      /* name, signature, funcPtr */
-    {"getOption_native", "(Ljava/io/FileDescriptor;I)I", (void*)socket_getOption},
-    {"setOption_native", "(Ljava/io/FileDescriptor;III)V", (void*)socket_setOption},
     {"connectLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V",
                                                 (void*)socket_connect_local},
     {"bindLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V", (void*)socket_bind_local},
-    {"listen_native", "(Ljava/io/FileDescriptor;I)V", (void*)socket_listen},
-    {"accept", "(Ljava/io/FileDescriptor;Landroid/net/LocalSocketImpl;)Ljava/io/FileDescriptor;", (void*)socket_accept},
-    {"shutdown", "(Ljava/io/FileDescriptor;Z)V", (void*)socket_shutdown},
-    {"available_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_available},
-    {"pending_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_pending},
     {"read_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_read},
     {"readba_native", "([BIILjava/io/FileDescriptor;)I", (void*) socket_readba},
     {"writeba_native", "([BIILjava/io/FileDescriptor;)V", (void*) socket_writeba},
@@ -876,9 +507,6 @@
     {"getPeerCredentials_native",
             "(Ljava/io/FileDescriptor;)Landroid/net/Credentials;",
             (void*) socket_get_peer_credentials}
-    //,{"getSockName_native", "(Ljava/io/FileDescriptor;)Ljava/lang/String;",
-    //        (void *) socket_getSockName}
-
 };
 
 int register_android_net_LocalSocketImpl(JNIEnv *env)
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index e8acd97..b969477 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -34,10 +34,7 @@
 #include <errno.h>
 #include <assert.h>
 #include <ctype.h>
-
-#ifdef HAVE_MALLOC_H
 #include <malloc.h>
-#endif
 
 namespace android
 {
@@ -128,32 +125,20 @@
 
 static jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz)
 {
-#ifdef HAVE_MALLOC_H
     struct mallinfo info = mallinfo();
     return (jlong) info.usmblks;
-#else
-    return -1;
-#endif
 }
 
 static jlong android_os_Debug_getNativeHeapAllocatedSize(JNIEnv *env, jobject clazz)
 {
-#ifdef HAVE_MALLOC_H
     struct mallinfo info = mallinfo();
     return (jlong) info.uordblks;
-#else
-    return -1;
-#endif
 }
 
 static jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz)
 {
-#ifdef HAVE_MALLOC_H
     struct mallinfo info = mallinfo();
     return (jlong) info.fordblks;
-#else
-    return -1;
-#endif
 }
 
 // Container used to retrieve graphics memory pss
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 0f5ba83f..a14afa0 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -451,15 +451,11 @@
         jniThrowNullPointerException(env, NULL);
         return NULL;
     }
-    const jchar* str = env->GetStringCritical(name, 0);
-    if (str == NULL) {
-        // Whatever, whatever.
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+    ScopedUtfChars name8(env, name);
+    if (name8.c_str() == NULL) {
         return NULL;
     }
-    String8 name8(reinterpret_cast<const char16_t*>(str),
-                  env->GetStringLength(name));
-    env->ReleaseStringCritical(name, str);
+
     int flags=0;
     switch (mode&0x30000000) {
         case 0:
@@ -482,7 +478,7 @@
     if (mode&0x00000001) realMode |= S_IROTH;
     if (mode&0x00000002) realMode |= S_IWOTH;
 
-    int fd = open(name8.string(), flags, realMode);
+    int fd = open(name8.c_str(), flags, realMode);
     if (fd < 0) {
         jniThrowException(env, "java/io/FileNotFoundException", strerror(errno));
         return NULL;
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index b431a3f..aef70be 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -368,8 +368,8 @@
     return;
   }
   jsize count = env->GetArrayLength(fdsToClose);
-  jint *ar = env->GetIntArrayElements(fdsToClose, 0);
-  if (!ar) {
+  ScopedIntArrayRO ar(env, fdsToClose);
+  if (ar.get() == NULL) {
       ALOGE("Bad fd array");
       RuntimeAbort(env);
   }
diff --git a/core/tests/overlaytests/testrunner.py b/core/tests/overlaytests/testrunner.py
index 3703f4a..2aa25ad 100755
--- a/core/tests/overlaytests/testrunner.py
+++ b/core/tests/overlaytests/testrunner.py
@@ -301,7 +301,7 @@
         return self.path
 
     def execute(self):
-        returncode, stdout, stderr = _adb_shell('md5 %s' % self.path)
+        returncode, stdout, stderr = _adb_shell('md5sum %s' % self.path)
         if returncode != 0:
             return returncode, stdout, stderr
         actual_md5 = stdout.split()[0]
diff --git a/data/keyboards/Android.mk b/data/keyboards/Android.mk
index 898efe8..4616838 100644
--- a/data/keyboards/Android.mk
+++ b/data/keyboards/Android.mk
@@ -32,7 +32,7 @@
 	$(hide) mkdir -p $(dir $@) && touch $@
 
 # Run validatekeymaps uncondionally for platform build.
-droidcore all_modules : $(LOCAL_BUILT_MODULE)
+droidcore : $(LOCAL_BUILT_MODULE)
 
 # Reset temp vars.
 validatekeymaps :=
diff --git a/docs/html/guide/topics/renderscript/reference/overview.jd b/docs/html/guide/topics/renderscript/reference/overview.jd
index 1aa791b..5e824ee 100644
--- a/docs/html/guide/topics/renderscript/reference/overview.jd
+++ b/docs/html/guide/topics/renderscript/reference/overview.jd
@@ -43,7 +43,7 @@
 </p>
 
 <p> To create vector literals, use the vector type followed by the values enclosed
-between parentheses, e.g. <code>(float3)(1.0f, 2.0f, 3.0f)</code>.
+between curly braces, e.g. <code>(float3){1.0f, 2.0f, 3.0f}</code>.
 </p>
 
 <p> Entries of a vector can be accessed using different naming styles.
diff --git a/docs/html/tools/debugging/debugging-log.jd b/docs/html/tools/debugging/debugging-log.jd
index d2baaf26..e222b2a 100644
--- a/docs/html/tools/debugging/debugging-log.jd
+++ b/docs/html/tools/debugging/debugging-log.jd
@@ -284,22 +284,8 @@
   <h2 id="viewingStd">Viewing stdout and stderr</h2>
 
   <p>By default, the Android system sends <code>stdout</code> and <code>stderr</code>
-  (<code>System.out</code> and <code>System.err</code>) output to <code>/dev/null</code>. In
-  processes that run the Dalvik VM, you can have the system write a copy of the output to the log
-  file. In this case, the system writes the messages to the log using the log tags
-  <code>stdout</code> and <code>stderr</code>, both with priority <code>I</code>.</p>
-
-  <p>To route the output in this way, you stop a running emulator/device instance and then use the
-  shell command <code>setprop</code> to enable the redirection of output. Here's how you do it:</p>
-  <pre>
-$ adb shell stop
-$ adb shell setprop log.redirect-stdio true
-$ adb shell start
-</pre>
-
-  <p>The system retains this setting until you terminate the emulator/device instance. To use the
-  setting as a default on the emulator/device instance, you can add an entry to
-  <code>/data/local.prop</code> on the device.</p>
+  output to <code>/dev/null</code>. (The Java <code>System.out</code> and <code>System.err</code>
+  streams go to the log.)
 
   <h2 id="DebuggingWebPages">Debugging Web Apps</h2>
   <p>
diff --git a/docs/knowntags.txt b/docs/knowntags.txt
index 5bebabb..3b7c8c7 100644
--- a/docs/knowntags.txt
+++ b/docs/knowntags.txt
@@ -15,7 +15,6 @@
 #
 # The grandfathered list.  We should get rid of these if possible.
 #
-@ToBeFixed
 @stable
 @com.intel.drl.spec_ref
 @ar.org.fitc.spec_ref
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index 2f28700..f682fb8 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -40,10 +40,9 @@
 # For the host
 # =====================================================
 include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 LOCAL_MODULE:= libandroidfw
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_HOST_OS := darwin linux windows
 LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
 LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
 LOCAL_SRC_FILES:= $(hostSources)
@@ -56,13 +55,10 @@
 # =====================================================
 
 include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 LOCAL_MODULE:= libandroidfw
-LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES:= $(deviceSources)
 LOCAL_C_INCLUDES := \
-    external/zlib \
     system/core/include
 LOCAL_STATIC_LIBRARIES := libziparchive libbase
 LOCAL_SHARED_LIBRARIES := \
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 2dc1c96..623ea89 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -34,7 +34,7 @@
 #include <utils/String8.h>
 #include <utils/threads.h>
 #include <utils/Timers.h>
-#ifdef HAVE_ANDROID_OS
+#ifdef __ANDROID__
 #include <cutils/trace.h>
 #endif
 
@@ -54,7 +54,7 @@
     _rc; })
 #endif
 
-#ifdef HAVE_ANDROID_OS
+#ifdef __ANDROID__
 #define MY_TRACE_BEGIN(x) ATRACE_BEGIN(x)
 #define MY_TRACE_END() ATRACE_END()
 #else
@@ -229,7 +229,7 @@
         *cookie = static_cast<int32_t>(mAssetPaths.size());
     }
 
-#ifdef HAVE_ANDROID_OS
+#ifdef __ANDROID__
     // Load overlays, if any
     asset_path oap;
     for (size_t idx = 0; mZipSet.getOverlay(ap.path, idx, &oap); idx++) {
@@ -657,7 +657,7 @@
                 ALOGV("Creating shared resources for %s", ap.path.string());
                 sharedRes = new ResTable();
                 sharedRes->add(ass, idmap, nextEntryIdx + 1, false);
-#ifdef HAVE_ANDROID_OS
+#ifdef __ANDROID__
                 const char* data = getenv("ANDROID_DATA");
                 LOG_ALWAYS_FATAL_IF(data == NULL, "ANDROID_DATA not set");
                 String8 overlaysListPath(data);
@@ -1545,7 +1545,7 @@
      */
     int dirNameLen = dirName.length();
     void *iterationCookie;
-    if (!pZip->startIteration(&iterationCookie)) {
+    if (!pZip->startIteration(&iterationCookie, dirName.string(), NULL)) {
         ALOGW("ZipFileRO::startIteration returned false");
         return false;
     }
@@ -1560,9 +1560,7 @@
             continue;
         }
         //printf("Comparing %s in %s?\n", nameBuf, dirName.string());
-        if (dirNameLen == 0 ||
-            (strncmp(nameBuf, dirName.string(), dirNameLen) == 0 &&
-             nameBuf[dirNameLen] == '/'))
+        if (dirNameLen == 0 || nameBuf[dirNameLen] == '/')
         {
             const char* cp;
             const char* nextSlash;
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 62aabb1..806eeda 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -47,7 +47,7 @@
 
 namespace android {
 
-#ifdef HAVE_WINSOCK
+#if defined(_WIN32)
 #undef  nhtol
 #undef  htonl
 #define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
@@ -727,7 +727,7 @@
                     AutoMutex lock(mDecodeLock);
 
                     if (mCache == NULL) {
-#ifndef HAVE_ANDROID_OS
+#ifndef __ANDROID__
                         if (kDebugStringPoolNoisy) {
                             ALOGI("CREATING STRING CACHE OF %zu bytes",
                                     mHeader->stringCount*sizeof(char16_t**));
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index a6f6d8c..49fe8a2 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -39,7 +39,7 @@
 class _ZipEntryRO {
 public:
     ZipEntry entry;
-    ZipEntryName name;
+    ZipString name;
     void *cookie;
 
     _ZipEntryRO() : cookie(NULL) {}
@@ -80,7 +80,7 @@
 {
     _ZipEntryRO* data = new _ZipEntryRO;
 
-    data->name = ZipEntryName(entryName);
+    data->name = ZipString(entryName);
 
     const int32_t error = FindEntry(mHandle, data->name, &(data->entry));
     if (error) {
@@ -133,8 +133,8 @@
 bool ZipFileRO::startIteration(void** cookie, const char* prefix, const char* suffix)
 {
     _ZipEntryRO* ze = new _ZipEntryRO;
-    ZipEntryName pe(prefix ? prefix : "");
-    ZipEntryName se(suffix ? suffix : "");
+    ZipString pe(prefix ? prefix : "");
+    ZipString se(suffix ? suffix : "");
     int32_t error = StartIteration(mHandle, &(ze->cookie),
                                    prefix ? &pe : NULL,
                                    suffix ? &se : NULL);
diff --git a/libs/androidfw/tests/BackupData_test.cpp b/libs/androidfw/tests/BackupData_test.cpp
index 92af7fe..e25b616 100644
--- a/libs/androidfw/tests/BackupData_test.cpp
+++ b/libs/androidfw/tests/BackupData_test.cpp
@@ -108,7 +108,7 @@
     EXPECT_EQ(DATA1[i], dataBytes[i])
              << "data character " << i << " should be equal";
   }
-  delete dataBytes;
+  delete[] dataBytes;
   delete writer;
   delete reader;
 }
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp
index 0dababd..cd30b18 100644
--- a/libs/hwui/AnimatorManager.cpp
+++ b/libs/hwui/AnimatorManager.cpp
@@ -124,8 +124,6 @@
 }
 
 void AnimatorManager::animateNoDamage(TreeInfo& info) {
-    if (!mAnimators.size()) return;
-
     animateCommon(info);
 }
 
@@ -169,7 +167,7 @@
 };
 
 void AnimatorManager::endAllActiveAnimators() {
-    ALOGD("endAllStagingAnimators on %p (%s) with handle %p",
+    ALOGD("endAllActiveAnimators on %p (%s) with handle %p",
             &mParent, mParent.getName(), mAnimationHandle);
     EndActiveAnimatorsFunctor functor(mAnimationHandle->context());
     for_each(mAnimators.begin(), mAnimators.end(), functor);
diff --git a/libs/hwui/Extensions.cpp b/libs/hwui/Extensions.cpp
index 2a82216..d96775a 100644
--- a/libs/hwui/Extensions.cpp
+++ b/libs/hwui/Extensions.cpp
@@ -58,6 +58,7 @@
     mHasTiledRendering = hasGlExtension("GL_QCOM_tiled_rendering");
     mHas1BitStencil = hasGlExtension("GL_OES_stencil1");
     mHas4BitStencil = hasGlExtension("GL_OES_stencil4");
+    mHasUnpackSubImage = hasGlExtension("GL_EXT_unpack_subimage");
 
     // Query EGL extensions
     findExtensions(eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS), mEglExtensionList);
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index e7d317d..a4eef0f 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -44,7 +44,7 @@
     inline bool has1BitStencil() const { return mHas1BitStencil; }
     inline bool has4BitStencil() const { return mHas4BitStencil; }
     inline bool hasNvSystemTime() const { return mHasNvSystemTime; }
-    inline bool hasUnpackRowLength() const { return mVersionMajor >= 3; }
+    inline bool hasUnpackRowLength() const { return mVersionMajor >= 3 || mHasUnpackSubImage; }
     inline bool hasPixelBufferObjects() const { return mVersionMajor >= 3; }
     inline bool hasOcclusionQueries() const { return mVersionMajor >= 3; }
     inline bool hasFloatTextures() const { return mVersionMajor >= 3; }
@@ -71,6 +71,7 @@
     bool mHas1BitStencil;
     bool mHas4BitStencil;
     bool mHasNvSystemTime;
+    bool mHasUnpackSubImage;
 
     int mVersionMajor;
     int mVersionMinor;
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 35051b7..9c2c119 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -474,7 +474,6 @@
     if (!mFunctor) return;
 
     bool first = true;
-    bool forceRebind = false;
     for (uint32_t i = 0; i < cacheTextures.size(); i++) {
         CacheTexture* texture = cacheTextures[i];
         if (texture->canDraw()) {
@@ -487,7 +486,6 @@
             mFunctor->draw(*texture, mLinearFiltering);
 
             texture->resetMesh();
-            forceRebind = false;
         }
     }
 }
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index a3ff080..7dd70d4 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -64,9 +64,7 @@
             throw new IllegalArgumentException();
         }
 
-        FileInputStream is = null;
-        try {
-            is = new FileInputStream(path);
+        try (FileInputStream is = new FileInputStream(path)) {
             FileDescriptor fd = is.getFD();
             setDataSource(fd, 0, 0x7ffffffffffffffL);
         } catch (FileNotFoundException fileEx) {
@@ -74,12 +72,6 @@
         } catch (IOException ioEx) {
             throw new IllegalArgumentException();
         }
-
-        try {
-            if (is != null) {
-                is.close();
-            }
-        } catch (Exception e) {}
     }
 
     /**
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 13b2878..bbd4c30 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -793,7 +793,7 @@
      * <li> {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}
      * </ul>
      *
-     * @param mode target video scaling mode. Most be one of the supported
+     * @param mode target video scaling mode. Must be one of the supported
      * video scaling modes; otherwise, IllegalArgumentException will be thrown.
      *
      * @see MediaPlayer#VIDEO_SCALING_MODE_SCALE_TO_FIT
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
index eb1a589..05df014 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
@@ -27,12 +27,9 @@
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import dalvik.annotation.TestTargetClass;
-
 import org.easymock.EasyMock;
 import org.easymock.IArgumentMatcher;
 
-@TestTargetClass(MediaInserter.class)
 public class MediaInserterTest extends InstrumentationTestCase {
 
     private MediaInserter mMediaInserter;
diff --git a/packages/InputDevices/Android.mk b/packages/InputDevices/Android.mk
index f537022..e7190dc 100644
--- a/packages/InputDevices/Android.mk
+++ b/packages/InputDevices/Android.mk
@@ -42,7 +42,7 @@
 	$(hide) mkdir -p $(dir $@) && touch $@
 
 # Run validatekeymaps unconditionally for platform build.
-droidcore all_modules : $(LOCAL_BUILT_MODULE)
+droidcore : $(LOCAL_BUILT_MODULE)
 
 # Reset temp vars.
 validatekeymaps :=
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 8556afc..5a6f3c9 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -236,7 +236,9 @@
                     Log.d(TAG, "Visibility changed to visible=" + visible);
                 }
                 mVisible = visible;
-                drawFrame();
+                if (visible) {
+                    drawFrame();
+                }
             }
         }
 
diff --git a/packages/WallpaperCropper/AndroidManifest.xml b/packages/WallpaperCropper/AndroidManifest.xml
index 81d1085..e558d7e 100644
--- a/packages/WallpaperCropper/AndroidManifest.xml
+++ b/packages/WallpaperCropper/AndroidManifest.xml
@@ -21,7 +21,10 @@
         <uses-permission android:name="android.permission.SET_WALLPAPER" />
         <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
 
-        <application android:requiredForAllUsers="true">
+        <application
+            android:requiredForAllUsers="true"
+            android:largeHeap="true">
+
         <activity
             android:name="WallpaperCropActivity"
             android:theme="@style/Theme.WallpaperCropper"
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index 0a50593..a4876b9 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -1505,7 +1505,7 @@
         }
 
         final byte[] data = fp.getData();
-        int data_length = fp.getPos();
+        int data_length = data.length;
         int eSize = mType.mElement.mElements[component_number].getBytesSize();
         eSize *= mType.mElement.mArraySizes[component_number];
 
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 8b1a032..a2967e8 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -30,6 +30,8 @@
 import android.os.Trace;
 import java.util.ArrayList;
 
+// TODO: Clean up the whitespace that separates methods in this class.
+
 /**
  * This class provides access to a RenderScript context, which controls RenderScript
  * initialization, resource management, and teardown. An instance of the RenderScript
@@ -88,6 +90,21 @@
     */
     public static final int CREATE_FLAG_LOW_POWER = 0x0004;
 
+    /**
+     * @hide
+     * Context creation flag which instructs the implementation to wait for
+     * a debugger to be attached before continuing execution.
+    */
+    public static final int CREATE_FLAG_WAIT_FOR_ATTACH = 0x0008;
+
+    /**
+     * @hide
+     * Context creation flag which specifies that optimization level 0 is
+     * passed to the device compiler upon execution of the RenderScript kernel.
+     * The default optimization level is 3.
+    */
+    public static final int CREATE_FLAG_OPT_LEVEL_0 = 0x0010;
+
     /*
      * Detect the bitness of the VM to allow FieldPacker to do the right thing.
      */
@@ -726,6 +743,14 @@
         rsnScriptForEach(mContext, id, slot, ains, aout, params, limits);
     }
 
+    native void rsnScriptReduce(long con, long id, int slot, long ain,
+                                long aout, int[] limits);
+    synchronized void nScriptReduce(long id, int slot, long ain, long aout,
+                                    int[] limits) {
+        validate();
+        rsnScriptReduce(mContext, id, slot, ain, aout, limits);
+    }
+
     native void rsnScriptInvokeV(long con, long id, int slot, byte[] params);
     synchronized void nScriptInvokeV(long id, int slot, byte[] params) {
         validate();
@@ -1356,7 +1381,8 @@
             return null;
         }
 
-        if ((flags & ~(CREATE_FLAG_LOW_LATENCY | CREATE_FLAG_LOW_POWER)) != 0) {
+        if ((flags & ~(CREATE_FLAG_LOW_LATENCY | CREATE_FLAG_LOW_POWER |
+                       CREATE_FLAG_WAIT_FOR_ATTACH | CREATE_FLAG_OPT_LEVEL_0)) != 0) {
             throw new RSIllegalArgumentException("Invalid flags passed.");
         }
 
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index 7cd6d09..ed4c6c7 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -283,6 +283,35 @@
         mRS.nScriptForEach(getID(mRS), slot, in_ids, out_id, params, limits);
     }
 
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @hide
+     */
+    protected void reduce(int slot, Allocation ain, Allocation aout, LaunchOptions sc) {
+        mRS.validate();
+        mRS.validateObject(ain);
+        mRS.validateObject(aout);
+
+        if (ain == null || aout == null) {
+            throw new RSIllegalArgumentException(
+                "Both ain and aout are required to be non-null.");
+        }
+
+        long in_id = ain.getID(mRS);
+        long out_id = aout.getID(mRS);
+
+        int[] limits = null;
+        if (sc != null) {
+            limits = new int[2];
+
+            limits[0] = sc.xstart;
+            limits[1] = sc.xend;
+        }
+
+        mRS.nScriptReduce(getID(mRS), slot, in_id, out_id, limits);
+    }
+
     long[] mInIdsBuffer;
 
     Script(long id, RenderScript rs) {
@@ -291,7 +320,6 @@
         mInIdsBuffer = new long[1];
     }
 
-
     /**
      * Only intended for use by generated reflected code.
      *
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBlend.java b/rs/java/android/renderscript/ScriptIntrinsicBlend.java
index 6b09bb7..fdcd61b 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBlend.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBlend.java
@@ -406,6 +406,8 @@
     /**
      * Sets dst = {src.r ^ dst.r, src.g ^ dst.g, src.b ^ dst.b, src.a ^ dst.a}
      *
+     * <b>Note:</b> this is NOT the Porter/Duff XOR mode; this is a bitwise xor.
+     *
      * @param ain The source buffer
      * @param aout The destination buffer
      * @param opt LaunchOptions for clipping
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index ffc4fd8..0419d33 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -1452,7 +1452,7 @@
     rsAllocationElementRead((RsContext)con, (RsAllocation)alloc,
                             xoff, yoff, zoff,
                             lod, ptr, sizeBytes, compIdx);
-    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
+    _env->ReleaseByteArrayElements(data, ptr, 0);
 }
 
 // Copies from the Allocation pointed to by _alloc into the Java object data.
@@ -1948,6 +1948,59 @@
     }
 }
 
+static void
+nScriptReduce(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
+              jlong ain, jlong aout, jintArray limits)
+{
+    if (kLogApi) {
+        ALOGD("nScriptReduce, con(%p), s(%p), slot(%i) ain(%" PRId64 ") aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ain, aout);
+    }
+
+    RsScriptCall sc, *sca = nullptr;
+    uint32_t sc_size = 0;
+
+    jint  limit_len = 0;
+    jint *limit_ptr = nullptr;
+
+    // If the caller passed limits, reflect them in the RsScriptCall.
+    if (limits != nullptr) {
+        limit_len = _env->GetArrayLength(limits);
+        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
+
+        // We expect to be passed an array [x1, x2] which specifies
+        // the sub-range for a 1-dimensional reduction.
+        assert(limit_len == 2);
+        UNUSED(limit_len);  // As the assert might not be compiled.
+
+        sc.xStart     = limit_ptr[0];
+        sc.xEnd       = limit_ptr[1];
+        sc.yStart     = 0;
+        sc.yEnd       = 0;
+        sc.zStart     = 0;
+        sc.zEnd       = 0;
+        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
+        sc.arrayStart = 0;
+        sc.arrayEnd = 0;
+        sc.array2Start = 0;
+        sc.array2End = 0;
+        sc.array3Start = 0;
+        sc.array3End = 0;
+        sc.array4Start = 0;
+        sc.array4End = 0;
+
+        sca = &sc;
+        sc_size = sizeof(sc);
+    }
+
+    rsScriptReduce((RsContext)con, (RsScript)script, slot,
+                   (RsAllocation)ain, (RsAllocation)aout,
+                   sca, sc_size);
+
+    if (limits != nullptr) {
+        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
+    }
+}
+
 // -----------------------------------
 
 static jlong
@@ -2531,6 +2584,7 @@
 {"rsnScriptInvokeV",                 "(JJI[B)V",                              (void*)nScriptInvokeV },
 
 {"rsnScriptForEach",                 "(JJI[JJ[B[I)V",                         (void*)nScriptForEach },
+{"rsnScriptReduce",                  "(JJIJJ[I)V",                            (void*)nScriptReduce },
 
 {"rsnScriptSetVarI",                 "(JJII)V",                               (void*)nScriptSetVarI },
 {"rsnScriptGetVarI",                 "(JJI)I",                                (void*)nScriptGetVarI },
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index e3d5d38..882899e 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -516,10 +516,10 @@
         public int compare(Batch b1, Batch b2) {
             long when1 = b1.start;
             long when2 = b2.start;
-            if (when1 - when2 > 0) {
+            if (when1 > when2) {
                 return 1;
             }
-            if (when1 - when2 < 0) {
+            if (when1 < when2) {
                 return -1;
             }
             return 0;
@@ -1932,10 +1932,10 @@
         public int compare(Alarm a1, Alarm a2) {
             long when1 = a1.whenElapsed;
             long when2 = a2.whenElapsed;
-            if (when1 - when2 > 0) {
+            if (when1 > when2) {
                 return 1;
             }
-            if (when1 - when2 < 0) {
+            if (when1 < when2) {
                 return -1;
             }
             return 0;
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index fda6479..92e6814 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.content.Context;
+import android.os.Trace;
 import android.util.Slog;
 
 import java.lang.reflect.Constructor;
@@ -75,43 +76,48 @@
      */
     @SuppressWarnings("unchecked")
     public <T extends SystemService> T startService(Class<T> serviceClass) {
-        final String name = serviceClass.getName();
-        Slog.i(TAG, "Starting " + name);
-
-        // Create the service.
-        if (!SystemService.class.isAssignableFrom(serviceClass)) {
-            throw new RuntimeException("Failed to create " + name
-                    + ": service must extend " + SystemService.class.getName());
-        }
-        final T service;
         try {
-            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
-            service = constructor.newInstance(mContext);
-        } catch (InstantiationException ex) {
-            throw new RuntimeException("Failed to create service " + name
-                    + ": service could not be instantiated", ex);
-        } catch (IllegalAccessException ex) {
-            throw new RuntimeException("Failed to create service " + name
-                    + ": service must have a public constructor with a Context argument", ex);
-        } catch (NoSuchMethodException ex) {
-            throw new RuntimeException("Failed to create service " + name
-                    + ": service must have a public constructor with a Context argument", ex);
-        } catch (InvocationTargetException ex) {
-            throw new RuntimeException("Failed to create service " + name
-                    + ": service constructor threw an exception", ex);
-        }
+            final String name = serviceClass.getName();
+            Slog.i(TAG, "Starting " + name);
+            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
 
-        // Register it.
-        mServices.add(service);
+            // Create the service.
+            if (!SystemService.class.isAssignableFrom(serviceClass)) {
+                throw new RuntimeException("Failed to create " + name
+                        + ": service must extend " + SystemService.class.getName());
+            }
+            final T service;
+            try {
+                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
+                service = constructor.newInstance(mContext);
+            } catch (InstantiationException ex) {
+                throw new RuntimeException("Failed to create service " + name
+                        + ": service could not be instantiated", ex);
+            } catch (IllegalAccessException ex) {
+                throw new RuntimeException("Failed to create service " + name
+                        + ": service must have a public constructor with a Context argument", ex);
+            } catch (NoSuchMethodException ex) {
+                throw new RuntimeException("Failed to create service " + name
+                        + ": service must have a public constructor with a Context argument", ex);
+            } catch (InvocationTargetException ex) {
+                throw new RuntimeException("Failed to create service " + name
+                        + ": service constructor threw an exception", ex);
+            }
 
-        // Start it.
-        try {
-            service.onStart();
-        } catch (RuntimeException ex) {
-            throw new RuntimeException("Failed to start service " + name
-                    + ": onStart threw an exception", ex);
+            // Register it.
+            mServices.add(service);
+
+            // Start it.
+            try {
+                service.onStart();
+            } catch (RuntimeException ex) {
+                throw new RuntimeException("Failed to start service " + name
+                        + ": onStart threw an exception", ex);
+            }
+            return service;
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
-        return service;
     }
 
     /**
@@ -127,18 +133,22 @@
         mCurrentPhase = phase;
 
         Slog.i(TAG, "Starting phase " + mCurrentPhase);
-
-        final int serviceLen = mServices.size();
-        for (int i = 0; i < serviceLen; i++) {
-            final SystemService service = mServices.get(i);
-            try {
-                service.onBootPhase(mCurrentPhase);
-            } catch (Exception ex) {
-                throw new RuntimeException("Failed to boot service "
-                        + service.getClass().getName()
-                        + ": onBootPhase threw an exception during phase "
-                        + mCurrentPhase, ex);
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase);
+            final int serviceLen = mServices.size();
+            for (int i = 0; i < serviceLen; i++) {
+                final SystemService service = mServices.get(i);
+                try {
+                    service.onBootPhase(mCurrentPhase);
+                } catch (Exception ex) {
+                    throw new RuntimeException("Failed to boot service "
+                            + service.getClass().getName()
+                            + ": onBootPhase threw an exception during phase "
+                            + mCurrentPhase, ex);
+                }
             }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3738d1e..adc294b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -209,6 +209,7 @@
 import android.os.StrictMode;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.os.UpdateLock;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -1215,6 +1216,7 @@
     String mMemWatchDumpFile;
     int mMemWatchDumpPid;
     int mMemWatchDumpUid;
+    String mTrackAllocationApp = null;
 
     final long[] mTmpLong = new long[1];
 
@@ -1883,7 +1885,9 @@
             }
             case FINISH_BOOTING_MSG: {
                 if (msg.arg1 != 0) {
+                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
                     finishBooting();
+                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                 }
                 if (msg.arg2 != 0) {
                     enableScreenAfterBoot();
@@ -4751,15 +4755,6 @@
 
         File tracesFile = new File(tracesPath);
         try {
-            File tracesDir = tracesFile.getParentFile();
-            if (!tracesDir.exists()) {
-                tracesDir.mkdirs();
-                if (!SELinux.restorecon(tracesDir)) {
-                    return null;
-                }
-            }
-            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
-
             if (clearTraces && tracesFile.exists()) tracesFile.delete();
             tracesFile.createNewFile();
             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
@@ -4862,14 +4857,6 @@
             final File tracesDir = tracesFile.getParentFile();
             final File tracesTmp = new File(tracesDir, "__tmp__");
             try {
-                if (!tracesDir.exists()) {
-                    tracesDir.mkdirs();
-                    if (!SELinux.restorecon(tracesDir.getPath())) {
-                        return;
-                    }
-                }
-                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
-
                 if (tracesFile.exists()) {
                     tracesTmp.delete();
                     tracesFile.renameTo(tracesTmp);
@@ -6101,6 +6088,11 @@
                 enableOpenGlTrace = true;
                 mOpenGlTraceApp = null;
             }
+            boolean enableTrackAllocation = false;
+            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
+                enableTrackAllocation = true;
+                mTrackAllocationApp = null;
+            }
 
             // If the app is being launched for restore or full backup, set it up specially
             boolean isRestrictedBackupMode = false;
@@ -6129,7 +6121,7 @@
             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
-                    isRestrictedBackupMode || !normalMode, app.persistent,
+                    enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
                     new Configuration(mConfiguration), app.compat,
                     getCommonServicesLocked(app.isolated),
                     mCoreSettingsObserver.getCoreSettingsLocked());
@@ -6434,7 +6426,9 @@
             mBootAnimationComplete = true;
         }
         if (callFinishBooting) {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
             finishBooting();
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
     }
 
@@ -6449,7 +6443,9 @@
         }
 
         if (booting) {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
             finishBooting();
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
 
         if (enableScreen) {
@@ -10575,7 +10571,7 @@
         synchronized (this) {
             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
             if (!isDebuggable) {
-                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
+                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
                     throw new SecurityException("Process not debuggable: " + app.packageName);
                 }
             }
@@ -10584,11 +10580,24 @@
         }
     }
 
+    void setTrackAllocationApp(ApplicationInfo app, String processName) {
+        synchronized (this) {
+            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
+            if (!isDebuggable) {
+                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
+                    throw new SecurityException("Process not debuggable: " + app.packageName);
+                }
+            }
+
+            mTrackAllocationApp = processName;
+        }
+    }
+
     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
         synchronized (this) {
             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
             if (!isDebuggable) {
-                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
+                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
                     throw new SecurityException("Process not debuggable: " + app.packageName);
                 }
             }
@@ -13660,6 +13669,15 @@
                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
             }
         }
+        if (mTrackAllocationApp != null) {
+            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
+                if (needSep) {
+                    pw.println();
+                    needSep = false;
+                }
+                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
+            }
+        }
         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
                 || mProfileFd != null) {
             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 6d91309..83fb7c2 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -884,20 +884,20 @@
                     aInfo.applicationInfo.packageName, aInfo.name));
 
             // Don't debug things in the system process
-            if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
-                if (!aInfo.processName.equals("system")) {
+            if (!aInfo.processName.equals("system")) {
+                if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) {
                     mService.setDebugApp(aInfo.processName, true, false);
                 }
-            }
 
-            if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
-                if (!aInfo.processName.equals("system")) {
+                if ((startFlags & ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
                     mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
                 }
-            }
 
-            if (profilerInfo != null) {
-                if (!aInfo.processName.equals("system")) {
+                if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
+                    mService.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
+                }
+
+                if (profilerInfo != null) {
                     mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
                 }
             }
diff --git a/services/core/java/com/android/server/am/NativeCrashListener.java b/services/core/java/com/android/server/am/NativeCrashListener.java
index d42d415..d0973d5 100644
--- a/services/core/java/com/android/server/am/NativeCrashListener.java
+++ b/services/core/java/com/android/server/am/NativeCrashListener.java
@@ -21,6 +21,7 @@
 import android.system.Os;
 import android.system.StructTimeval;
 import android.system.StructUcred;
+import android.system.UnixSocketAddress;
 import android.util.Slog;
 
 import static android.system.OsConstants.*;
@@ -30,7 +31,6 @@
 import java.io.FileDescriptor;
 import java.io.InterruptedIOException;
 import java.net.InetSocketAddress;
-import java.net.InetUnixAddress;
 
 /**
  * Set up a Unix domain socket that debuggerd will connect() to in
@@ -117,16 +117,16 @@
 
         try {
             FileDescriptor serverFd = Os.socket(AF_UNIX, SOCK_STREAM, 0);
-            final InetUnixAddress sockAddr = new InetUnixAddress(DEBUGGERD_SOCKET_PATH);
-            Os.bind(serverFd, sockAddr, 0);
+            final UnixSocketAddress sockAddr = UnixSocketAddress.createFileSystem(
+                    DEBUGGERD_SOCKET_PATH);
+            Os.bind(serverFd, sockAddr);
             Os.listen(serverFd, 1);
 
             while (true) {
-                InetSocketAddress peer = new InetSocketAddress();
                 FileDescriptor peerFd = null;
                 try {
                     if (MORE_DEBUG) Slog.v(TAG, "Waiting for debuggerd connection");
-                    peerFd = Os.accept(serverFd, peer);
+                    peerFd = Os.accept(serverFd, null /* peerAddress */);
                     if (MORE_DEBUG) Slog.v(TAG, "Got debuggerd socket " + peerFd);
                     if (peerFd != null) {
                         // Only the superuser is allowed to talk to us over this socket
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index bb4e388..d26319b 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -73,7 +73,7 @@
     private static final long OP_TIMEOUT_MILLIS = 8 * 1000;
 
     private static final String[] VERB_STRINGS = {
-            "VERB_BINDING", "VERB_STARTING", "VERB_EXECUTING", "VERB_STOPPING"
+            "VERB_BINDING", "VERB_STARTING", "VERB_EXECUTING", "VERB_STOPPING", "VERB_FINISHED"
     };
 
     // States that a job occupies while interacting with the client.
@@ -81,6 +81,7 @@
     static final int VERB_STARTING = 1;
     static final int VERB_EXECUTING = 2;
     static final int VERB_STOPPING = 3;
+    static final int VERB_FINISHED = 4;
 
     // Messages that result from interactions with the client service.
     /** System timed out waiting for a response. */
@@ -172,6 +173,7 @@
                 mRunningJob = null;
                 mParams = null;
                 mExecutionStartTimeElapsed = 0L;
+                mVerb = VERB_FINISHED;
                 removeOpTimeOut();
                 return false;
             }
@@ -307,8 +309,8 @@
                     break;
                 case MSG_CALLBACK:
                     if (DEBUG) {
-                        Slog.d(TAG, "MSG_CALLBACK of : " + mRunningJob + " v:" +
-                                (mVerb >= 0 ? VERB_STRINGS[mVerb] : "[invalid]"));
+                        Slog.d(TAG, "MSG_CALLBACK of : " + mRunningJob
+                                + " v:" + VERB_STRINGS[mVerb]);
                     }
                     removeOpTimeOut();
 
@@ -524,8 +526,12 @@
          * we want to clean up internally.
          */
         private void closeAndCleanupJobH(boolean reschedule) {
-            final JobStatus completedJob = mRunningJob;
+            final JobStatus completedJob;
             synchronized (mLock) {
+                if (mVerb == VERB_FINISHED) {
+                    return;
+                }
+                completedJob = mRunningJob;
                 try {
                     mBatteryStats.noteJobFinish(mRunningJob.getName(), mRunningJob.getUid());
                 } catch (RemoteException e) {
@@ -538,7 +544,7 @@
                 mWakeLock = null;
                 mRunningJob = null;
                 mParams = null;
-                mVerb = -1;
+                mVerb = VERB_FINISHED;
                 mCancelled.set(false);
                 service = null;
                 mAvailable = true;
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 24d4f15..11e7605 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -457,7 +457,7 @@
             while (eventType != XmlPullParser.START_TAG &&
                     eventType != XmlPullParser.END_DOCUMENT) {
                 eventType = parser.next();
-                Slog.d(TAG, parser.getName());
+                Slog.d(TAG, "Start tag: " + parser.getName());
             }
             if (eventType == XmlPullParser.END_DOCUMENT) {
                 if (DEBUG) {
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index c75a1d3..66170d4 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -136,9 +136,6 @@
                     case "signer":
                         policies.add(readSignerOrThrow(parser));
                         break;
-                    case "default":
-                        policies.add(readDefaultOrThrow(parser));
-                        break;
                     default:
                         skip(parser);
                 }
@@ -233,45 +230,6 @@
     }
 
     /**
-     * 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 {
-
-        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)) {
-                String seinfo = parser.getAttributeValue(null, "value");
-                pb.setGlobalSeinfoOrThrow(seinfo);
-                readSeinfo(parser);
-            } else {
-                skip(parser);
-            }
-        }
-
-        return pb.build();
-    }
-
-    /**
      * 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.
@@ -337,35 +295,28 @@
 
     /**
      * 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.
+     * policy. All signature based policy stanzas are consulted and, if no match is
+     * found, the default seinfo label of 'default' (set in ApplicationInfo object) is
+     * used. 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 represents that no policy matched.
      */
-    public static boolean assignSeinfoValue(PackageParser.Package pkg) {
+    public static void assignSeinfoValue(PackageParser.Package pkg) {
         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);
-                    }
-                    return true;
+                    break;
                 }
             }
         }
 
         if (DEBUG_POLICY_INSTALL) {
-            Slog.i(TAG, "package (" + pkg.packageName + ") doesn't match any policy; " +
-                   "seinfo will remain null");
+            Slog.i(TAG, "package (" + pkg.packageName + ") labeled with " +
+                    "seinfo=" + pkg.applicationInfo.seinfo);
         }
-        return false;
     }
 
     /**
@@ -506,30 +457,16 @@
  *         .build();
  * }
  * </pre>
- * <p>
- * The following is 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("default")
- *         .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);
     }
@@ -545,15 +482,6 @@
     }
 
     /**
-     * Return whether this policy object represents a default stanza.
-     *
-     * @return A boolean indicating if this object represents a default policy stanza.
-     */
-    public boolean isDefaultStanza() {
-        return mDefaultStanza;
-    }
-
-    /**
      * Return whether this policy object contains package name mapping refinements.
      *
      * @return A boolean indicating if this object has inner package name mappings.
@@ -584,10 +512,6 @@
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        if (mDefaultStanza) {
-            sb.append("defaultStanza=true ");
-        }
-
         for (Signature cert : mCerts) {
             sb.append("cert=" + cert.toCharsString().substring(0, 11) + "... ");
         }
@@ -609,22 +533,15 @@
      * 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> 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 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> 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>
      * <p>
@@ -636,37 +553,34 @@
      *         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;
-            }
+        // Check for exact signature matches across all certs.
+        Signature[] certs = mCerts.toArray(new Signature[0]);
+        if (!Signature.areExactMatch(certs, pkg.mSignatures)) {
+            return null;
         }
 
-        // Return the global seinfo value (even if it's 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.
         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.
+     * file. A valid policy stanza is defined to be a signer 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;
 
@@ -676,19 +590,6 @@
         }
 
         /**
-         * Sets this stanza as a default 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.
@@ -710,11 +611,8 @@
 
         /**
          * 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.
+         * when attached to a signer tag represents the assignment when there isn't a
+         * further inner package refinement in policy.
          *
          * @param seinfo the seinfo value given as a String.
          * @return The reference to this PolicyBuilder.
@@ -740,9 +638,7 @@
         /**
          * 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.
+         * These localized mappings allow the global seinfo to be overriden.
          *
          * @param pkgName the android package name given to the app
          * @param seinfo the seinfo value that will be assigned to the passed pkgName
@@ -799,51 +695,25 @@
          * 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 BUT not both. </li>
-         *        </ul>
-         *      </li>
-         *    </ul>
-         *
+         * <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 BUT not both. </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 = "Only seinfo tag XOR package tags are allowed within " +
-                            "a signer stanza.";
-                    throw new IllegalStateException(err);
-                }
+            if (p.mCerts.isEmpty()) {
+                String err = "Missing certs with signer tag. Expecting at least one.";
+                throw new IllegalStateException(err);
+            }
+            if (!(p.mSeinfo == null ^ p.mPkgMap.isEmpty())) {
+                String err = "Only seinfo tag XOR package tags are allowed within " +
+                        "a signer stanza.";
+                throw new IllegalStateException(err);
             }
 
             return p;
@@ -858,7 +728,6 @@
  * <ul>
  *   <li> signer stanzas with inner package mappings </li>
  *   <li> signer stanzas with global seinfo tags </li>
- *   <li> default stanza </li>
  * </ul>
  * This comparison also checks for duplicate entries on the input selectors. Any
  * found duplicates will be flagged and can be checked with {@link #foundDuplicate}.
@@ -875,11 +744,6 @@
     @Override
     public int compare(Policy p1, Policy p2) {
 
-        // Give precedence to signature stanzas over default stanzas
-        if (p1.isDefaultStanza() != p2.isDefaultStanza()) {
-            return p1.isDefaultStanza() ? 1 : -1;
-        }
-
         // Give precedence to stanzas with inner package mappings
         if (p1.hasInnerPackages() != p2.hasInnerPackages()) {
             return p1.hasInnerPackages() ? -1 : 1;
@@ -887,7 +751,7 @@
 
         // Check for duplicate entries
         if (p1.getSignatures().equals(p2.getSignatures())) {
-            // Checks if default stanza or a signer w/o inner package names
+            // Checks if signer w/o inner package names
             if (p1.hasGlobalSeinfo()) {
                 duplicateFound = true;
                 Slog.e(SELinuxMMAC.TAG, "Duplicate policy entry: " + p1.toString());
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index b920f97..7ebb7f8 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -2269,7 +2269,7 @@
             public void run() {
                 synchronized (this) {
                     if (shutdown) {
-                        ShutdownThread.shutdown(mContext, confirm);
+                        ShutdownThread.shutdown(mContext, reason, confirm);
                     } else {
                         ShutdownThread.reboot(mContext, reason, confirm);
                     }
@@ -2546,9 +2546,14 @@
     /**
      * Low-level function turn the device off immediately, without trying
      * to be clean.  Most people should use {@link ShutdownThread} for a clean shutdown.
+     *
+     * @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
      */
-    public static void lowLevelShutdown() {
-        SystemProperties.set("sys.powerctl", "shutdown");
+    public static void lowLevelShutdown(String reason) {
+        if (reason == null) {
+            reason = "";
+        }
+        SystemProperties.set("sys.powerctl", "shutdown," + reason);
     }
 
     /**
@@ -3277,12 +3282,12 @@
          * @param wait If true, this call waits for the shutdown to complete and does not return.
          */
         @Override // Binder call
-        public void shutdown(boolean confirm, boolean wait) {
+        public void shutdown(boolean confirm, String reason, boolean wait) {
             mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
 
             final long ident = Binder.clearCallingIdentity();
             try {
-                shutdownOrRebootInternal(true, confirm, null, wait);
+                shutdownOrRebootInternal(true, confirm, reason, wait);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index dd8648d..ac6a28e 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -88,7 +88,7 @@
     private static boolean mReboot;
     private static boolean mRebootSafeMode;
     private static boolean mRebootUpdate;
-    private static String mRebootReason;
+    private static String mReason;
 
     // Provides shutdown assurance in case the system_server is killed
     public static final String SHUTDOWN_ACTION_PROPERTY = "sys.shutdown.requested";
@@ -124,11 +124,13 @@
      * is shown.
      *
      * @param context Context used to display the shutdown progress dialog.
+     * @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
      * @param confirm true if user confirmation is needed before shutting down.
      */
-    public static void shutdown(final Context context, boolean confirm) {
+    public static void shutdown(final Context context, String reason, boolean confirm) {
         mReboot = false;
         mRebootSafeMode = false;
+        mReason = reason;
         shutdownInner(context, confirm);
     }
 
@@ -212,7 +214,7 @@
         mReboot = true;
         mRebootSafeMode = false;
         mRebootUpdate = false;
-        mRebootReason = reason;
+        mReason = reason;
         shutdownInner(context, confirm);
     }
 
@@ -232,7 +234,7 @@
         mReboot = true;
         mRebootSafeMode = true;
         mRebootUpdate = false;
-        mRebootReason = null;
+        mReason = null;
         shutdownInner(context, confirm);
     }
 
@@ -249,18 +251,18 @@
         ProgressDialog pd = new ProgressDialog(context);
 
         // Path 1: Reboot to recovery and install the update
-        //   Condition: mRebootReason == REBOOT_RECOVERY and mRebootUpdate == True
+        //   Condition: mReason == REBOOT_RECOVERY and mRebootUpdate == True
         //   (mRebootUpdate is set by checking if /cache/recovery/uncrypt_file exists.)
         //   UI: progress bar
         //
         // Path 2: Reboot to recovery for factory reset
-        //   Condition: mRebootReason == REBOOT_RECOVERY
+        //   Condition: mReason == REBOOT_RECOVERY
         //   UI: spinning circle only (no progress bar)
         //
         // Path 3: Regular reboot / shutdown
         //   Condition: Otherwise
         //   UI: spinning circle only (no progress bar)
-        if (PowerManager.REBOOT_RECOVERY.equals(mRebootReason)) {
+        if (PowerManager.REBOOT_RECOVERY.equals(mReason)) {
             mRebootUpdate = new File(UNCRYPT_PACKAGE_FILE).exists();
             if (mRebootUpdate) {
                 pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_update_title));
@@ -349,7 +351,7 @@
          * the beginning of the SystemServer startup.
          */
         {
-            String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : "");
+            String reason = (mReboot ? "1" : "0") + (mReason != null ? mReason : "");
             SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
         }
 
@@ -473,7 +475,7 @@
             uncrypt();
         }
 
-        rebootOrShutdown(mContext, mReboot, mRebootReason);
+        rebootOrShutdown(mContext, mReboot, mReason);
     }
 
     private void setRebootProgress(final int progress, final CharSequence message) {
@@ -616,13 +618,14 @@
      *
      * @param context Context used to vibrate or null without vibration
      * @param reboot true to reboot or false to shutdown
-     * @param reason reason for reboot
+     * @param reason reason for reboot/shutdown
      */
     public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {
         if (reboot) {
             Log.i(TAG, "Rebooting, reason: " + reason);
             PowerManagerService.lowLevelReboot(reason);
             Log.e(TAG, "Reboot failed, will attempt shutdown instead");
+            reason = null;
         } else if (SHUTDOWN_VIBRATE_MS > 0 && context != null) {
             // vibrate before shutting down
             Vibrator vibrator = new SystemVibrator(context);
@@ -642,7 +645,7 @@
 
         // Shutdown power
         Log.i(TAG, "Performing low-level shutdown...");
-        PowerManagerService.lowLevelShutdown();
+        PowerManagerService.lowLevelShutdown(reason);
     }
 
     private void uncrypt() {
diff --git a/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java b/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
index 4e53687..c81398f 100644
--- a/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
@@ -36,7 +36,7 @@
     private static final String TAG = "SELinuxPolicyInstallReceiver";
 
     private static final String sepolicyPath = "sepolicy";
-    private static final String fileContextsPath = "file_contexts";
+    private static final String fileContextsPath = "file_contexts.bin";
     private static final String propertyContextsPath = "property_contexts";
     private static final String seappContextsPath = "seapp_contexts";
     private static final String versionPath = "selinux_version";
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a0499b7..d0f79db 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -642,6 +642,7 @@
     final InputManagerService mInputManager;
     final DisplayManagerInternal mDisplayManagerInternal;
     final DisplayManager mDisplayManager;
+    final Display[] mDisplays;
 
     // Who is holding the screen on.
     Session mHoldingScreenOn;
@@ -915,8 +916,8 @@
 
         mFxSession = new SurfaceSession();
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
-        Display[] displays = mDisplayManager.getDisplays();
-        for (Display display : displays) {
+        mDisplays = mDisplayManager.getDisplays();
+        for (Display display : mDisplays) {
             createDisplayContentLocked(display);
         }
 
@@ -5663,7 +5664,7 @@
     // Called by window manager policy.  Not exposed externally.
     @Override
     public void shutdown(boolean confirm) {
-        ShutdownThread.shutdown(mContext, confirm);
+        ShutdownThread.shutdown(mContext, PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
     }
 
     // Called by window manager policy.  Not exposed externally.
@@ -7641,7 +7642,9 @@
     }
 
     public void displayReady() {
-        displayReady(Display.DEFAULT_DISPLAY);
+        for (Display display : mDisplays) {
+            displayReady(display.getDisplayId());
+        }
 
         synchronized(mWindowMap) {
             final DisplayContent displayContent = getDefaultDisplayContentLocked();
diff --git a/services/core/jni/com_android_server_PersistentDataBlockService.cpp b/services/core/jni/com_android_server_PersistentDataBlockService.cpp
index e842eeb..4ccfa56 100644
--- a/services/core/jni/com_android_server_PersistentDataBlockService.cpp
+++ b/services/core/jni/com_android_server_PersistentDataBlockService.cpp
@@ -17,6 +17,7 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <JNIHelp.h>
 #include <jni.h>
+#include <ScopedUtfChars.h>
 
 #include <utils/misc.h>
 #include <sys/ioctl.h>
@@ -77,8 +78,8 @@
 
     static jlong com_android_server_PersistentDataBlockService_getBlockDeviceSize(JNIEnv *env, jclass, jstring jpath)
     {
-        const char *path = env->GetStringUTFChars(jpath, 0);
-        int fd = open(path, O_RDONLY);
+        ScopedUtfChars path(env, jpath);
+        int fd = open(path.c_str(), O_RDONLY);
 
         if (fd < 0)
             return 0;
@@ -87,8 +88,8 @@
     }
 
     static int com_android_server_PersistentDataBlockService_wipe(JNIEnv *env, jclass, jstring jpath) {
-        const char *path = env->GetStringUTFChars(jpath, 0);
-        int fd = open(path, O_WRONLY);
+        ScopedUtfChars path(env, jpath);
+        int fd = open(path.c_str(), O_WRONLY);
 
         if (fd < 0)
             return 0;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 7dd16d1..0e553b5 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -38,6 +38,7 @@
 import android.os.StrictMode;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.os.storage.IMountService;
 import android.util.DisplayMetrics;
@@ -174,97 +175,103 @@
     }
 
     private void run() {
-        // If a device's clock is before 1970 (before 0), a lot of
-        // APIs crash dealing with negative numbers, notably
-        // java.io.File#setLastModified, so instead we fake it and
-        // hope that time from cell towers or NTP fixes it shortly.
-        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
-            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
-            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
-        }
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitBeforeStartServices");
+            // If a device's clock is before 1970 (before 0), a lot of
+            // APIs crash dealing with negative numbers, notably
+            // java.io.File#setLastModified, so instead we fake it and
+            // hope that time from cell towers or NTP fixes it shortly.
+            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
+                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
+                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
+            }
 
-        // If the system has "persist.sys.language" and friends set, replace them with
-        // "persist.sys.locale". Note that the default locale at this point is calculated
-        // using the "-Duser.locale" command line flag. That flag is usually populated by
-        // AndroidRuntime using the same set of system properties, but only the system_server
-        // and system apps are allowed to set them.
-        //
-        // NOTE: Most changes made here will need an equivalent change to
-        // core/jni/AndroidRuntime.cpp
-        if (!SystemProperties.get("persist.sys.language").isEmpty()) {
-            final String languageTag = Locale.getDefault().toLanguageTag();
+            // If the system has "persist.sys.language" and friends set, replace them with
+            // "persist.sys.locale". Note that the default locale at this point is calculated
+            // using the "-Duser.locale" command line flag. That flag is usually populated by
+            // AndroidRuntime using the same set of system properties, but only the system_server
+            // and system apps are allowed to set them.
+            //
+            // NOTE: Most changes made here will need an equivalent change to
+            // core/jni/AndroidRuntime.cpp
+            if (!SystemProperties.get("persist.sys.language").isEmpty()) {
+                final String languageTag = Locale.getDefault().toLanguageTag();
 
-            SystemProperties.set("persist.sys.locale", languageTag);
-            SystemProperties.set("persist.sys.language", "");
-            SystemProperties.set("persist.sys.country", "");
-            SystemProperties.set("persist.sys.localevar", "");
-        }
+                SystemProperties.set("persist.sys.locale", languageTag);
+                SystemProperties.set("persist.sys.language", "");
+                SystemProperties.set("persist.sys.country", "");
+                SystemProperties.set("persist.sys.localevar", "");
+            }
 
-        // Here we go!
-        Slog.i(TAG, "Entered the Android system server!");
-        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
+            // Here we go!
+            Slog.i(TAG, "Entered the Android system server!");
+            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
 
-        // In case the runtime switched since last boot (such as when
-        // the old runtime was removed in an OTA), set the system
-        // property so that it is in sync. We can't do this in
-        // libnativehelper's JniInvocation::Init code where we already
-        // had to fallback to a different runtime because it is
-        // running as root and we need to be the system user to set
-        // the property. http://b/11463182
-        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
+            // In case the runtime switched since last boot (such as when
+            // the old runtime was removed in an OTA), set the system
+            // property so that it is in sync. We can't do this in
+            // libnativehelper's JniInvocation::Init code where we already
+            // had to fallback to a different runtime because it is
+            // running as root and we need to be the system user to set
+            // the property. http://b/11463182
+            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
 
-        // Enable the sampling profiler.
-        if (SamplingProfilerIntegration.isEnabled()) {
-            SamplingProfilerIntegration.start();
-            mProfilerSnapshotTimer = new Timer();
-            mProfilerSnapshotTimer.schedule(new TimerTask() {
-                @Override
-                public void run() {
-                    SamplingProfilerIntegration.writeSnapshot("system_server", null);
-                }
-            }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
-        }
+            // Enable the sampling profiler.
+            if (SamplingProfilerIntegration.isEnabled()) {
+                SamplingProfilerIntegration.start();
+                mProfilerSnapshotTimer = new Timer();
+                mProfilerSnapshotTimer.schedule(new TimerTask() {
+                        @Override
+                        public void run() {
+                            SamplingProfilerIntegration.writeSnapshot("system_server", null);
+                        }
+                    }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
+            }
 
-        // Mmmmmm... more memory!
-        VMRuntime.getRuntime().clearGrowthLimit();
+            // Mmmmmm... more memory!
+            VMRuntime.getRuntime().clearGrowthLimit();
 
-        // The system server has to run all of the time, so it needs to be
-        // as efficient as possible with its memory usage.
-        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
+            // The system server has to run all of the time, so it needs to be
+            // as efficient as possible with its memory usage.
+            VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
 
-        // Some devices rely on runtime fingerprint generation, so make sure
-        // we've defined it before booting further.
-        Build.ensureFingerprintProperty();
+            // Some devices rely on runtime fingerprint generation, so make sure
+            // we've defined it before booting further.
+            Build.ensureFingerprintProperty();
 
-        // Within the system server, it is an error to access Environment paths without
-        // explicitly specifying a user.
-        Environment.setUserRequired(true);
+            // Within the system server, it is an error to access Environment paths without
+            // explicitly specifying a user.
+            Environment.setUserRequired(true);
 
-        // Ensure binder calls into the system always run at foreground priority.
-        BinderInternal.disableBackgroundScheduling(true);
+            // Ensure binder calls into the system always run at foreground priority.
+            BinderInternal.disableBackgroundScheduling(true);
 
-        // Prepare the main looper thread (this thread).
-        android.os.Process.setThreadPriority(
+            // Prepare the main looper thread (this thread).
+            android.os.Process.setThreadPriority(
                 android.os.Process.THREAD_PRIORITY_FOREGROUND);
-        android.os.Process.setCanSelfBackground(false);
-        Looper.prepareMainLooper();
+            android.os.Process.setCanSelfBackground(false);
+            Looper.prepareMainLooper();
 
-        // Initialize native services.
-        System.loadLibrary("android_servers");
+            // Initialize native services.
+            System.loadLibrary("android_servers");
 
-        // Check whether we failed to shut down last time we tried.
-        // This call may not return.
-        performPendingShutdown();
+            // Check whether we failed to shut down last time we tried.
+            // This call may not return.
+            performPendingShutdown();
 
-        // Initialize the system context.
-        createSystemContext();
+            // Initialize the system context.
+            createSystemContext();
 
-        // Create the system service manager.
-        mSystemServiceManager = new SystemServiceManager(mSystemContext);
-        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
+            // Create the system service manager.
+            mSystemServiceManager = new SystemServiceManager(mSystemContext);
+            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+        }
 
         // Start services.
         try {
+            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
             startBootstrapServices();
             startCoreServices();
             startOtherServices();
@@ -272,6 +279,8 @@
             Slog.e("System", "******************************************");
             Slog.e("System", "************ Failure starting system services", ex);
             throw ex;
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
 
         // For debug builds, log event loop stalls to dropbox for analysis.
@@ -339,7 +348,9 @@
 
         // Now that the power manager has been started, let the activity manager
         // initialize power management features.
+        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitPowerManagement");
         mActivityManagerService.initPowerManagement();
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
         // Manages LEDs and display backlight so we need it to bring up the display.
         mSystemServiceManager.startService(LightsService.class);
@@ -362,14 +373,16 @@
         }
 
         // Start the package manager.
-        Slog.i(TAG, "Package Manager");
+        traceBeginAndSlog("StartPackageManagerService");
         mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
         mFirstBoot = mPackageManagerService.isFirstBoot();
         mPackageManager = mSystemContext.getPackageManager();
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
-        Slog.i(TAG, "User Service");
+        traceBeginAndSlog("StartUserManagerService");
         ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
         // Initialize attribute cache used to cache resources from packages.
         AttributeCache.init(mSystemContext);
@@ -443,17 +456,20 @@
             Slog.i(TAG, "Reading configuration...");
             SystemConfig.getInstance();
 
-            Slog.i(TAG, "Scheduling Policy");
+            traceBeginAndSlog("StartSchedulingPolicyService");
             ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             mSystemServiceManager.startService(TelecomLoaderService.class);
 
-            Slog.i(TAG, "Telephony Registry");
+            traceBeginAndSlog("StartTelephonyRegistry");
             telephonyRegistry = new TelephonyRegistry(context);
             ServiceManager.addService("telephony.registry", telephonyRegistry);
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
-            Slog.i(TAG, "Entropy Mixer");
+            traceBeginAndSlog("StartEntropyMixer");
             entropyMixer = new EntropyMixer(context);
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             mContentResolver = context.getContentResolver();
 
@@ -461,47 +477,55 @@
             mSystemServiceManager.startService(CameraService.class);
 
             // The AccountManager must come before the ContentService
+            traceBeginAndSlog("StartAccountManagerService");
             try {
                 // TODO: seems like this should be disable-able, but req'd by ContentService
-                Slog.i(TAG, "Account Manager");
                 accountManager = new AccountManagerService(context);
                 ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
             } catch (Throwable e) {
                 Slog.e(TAG, "Failure starting Account Manager", e);
             }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
-            Slog.i(TAG, "Content Manager");
+            traceBeginAndSlog("StartContentService");
             contentService = ContentService.main(context,
                     mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL);
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
-            Slog.i(TAG, "System Content Providers");
+            traceBeginAndSlog("InstallSystemProviders");
             mActivityManagerService.installSystemProviders();
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
-            Slog.i(TAG, "Vibrator Service");
+            traceBeginAndSlog("StartVibratorService");
             vibrator = new VibratorService(context);
             ServiceManager.addService("vibrator", vibrator);
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
-            Slog.i(TAG, "Consumer IR Service");
+            traceBeginAndSlog("StartConsumerIrService");
             consumerIr = new ConsumerIrService(context);
             ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             mSystemServiceManager.startService(AlarmManagerService.class);
             alarm = IAlarmManager.Stub.asInterface(
                     ServiceManager.getService(Context.ALARM_SERVICE));
 
-            Slog.i(TAG, "Init Watchdog");
+            traceBeginAndSlog("InitWatchdog");
             final Watchdog watchdog = Watchdog.getInstance();
             watchdog.init(context, mActivityManagerService);
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
-            Slog.i(TAG, "Input Manager");
+            traceBeginAndSlog("StartInputManagerService");
             inputManager = new InputManagerService(context);
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
-            Slog.i(TAG, "Window Manager");
+            traceBeginAndSlog("StartWindowManagerService");
             wm = WindowManagerService.main(context, inputManager,
                     mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                     !mFirstBoot, mOnlyCore);
             ServiceManager.addService(Context.WINDOW_SERVICE, wm);
             ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             mActivityManagerService.setWindowManager(wm);
 
@@ -515,7 +539,7 @@
             // TODO: Use a more reliable check to see if this product should
             // support Bluetooth - see bug 988521
             if (isEmulator) {
-                Slog.i(TAG, "No Bluetooh Service (emulator)");
+                Slog.i(TAG, "No Bluetooth Service (emulator)");
             } else if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
                 Slog.i(TAG, "No Bluetooth Service (factory test)");
             } else if (!context.getPackageManager().hasSystemFeature
@@ -524,7 +548,6 @@
             } else if (disableBluetooth) {
                 Slog.i(TAG, "Bluetooth Service disabled by config");
             } else {
-                Slog.i(TAG, "Bluetooth Service");
                 mSystemServiceManager.startService(BluetoothService.class);
             }
         } catch (RuntimeException e) {
@@ -545,21 +568,23 @@
 
         // Bring up services needed for UI.
         if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
+            traceBeginAndSlog("StartInputMethodManagerService");
             try {
-                Slog.i(TAG, "Input Method Service");
                 imm = new InputMethodManagerService(context, wm);
                 ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
             } catch (Throwable e) {
                 reportWtf("starting Input Manager Service", e);
             }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+            traceBeginAndSlog("StartAccessibilityManagerService");
             try {
-                Slog.i(TAG, "Accessibility Manager");
                 ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
                         new AccessibilityManagerService(context));
             } catch (Throwable e) {
                 reportWtf("starting Accessibility Manager", e);
             }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
 
         try {
@@ -589,11 +614,13 @@
         // as appropriate.
         mSystemServiceManager.startService(UiModeManagerService.class);
 
+        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PerformBootDexOpt");
         try {
             mPackageManagerService.performBootDexOpt();
         } catch (Throwable e) {
             reportWtf("performing boot dexopt", e);
         }
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
         try {
             ActivityManagerNative.getDefault().showBootMessage(
@@ -605,13 +632,14 @@
 
         if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
             if (!disableNonCoreServices) {
+                traceBeginAndSlog("StartLockSettingsService");
                 try {
-                    Slog.i(TAG,  "LockSettingsService");
                     lockSettings = new LockSettingsService(context);
                     ServiceManager.addService("lock_settings", lockSettings);
                 } catch (Throwable e) {
                     reportWtf("starting LockSettingsService service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
                 if (!SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("")) {
                     mSystemServiceManager.startService(PersistentDataBlockService.class);
@@ -625,64 +653,70 @@
             }
 
             if (!disableSystemUI) {
+                traceBeginAndSlog("StartStatusBarManagerService");
                 try {
-                    Slog.i(TAG, "Status Bar");
                     statusBar = new StatusBarManagerService(context, wm);
                     ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
                 } catch (Throwable e) {
                     reportWtf("starting StatusBarManagerService", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
             if (!disableNonCoreServices) {
+                traceBeginAndSlog("StartClipboardService");
                 try {
-                    Slog.i(TAG, "Clipboard Service");
                     ServiceManager.addService(Context.CLIPBOARD_SERVICE,
                             new ClipboardService(context));
                 } catch (Throwable e) {
                     reportWtf("starting Clipboard Service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
             if (!disableNetwork) {
+                traceBeginAndSlog("StartNetworkManagementService");
                 try {
-                    Slog.i(TAG, "NetworkManagement Service");
                     networkManagement = NetworkManagementService.create(context);
                     ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
                 } catch (Throwable e) {
                     reportWtf("starting NetworkManagement Service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
             if (!disableNonCoreServices) {
+                traceBeginAndSlog("StartTextServicesManagerService");
                 try {
-                    Slog.i(TAG, "Text Service Manager Service");
                     tsms = new TextServicesManagerService(context);
                     ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms);
                 } catch (Throwable e) {
                     reportWtf("starting Text Service Manager Service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
             if (!disableNetwork) {
+                traceBeginAndSlog("StartNetworkScoreService");
                 try {
-                    Slog.i(TAG, "Network Score Service");
                     networkScore = new NetworkScoreService(context);
                     ServiceManager.addService(Context.NETWORK_SCORE_SERVICE, networkScore);
                 } catch (Throwable e) {
                     reportWtf("starting Network Score Service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+                traceBeginAndSlog("StartNetworkStatsService");
                 try {
-                    Slog.i(TAG, "NetworkStats Service");
                     networkStats = new NetworkStatsService(context, networkManagement, alarm);
                     ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
                 } catch (Throwable e) {
                     reportWtf("starting NetworkStats Service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+                traceBeginAndSlog("StartNetworkPolicyManagerService");
                 try {
-                    Slog.i(TAG, "NetworkPolicy Service");
                     networkPolicy = new NetworkPolicyManagerService(
                             context, mActivityManagerService,
                             (IPowerManager)ServiceManager.getService(Context.POWER_SERVICE),
@@ -691,6 +725,7 @@
                 } catch (Throwable e) {
                     reportWtf("starting NetworkPolicy Service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
                 mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
                 mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
@@ -704,8 +739,8 @@
                     mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
                 }
 
+                traceBeginAndSlog("StartConnectivityService");
                 try {
-                    Slog.i(TAG, "Connectivity Service");
                     connectivity = new ConnectivityService(
                             context, networkManagement, networkStats, networkPolicy);
                     ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
@@ -714,25 +749,28 @@
                 } catch (Throwable e) {
                     reportWtf("starting Connectivity Service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+                traceBeginAndSlog("StartNsdService");
                 try {
-                    Slog.i(TAG, "Network Service Discovery Service");
                     serviceDiscovery = NsdService.create(context);
                     ServiceManager.addService(
                             Context.NSD_SERVICE, serviceDiscovery);
                 } catch (Throwable e) {
                     reportWtf("starting Service Discovery Service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
             if (!disableNonCoreServices) {
+                traceBeginAndSlog("StartUpdateLockService");
                 try {
-                    Slog.i(TAG, "UpdateLock Service");
                     ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,
                             new UpdateLockService(context));
                 } catch (Throwable e) {
                     reportWtf("starting UpdateLockService", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
             /*
@@ -741,25 +779,31 @@
              * first before continuing.
              */
             if (mountService != null && !mOnlyCore) {
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "WaitForAsecScan");
                 try {
                     mountService.waitForAsecScan();
                 } catch (RemoteException ignored) {
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
+            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeAccountManagerServiceReady");
             try {
                 if (accountManager != null)
                     accountManager.systemReady();
             } catch (Throwable e) {
                 reportWtf("making Account Manager Service ready", e);
             }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeContentServiceReady");
             try {
                 if (contentService != null)
                     contentService.systemReady();
             } catch (Throwable e) {
                 reportWtf("making Content Service ready", e);
             }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             mSystemServiceManager.startService(NotificationManagerService.class);
             notification = INotificationManager.Stub.asInterface(
@@ -769,72 +813,79 @@
             mSystemServiceManager.startService(DeviceStorageMonitorService.class);
 
             if (!disableLocation) {
+                traceBeginAndSlog("StartLocationManagerService");
                 try {
-                    Slog.i(TAG, "Location Manager");
                     location = new LocationManagerService(context);
                     ServiceManager.addService(Context.LOCATION_SERVICE, location);
                 } catch (Throwable e) {
                     reportWtf("starting Location Manager", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+                traceBeginAndSlog("StartCountryDetectorService");
                 try {
-                    Slog.i(TAG, "Country Detector");
                     countryDetector = new CountryDetectorService(context);
                     ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);
                 } catch (Throwable e) {
                     reportWtf("starting Country Detector", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
             if (!disableNonCoreServices) {
+                traceBeginAndSlog("StartSearchManagerService");
                 try {
-                    Slog.i(TAG, "Search Service");
                     ServiceManager.addService(Context.SEARCH_SERVICE,
                             new SearchManagerService(context));
                 } catch (Throwable e) {
                     reportWtf("starting Search Service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
+            traceBeginAndSlog("StartDropBoxManagerService");
             try {
-                Slog.i(TAG, "DropBox Service");
                 ServiceManager.addService(Context.DROPBOX_SERVICE,
                         new DropBoxManagerService(context, new File("/data/system/dropbox")));
             } catch (Throwable e) {
                 reportWtf("starting DropBoxManagerService", e);
             }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             if (!disableNonCoreServices && context.getResources().getBoolean(
                         R.bool.config_enableWallpaperService)) {
+                traceBeginAndSlog("StartWallpaperManagerService");
                 try {
-                    Slog.i(TAG, "Wallpaper Service");
                     wallpaper = new WallpaperManagerService(context);
                     ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
                 } catch (Throwable e) {
                     reportWtf("starting Wallpaper Service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
+            traceBeginAndSlog("StartAudioService");
             try {
-                Slog.i(TAG, "Audio Service");
                 audioService = new AudioService(context);
                 ServiceManager.addService(Context.AUDIO_SERVICE, audioService);
             } catch (Throwable e) {
                 reportWtf("starting Audio Service", e);
             }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             if (!disableNonCoreServices) {
                 mSystemServiceManager.startService(DockObserver.class);
             }
 
+            traceBeginAndSlog("StartWiredAccessoryManager");
             try {
-                Slog.i(TAG, "Wired Accessory Manager");
                 // Listen for wired headset changes
                 inputManager.setWiredAccessoryCallbacks(
                         new WiredAccessoryManager(context, inputManager));
             } catch (Throwable e) {
                 reportWtf("starting WiredAccessoryManager", e);
             }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             if (!disableNonCoreServices) {
                 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
@@ -846,17 +897,20 @@
                         || mPackageManager.hasSystemFeature(
                                 PackageManager.FEATURE_USB_ACCESSORY)) {
                     // Manage USB host and device support
+                    Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartUsbService");
                     mSystemServiceManager.startService(USB_SERVICE_CLASS);
+                    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                 }
 
+                traceBeginAndSlog("StartSerialService");
                 try {
-                    Slog.i(TAG, "Serial Service");
                     // Serial port support
                     serial = new SerialService(context);
                     ServiceManager.addService(Context.SERIAL_SERVICE, serial);
                 } catch (Throwable e) {
                     Slog.e(TAG, "Failure starting SerialService", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
             mSystemServiceManager.startService(TwilightService.class);
@@ -882,49 +936,54 @@
                 }
             }
 
+            traceBeginAndSlog("StartDiskStatsService");
             try {
-                Slog.i(TAG, "DiskStats Service");
                 ServiceManager.addService("diskstats", new DiskStatsService(context));
             } catch (Throwable e) {
                 reportWtf("starting DiskStats Service", e);
             }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+            traceBeginAndSlog("StartSamplingProfilerService");
             try {
                 // need to add this service even if SamplingProfilerIntegration.isEnabled()
                 // is false, because it is this service that detects system property change and
                 // turns on SamplingProfilerIntegration. Plus, when sampling profiler doesn't work,
                 // there is little overhead for running this service.
-                Slog.i(TAG, "SamplingProfiler Service");
                 ServiceManager.addService("samplingprofiler",
                             new SamplingProfilerService(context));
             } catch (Throwable e) {
                 reportWtf("starting SamplingProfiler Service", e);
             }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             if (!disableNetwork && !disableNetworkTime) {
+                traceBeginAndSlog("StartNetworkTimeUpdateService");
                 try {
-                    Slog.i(TAG, "NetworkTimeUpdateService");
                     networkTimeUpdater = new NetworkTimeUpdateService(context);
                 } catch (Throwable e) {
                     reportWtf("starting NetworkTimeUpdate service", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
+            traceBeginAndSlog("StartCommonTimeManagementService");
             try {
-                Slog.i(TAG, "CommonTimeManagementService");
                 commonTimeMgmtService = new CommonTimeManagementService(context);
                 ServiceManager.addService("commontime_management", commonTimeMgmtService);
             } catch (Throwable e) {
                 reportWtf("starting CommonTimeManagementService service", e);
             }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             if (!disableNetwork) {
+                traceBeginAndSlog("CertBlacklister");
                 try {
-                    Slog.i(TAG, "CertBlacklister");
                     CertBlacklister blacklister = new CertBlacklister(context);
                 } catch (Throwable e) {
                     reportWtf("starting CertBlacklister", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
             if (!disableNonCoreServices) {
@@ -933,13 +992,14 @@
             }
 
             if (!disableNonCoreServices) {
+                traceBeginAndSlog("StartAssetAtlasService");
                 try {
-                    Slog.i(TAG, "Assets Atlas Service");
                     atlas = new AssetAtlasService(context);
                     ServiceManager.addService(AssetAtlasService.ASSET_ATLAS_SERVICE, atlas);
                 } catch (Throwable e) {
                     reportWtf("starting AssetAtlasService", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
             if (!disableNonCoreServices) {
@@ -964,24 +1024,26 @@
             }
 
             if (!disableNonCoreServices) {
+                traceBeginAndSlog("StartMediaRouterService");
                 try {
-                    Slog.i(TAG, "Media Router Service");
                     mediaRouter = new MediaRouterService(context);
                     ServiceManager.addService(Context.MEDIA_ROUTER_SERVICE, mediaRouter);
                 } catch (Throwable e) {
                     reportWtf("starting MediaRouterService", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
                 mSystemServiceManager.startService(TrustManagerService.class);
 
                 mSystemServiceManager.startService(FingerprintService.class);
 
+                traceBeginAndSlog("StartBackgroundDexOptService");
                 try {
-                    Slog.i(TAG, "BackgroundDexOptService");
                     BackgroundDexOptService.schedule(context, 0);
                 } catch (Throwable e) {
                     reportWtf("starting BackgroundDexOptService", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             }
 
@@ -1009,12 +1071,15 @@
 
         // It is now time to start up the app processes...
 
+        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeVibratorServiceReady");
         try {
             vibrator.systemReady();
         } catch (Throwable e) {
             reportWtf("making Vibrator Service ready", e);
         }
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeLockSettingsServiceReady");
         if (lockSettings != null) {
             try {
                 lockSettings.systemReady();
@@ -1022,17 +1087,20 @@
                 reportWtf("making Lock Settings Service ready", e);
             }
         }
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
         // Needed by DevicePolicyManager for initialization
         mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
 
         mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
 
+        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeWindowManagerServiceReady");
         try {
             wm.systemReady();
         } catch (Throwable e) {
             reportWtf("making Window Manager Service ready", e);
         }
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
         if (safeMode) {
             mActivityManagerService.showSafeModeOverlay();
@@ -1047,25 +1115,32 @@
         w.getDefaultDisplay().getMetrics(metrics);
         context.getResources().updateConfiguration(config, metrics);
 
+        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakePowerManagerServiceReady");
         try {
             // TODO: use boot phase
             mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         } catch (Throwable e) {
             reportWtf("making Power Manager Service ready", e);
         }
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakePackageManagerServiceReady");
         try {
             mPackageManagerService.systemReady();
         } catch (Throwable e) {
             reportWtf("making Package Manager Service ready", e);
         }
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeDisplayManagerServiceReady");
         try {
             // TODO: use boot phase and communicate these flags some other way
             mDisplayManagerService.systemReady(safeMode, mOnlyCore);
         } catch (Throwable e) {
             reportWtf("making Display Manager Service ready", e);
         }
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
         // These are needed to propagate to the runnable below.
         final NetworkManagementService networkManagementF = networkManagement;
@@ -1099,55 +1174,76 @@
                 Slog.i(TAG, "Making services ready");
                 mSystemServiceManager.startBootPhase(
                         SystemService.PHASE_ACTIVITY_MANAGER_READY);
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PhaseActivityManagerReady");
 
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartObservingNativeCrashes");
                 try {
                     mActivityManagerService.startObservingNativeCrashes();
                 } catch (Throwable e) {
                     reportWtf("observing native crashes", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
                 Slog.i(TAG, "WebViewFactory preparation");
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "WebViewFactoryPreparation");
                 WebViewFactory.prepareWebViewInSystemServer();
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartSystemUI");
                 try {
                     startSystemUi(context);
                 } catch (Throwable e) {
                     reportWtf("starting System UI", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeMountServiceReady");
                 try {
                     if (networkScoreF != null) networkScoreF.systemReady();
                 } catch (Throwable e) {
                     reportWtf("making Network Score Service ready", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeNetworkManagementServiceReady");
                 try {
                     if (networkManagementF != null) networkManagementF.systemReady();
                 } catch (Throwable e) {
                     reportWtf("making Network Managment Service ready", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeNetworkStatsServiceReady");
                 try {
                     if (networkStatsF != null) networkStatsF.systemReady();
                 } catch (Throwable e) {
                     reportWtf("making Network Stats Service ready", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeNetworkPolicyServiceReady");
                 try {
                     if (networkPolicyF != null) networkPolicyF.systemReady();
                 } catch (Throwable e) {
                     reportWtf("making Network Policy Service ready", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeConnectivityServiceReady");
                 try {
                     if (connectivityF != null) connectivityF.systemReady();
                 } catch (Throwable e) {
                     reportWtf("making Connectivity Service ready", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeAudioServiceReady");
                 try {
                     if (audioServiceF != null) audioServiceF.systemReady();
                 } catch (Throwable e) {
                     reportWtf("Notifying AudioService running", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                 Watchdog.getInstance().start();
 
                 // It is now okay to let the various system services start their
                 // third party code...
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PhaseThirdPartyAppsCanStart");
                 mSystemServiceManager.startBootPhase(
                         SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
 
@@ -1216,6 +1312,7 @@
                 } catch (Throwable e) {
                     reportWtf("Notifying MmsService running", e);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
         });
     }
@@ -1227,4 +1324,9 @@
         //Slog.d(TAG, "Starting service: " + intent);
         context.startServiceAsUser(intent, UserHandle.OWNER);
     }
+
+    private static void traceBeginAndSlog(String name) {
+        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, name);
+        Slog.i(TAG, name);
+    }
 }
diff --git a/test-runner/src/android/test/InstrumentationCoreTestRunner.java b/test-runner/src/android/test/InstrumentationCoreTestRunner.java
index 036a2275..655a65c 100644
--- a/test-runner/src/android/test/InstrumentationCoreTestRunner.java
+++ b/test-runner/src/android/test/InstrumentationCoreTestRunner.java
@@ -21,12 +21,6 @@
 import java.lang.reflect.Modifier;
 import java.util.List;
 
-import com.android.internal.util.Predicate;
-import com.android.internal.util.Predicates;
-
-import dalvik.annotation.BrokenTest;
-import dalvik.annotation.SideEffect;
-
 import junit.framework.AssertionFailedError;
 import junit.framework.Test;
 import junit.framework.TestCase;
@@ -192,19 +186,4 @@
 
         return runner;
     }
-
-    @Override
-    List<Predicate<TestMethod>> getBuilderRequirements() {
-        List<Predicate<TestMethod>> builderRequirements =
-                super.getBuilderRequirements();
-        Predicate<TestMethod> brokenTestPredicate =
-                Predicates.not(new HasAnnotation(BrokenTest.class));
-        builderRequirements.add(brokenTestPredicate);
-        if (!singleTest) {
-            Predicate<TestMethod> sideEffectPredicate =
-                    Predicates.not(new HasAnnotation(SideEffect.class));
-            builderRequirements.add(sideEffectPredicate);
-        }
-        return builderRequirements;
-    }
 }
diff --git a/tests/CoreTests/run_core_test.sh b/tests/CoreTests/run_core_test.sh
deleted file mode 100755
index ffa31ed..0000000
--- a/tests/CoreTests/run_core_test.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-framework=/system/framework
-bpath=$framework/core.jar:$framework/ext.jar:$framework/framework.jar:$framework/android.test.runner.jar
-adb shell exec dalvikvm -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=3001 \
-      -Xbootclasspath:$bpath -cp /data/app/android.core.apk \
-      -Djava.io.tmpdir=/sdcard/tmp \
-      com.android.internal.util.WithFramework junit.textui.TestRunner $*
diff --git a/tests/CoreTests/run_junit.sh b/tests/CoreTests/run_junit.sh
deleted file mode 100755
index b77794d..0000000
--- a/tests/CoreTests/run_junit.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-# runs unit tests over adb shell using dalvikvm.  The value added is setting the classpath for you
-# and pointing to the junit textui test runner.
-#
-# the normal usage might be:
-# (make MoreJavaTests)
-# $ adb sync
-# $ java/tests/run_junit.sh android.util.MyTest
-
-adb shell exec dalvikvm -cp system/app/MoreTests.apk junit.textui.TestRunner $*
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index b991d55..b701445 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -54,12 +54,6 @@
     tests/ResourceFilter_test.cpp \
     tests/ResourceTable_test.cpp
 
-aaptCIncludes := \
-    system/core/base/include \
-    external/libpng \
-    external/zlib
-
-aaptHostLdLibs :=
 aaptHostStaticLibs := \
     libandroidfw \
     libpng \
@@ -70,20 +64,16 @@
     libziparchive-host \
     libbase
 
-aaptCFlags := -DAAPT_VERSION=\"$(BUILD_NUMBER)\"
+aaptCFlags := -DAAPT_VERSION=\"$(BUILD_NUMBER_FROM_FILE)\"
 aaptCFlags += -Wall -Werror
 
-ifeq ($(HOST_OS),linux)
-    aaptHostLdLibs += -lrt -ldl -lpthread
-endif
+aaptHostLdLibs_linux := -lrt -ldl -lpthread
 
 # Statically link libz for MinGW (Win SDK under Linux),
 # and dynamically link for all others.
-ifneq ($(strip $(USE_MINGW)),)
-    aaptHostStaticLibs += libz
-else
-    aaptHostLdLibs += -lz
-endif
+aaptHostStaticLibs_windows := libz
+aaptHostLdLibs_linux += -lz
+aaptHostLdLibs_darwin := -lz
 
 
 # ==========================================================
@@ -92,13 +82,13 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := libaapt
-LOCAL_CFLAGS += -Wno-format-y2k -DSTATIC_ANDROIDFW_FOR_TOOLS $(aaptCFlags)
-LOCAL_CPPFLAGS += $(aaptCppFlags)
-ifeq (darwin,$(HOST_OS))
-LOCAL_CFLAGS += -D_DARWIN_UNLIMITED_STREAMS
-endif
-LOCAL_C_INCLUDES += $(aaptCIncludes)
+LOCAL_MODULE_HOST_OS := darwin linux windows
+LOCAL_CFLAGS := -Wno-format-y2k -DSTATIC_ANDROIDFW_FOR_TOOLS $(aaptCFlags)
+LOCAL_CPPFLAGS := $(aaptCppFlags)
+LOCAL_CFLAGS_darwin := -D_DARWIN_UNLIMITED_STREAMS
 LOCAL_SRC_FILES := $(aaptSources)
+LOCAL_STATIC_LIBRARIES := $(aaptHostStaticLibs)
+LOCAL_STATIC_LIBRARIES_windows := $(aaptHostStaticLibs_windows)
 
 include $(BUILD_HOST_STATIC_LIBRARY)
 
@@ -108,11 +98,14 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := aapt
-LOCAL_CFLAGS += $(aaptCFlags)
-LOCAL_CPPFLAGS += $(aaptCppFlags)
-LOCAL_LDLIBS += $(aaptHostLdLibs)
+LOCAL_MODULE_HOST_OS := darwin linux windows
+LOCAL_CFLAGS := $(aaptCFlags)
+LOCAL_CPPFLAGS := $(aaptCppFlags)
+LOCAL_LDLIBS_darwin := $(aaptHostLdLibs_darwin)
+LOCAL_LDLIBS_linux := $(aaptHostLdLibs_linux)
 LOCAL_SRC_FILES := $(aaptMain)
-LOCAL_STATIC_LIBRARIES += libaapt $(aaptHostStaticLibs)
+LOCAL_STATIC_LIBRARIES := libaapt $(aaptHostStaticLibs)
+LOCAL_STATIC_LIBRARIES_windows := $(aaptHostStaticLibs_windows)
 
 include $(BUILD_HOST_EXECUTABLE)
 
@@ -121,15 +114,16 @@
 # Build the host tests: libaapt_tests
 # ==========================================================
 include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 LOCAL_MODULE := libaapt_tests
-LOCAL_CFLAGS += $(aaptCFlags)
-LOCAL_CPPFLAGS += $(aaptCppFlags)
-LOCAL_LDLIBS += $(aaptHostLdLibs)
-LOCAL_SRC_FILES += $(aaptTests)
-LOCAL_C_INCLUDES += $(LOCAL_PATH)
-LOCAL_STATIC_LIBRARIES += libaapt $(aaptHostStaticLibs)
+LOCAL_CFLAGS := $(aaptCFlags)
+LOCAL_CPPFLAGS := $(aaptCppFlags)
+LOCAL_LDLIBS_darwin := $(aaptHostLdLibs_darwin)
+LOCAL_LDLIBS_linux := $(aaptHostLdLibs_linux)
+LOCAL_SRC_FILES := $(aaptTests)
+LOCAL_C_INCLUDES := $(LOCAL_PATH)
+LOCAL_STATIC_LIBRARIES := libaapt $(aaptHostStaticLibs)
+LOCAL_STATIC_LIBRARIES_windows := $(aaptHostStaticLibs_windows)
 
 include $(BUILD_HOST_NATIVE_TEST)
 
diff --git a/tools/aapt/CacheUpdater.h b/tools/aapt/CacheUpdater.h
index fade53a..10a1bbc 100644
--- a/tools/aapt/CacheUpdater.h
+++ b/tools/aapt/CacheUpdater.h
@@ -12,7 +12,7 @@
 #include <sys/stat.h>
 #include <stdio.h>
 #include "Images.h"
-#ifdef HAVE_MS_C_RUNTIME
+#ifdef _WIN32
 #include <direct.h>
 #endif
 
@@ -81,7 +81,7 @@
                 // Advance to the next segment of the path
                 existsPath.appendPath(toCreate.walkPath(&remains));
                 toCreate = remains;
-#ifdef HAVE_MS_C_RUNTIME
+#ifdef _WIN32
                 _mkdir(existsPath.string());
 #else
                 mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 8a0a39c..d12ab3b 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -215,7 +215,7 @@
             goto bail;
         }
 
-#ifdef HAVE_ANDROID_OS
+#ifdef __ANDROID__
         static const bool kHaveAndroidOs = true;
 #else
         static const bool kHaveAndroidOs = false;
@@ -633,7 +633,7 @@
     Asset* asset = NULL;
 
     if (strcmp("resources", option) == 0) {
-#ifndef HAVE_ANDROID_OS
+#ifndef __ANDROID__
         res.print(bundle->getValues());
 #endif
 
diff --git a/tools/aapt/CrunchCache.cpp b/tools/aapt/CrunchCache.cpp
index 6c39d1d..0d574cf 100644
--- a/tools/aapt/CrunchCache.cpp
+++ b/tools/aapt/CrunchCache.cpp
@@ -5,6 +5,7 @@
 // This file defines functions laid out and documented in
 // CrunchCache.h
 
+#include <utils/Compat.h>
 #include <utils/Vector.h>
 #include <utils/String8.h>
 
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index f832c60..bcf0d5e 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -6,6 +6,7 @@
 #include "Main.h"
 #include "Bundle.h"
 
+#include <utils/Compat.h>
 #include <utils/Log.h>
 #include <utils/threads.h>
 #include <utils/List.h>
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 5d20815..a4e5d3d 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -2682,7 +2682,7 @@
                 if (s > last && (*s == '.' || *s == 0)) {
                     String8 part(last, s-last);
                     dest.appendPath(part);
-#ifdef HAVE_MS_C_RUNTIME
+#ifdef _WIN32
                     _mkdir(dest.string());
 #else
                     mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
index dbe8c85..4b0d920 100644
--- a/tools/aapt/StringPool.h
+++ b/tools/aapt/StringPool.h
@@ -20,8 +20,6 @@
 #include <ctype.h>
 #include <errno.h>
 
-#include <libexpat/expat.h>
-
 using namespace android;
 
 #define PRINT_STRING_METRICS 0
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index ca3f687..dc08eb8 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -12,7 +12,7 @@
 #include <errno.h>
 #include <string.h>
 
-#ifndef HAVE_MS_C_RUNTIME
+#ifndef _WIN32
 #define O_BINARY 0
 #endif
 
diff --git a/tools/aapt/XMLNode.h b/tools/aapt/XMLNode.h
index 3161f65..b9e5cd5 100644
--- a/tools/aapt/XMLNode.h
+++ b/tools/aapt/XMLNode.h
@@ -10,6 +10,8 @@
 #include "StringPool.h"
 #include "ResourceTable.h"
 
+#include <expat.h>
+
 class XMLNode;
 
 extern const char* const RESOURCES_ROOT_NAMESPACE;
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index 10f8150..e5c42d5 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -82,10 +82,6 @@
 	XmlDom_test.cpp \
 	XmlFlattener_test.cpp
 
-cIncludes := \
-	external/libpng \
-	external/libz
-
 hostLdLibs :=
 
 hostStaticLibs := \
@@ -114,7 +110,7 @@
 LOCAL_MODULE := libaapt2
 
 LOCAL_SRC_FILES := $(sources)
-LOCAL_C_INCLUDES += $(cIncludes)
+LOCAL_STATIC_LIBRARIES += $(hostStaticLibs)
 LOCAL_CFLAGS += $(cFlags)
 LOCAL_CPPFLAGS += $(cppFlags)
 
@@ -130,7 +126,6 @@
 
 LOCAL_SRC_FILES := $(testSources)
 
-LOCAL_C_INCLUDES += $(cIncludes)
 LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs)
 LOCAL_LDLIBS += $(hostLdLibs)
 LOCAL_CFLAGS += $(cFlags)
@@ -146,7 +141,6 @@
 
 LOCAL_SRC_FILES := $(main)
 
-LOCAL_C_INCLUDES += $(cIncludes)
 LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs)
 LOCAL_LDLIBS += $(hostLdLibs)
 LOCAL_CFLAGS += $(cFlags)
diff --git a/tools/aapt2/Files.cpp b/tools/aapt2/Files.cpp
index 8484148..b24ff6b 100644
--- a/tools/aapt2/Files.cpp
+++ b/tools/aapt2/Files.cpp
@@ -22,7 +22,7 @@
 #include <string>
 #include <sys/stat.h>
 
-#ifdef HAVE_MS_C_RUNTIME
+#ifdef _WIN32
 // Windows includes.
 #include <direct.h>
 #endif
@@ -83,7 +83,7 @@
 }
 
 inline static int mkdirImpl(const StringPiece& path) {
-#ifdef HAVE_MS_C_RUNTIME
+#ifdef _WIN32
     return _mkdir(path.toString().c_str());
 #else
     return mkdir(path.toString().c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
diff --git a/tools/aapt2/SourceXmlPullParser.h b/tools/aapt2/SourceXmlPullParser.h
index 15936d6..d8ed459 100644
--- a/tools/aapt2/SourceXmlPullParser.h
+++ b/tools/aapt2/SourceXmlPullParser.h
@@ -20,7 +20,7 @@
 #include "XmlPullParser.h"
 
 #include <istream>
-#include <libexpat/expat.h>
+#include <expat.h>
 #include <queue>
 #include <stack>
 #include <string>
diff --git a/tools/aapt2/XmlDom.cpp b/tools/aapt2/XmlDom.cpp
index 763029f..b8b2d12 100644
--- a/tools/aapt2/XmlDom.cpp
+++ b/tools/aapt2/XmlDom.cpp
@@ -312,7 +312,7 @@
             }
         }
     }
-    return std::move(root);
+    return root;
 }
 
 Node::Node(NodeType type) : type(type), parent(nullptr), lineNumber(0), columnNumber(0) {
diff --git a/tools/aapt2/XmlDom.h b/tools/aapt2/XmlDom.h
index 6931884..035e7c4 100644
--- a/tools/aapt2/XmlDom.h
+++ b/tools/aapt2/XmlDom.h
@@ -21,7 +21,7 @@
 #include "StringPiece.h"
 
 #include <istream>
-#include <libexpat/expat.h>
+#include <expat.h>
 #include <memory>
 #include <string>
 #include <vector>
diff --git a/tools/aidl/AST.h b/tools/aidl/AST.h
index ead5e7a..d7bfccb 100644
--- a/tools/aidl/AST.h
+++ b/tools/aidl/AST.h
@@ -1,5 +1,5 @@
-#ifndef AIDL_AST_H
-#define AIDL_AST_H
+#ifndef AIDL_AST_H_
+#define AIDL_AST_H_
 
 #include <string>
 #include <vector>
@@ -368,4 +368,4 @@
     virtual void Write(FILE* to);
 };
 
-#endif // AIDL_AST_H
+#endif // AIDL_AST_H_
diff --git a/tools/aidl/Android.mk b/tools/aidl/Android.mk
index efd60a2..8e6189f 100644
--- a/tools/aidl/Android.mk
+++ b/tools/aidl/Android.mk
@@ -6,24 +6,74 @@
 ifeq ($(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)),)
 
 LOCAL_PATH:= $(call my-dir)
+
+# Logic shared between aidl and its unittests
 include $(CLEAR_VARS)
+LOCAL_MODULE := libaidl-common
+
+LOCAL_CLANG_CFLAGS := -Wall -Werror
+# Tragically, the code is riddled with unused parameters.
+LOCAL_CLANG_CFLAGS += -Wno-unused-parameter
+# yacc dumps a lot of code *just in case*.
+LOCAL_CLANG_CFLAGS += -Wno-unused-function
+LOCAL_CLANG_CFLAGS += -Wno-unneeded-internal-declaration
+# yacc is a tool from a more civilized age.
+LOCAL_CLANG_CFLAGS += -Wno-deprecated-register
+# yacc also has a habit of using char* over const char*.
+LOCAL_CLANG_CFLAGS += -Wno-writable-strings
 
 LOCAL_SRC_FILES := \
-	aidl_language_l.l \
-	aidl_language_y.y \
-	aidl.cpp \
-	aidl_language.cpp \
-	options.cpp \
-	search_path.cpp \
-	AST.cpp \
-	Type.cpp \
-	generate_java.cpp \
-	generate_java_binder.cpp \
-	generate_java_rpc.cpp
+    AST.cpp \
+    Type.cpp \
+    aidl.cpp \
+    aidl_language.cpp \
+    aidl_language_l.l \
+    aidl_language_y.y \
+    generate_java.cpp \
+    generate_java_binder.cpp \
+    options.cpp \
+    search_path.cpp \
 
-LOCAL_CFLAGS := -g
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
+# aidl executable
+include $(CLEAR_VARS)
 LOCAL_MODULE := aidl
 
+LOCAL_MODULE_HOST_OS := darwin linux windows
+LOCAL_CFLAGS := -Wall -Werror
+LOCAL_SRC_FILES := main.cpp
+LOCAL_STATIC_LIBRARIES := libaidl-common
 include $(BUILD_HOST_EXECUTABLE)
 
+
+# TODO(wiley) Compile these for mac as well after b/22771504
+ifeq ($(HOST_OS),linux)
+# Unit tests
+include $(CLEAR_VARS)
+LOCAL_MODULE := aidl_unittests
+
+LOCAL_CFLAGS := -g -DUNIT_TEST -Wall -Werror
+# Tragically, the code is riddled with unused parameters.
+LOCAL_CLANG_CFLAGS := -Wno-unused-parameter
+LOCAL_SRC_FILES := \
+    options_unittest.cpp \
+    test_main.cpp \
+    tests/end_to_end_tests.cpp \
+    tests/example_interface_test_data.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    libchrome-host \
+
+LOCAL_STATIC_LIBRARIES := \
+    libaidl-common \
+    libgmock_host \
+    libgtest_host \
+
+LOCAL_LDLIBS_linux := -lrt
+
+include $(BUILD_HOST_NATIVE_TEST)
+endif # HOST_OS == linux
+
 endif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK
diff --git a/tools/aidl/Type.cpp b/tools/aidl/Type.cpp
index 2267750..d9b8b88 100644
--- a/tools/aidl/Type.cpp
+++ b/tools/aidl/Type.cpp
@@ -28,9 +28,6 @@
 Type* MAP_TYPE;
 Type* LIST_TYPE;
 Type* CLASSLOADER_TYPE;
-Type* RPC_DATA_TYPE;
-Type* RPC_ERROR_TYPE;
-Type* EVENT_FAKE_TYPE;
 
 Expression* NULL_VALUE;
 Expression* THIS_VALUE;
@@ -42,7 +39,6 @@
 register_base_types()
 {
     VOID_TYPE = new BasicType("void",
-            "XXX", "XXX", "XXX", "XXX", "XXX",
             "XXX", "XXX", "XXX", "XXX", "XXX");
     NAMES.Add(VOID_TYPE);
 
@@ -50,37 +46,37 @@
     NAMES.Add(BOOLEAN_TYPE);
 
     BYTE_TYPE = new BasicType("byte",
-            "writeByte", "readByte", "writeByteArray", "createByteArray", "readByteArray",
-            "putByte", "getByte", "putByteArray", "createByteArray", "getByteArray");
+            "writeByte", "readByte", "writeByteArray", "createByteArray",
+            "readByteArray");
     NAMES.Add(BYTE_TYPE);
 
     CHAR_TYPE = new CharType();
     NAMES.Add(CHAR_TYPE);
 
     INT_TYPE = new BasicType("int",
-            "writeInt", "readInt", "writeIntArray", "createIntArray", "readIntArray",
-            "putInteger", "getInteger", "putIntegerArray", "createIntegerArray", "getIntegerArray");
+            "writeInt", "readInt", "writeIntArray", "createIntArray",
+            "readIntArray");
     NAMES.Add(INT_TYPE);
 
     LONG_TYPE = new BasicType("long",
-            "writeLong", "readLong", "writeLongArray", "createLongArray", "readLongArray",
-            "putLong", "getLong", "putLongArray", "createLongArray", "getLongArray");
+            "writeLong", "readLong", "writeLongArray", "createLongArray",
+            "readLongArray");
     NAMES.Add(LONG_TYPE);
 
     FLOAT_TYPE = new BasicType("float",
-            "writeFloat", "readFloat", "writeFloatArray", "createFloatArray", "readFloatArray",
-            "putFloat", "getFloat", "putFloatArray", "createFloatArray", "getFloatArray");
+            "writeFloat", "readFloat", "writeFloatArray", "createFloatArray",
+            "readFloatArray");
     NAMES.Add(FLOAT_TYPE);
 
     DOUBLE_TYPE = new BasicType("double",
-            "writeDouble", "readDouble", "writeDoubleArray", "createDoubleArray", "readDoubleArray",
-            "putDouble", "getDouble", "putDoubleArray", "createDoubleArray", "getDoubleArray");
+            "writeDouble", "readDouble", "writeDoubleArray",
+            "createDoubleArray", "readDoubleArray");
     NAMES.Add(DOUBLE_TYPE);
 
     STRING_TYPE = new StringType();
     NAMES.Add(STRING_TYPE);
 
-    OBJECT_TYPE = new Type("java.lang", "Object", Type::BUILT_IN, false, false, false);
+    OBJECT_TYPE = new Type("java.lang", "Object", Type::BUILT_IN, false, false);
     NAMES.Add(OBJECT_TYPE);
 
     CHAR_SEQUENCE_TYPE = new CharSequenceType();
@@ -92,7 +88,7 @@
     LIST_TYPE = new ListType();
     NAMES.Add(LIST_TYPE);
 
-    TEXT_UTILS_TYPE = new Type("android.text", "TextUtils", Type::BUILT_IN, false, false, false);
+    TEXT_UTILS_TYPE = new Type("android.text", "TextUtils", Type::BUILT_IN, false, false);
     NAMES.Add(TEXT_UTILS_TYPE);
 
     REMOTE_EXCEPTION_TYPE = new RemoteExceptionType();
@@ -119,19 +115,9 @@
     PARCELABLE_INTERFACE_TYPE = new ParcelableInterfaceType();
     NAMES.Add(PARCELABLE_INTERFACE_TYPE);
 
-    CONTEXT_TYPE = new Type("android.content", "Context", Type::BUILT_IN, false, false, false);
+    CONTEXT_TYPE = new Type("android.content", "Context", Type::BUILT_IN, false, false);
     NAMES.Add(CONTEXT_TYPE);
 
-    RPC_DATA_TYPE = new RpcDataType();
-    NAMES.Add(RPC_DATA_TYPE);
-
-    RPC_ERROR_TYPE = new UserDataType("android.support.place.rpc", "RpcError",
-                                    true, __FILE__, __LINE__);
-    NAMES.Add(RPC_ERROR_TYPE);
-
-    EVENT_FAKE_TYPE = new Type("event", Type::BUILT_IN, false, false, false);
-    NAMES.Add(EVENT_FAKE_TYPE);
-
     CLASSLOADER_TYPE = new ClassLoaderType();
     NAMES.Add(CLASSLOADER_TYPE);
 
@@ -158,30 +144,27 @@
 
 // ================================================================
 
-Type::Type(const string& name, int kind, bool canWriteToParcel, bool canWriteToRpcData,
-        bool canBeOut)
+Type::Type(const string& name, int kind, bool canWriteToParcel, bool canBeOut)
     :m_package(),
      m_name(name),
      m_declFile(""),
      m_declLine(-1),
      m_kind(kind),
      m_canWriteToParcel(canWriteToParcel),
-     m_canWriteToRpcData(canWriteToRpcData),
      m_canBeOut(canBeOut)
 {
     m_qualifiedName = name;
 }
 
 Type::Type(const string& package, const string& name,
-            int kind, bool canWriteToParcel, bool canWriteToRpcData,
-            bool canBeOut, const string& declFile, int declLine)
+            int kind, bool canWriteToParcel, bool canBeOut,
+            const string& declFile, int declLine)
     :m_package(package),
      m_name(name),
      m_declFile(declFile),
      m_declLine(declLine),
      m_kind(kind),
      m_canWriteToParcel(canWriteToParcel),
-     m_canWriteToRpcData(canWriteToRpcData),
      m_canBeOut(canBeOut)
 {
     if (package.length() > 0) {
@@ -214,12 +197,6 @@
 }
 
 string
-Type::RpcCreatorName() const
-{
-    return "";
-}
-
-string
 Type::InstantiableName() const
 {
     return QualifiedName();
@@ -282,26 +259,6 @@
 }
 
 void
-Type::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
-            __FILE__, __LINE__, m_qualifiedName.c_str());
-    addTo->Add(new LiteralExpression("/* WriteToRpcData error "
-                + m_qualifiedName + " */"));
-}
-
-void
-Type::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
-            __FILE__, __LINE__, m_qualifiedName.c_str());
-    addTo->Add(new LiteralExpression("/* ReadFromRpcData error "
-                + m_qualifiedName + " */"));
-}
-
-void
 Type::SetQualifiedName(const string& qualified)
 {
     m_qualifiedName = qualified;
@@ -324,20 +281,13 @@
 
 BasicType::BasicType(const string& name, const string& marshallParcel,
           const string& unmarshallParcel, const string& writeArrayParcel,
-          const string& createArrayParcel, const string& readArrayParcel,
-          const string& marshallRpc, const string& unmarshallRpc,
-          const string& writeArrayRpc, const string& createArrayRpc, const string& readArrayRpc)
-    :Type(name, BUILT_IN, true, true, false),
+          const string& createArrayParcel, const string& readArrayParcel)
+    :Type(name, BUILT_IN, true, false),
      m_marshallParcel(marshallParcel),
      m_unmarshallParcel(unmarshallParcel),
      m_writeArrayParcel(writeArrayParcel),
      m_createArrayParcel(createArrayParcel),
-     m_readArrayParcel(readArrayParcel),
-     m_marshallRpc(marshallRpc),
-     m_unmarshallRpc(unmarshallRpc),
-     m_writeArrayRpc(writeArrayRpc),
-     m_createArrayRpc(createArrayRpc),
-     m_readArrayRpc(readArrayRpc)
+     m_readArrayParcel(readArrayParcel)
 {
 }
 
@@ -378,24 +328,10 @@
     addTo->Add(new MethodCall(parcel, m_readArrayParcel, 1, v));
 }
 
-void
-BasicType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, m_marshallRpc, 2, k, v));
-}
-
-void
-BasicType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, m_unmarshallRpc, 1, k)));
-}
-
 // ================================================================
 
 BooleanType::BooleanType()
-    :Type("boolean", BUILT_IN, true, true, false)
+    :Type("boolean", BUILT_IN, true, false)
 {
 }
 
@@ -439,24 +375,10 @@
     addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
 }
 
-void
-BooleanType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, "putBoolean", 2, k, v));
-}
-
-void
-BooleanType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, "getBoolean", 1, k)));
-}
-
 // ================================================================
 
 CharType::CharType()
-    :Type("char", BUILT_IN, true, true, false)
+    :Type("char", BUILT_IN, true, false)
 {
 }
 
@@ -498,24 +420,10 @@
     addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
 }
 
-void
-CharType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, "putChar", 2, k, v));
-}
-
-void
-CharType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, "getChar", 1, k)));
-}
-
 // ================================================================
 
 StringType::StringType()
-    :Type("java.lang", "String", BUILT_IN, true, true, false)
+    :Type("java.lang", "String", BUILT_IN, true, false)
 {
 }
 
@@ -562,24 +470,10 @@
     addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
 }
 
-void
-StringType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, "putString", 2, k, v));
-}
-
-void
-StringType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, Variable**)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, "getString", 1, k)));
-}
-
 // ================================================================
 
 CharSequenceType::CharSequenceType()
-    :Type("java.lang", "CharSequence", BUILT_IN, true, true, false)
+    :Type("java.lang", "CharSequence", BUILT_IN, true, false)
 {
 }
 
@@ -639,7 +533,7 @@
 // ================================================================
 
 RemoteExceptionType::RemoteExceptionType()
-    :Type("android.os", "RemoteException", BUILT_IN, false, false, false)
+    :Type("android.os", "RemoteException", BUILT_IN, false, false)
 {
 }
 
@@ -658,7 +552,7 @@
 // ================================================================
 
 RuntimeExceptionType::RuntimeExceptionType()
-    :Type("java.lang", "RuntimeException", BUILT_IN, false, false, false)
+    :Type("java.lang", "RuntimeException", BUILT_IN, false, false)
 {
 }
 
@@ -678,7 +572,7 @@
 // ================================================================
 
 IBinderType::IBinderType()
-    :Type("android.os", "IBinder", BUILT_IN, true, false, false)
+    :Type("android.os", "IBinder", BUILT_IN, true, false)
 {
 }
 
@@ -717,7 +611,7 @@
 // ================================================================
 
 IInterfaceType::IInterfaceType()
-    :Type("android.os", "IInterface", BUILT_IN, false, false, false)
+    :Type("android.os", "IInterface", BUILT_IN, false, false)
 {
 }
 
@@ -737,7 +631,7 @@
 // ================================================================
 
 BinderType::BinderType()
-    :Type("android.os", "Binder", BUILT_IN, false, false, false)
+    :Type("android.os", "Binder", BUILT_IN, false, false)
 {
 }
 
@@ -758,7 +652,7 @@
 // ================================================================
 
 BinderProxyType::BinderProxyType()
-    :Type("android.os", "BinderProxy", BUILT_IN, false, false, false)
+    :Type("android.os", "BinderProxy", BUILT_IN, false, false)
 {
 }
 
@@ -779,7 +673,7 @@
 // ================================================================
 
 ParcelType::ParcelType()
-    :Type("android.os", "Parcel", BUILT_IN, false, false, false)
+    :Type("android.os", "Parcel", BUILT_IN, false, false)
 {
 }
 
@@ -798,7 +692,7 @@
 // ================================================================
 
 ParcelableInterfaceType::ParcelableInterfaceType()
-    :Type("android.os", "Parcelable", BUILT_IN, false, false, false)
+    :Type("android.os", "Parcelable", BUILT_IN, false, false)
 {
 }
 
@@ -817,7 +711,7 @@
 // ================================================================
 
 MapType::MapType()
-    :Type("java.util", "Map", BUILT_IN, true, false, true)
+    :Type("java.util", "Map", BUILT_IN, true, true)
 {
 }
 
@@ -857,7 +751,7 @@
 // ================================================================
 
 ListType::ListType()
-    :Type("java.util", "List", BUILT_IN, true, true, true)
+    :Type("java.util", "List", BUILT_IN, true, true)
 {
 }
 
@@ -888,26 +782,12 @@
     addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
 }
 
-void
-ListType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, "putList", 2, k, v));
-}
-
-void
-ListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, "getList", 1, k)));
-}
-
 // ================================================================
 
 UserDataType::UserDataType(const string& package, const string& name,
-                        bool builtIn, bool canWriteToParcel, bool canWriteToRpcData,
+                        bool builtIn, bool canWriteToParcel,
                         const string& declFile, int declLine)
-    :Type(package, name, builtIn ? BUILT_IN : USERDATA, canWriteToParcel, canWriteToRpcData,
+    :Type(package, name, builtIn ? BUILT_IN : USERDATA, canWriteToParcel,
             true, declFile, declLine)
 {
 }
@@ -918,12 +798,6 @@
     return QualifiedName() + ".CREATOR";
 }
 
-string
-UserDataType::RpcCreatorName() const
-{
-    return QualifiedName() + ".RPC_CREATOR";
-}
-
 void
 UserDataType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
 {
@@ -1014,29 +888,12 @@
                     v, new LiteralExpression(creator)));
 }
 
-void
-UserDataType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags)
-{
-    // data.putFlattenable(k, v);
-    addTo->Add(new MethodCall(data, "putFlattenable", 2, k, v));
-}
-
-void
-UserDataType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl)
-{
-    // data.getFlattenable(k, CLASS.RPC_CREATOR);
-    addTo->Add(new Assignment(v, new MethodCall(data, "getFlattenable", 2, k,
-                new FieldVariable(v->type, "RPC_CREATOR"))));
-}
-
 // ================================================================
 
 InterfaceType::InterfaceType(const string& package, const string& name,
                         bool builtIn, bool oneway,
                         const string& declFile, int declLine)
-    :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false, false,
+    :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false,
                         declFile, declLine)
     ,m_oneway(oneway)
 {
@@ -1075,7 +932,7 @@
 
 GenericType::GenericType(const string& package, const string& name,
                          const vector<Type*>& args)
-    :Type(package, name, BUILT_IN, true, true, true)
+    :Type(package, name, BUILT_IN, true, true)
 {
     m_args = args;
 
@@ -1200,65 +1057,11 @@
     }
 }
 
-void
-GenericListType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    Type* generic = GenericArgumentTypes()[0];
-    if (generic == RPC_DATA_TYPE) {
-        addTo->Add(new MethodCall(data, "putRpcDataList", 2, k, v));
-    } else if (generic->RpcCreatorName() != "") {
-        addTo->Add(new MethodCall(data, "putFlattenableList", 2, k, v));
-    } else {
-        addTo->Add(new MethodCall(data, "putList", 2, k, v));
-    }
-}
-
-void
-GenericListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, Variable** cl)
-{
-    Type* generic = GenericArgumentTypes()[0];
-    if (generic == RPC_DATA_TYPE) {
-        addTo->Add(new Assignment(v, new MethodCall(data, "getRpcDataList", 2, k)));
-    } else if (generic->RpcCreatorName() != "") {
-        addTo->Add(new Assignment(v, new MethodCall(data, "getFlattenableList", 2, k, 
-                        new LiteralExpression(generic->RpcCreatorName()))));
-    } else {
-        string classArg = GenericArgumentTypes()[0]->QualifiedName();
-        classArg += ".class";
-        addTo->Add(new Assignment(v, new MethodCall(data, "getList", 2, k,
-                        new LiteralExpression(classArg))));
-    }
-}
-
-
-// ================================================================
-
-RpcDataType::RpcDataType()
-    :UserDataType("android.support.place.rpc", "RpcData", true, true, true)
-{
-}
-
-void
-RpcDataType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data, int flags)
-{
-    addTo->Add(new MethodCall(data, "putRpcData", 2, k, v));
-}
-
-void
-RpcDataType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
-        Variable** cl)
-{
-    addTo->Add(new Assignment(v, new MethodCall(data, "getRpcData", 1, k)));
-}
-
 
 // ================================================================
 
 ClassLoaderType::ClassLoaderType()
-    :Type("java.lang", "ClassLoader", BUILT_IN, false, false, false)
+    :Type("java.lang", "ClassLoader", BUILT_IN, false, false)
 {
 }
 
diff --git a/tools/aidl/Type.h b/tools/aidl/Type.h
index ae12720..6ede79a 100644
--- a/tools/aidl/Type.h
+++ b/tools/aidl/Type.h
@@ -1,5 +1,5 @@
-#ifndef AIDL_TYPE_H
-#define AIDL_TYPE_H
+#ifndef AIDL_TYPE_H_
+#define AIDL_TYPE_H_
 
 #include "AST.h"
 #include <string>
@@ -24,9 +24,9 @@
     };
 
                     Type(const string& name, int kind, bool canWriteToParcel,
-                            bool canWriteToRpcData, bool canBeOut);
+                         bool canBeOut);
                     Type(const string& package, const string& name,
-                            int kind, bool canWriteToParcel, bool canWriteToRpcData, bool canBeOut,
+                            int kind, bool canWriteToParcel, bool canBeOut,
                             const string& declFile = "", int declLine = -1);
     virtual         ~Type();
 
@@ -37,12 +37,10 @@
     inline string   DeclFile() const            { return m_declFile; }
     inline int      DeclLine() const            { return m_declLine; }
     inline bool     CanWriteToParcel() const    { return m_canWriteToParcel; }
-    inline bool     CanWriteToRpcData() const   { return m_canWriteToRpcData; }
     inline bool     CanBeOutParameter() const   { return m_canBeOut; }
     
     virtual string  ImportType() const;
     virtual string  CreatorName() const;
-    virtual string  RpcCreatorName() const;
     virtual string  InstantiableName() const;
 
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
@@ -61,11 +59,6 @@
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, Variable** cl);
 
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-
 protected:
     void SetQualifiedName(const string& qualified);
     Expression* BuildWriteToParcelFlags(int flags);
@@ -81,7 +74,6 @@
     int m_declLine;
     int m_kind;
     bool m_canWriteToParcel;
-    bool m_canWriteToRpcData;
     bool m_canBeOut;
 };
 
@@ -93,12 +85,7 @@
                               const string& unmarshallParcel,
                               const string& writeArrayParcel,
                               const string& createArrayParcel,
-                              const string& readArrayParcel,
-                              const string& marshallRpc,
-                              const string& unmarshallRpc,
-                              const string& writeArrayRpc,
-                              const string& createArrayRpc,
-                              const string& readArrayRpc);
+                              const string& readArrayParcel);
 
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
@@ -114,22 +101,12 @@
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, Variable** cl);
 
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-
 private:
     string m_marshallParcel;
     string m_unmarshallParcel;
     string m_writeArrayParcel;
     string m_createArrayParcel;
     string m_readArrayParcel;
-    string m_marshallRpc;
-    string m_unmarshallRpc;
-    string m_writeArrayRpc;
-    string m_createArrayRpc;
-    string m_readArrayRpc;
 };
 
 class BooleanType : public Type
@@ -150,11 +127,6 @@
                                     Variable* parcel, Variable** cl);
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
 };
 
 class CharType : public Type
@@ -175,11 +147,6 @@
                                     Variable* parcel, Variable** cl);
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
 };
 
 
@@ -203,11 +170,6 @@
                                     Variable* parcel, Variable** cl);
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
 };
 
 class CharSequenceType : public Type
@@ -344,22 +306,16 @@
                                     Variable* parcel, Variable** cl);
     virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
 };
 
 class UserDataType : public Type
 {
 public:
                     UserDataType(const string& package, const string& name,
-                            bool builtIn, bool canWriteToParcel, bool canWriteToRpcData,
+                            bool builtIn, bool canWriteToParcel,
                             const string& declFile = "", int declLine = -1);
 
     virtual string  CreatorName() const;
-    virtual string  RpcCreatorName() const;
 
     virtual void    WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags);
@@ -376,11 +332,6 @@
                                     Variable* parcel, Variable** cl);
     virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, Variable** cl);
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
 };
 
 class InterfaceType : public Type
@@ -426,17 +377,6 @@
     vector<Type*> m_args;
 };
 
-class RpcDataType : public UserDataType
-{
-public:
-                    RpcDataType();
-
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-};
-
 class ClassLoaderType : public Type
 {
 public:
@@ -459,11 +399,6 @@
     virtual void    ReadFromParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, Variable** cl);
 
-    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, int flags);
-    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
-                                    Variable* data, Variable** cl);
-    
 private:
     string m_creator;
 };
@@ -526,11 +461,6 @@
 
 extern Type* CONTEXT_TYPE;
 
-extern Type* RPC_DATA_TYPE;
-extern Type* RPC_ERROR_TYPE;
-extern Type* RPC_CONTEXT_TYPE;
-extern Type* EVENT_FAKE_TYPE;
-
 extern Expression* NULL_VALUE;
 extern Expression* THIS_VALUE;
 extern Expression* SUPER_VALUE;
@@ -539,4 +469,4 @@
 
 void register_base_types();
 
-#endif // AIDL_TYPE_H
+#endif // AIDL_TYPE_H_
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp
index 14c9f95..832c51c 100644
--- a/tools/aidl/aidl.cpp
+++ b/tools/aidl/aidl.cpp
@@ -1,6 +1,7 @@
 
 #include "aidl_language.h"
 #include "options.h"
+#include "os.h"
 #include "search_path.h"
 #include "Type.h"
 #include "generate_java.h"
@@ -14,7 +15,7 @@
 #include <string.h>
 #include <map>
 
-#ifdef HAVE_MS_C_RUNTIME
+#ifdef _WIN32
 #include <io.h>
 #include <direct.h>
 #include <sys/stat.h>
@@ -59,12 +60,9 @@
         }
         else if (d->item_type == USER_DATA_TYPE) {
             user_data_type* b = (user_data_type*)d;
-            if ((b->flattening_methods & PARCELABLE_DATA) != 0) {
+            if (b->parcelable) {
                 printf("parcelable %s %s;\n", b->package, b->name.data);
             }
-            if ((b->flattening_methods & RPC_DATA) != 0) {
-                printf("flattenable %s %s;\n", b->package, b->name.data);
-            }
         }
         else {
             printf("UNKNOWN d=0x%08lx d->item_type=%d\n", (long)d, d->item_type);
@@ -161,11 +159,6 @@
 {
 }
 
-static ParserCallbacks g_importCallbacks = {
-    &main_document_parsed,
-    &import_import_parsed
-};
-
 // ==========================================================
 static int
 check_filename(const char* filename, const char* package, buffer_type* name)
@@ -177,7 +170,7 @@
     char cwd[MAXPATHLEN];
     bool valid = false;
 
-#ifdef HAVE_WINDOWS_PATHS
+#ifdef _WIN32
     if (isalpha(filename[0]) && filename[1] == ':'
         && filename[2] == OS_PATH_SEPARATOR) {
 #else
@@ -217,7 +210,7 @@
     if (valid) {
         p = fn.c_str() + (len - expected.length());
 
-#ifdef HAVE_WINDOWS_PATHS
+#ifdef _WIN32
         if (OS_PATH_SEPARATOR != '/') {
             // Input filename under cygwin most likely has / separators
             // whereas the expected string uses \\ separators. Adjust
@@ -255,8 +248,7 @@
             user_data_type* p = (user_data_type*)items;
             err |= check_filename(filename, p->package, &p->name);
         }
-        else if (items->item_type == INTERFACE_TYPE_BINDER
-                || items->item_type == INTERFACE_TYPE_RPC) {
+        else if (items->item_type == INTERFACE_TYPE_BINDER) {
             interface_type* c = (interface_type*)items;
             err |= check_filename(filename, c->package, &c->name);
         }
@@ -307,11 +299,9 @@
         if (items->item_type == USER_DATA_TYPE) {
             user_data_type* p = (user_data_type*)items;
             type = new UserDataType(p->package ? p->package : "", p->name.data,
-                    false, ((p->flattening_methods & PARCELABLE_DATA) != 0),
-                    ((p->flattening_methods & RPC_DATA) != 0), filename, p->name.lineno);
+                    false, p->parcelable, filename, p->name.lineno);
         }
-        else if (items->item_type == INTERFACE_TYPE_BINDER
-                || items->item_type == INTERFACE_TYPE_RPC) {
+        else if (items->item_type == INTERFACE_TYPE_BINDER) {
             interface_type* c = (interface_type*)items;
             type = new InterfaceType(c->package ? c->package : "",
                             c->name.data, false, c->oneway,
@@ -335,30 +325,17 @@
                 string name = c->name.data;
                 name += ".Stub";
                 Type* stub = new Type(c->package ? c->package : "",
-                                        name, Type::GENERATED, false, false, false,
+                                        name, Type::GENERATED, false, false,
                                         filename, c->name.lineno);
                 NAMES.Add(stub);
 
                 name = c->name.data;
                 name += ".Stub.Proxy";
                 Type* proxy = new Type(c->package ? c->package : "",
-                                        name, Type::GENERATED, false, false, false,
+                                        name, Type::GENERATED, false, false,
                                         filename, c->name.lineno);
                 NAMES.Add(proxy);
             }
-            else if (items->item_type == INTERFACE_TYPE_RPC) {
-                // for interfaces, also add the service base type, we don't
-                // bother checking these for duplicates, because the parser
-                // won't let us do it.
-                interface_type* c = (interface_type*)items;
-
-                string name = c->name.data;
-                name += ".ServiceBase";
-                Type* base = new Type(c->package ? c->package : "",
-                                        name, Type::GENERATED, false, false, false,
-                                        filename, c->name.lineno);
-                NAMES.Add(base);
-            }
         } else {
             if (old->Kind() == Type::BUILT_IN) {
                 fprintf(stderr, "%s:%d attempt to redefine built in class %s\n",
@@ -410,7 +387,7 @@
 }
 
 static int
-check_method(const char* filename, int kind, method_type* m)
+check_method(const char* filename, method_type* m)
 {
     int err = 0;
 
@@ -423,19 +400,10 @@
         return err;
     }
 
-    if (returnType == EVENT_FAKE_TYPE) {
-        if (kind != INTERFACE_TYPE_RPC) {
-            fprintf(stderr, "%s:%d event methods only supported for rpc interfaces\n",
-                    filename, m->type.type.lineno);
-            err = 1;
-        }
-    } else {
-        if (!(kind == INTERFACE_TYPE_BINDER ? returnType->CanWriteToParcel()
-                    : returnType->CanWriteToRpcData())) {
-            fprintf(stderr, "%s:%d return type %s can't be marshalled.\n", filename,
+    if (!returnType->CanWriteToParcel()) {
+        fprintf(stderr, "%s:%d return type %s can't be marshalled.\n", filename,
                         m->type.type.lineno, m->type.type.data);
-            err = 1;
-        }
+        err = 1;
     }
 
     if (m->type.dimension > 0 && !returnType->CanBeArray()) {
@@ -468,30 +436,13 @@
             goto next;
         }
 
-        if (t == EVENT_FAKE_TYPE) {
-            fprintf(stderr, "%s:%d parameter %s (%d) event can not be used as a parameter %s\n",
-                    filename, m->type.type.lineno, arg->name.data, index,
-                    arg->type.type.data);
-            err = 1;
-            goto next;
-        }
-        
-        if (!(kind == INTERFACE_TYPE_BINDER ? t->CanWriteToParcel() : t->CanWriteToRpcData())) {
+        if (!t->CanWriteToParcel()) {
             fprintf(stderr, "%s:%d parameter %d: '%s %s' can't be marshalled.\n",
                         filename, m->type.type.lineno, index,
                         arg->type.type.data, arg->name.data);
             err = 1;
         }
 
-        if (returnType == EVENT_FAKE_TYPE
-                && convert_direction(arg->direction.data) != IN_PARAMETER) {
-            fprintf(stderr, "%s:%d parameter %d: '%s %s' All paremeters on events must be 'in'.\n",
-                    filename, m->type.type.lineno, index,
-                    arg->type.type.data, arg->name.data);
-            err = 1;
-            goto next;
-        }
-
         if (arg->direction.data == NULL
                 && (arg->type.dimension != 0 || t->CanBeOutParameter())) {
             fprintf(stderr, "%s:%d parameter %d: '%s %s' can be an out"
@@ -553,8 +504,7 @@
     int err = 0;
     while (items) {
         // (nothing to check for USER_DATA_TYPE)
-        if (items->item_type == INTERFACE_TYPE_BINDER
-                || items->item_type == INTERFACE_TYPE_RPC) {
+        if (items->item_type == INTERFACE_TYPE_BINDER) {
             map<string,method_type*> methodNames;
             interface_type* c = (interface_type*)items;
 
@@ -563,7 +513,7 @@
                 if (member->item_type == METHOD_TYPE) {
                     method_type* m = (method_type*)member;
 
-                    err |= check_method(filename, items->item_type, m);
+                    err |= check_method(filename, m);
 
                     // prevent duplicate methods
                     if (methodNames.find(m->name.data) == methodNames.end()) {
@@ -604,9 +554,6 @@
         if (next->item_type == INTERFACE_TYPE_BINDER) {
             lineno = ((interface_type*)next)->interface_token.lineno;
         }
-        else if (next->item_type == INTERFACE_TYPE_RPC) {
-            lineno = ((interface_type*)next)->interface_token.lineno;
-        }
         fprintf(stderr, "%s:%d aidl can only handle one interface per file\n",
                             filename, lineno);
         return 1;
@@ -616,9 +563,9 @@
         *onlyParcelable = true;
         if (options.failOnParcelable) {
             fprintf(stderr, "%s:%d aidl can only generate code for interfaces, not"
-                            " parcelables or flattenables,\n", filename,
+                            " parcelables,\n", filename,
                             ((user_data_type*)items)->keyword_token.lineno);
-            fprintf(stderr, "%s:%d .aidl files that only declare parcelables or flattenables"
+            fprintf(stderr, "%s:%d .aidl files that only declare parcelables"
                             "may not go in the Makefile.\n", filename,
                             ((user_data_type*)items)->keyword_token.lineno);
             return 1;
@@ -655,7 +602,7 @@
         slash = "";
     }
 
-    if (items->item_type == INTERFACE_TYPE_BINDER || items->item_type == INTERFACE_TYPE_RPC) {
+    if (items->item_type == INTERFACE_TYPE_BINDER) {
         fprintf(to, "%s: \\\n", options.outputFileName.c_str());
     } else {
         // parcelable: there's no output file.
@@ -675,6 +622,10 @@
 
     fprintf(to, "\n");
 
+    // Output "<input_aidl_file>: " so make won't fail if the input .aidl file
+    // has been deleted, moved or renamed in incremental build.
+    fprintf(to, "%s :\n", options.inputFileName.c_str());
+
     // Output "<imported_file>: " so make won't fail if the imported file has
     // been deleted, moved or renamed in incremental build.
     import = g_imports;
@@ -725,7 +676,7 @@
 generate_outputFileName(const Options& options, const document_item_type* items)
 {
     // items has already been checked to have only one interface.
-    if (items->item_type == INTERFACE_TYPE_BINDER || items->item_type == INTERFACE_TYPE_RPC) {
+    if (items->item_type == INTERFACE_TYPE_BINDER) {
         interface_type* type = (interface_type*)items;
 
         return generate_outputFileName2(options, type->name, type->package);
@@ -749,7 +700,7 @@
         if (path[i] == OS_PATH_SEPARATOR) {
             string p = path.substr(0, i);
             if (access(path.data(), F_OK) != 0) {
-#ifdef HAVE_MS_C_RUNTIME
+#ifdef _WIN32
                 _mkdir(p.data());
 #else
                 mkdir(p.data(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
@@ -812,22 +763,7 @@
             parcl->name.data = strdup(classname);
             parcl->semicolon_token.lineno = lineno;
             parcl->semicolon_token.data = strdup(";");
-            parcl->flattening_methods = PARCELABLE_DATA;
-            doc = (document_item_type*)parcl;
-        }
-        else if (0 == strcmp("flattenable", type)) {
-            user_data_type* parcl = (user_data_type*)malloc(
-                    sizeof(user_data_type));
-            memset(parcl, 0, sizeof(user_data_type));
-            parcl->document_item.item_type = USER_DATA_TYPE;
-            parcl->keyword_token.lineno = lineno;
-            parcl->keyword_token.data = strdup(type);
-            parcl->package = packagename ? strdup(packagename) : NULL;
-            parcl->name.lineno = lineno;
-            parcl->name.data = strdup(classname);
-            parcl->semicolon_token.lineno = lineno;
-            parcl->semicolon_token.data = strdup(";");
-            parcl->flattening_methods = RPC_DATA;
+            parcl->parcelable = true;
             doc = (document_item_type*)parcl;
         }
         else if (0 == strcmp("interface", type)) {
@@ -933,7 +869,7 @@
 }
 
 // ==========================================================
-static int
+int
 compile_aidl(Options& options)
 {
     int err = 0, N;
@@ -1063,7 +999,7 @@
     return err;
 }
 
-static int
+int
 preprocess_aidl(const Options& options)
 {
     vector<string> lines;
@@ -1081,12 +1017,9 @@
         string line;
         if (doc->item_type == USER_DATA_TYPE) {
             user_data_type* parcelable = (user_data_type*)doc;
-            if ((parcelable->flattening_methods & PARCELABLE_DATA) != 0) {
+            if (parcelable->parcelable) {
                 line = "parcelable ";
             }
-            if ((parcelable->flattening_methods & RPC_DATA) != 0) {
-                line = "flattenable ";
-            }
             if (parcelable->package) {
                 line += parcelable->package;
                 line += '.';
@@ -1108,7 +1041,7 @@
     // write preprocessed file
     int fd = open( options.outputFileName.c_str(), 
                    O_RDWR|O_CREAT|O_TRUNC|O_BINARY,
-#ifdef HAVE_MS_C_RUNTIME
+#ifdef _WIN32
                    _S_IREAD|_S_IWRITE);
 #else    
                    S_IRUSR|S_IWUSR|S_IRGRP);
@@ -1135,24 +1068,3 @@
     close(fd);
     return 0;
 }
-
-// ==========================================================
-int
-main(int argc, const char **argv)
-{
-    Options options;
-    int result = parse_options(argc, argv, &options);
-    if (result) {
-        return result;
-    }
-
-    switch (options.task)
-    {
-        case COMPILE_AIDL:
-            return compile_aidl(options);
-        case PREPROCESS_AIDL:
-            return preprocess_aidl(options);
-    }
-    fprintf(stderr, "aidl: internal error\n");
-    return 1;
-}
diff --git a/tools/aidl/aidl.h b/tools/aidl/aidl.h
new file mode 100644
index 0000000..98b15f3
--- /dev/null
+++ b/tools/aidl/aidl.h
@@ -0,0 +1,9 @@
+#ifndef AIDL_AIDL_H_
+#define AIDL_AIDL_H_
+
+#include "options.h"
+
+int compile_aidl(Options& options);
+int preprocess_aidl(const Options& options);
+
+#endif  // AIDL_AIDL_H_
diff --git a/tools/aidl/aidl_language.cpp b/tools/aidl/aidl_language.cpp
index cd6a3bd..5fab6c2 100644
--- a/tools/aidl/aidl_language.cpp
+++ b/tools/aidl/aidl_language.cpp
@@ -3,7 +3,7 @@
 #include <string.h>
 #include <stdlib.h>
 
-#ifdef HAVE_MS_C_RUNTIME
+#ifdef _WIN32
 int isatty(int  fd)
 {
     return (fd == 0);
diff --git a/tools/aidl/aidl_language.h b/tools/aidl/aidl_language.h
index de1370c..a3b1efc 100644
--- a/tools/aidl/aidl_language.h
+++ b/tools/aidl/aidl_language.h
@@ -1,5 +1,5 @@
-#ifndef DEVICE_TOOLS_AIDL_AIDL_LANGUAGE_H
-#define DEVICE_TOOLS_AIDL_AIDL_LANGUAGE_H
+#ifndef AIDL_AIDL_LANGUAGE_H_
+#define AIDL_AIDL_LANGUAGE_H_
 
 
 typedef enum {
@@ -68,8 +68,7 @@
 
 enum {
     USER_DATA_TYPE = 12,
-    INTERFACE_TYPE_BINDER,
-    INTERFACE_TYPE_RPC
+    INTERFACE_TYPE_BINDER
 };
 
 typedef struct document_item_type {
@@ -78,19 +77,13 @@
 } document_item_type;
 
 
-// for user_data_type.flattening_methods
-enum {
-    PARCELABLE_DATA = 0x1,
-    RPC_DATA = 0x2
-};
-
 typedef struct user_data_type {
     document_item_type document_item;
     buffer_type keyword_token; // only the first one
     char* package;
     buffer_type name;
     buffer_type semicolon_token;
-    int flattening_methods;
+    bool parcelable;
 } user_data_type;
 
 typedef struct interface_type {
@@ -169,4 +162,4 @@
 #endif
 
 
-#endif // DEVICE_TOOLS_AIDL_AIDL_LANGUAGE_H
+#endif // AIDL_AIDL_LANGUAGE_H_
diff --git a/tools/aidl/aidl_language_l.l b/tools/aidl/aidl_language_l.l
index 3d33e7a..aa42f2e 100644
--- a/tools/aidl/aidl_language_l.l
+++ b/tools/aidl/aidl_language_l.l
@@ -83,8 +83,6 @@
     /* keywords */
 parcelable      { SET_BUFFER(PARCELABLE); return PARCELABLE; }
 interface       { SET_BUFFER(INTERFACE); return INTERFACE; }
-flattenable     { SET_BUFFER(FLATTENABLE); return FLATTENABLE; }
-rpc             { SET_BUFFER(INTERFACE); return RPC; }
 in              { SET_BUFFER(IN); return IN; }
 out             { SET_BUFFER(OUT); return OUT; }
 inout           { SET_BUFFER(INOUT); return INOUT; }
diff --git a/tools/aidl/aidl_language_y.y b/tools/aidl/aidl_language_y.y
index 9b40d28..9c5d10e 100644
--- a/tools/aidl/aidl_language_y.y
+++ b/tools/aidl/aidl_language_y.y
@@ -20,8 +20,6 @@
 %token ARRAY
 %token PARCELABLE
 %token INTERFACE
-%token FLATTENABLE
-%token RPC
 %token IN
 %token OUT
 %token INOUT
@@ -88,7 +86,7 @@
                                                         b->name = $2.buffer;
                                                         b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
                                                         b->semicolon_token = $3.buffer;
-                                                        b->flattening_methods = PARCELABLE_DATA;
+                                                        b->parcelable = true;
                                                         $$.user_data = b;
                                                     }
     |   PARCELABLE ';'                              {
@@ -101,28 +99,6 @@
                                                                      g_currentFilename, $2.buffer.lineno, $2.buffer.data);
                                                         $$.user_data = NULL;
                                                     }
-    |   FLATTENABLE IDENTIFIER ';'                  {
-                                                        user_data_type* b = (user_data_type*)malloc(sizeof(user_data_type));
-                                                        b->document_item.item_type = USER_DATA_TYPE;
-                                                        b->document_item.next = NULL;
-                                                        b->keyword_token = $1.buffer;
-                                                        b->name = $2.buffer;
-                                                        b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
-                                                        b->semicolon_token = $3.buffer;
-                                                        b->flattening_methods = PARCELABLE_DATA | RPC_DATA;
-                                                        $$.user_data = b;
-                                                    }
-    |   FLATTENABLE ';'                             {
-                                                        fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name.\n",
-                                                                     g_currentFilename, $1.buffer.lineno);
-                                                        $$.user_data = NULL;
-                                                    }
-    |   FLATTENABLE error ';'                       {
-                                                        fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name, saw \"%s\".\n",
-                                                                     g_currentFilename, $2.buffer.lineno, $2.buffer.data);
-                                                        $$.user_data = NULL;
-                                                    }
-
     ;
 
 interface_header:
@@ -146,21 +122,6 @@
                                                         c->comments_token = &c->oneway_token;
                                                         $$.interface_obj = c;
                                                    }
-    |   RPC                                        {
-                                                        interface_type* c = (interface_type*)malloc(sizeof(interface_type));
-                                                        c->document_item.item_type = INTERFACE_TYPE_RPC;
-                                                        c->document_item.next = NULL;
-                                                        c->interface_token = $1.buffer;
-                                                        c->oneway = false;
-                                                        memset(&c->oneway_token, 0, sizeof(buffer_type));
-                                                        c->comments_token = &c->interface_token;
-                                                        $$.interface_obj = c;
-                                                   }
-    ;
-
-interface_keywords:
-        INTERFACE
-    |   RPC
     ;
 
 interface_decl:
@@ -173,12 +134,12 @@
                                                         c->close_brace_token = $5.buffer;
                                                         $$.interface_obj = c;
                                                     }
-    |   interface_keywords error '{' interface_items '}'     {
+    |   INTERFACE error '{' interface_items '}'     {
                                                         fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected type name, saw \"%s\"\n",
                                                                     g_currentFilename, $2.buffer.lineno, $2.buffer.data);
                                                         $$.document_item = NULL;
                                                     }
-    |   interface_keywords error '}'                {
+    |   INTERFACE error '}'                {
                                                         fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected type name, saw \"%s\"\n",
                                                                     g_currentFilename, $2.buffer.lineno, $2.buffer.data);
                                                         $$.document_item = NULL;
diff --git a/tools/aidl/generate_java.cpp b/tools/aidl/generate_java.cpp
index 9e57407..1509340 100644
--- a/tools/aidl/generate_java.cpp
+++ b/tools/aidl/generate_java.cpp
@@ -66,9 +66,6 @@
     if (iface->document_item.item_type == INTERFACE_TYPE_BINDER) {
         cl = generate_binder_interface_class(iface);
     }
-    else if (iface->document_item.item_type == INTERFACE_TYPE_RPC) {
-        cl = generate_rpc_interface_class(iface);
-    }
 
     Document* document = new Document;
         document->comment = "";
diff --git a/tools/aidl/generate_java.h b/tools/aidl/generate_java.h
index 4bfcfeb..4e79743 100644
--- a/tools/aidl/generate_java.h
+++ b/tools/aidl/generate_java.h
@@ -1,5 +1,5 @@
-#ifndef GENERATE_JAVA_H
-#define GENERATE_JAVA_H
+#ifndef AIDL_GENERATE_JAVA_H_
+#define AIDL_GENERATE_JAVA_H_
 
 #include "aidl_language.h"
 #include "AST.h"
@@ -12,7 +12,6 @@
                 interface_type* iface);
 
 Class* generate_binder_interface_class(const interface_type* iface);
-Class* generate_rpc_interface_class(const interface_type* iface);
 
 string gather_comments(extra_text_type* extra);
 string append(const char* a, const char* b);
@@ -29,5 +28,5 @@
     int m_index;
 };
 
-#endif // GENERATE_JAVA_H
+#endif // AIDL_GENERATE_JAVA_H_
 
diff --git a/tools/aidl/generate_java_rpc.cpp b/tools/aidl/generate_java_rpc.cpp
deleted file mode 100644
index 5e4dacc..0000000
--- a/tools/aidl/generate_java_rpc.cpp
+++ /dev/null
@@ -1,1001 +0,0 @@
-#include "generate_java.h"
-#include "Type.h"
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-Type* SERVICE_CONTEXT_TYPE = new Type("android.content",
-        "Context", Type::BUILT_IN, false, false, false);
-Type* PRESENTER_BASE_TYPE = new Type("android.support.place.connector",
-        "EventListener", Type::BUILT_IN, false, false, false);
-Type* PRESENTER_LISTENER_BASE_TYPE = new Type("android.support.place.connector",
-        "EventListener.Listener", Type::BUILT_IN, false, false, false);
-Type* RPC_BROKER_TYPE = new Type("android.support.place.connector", "Broker",
-        Type::BUILT_IN, false, false, false);
-Type* RPC_CONTAINER_TYPE = new Type("com.android.athome.connector", "ConnectorContainer",
-        Type::BUILT_IN, false, false, false);
-Type* PLACE_INFO_TYPE = new Type("android.support.place.connector", "PlaceInfo",
-        Type::BUILT_IN, false, false, false);
-// TODO: Just use Endpoint, so this works for all endpoints.
-Type* RPC_CONNECTOR_TYPE = new Type("android.support.place.connector", "Connector",
-        Type::BUILT_IN, false, false, false);
-Type* RPC_ENDPOINT_INFO_TYPE = new UserDataType("android.support.place.rpc",
-        "EndpointInfo", true, __FILE__, __LINE__);
-Type* RPC_RESULT_HANDLER_TYPE = new UserDataType("android.support.place.rpc", "RpcResultHandler",
-        true, __FILE__, __LINE__);
-Type* RPC_ERROR_LISTENER_TYPE = new Type("android.support.place.rpc", "RpcErrorHandler",
-        Type::BUILT_IN, false, false, false);
-Type* RPC_CONTEXT_TYPE = new UserDataType("android.support.place.rpc", "RpcContext", true,
-        __FILE__, __LINE__);
-
-static void generate_create_from_data(Type* t, StatementBlock* addTo, const string& key,
-        Variable* v, Variable* data, Variable** cl);
-static void generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from);
-static void generate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v,
-        Variable* data);
-
-static string
-format_int(int n)
-{
-    char str[20];
-    sprintf(str, "%d", n);
-    return string(str);
-}
-
-static string
-class_name_leaf(const string& str)
-{
-    string::size_type pos = str.rfind('.');
-    if (pos == string::npos) {
-        return str;
-    } else {
-        return string(str, pos+1);
-    }
-}
-
-static string
-results_class_name(const string& n)
-{
-    string str = n;
-    str[0] = toupper(str[0]);
-    str.insert(0, "On");
-    return str;
-}
-
-static string
-results_method_name(const string& n)
-{
-    string str = n;
-    str[0] = toupper(str[0]);
-    str.insert(0, "on");
-    return str;
-}
-
-static string
-push_method_name(const string& n)
-{
-    string str = n;
-    str[0] = toupper(str[0]);
-    str.insert(0, "push");
-    return str;
-}
-
-// =================================================
-class DispatcherClass : public Class
-{
-public:
-    DispatcherClass(const interface_type* iface, Expression* target);
-    virtual ~DispatcherClass();
-
-    void AddMethod(const method_type* method);
-    void DoneWithMethods();
-
-    Method* processMethod;
-    Variable* actionParam;
-    Variable* requestParam;
-    Variable* rpcContextParam;
-    Variable* errorParam;
-    Variable* requestData;
-    Variable* resultData;
-    IfStatement* dispatchIfStatement;
-    Expression* targetExpression;
-
-private:
-    void generate_process();
-};
-
-DispatcherClass::DispatcherClass(const interface_type* iface, Expression* target)
-    :Class(),
-     dispatchIfStatement(NULL),
-     targetExpression(target)
-{
-    generate_process();
-}
-
-DispatcherClass::~DispatcherClass()
-{
-}
-
-void
-DispatcherClass::generate_process()
-{
-    // byte[] process(String action, byte[] params, RpcContext context, RpcError status)
-    this->processMethod = new Method;
-        this->processMethod->modifiers = PUBLIC;
-        this->processMethod->returnType = BYTE_TYPE;
-        this->processMethod->returnTypeDimension = 1;
-        this->processMethod->name = "process";
-        this->processMethod->statements = new StatementBlock;
-
-    this->actionParam = new Variable(STRING_TYPE, "action");
-    this->processMethod->parameters.push_back(this->actionParam);
-
-    this->requestParam = new Variable(BYTE_TYPE, "requestParam", 1);
-    this->processMethod->parameters.push_back(this->requestParam);
-
-    this->rpcContextParam = new Variable(RPC_CONTEXT_TYPE, "context", 0);
-    this->processMethod->parameters.push_back(this->rpcContextParam);    
-
-    this->errorParam = new Variable(RPC_ERROR_TYPE, "errorParam", 0);
-    this->processMethod->parameters.push_back(this->errorParam);
-
-    this->requestData = new Variable(RPC_DATA_TYPE, "request");
-    this->processMethod->statements->Add(new VariableDeclaration(requestData,
-                new NewExpression(RPC_DATA_TYPE, 1, this->requestParam)));
-
-    this->resultData = new Variable(RPC_DATA_TYPE, "resultData");
-    this->processMethod->statements->Add(new VariableDeclaration(this->resultData,
-                NULL_VALUE));
-}
-
-void
-DispatcherClass::AddMethod(const method_type* method)
-{
-    arg_type* arg;
-
-    // The if/switch statement
-    IfStatement* ifs = new IfStatement();
-        ifs->expression = new MethodCall(new StringLiteralExpression(method->name.data), "equals",
-                1, this->actionParam);
-    StatementBlock* block = ifs->statements = new StatementBlock;
-    if (this->dispatchIfStatement == NULL) {
-        this->dispatchIfStatement = ifs;
-        this->processMethod->statements->Add(dispatchIfStatement);
-    } else {
-        this->dispatchIfStatement->elseif = ifs;
-        this->dispatchIfStatement = ifs;
-    }
-    
-    // The call to decl (from above)
-    MethodCall* realCall = new MethodCall(this->targetExpression, method->name.data);
-
-    // args
-    Variable* classLoader = NULL;
-    VariableFactory stubArgs("_arg");
-    arg = method->args;
-    while (arg != NULL) {
-        Type* t = NAMES.Search(arg->type.type.data);
-        Variable* v = stubArgs.Get(t);
-        v->dimension = arg->type.dimension;
-
-        // Unmarshall the parameter
-        block->Add(new VariableDeclaration(v));
-        if (convert_direction(arg->direction.data) & IN_PARAMETER) {
-            generate_create_from_data(t, block, arg->name.data, v,
-                    this->requestData, &classLoader);
-        } else {
-            if (arg->type.dimension == 0) {
-                block->Add(new Assignment(v, new NewExpression(v->type)));
-            }
-            else if (arg->type.dimension == 1) {
-                generate_new_array(v->type, block, v, this->requestData);
-            }
-            else {
-                fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__,
-                        __LINE__);
-            }
-        }
-
-        // Add that parameter to the method call
-        realCall->arguments.push_back(v);
-
-        arg = arg->next;
-    }
-
-    // Add a final parameter: RpcContext. Contains data about
-    // incoming request (e.g., certificate)
-    realCall->arguments.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
-
-    Type* returnType = NAMES.Search(method->type.type.data);
-    if (returnType == EVENT_FAKE_TYPE) {
-        returnType = VOID_TYPE;
-    }
-    
-    // the real call
-    bool first = true;
-    Variable* _result = NULL;
-    if (returnType == VOID_TYPE) {
-        block->Add(realCall);
-    } else {
-        _result = new Variable(returnType, "_result",
-                                method->type.dimension);
-        block->Add(new VariableDeclaration(_result, realCall));
-
-        // need the result RpcData
-        if (first) {
-            block->Add(new Assignment(this->resultData,
-                        new NewExpression(RPC_DATA_TYPE)));
-            first = false;
-        }
-
-        // marshall the return value
-        generate_write_to_data(returnType, block,
-                new StringLiteralExpression("_result"), _result, this->resultData);
-    }
-
-    // out parameters
-    int i = 0;
-    arg = method->args;
-    while (arg != NULL) {
-        Type* t = NAMES.Search(arg->type.type.data);
-        Variable* v = stubArgs.Get(i++);
-
-        if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
-            // need the result RpcData
-            if (first) {
-                block->Add(new Assignment(this->resultData, new NewExpression(RPC_DATA_TYPE)));
-                first = false;
-            }
-
-            generate_write_to_data(t, block, new StringLiteralExpression(arg->name.data),
-                    v, this->resultData);
-        }
-
-        arg = arg->next;
-    }
-}
-
-void
-DispatcherClass::DoneWithMethods()
-{
-    if (this->dispatchIfStatement == NULL) {
-        return;
-    }
-
-    this->elements.push_back(this->processMethod);
-
-    IfStatement* fallthrough = new IfStatement();
-        fallthrough->statements = new StatementBlock;
-        fallthrough->statements->Add(new ReturnStatement(
-                    new MethodCall(SUPER_VALUE, "process", 4, 
-                    this->actionParam, this->requestParam, 
-                    this->rpcContextParam,
-                    this->errorParam)));
-    this->dispatchIfStatement->elseif = fallthrough;
-    IfStatement* s = new IfStatement;
-        s->statements = new StatementBlock;
-    this->processMethod->statements->Add(s);
-    s->expression = new Comparison(this->resultData, "!=", NULL_VALUE);
-    s->statements->Add(new ReturnStatement(new MethodCall(this->resultData, "serialize")));
-    s->elseif = new IfStatement;
-    s = s->elseif;
-    s->statements->Add(new ReturnStatement(NULL_VALUE));
-}
-
-// =================================================
-class RpcProxyClass : public Class
-{
-public:
-    RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType);
-    virtual ~RpcProxyClass();
-
-    Variable* endpoint;
-    Variable* broker;
-
-private:
-    void generate_ctor();
-    void generate_get_endpoint_info();
-};
-
-RpcProxyClass::RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType)
-    :Class()
-{
-    this->comment = gather_comments(iface->comments_token->extra);
-    this->modifiers = PUBLIC;
-    this->what = Class::CLASS;
-    this->type = interfaceType;
-
-    // broker
-    this->broker = new Variable(RPC_BROKER_TYPE, "_broker");
-    this->elements.push_back(new Field(PRIVATE, this->broker));
-    // endpoint
-    this->endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "_endpoint");
-    this->elements.push_back(new Field(PRIVATE, this->endpoint));
-
-    // methods
-    generate_ctor();
-    generate_get_endpoint_info();
-}
-
-RpcProxyClass::~RpcProxyClass()
-{
-}
-
-void
-RpcProxyClass::generate_ctor()
-{
-    Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
-    Variable* endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "endpoint");
-    Method* ctor = new Method;
-        ctor->modifiers = PUBLIC;
-        ctor->name = class_name_leaf(this->type->Name());
-        ctor->statements = new StatementBlock;
-        ctor->parameters.push_back(broker);
-        ctor->parameters.push_back(endpoint);
-    this->elements.push_back(ctor);
-
-    ctor->statements->Add(new Assignment(this->broker, broker));
-    ctor->statements->Add(new Assignment(this->endpoint, endpoint));
-}
-
-void
-RpcProxyClass::generate_get_endpoint_info()
-{
-    Method* get = new Method;
-    get->modifiers = PUBLIC;
-    get->returnType = RPC_ENDPOINT_INFO_TYPE;
-    get->name = "getEndpointInfo";
-    get->statements = new StatementBlock;
-    this->elements.push_back(get);
-
-    get->statements->Add(new ReturnStatement(this->endpoint));
-}
-
-// =================================================
-class EventListenerClass : public DispatcherClass
-{
-public:
-    EventListenerClass(const interface_type* iface, Type* listenerType);
-    virtual ~EventListenerClass();
-
-    Variable* _listener;
-
-private:
-    void generate_ctor();
-};
-
-Expression*
-generate_get_listener_expression(Type* cast)
-{
-    return new Cast(cast, new MethodCall(THIS_VALUE, "getView"));
-}
-
-EventListenerClass::EventListenerClass(const interface_type* iface, Type* listenerType)
-    :DispatcherClass(iface, new FieldVariable(THIS_VALUE, "_listener"))
-{
-    this->modifiers = PRIVATE;
-    this->what = Class::CLASS;
-    this->type = new Type(iface->package ? iface->package : "",
-                        append(iface->name.data, ".Presenter"),
-                        Type::GENERATED, false, false, false);
-    this->extends = PRESENTER_BASE_TYPE;
-
-    this->_listener = new Variable(listenerType, "_listener");
-    this->elements.push_back(new Field(PRIVATE, this->_listener));
-
-    // methods
-    generate_ctor();
-}
-
-EventListenerClass::~EventListenerClass()
-{
-}
-
-void
-EventListenerClass::generate_ctor()
-{
-    Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
-    Variable* listener = new Variable(this->_listener->type, "listener");
-    Method* ctor = new Method;
-        ctor->modifiers = PUBLIC;
-        ctor->name = class_name_leaf(this->type->Name());
-        ctor->statements = new StatementBlock;
-        ctor->parameters.push_back(broker);
-        ctor->parameters.push_back(listener);
-    this->elements.push_back(ctor);
-
-    ctor->statements->Add(new MethodCall("super", 2, broker, listener));
-    ctor->statements->Add(new Assignment(this->_listener, listener));
-}
-
-// =================================================
-class ListenerClass : public Class
-{
-public:
-    ListenerClass(const interface_type* iface);
-    virtual ~ListenerClass();
-
-    bool needed;
-
-private:
-    void generate_ctor();
-};
-
-ListenerClass::ListenerClass(const interface_type* iface)
-    :Class(),
-     needed(false)
-{
-    this->comment = "/** Extend this to listen to the events from this class. */";
-    this->modifiers = STATIC | PUBLIC ;
-    this->what = Class::CLASS;
-    this->type = new Type(iface->package ? iface->package : "",
-                        append(iface->name.data, ".Listener"),
-                        Type::GENERATED, false, false, false);
-    this->extends = PRESENTER_LISTENER_BASE_TYPE;
-}
-
-ListenerClass::~ListenerClass()
-{
-}
-
-// =================================================
-class EndpointBaseClass : public DispatcherClass
-{
-public:
-    EndpointBaseClass(const interface_type* iface);
-    virtual ~EndpointBaseClass();
-
-    bool needed;
-
-private:
-    void generate_ctor();
-};
-
-EndpointBaseClass::EndpointBaseClass(const interface_type* iface)
-    :DispatcherClass(iface, THIS_VALUE),
-     needed(false)
-{
-    this->comment = "/** Extend this to implement a link service. */";
-    this->modifiers = STATIC | PUBLIC | ABSTRACT;
-    this->what = Class::CLASS;
-    this->type = new Type(iface->package ? iface->package : "",
-                        append(iface->name.data, ".EndpointBase"),
-                        Type::GENERATED, false, false, false);
-    this->extends = RPC_CONNECTOR_TYPE;
-
-    // methods
-    generate_ctor();
-}
-
-EndpointBaseClass::~EndpointBaseClass()
-{
-}
-
-void
-EndpointBaseClass::generate_ctor()
-{
-    Variable* container = new Variable(RPC_CONTAINER_TYPE, "container");
-    Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
-	Variable* place = new Variable(PLACE_INFO_TYPE, "placeInfo");
-    Method* ctor = new Method;
-        ctor->modifiers = PUBLIC;
-        ctor->name = class_name_leaf(this->type->Name());
-        ctor->statements = new StatementBlock;
-        ctor->parameters.push_back(container);
-        ctor->parameters.push_back(broker);
-        ctor->parameters.push_back(place);
-    this->elements.push_back(ctor);
-
-    ctor->statements->Add(new MethodCall("super", 3, container, broker, place));
-}
-
-// =================================================
-class ResultDispatcherClass : public Class
-{
-public:
-    ResultDispatcherClass();
-    virtual ~ResultDispatcherClass();
-
-    void AddMethod(int index, const string& name, Method** method, Variable** param);
-
-    bool needed;
-    Variable* methodId;
-    Variable* callback;
-    Method* onResultMethod;
-    Variable* resultParam;
-    SwitchStatement* methodSwitch;
-
-private:
-    void generate_ctor();
-    void generate_onResult();
-};
-
-ResultDispatcherClass::ResultDispatcherClass()
-    :Class(),
-     needed(false)
-{
-    this->modifiers = PRIVATE | FINAL;
-    this->what = Class::CLASS;
-    this->type = new Type("_ResultDispatcher", Type::GENERATED, false, false, false);
-    this->interfaces.push_back(RPC_RESULT_HANDLER_TYPE);
-
-    // methodId
-    this->methodId = new Variable(INT_TYPE, "methodId");
-    this->elements.push_back(new Field(PRIVATE, this->methodId));
-    this->callback = new Variable(OBJECT_TYPE, "callback");
-    this->elements.push_back(new Field(PRIVATE, this->callback));
-
-    // methods
-    generate_ctor();
-    generate_onResult();
-}
-
-ResultDispatcherClass::~ResultDispatcherClass()
-{
-}
-
-void
-ResultDispatcherClass::generate_ctor()
-{
-    Variable* methodIdParam = new Variable(INT_TYPE, "methId");
-    Variable* callbackParam = new Variable(OBJECT_TYPE, "cbObj");
-    Method* ctor = new Method;
-        ctor->modifiers = PUBLIC;
-        ctor->name = class_name_leaf(this->type->Name());
-        ctor->statements = new StatementBlock;
-        ctor->parameters.push_back(methodIdParam);
-        ctor->parameters.push_back(callbackParam);
-    this->elements.push_back(ctor);
-
-    ctor->statements->Add(new Assignment(this->methodId, methodIdParam));
-    ctor->statements->Add(new Assignment(this->callback, callbackParam));
-}
-
-void
-ResultDispatcherClass::generate_onResult()
-{
-    this->onResultMethod = new Method;
-        this->onResultMethod->modifiers = PUBLIC;
-        this->onResultMethod->returnType = VOID_TYPE;
-        this->onResultMethod->returnTypeDimension = 0;
-        this->onResultMethod->name = "onResult";
-        this->onResultMethod->statements = new StatementBlock;
-    this->elements.push_back(this->onResultMethod);
-
-    this->resultParam = new Variable(BYTE_TYPE, "result", 1);
-    this->onResultMethod->parameters.push_back(this->resultParam);
-
-    this->methodSwitch = new SwitchStatement(this->methodId);
-    this->onResultMethod->statements->Add(this->methodSwitch);
-}
-
-void
-ResultDispatcherClass::AddMethod(int index, const string& name, Method** method, Variable** param)
-{
-    Method* m = new Method;
-        m->modifiers = PUBLIC;
-        m->returnType = VOID_TYPE;
-        m->returnTypeDimension = 0;
-        m->name = name;
-        m->statements = new StatementBlock;
-    *param = new Variable(BYTE_TYPE, "result", 1);
-    m->parameters.push_back(*param);
-    this->elements.push_back(m);
-    *method = m;
-
-    Case* c = new Case(format_int(index));
-    c->statements->Add(new MethodCall(new LiteralExpression("this"), name, 1, this->resultParam));
-    c->statements->Add(new Break());
-
-    this->methodSwitch->cases.push_back(c);
-}
-
-// =================================================
-static void
-generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from)
-{
-    fprintf(stderr, "aidl: implement generate_new_array %s:%d\n", __FILE__, __LINE__);
-    exit(1);
-}
-
-static void
-generate_create_from_data(Type* t, StatementBlock* addTo, const string& key, Variable* v,
-                            Variable* data, Variable** cl)
-{
-    Expression* k = new StringLiteralExpression(key);
-    if (v->dimension == 0) {
-        t->CreateFromRpcData(addTo, k, v, data, cl);
-    }
-    if (v->dimension == 1) {
-        //t->ReadArrayFromRpcData(addTo, v, data, cl);
-        fprintf(stderr, "aidl: implement generate_create_from_data for arrays%s:%d\n",
-                __FILE__, __LINE__);
-    }
-}
-
-static void
-generate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v, Variable* data)
-{
-    if (v->dimension == 0) {
-        t->WriteToRpcData(addTo, k, v, data, 0);
-    }
-    if (v->dimension == 1) {
-        //t->WriteArrayToParcel(addTo, v, data);
-        fprintf(stderr, "aidl: implement generate_write_to_data for arrays%s:%d\n",
-                __FILE__, __LINE__);
-    }
-}
-
-// =================================================
-static Type*
-generate_results_method(const method_type* method, RpcProxyClass* proxyClass)
-{
-    arg_type* arg;
-
-    string resultsMethodName = results_method_name(method->name.data);
-    Type* resultsInterfaceType = new Type(results_class_name(method->name.data),
-            Type::GENERATED, false, false, false);
-
-    if (!method->oneway) {
-        Class* resultsClass = new Class;
-            resultsClass->modifiers = STATIC | PUBLIC;
-            resultsClass->what = Class::INTERFACE;
-            resultsClass->type = resultsInterfaceType;
-
-        Method* resultMethod = new Method;
-            resultMethod->comment = gather_comments(method->comments_token->extra);
-            resultMethod->modifiers = PUBLIC;
-            resultMethod->returnType = VOID_TYPE;
-            resultMethod->returnTypeDimension = 0;
-            resultMethod->name = resultsMethodName;
-        if (0 != strcmp("void", method->type.type.data)) {
-            resultMethod->parameters.push_back(new Variable(NAMES.Search(method->type.type.data),
-                        "_result", method->type.dimension));
-        }
-        arg = method->args;
-        while (arg != NULL) {
-            if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
-                resultMethod->parameters.push_back(new Variable(
-                                    NAMES.Search(arg->type.type.data), arg->name.data,
-                                    arg->type.dimension));
-            }
-            arg = arg->next;
-        }
-        resultsClass->elements.push_back(resultMethod);
-
-        if (resultMethod->parameters.size() > 0) {
-            proxyClass->elements.push_back(resultsClass);
-            return resultsInterfaceType;
-        } 
-    }
-    //delete resultsInterfaceType;
-    return NULL;
-}
-
-static void
-generate_proxy_method(const method_type* method, RpcProxyClass* proxyClass,
-        ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index)
-{
-    arg_type* arg;
-    Method* proxyMethod = new Method;
-        proxyMethod->comment = gather_comments(method->comments_token->extra);
-        proxyMethod->modifiers = PUBLIC;
-        proxyMethod->returnType = VOID_TYPE;
-        proxyMethod->returnTypeDimension = 0;
-        proxyMethod->name = method->name.data;
-        proxyMethod->statements = new StatementBlock;
-    proxyClass->elements.push_back(proxyMethod);
-
-    // The local variables
-    Variable* _data = new Variable(RPC_DATA_TYPE, "_data");
-    proxyMethod->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE)));
-
-    // Add the arguments
-    arg = method->args;
-    while (arg != NULL) {
-        if (convert_direction(arg->direction.data) & IN_PARAMETER) {
-            // Function signature
-            Type* t = NAMES.Search(arg->type.type.data);
-            Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
-            proxyMethod->parameters.push_back(v);
-
-            // Input parameter marshalling
-            generate_write_to_data(t, proxyMethod->statements,
-                    new StringLiteralExpression(arg->name.data), v, _data);
-        }
-        arg = arg->next;
-    }
-
-    // If there is a results interface for this class
-    Expression* resultParameter;
-    if (resultsInterfaceType != NULL) {
-        // Result interface parameter
-        Variable* resultListener = new Variable(resultsInterfaceType, "_result");
-        proxyMethod->parameters.push_back(resultListener);
-
-        // Add the results dispatcher callback
-        resultsDispatcherClass->needed = true;
-        resultParameter = new NewExpression(resultsDispatcherClass->type, 2,
-                new LiteralExpression(format_int(index)), resultListener);
-    } else {
-        resultParameter = NULL_VALUE;
-    }
-
-    // All proxy methods take an error parameter
-    Variable* errorListener = new Variable(RPC_ERROR_LISTENER_TYPE, "_errors");
-    proxyMethod->parameters.push_back(errorListener);
-
-    // Call the broker
-    proxyMethod->statements->Add(new MethodCall(new FieldVariable(THIS_VALUE, "_broker"),
-                "sendRpc", 5,
-                proxyClass->endpoint,
-                new StringLiteralExpression(method->name.data),
-                new MethodCall(_data, "serialize"),
-                resultParameter,
-                errorListener));
-}
-
-static void
-generate_result_dispatcher_method(const method_type* method,
-        ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index)
-{
-    arg_type* arg;
-    Method* dispatchMethod;
-    Variable* dispatchParam;
-    resultsDispatcherClass->AddMethod(index, method->name.data, &dispatchMethod, &dispatchParam);
-
-    Variable* classLoader = NULL;
-    Variable* resultData = new Variable(RPC_DATA_TYPE, "resultData");
-    dispatchMethod->statements->Add(new VariableDeclaration(resultData,
-                new NewExpression(RPC_DATA_TYPE, 1, dispatchParam)));
-
-    // The callback method itself
-    MethodCall* realCall = new MethodCall(
-            new Cast(resultsInterfaceType, new FieldVariable(THIS_VALUE, "callback")),
-            results_method_name(method->name.data));
-
-    // The return value
-    {
-        Type* t = NAMES.Search(method->type.type.data);
-        if (t != VOID_TYPE) {
-            Variable* rv = new Variable(t, "rv");
-            dispatchMethod->statements->Add(new VariableDeclaration(rv));
-            generate_create_from_data(t, dispatchMethod->statements, "_result", rv,
-                    resultData, &classLoader);
-            realCall->arguments.push_back(rv);
-        }
-    }
-
-    VariableFactory stubArgs("arg");
-    arg = method->args;
-    while (arg != NULL) {
-        if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
-            // Unmarshall the results
-            Type* t = NAMES.Search(arg->type.type.data);
-            Variable* v = stubArgs.Get(t);
-            dispatchMethod->statements->Add(new VariableDeclaration(v));
-
-            generate_create_from_data(t, dispatchMethod->statements, arg->name.data, v,
-                    resultData, &classLoader);
-
-            // Add the argument to the callback
-            realCall->arguments.push_back(v);
-        }
-        arg = arg->next;
-    }
-
-    // Call the callback method
-    IfStatement* ifst = new IfStatement;
-        ifst->expression = new Comparison(new FieldVariable(THIS_VALUE, "callback"), "!=", NULL_VALUE);
-    dispatchMethod->statements->Add(ifst);
-    ifst->statements->Add(realCall);
-}
-
-static void
-generate_regular_method(const method_type* method, RpcProxyClass* proxyClass,
-        EndpointBaseClass* serviceBaseClass, ResultDispatcherClass* resultsDispatcherClass,
-        int index)
-{
-    arg_type* arg;
-
-    // == the callback interface for results ================================
-    // the service base class
-    Type* resultsInterfaceType = generate_results_method(method, proxyClass);
-    
-    // == the method in the proxy class =====================================
-    generate_proxy_method(method, proxyClass, resultsDispatcherClass, resultsInterfaceType, index);
-
-    // == the method in the result dispatcher class =========================
-    if (resultsInterfaceType != NULL) {
-        generate_result_dispatcher_method(method, resultsDispatcherClass, resultsInterfaceType,
-                index);
-    }
-
-    // == The abstract method that the service developers implement ==========
-    Method* decl = new Method;
-        decl->comment = gather_comments(method->comments_token->extra);
-        decl->modifiers = PUBLIC | ABSTRACT;
-        decl->returnType = NAMES.Search(method->type.type.data);
-        decl->returnTypeDimension = method->type.dimension;
-        decl->name = method->name.data;
-    arg = method->args;
-    while (arg != NULL) {
-        decl->parameters.push_back(new Variable(
-                            NAMES.Search(arg->type.type.data), arg->name.data,
-                            arg->type.dimension));
-        arg = arg->next;
-    }
-
-    // Add the default RpcContext param to all methods
-    decl->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
-	
-    serviceBaseClass->elements.push_back(decl);
-    
-
-    // == the dispatch method in the service base class ======================
-    serviceBaseClass->AddMethod(method);
-}
-
-static void
-generate_event_method(const method_type* method, RpcProxyClass* proxyClass,
-        EndpointBaseClass* serviceBaseClass, ListenerClass* listenerClass,
-        EventListenerClass* presenterClass, int index)
-{
-    arg_type* arg;
-    listenerClass->needed = true;
-
-    // == the push method in the service base class =========================
-    Method* push = new Method;
-        push->modifiers = PUBLIC;
-        push->name = push_method_name(method->name.data);
-        push->statements = new StatementBlock;
-        push->returnType = VOID_TYPE;
-    serviceBaseClass->elements.push_back(push);
-
-    // The local variables
-    Variable* _data = new Variable(RPC_DATA_TYPE, "_data");
-    push->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE)));
-
-    // Add the arguments
-    arg = method->args;
-    while (arg != NULL) {
-        // Function signature
-        Type* t = NAMES.Search(arg->type.type.data);
-        Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
-        push->parameters.push_back(v);
-
-        // Input parameter marshalling
-        generate_write_to_data(t, push->statements,
-                new StringLiteralExpression(arg->name.data), v, _data);
-
-        arg = arg->next;
-    }
-
-    // Send the notifications
-    push->statements->Add(new MethodCall("pushEvent", 2,
-                new StringLiteralExpression(method->name.data),
-                new MethodCall(_data, "serialize")));
-
-    // == the event callback dispatcher method  ====================================
-    presenterClass->AddMethod(method);
-
-    // == the event method in the listener base class =====================
-    Method* event = new Method;
-        event->modifiers = PUBLIC;
-        event->name = method->name.data;
-        event->statements = new StatementBlock;
-        event->returnType = VOID_TYPE;
-    listenerClass->elements.push_back(event);
-    arg = method->args;
-    while (arg != NULL) {
-        event->parameters.push_back(new Variable(
-                            NAMES.Search(arg->type.type.data), arg->name.data,
-                            arg->type.dimension));
-        arg = arg->next;
-    }
-
-    // Add a final parameter: RpcContext. Contains data about
-    // incoming request (e.g., certificate)
-    event->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
-}
-
-static void
-generate_listener_methods(RpcProxyClass* proxyClass, Type* presenterType, Type* listenerType)
-{
-    // AndroidAtHomePresenter _presenter;
-    // void startListening(Listener listener) {
-    //     stopListening();
-    //     _presenter = new Presenter(_broker, listener);
-    //     _presenter.startListening(_endpoint);
-    // }
-    // void stopListening() {
-    //     if (_presenter != null) {
-    //         _presenter.stopListening();
-    //     }
-    // }
-
-    Variable* _presenter = new Variable(presenterType, "_presenter");
-    proxyClass->elements.push_back(new Field(PRIVATE, _presenter));
-
-    Variable* listener = new Variable(listenerType, "listener");
-
-    Method* startListeningMethod = new Method;
-        startListeningMethod->modifiers = PUBLIC;
-        startListeningMethod->returnType = VOID_TYPE;
-        startListeningMethod->name = "startListening";
-        startListeningMethod->statements = new StatementBlock;
-        startListeningMethod->parameters.push_back(listener);
-    proxyClass->elements.push_back(startListeningMethod);
-
-    startListeningMethod->statements->Add(new MethodCall(THIS_VALUE, "stopListening"));
-    startListeningMethod->statements->Add(new Assignment(_presenter,
-                new NewExpression(presenterType, 2, proxyClass->broker, listener)));
-    startListeningMethod->statements->Add(new MethodCall(_presenter,
-                "startListening", 1, proxyClass->endpoint));
-
-    Method* stopListeningMethod = new Method;
-        stopListeningMethod->modifiers = PUBLIC;
-        stopListeningMethod->returnType = VOID_TYPE;
-        stopListeningMethod->name = "stopListening";
-        stopListeningMethod->statements = new StatementBlock;
-    proxyClass->elements.push_back(stopListeningMethod);
-
-    IfStatement* ifst = new IfStatement;
-        ifst->expression = new Comparison(_presenter, "!=", NULL_VALUE);
-    stopListeningMethod->statements->Add(ifst);
-
-    ifst->statements->Add(new MethodCall(_presenter, "stopListening"));
-    ifst->statements->Add(new Assignment(_presenter, NULL_VALUE));
-}
-
-Class*
-generate_rpc_interface_class(const interface_type* iface)
-{
-    // the proxy class
-    InterfaceType* interfaceType = static_cast<InterfaceType*>(
-        NAMES.Find(iface->package, iface->name.data));
-    RpcProxyClass* proxy = new RpcProxyClass(iface, interfaceType);
-
-    // the listener class
-    ListenerClass* listener = new ListenerClass(iface);
-
-    // the presenter class
-    EventListenerClass* presenter = new EventListenerClass(iface, listener->type);
-
-    // the service base class
-    EndpointBaseClass* base = new EndpointBaseClass(iface);
-    proxy->elements.push_back(base);
-
-    // the result dispatcher
-    ResultDispatcherClass* results = new ResultDispatcherClass();
-
-    // all the declared methods of the proxy
-    int index = 0;
-    interface_item_type* item = iface->interface_items;
-    while (item != NULL) {
-        if (item->item_type == METHOD_TYPE) {
-            if (NAMES.Search(((method_type*)item)->type.type.data) == EVENT_FAKE_TYPE) {
-                generate_event_method((method_type*)item, proxy, base, listener, presenter, index);
-            } else {
-                generate_regular_method((method_type*)item, proxy, base, results, index);
-            }
-        }
-        item = item->next;
-        index++;
-    }
-    presenter->DoneWithMethods();
-    base->DoneWithMethods();
-
-    // only add this if there are methods with results / out parameters
-    if (results->needed) {
-        proxy->elements.push_back(results);
-    }
-    if (listener->needed) {
-        proxy->elements.push_back(listener);
-        proxy->elements.push_back(presenter);
-        generate_listener_methods(proxy, presenter->type, listener->type);
-    }
-
-    return proxy;
-}
diff --git a/tools/aidl/main.cpp b/tools/aidl/main.cpp
new file mode 100644
index 0000000..7cc2198
--- /dev/null
+++ b/tools/aidl/main.cpp
@@ -0,0 +1,23 @@
+#include "aidl.h"
+#include "options.h"
+
+#include <stdio.h>
+
+int
+main(int argc, const char **argv)
+{
+    Options options;
+    int result = parse_options(argc, argv, &options);
+    if (result) {
+        return result;
+    }
+
+    switch (options.task) {
+        case COMPILE_AIDL:
+            return compile_aidl(options);
+        case PREPROCESS_AIDL:
+            return preprocess_aidl(options);
+    }
+    fprintf(stderr, "aidl: internal error\n");
+    return 1;
+}
diff --git a/tools/aidl/options.cpp b/tools/aidl/options.cpp
index 7b2daeb..52b0972 100644
--- a/tools/aidl/options.cpp
+++ b/tools/aidl/options.cpp
@@ -48,10 +48,6 @@
         return 0;
     }
 
-    options->task = COMPILE_AIDL;
-    options->failOnParcelable = false;
-    options->autoDepFile = false;
-
     // OPTIONS
     while (i < argc) {
         const char* s = argv[i];
diff --git a/tools/aidl/options.h b/tools/aidl/options.h
index 387e37d..4e95e11 100644
--- a/tools/aidl/options.h
+++ b/tools/aidl/options.h
@@ -1,5 +1,5 @@
-#ifndef DEVICE_TOOLS_AIDL_H
-#define DEVICE_TOOLS_AIDL_H
+#ifndef AIDL_OPTIONS_H_
+#define AIDL_OPTIONS_H_
 
 #include <string.h>
 #include <string>
@@ -15,15 +15,15 @@
 // This struct is the parsed version of the command line options
 struct Options
 {
-    int task;
-    bool failOnParcelable;
+    int task{COMPILE_AIDL};
+    bool failOnParcelable{false};
     vector<string> importPaths;
     vector<string> preprocessedFiles;
     string inputFileName;
     string outputFileName;
     string outputBaseFolder;
     string depFileName;
-    bool autoDepFile;
+    bool autoDepFile{false};
 
     vector<string> filesToPreprocess;
 };
@@ -33,4 +33,4 @@
 // It also prints the usage statement on failure.
 int parse_options(int argc, const char* const* argv, Options *options);
 
-#endif // DEVICE_TOOLS_AIDL_H
+#endif // AIDL_OPTIONS_H_
diff --git a/tools/aidl/options_test.cpp b/tools/aidl/options_test.cpp
deleted file mode 100644
index bd106ce..0000000
--- a/tools/aidl/options_test.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-#include <iostream>
-#include "options.h"
-
-const bool VERBOSE = false;
-
-using namespace std;
-
-struct Answer {
-    const char* argv[8];
-    int result;
-    const char* systemSearchPath[8];
-    const char* localSearchPath[8];
-    const char* inputFileName;
-    language_t nativeLanguage;
-    const char* outputH;
-    const char* outputCPP;
-    const char* outputJava;
-};
-
-bool
-match_arrays(const char* const*expected, const vector<string> &got)
-{
-    int count = 0;
-    while (expected[count] != NULL) {
-        count++;
-    }
-    if (got.size() != count) {
-        return false;
-    }
-    for (int i=0; i<count; i++) {
-        if (got[i] != expected[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void
-print_array(const char* prefix, const char* const*expected)
-{
-    while (*expected) {
-        cout << prefix << *expected << endl;
-        expected++;
-    }
-}
-
-void
-print_array(const char* prefix, const vector<string> &got)
-{
-    size_t count = got.size();
-    for (size_t i=0; i<count; i++) {
-        cout << prefix << got[i] << endl;
-    }
-}
-
-static int
-test(const Answer& answer)
-{
-    int argc = 0;
-    while (answer.argv[argc]) {
-        argc++;
-    }
-
-    int err = 0;
-
-    Options options;
-    int result = parse_options(argc, answer.argv, &options);
-
-    // result
-    if (((bool)result) != ((bool)answer.result)) {
-        cout << "mismatch: result: got " << result << " expected " <<
-            answer.result << endl;
-        err = 1;
-    }
-
-    if (result != 0) {
-        // if it failed, everything is invalid
-        return err;
-    }
-
-    // systemSearchPath
-    if (!match_arrays(answer.systemSearchPath, options.systemSearchPath)) {
-        cout << "mismatch: systemSearchPath: got" << endl;
-        print_array("        ", options.systemSearchPath);
-        cout << "    expected" << endl;
-        print_array("        ", answer.systemSearchPath);
-        err = 1;
-    }
-
-    // localSearchPath
-    if (!match_arrays(answer.localSearchPath, options.localSearchPath)) {
-        cout << "mismatch: localSearchPath: got" << endl;
-        print_array("        ", options.localSearchPath);
-        cout << "    expected" << endl;
-        print_array("        ", answer.localSearchPath);
-        err = 1;
-    }
-
-    // inputFileName
-    if (answer.inputFileName != options.inputFileName) {
-        cout << "mismatch: inputFileName: got " << options.inputFileName
-            << " expected " << answer.inputFileName << endl;
-        err = 1;
-    }
-
-    // nativeLanguage
-    if (answer.nativeLanguage != options.nativeLanguage) {
-        cout << "mismatch: nativeLanguage: got " << options.nativeLanguage
-            << " expected " << answer.nativeLanguage << endl;
-        err = 1;
-    }
-
-    // outputH
-    if (answer.outputH != options.outputH) {
-        cout << "mismatch: outputH: got " << options.outputH
-            << " expected " << answer.outputH << endl;
-        err = 1;
-    }
-
-    // outputCPP
-    if (answer.outputCPP != options.outputCPP) {
-        cout << "mismatch: outputCPP: got " << options.outputCPP
-            << " expected " << answer.outputCPP << endl;
-        err = 1;
-    }
-
-    // outputJava
-    if (answer.outputJava != options.outputJava) {
-        cout << "mismatch: outputJava: got " << options.outputJava
-            << " expected " << answer.outputJava << endl;
-        err = 1;
-    }
-
-    return err;
-}
-
-const Answer g_tests[] = {
-
-    {
-        /* argv */              { "test", "-i/moof", "-I/blah", "-Ibleh", "-imoo", "inputFileName.aidl_cpp", NULL, NULL },
-        /* result */            0,
-        /* systemSearchPath */  { "/blah", "bleh", NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { "/moof", "moo", NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "inputFileName.aidl_cpp",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "",
-        /* outputJava */        ""
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-oh", "outputH", NULL, NULL, NULL, NULL },
-        /* result */            0,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "inputFileName.aidl_cpp",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "outputH",
-        /* outputCPP */         "",
-        /* outputJava */        ""
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-ocpp", "outputCPP", NULL, NULL, NULL, NULL },
-        /* result */            0,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "inputFileName.aidl_cpp",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "outputCPP",
-        /* outputJava */        ""
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-ojava", "outputJava", NULL, NULL, NULL, NULL },
-        /* result */            0,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "inputFileName.aidl_cpp",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "",
-        /* outputJava */        "outputJava"
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-oh", "outputH", "-ocpp", "outputCPP", "-ojava", "outputJava" },
-        /* result */            0,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "inputFileName.aidl_cpp",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "outputH",
-        /* outputCPP */         "outputCPP",
-        /* outputJava */        "outputJava"
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-oh", "outputH", "-oh", "outputH1", NULL, NULL },
-        /* result */            1,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "",
-        /* outputJava */        ""
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-ocpp", "outputCPP", "-ocpp", "outputCPP1", NULL, NULL },
-        /* result */            1,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "",
-        /* outputJava */        ""
-    },
-
-    {
-        /* argv */              { "test", "inputFileName.aidl_cpp", "-ojava", "outputJava", "-ojava", "outputJava1", NULL, NULL },
-        /* result */            1,
-        /* systemSearchPath */  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* localSearchPath */   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
-        /* inputFileName */     "",
-        /* nativeLanguage */    CPP,
-        /* outputH */           "",
-        /* outputCPP */         "",
-        /* outputJava */        ""
-    },
-
-};
-
-int
-main(int argc, const char** argv)
-{
-    const int count = sizeof(g_tests)/sizeof(g_tests[0]);
-    int matches[count];
-
-    int result = 0;
-    for (int i=0; i<count; i++) {
-        if (VERBOSE) {
-            cout << endl;
-            cout << "---------------------------------------------" << endl;
-            const char* const* p = g_tests[i].argv;
-            while (*p) {
-                cout << " " << *p;
-                p++;
-            }
-            cout << endl;
-            cout << "---------------------------------------------" << endl;
-        }
-        matches[i] = test(g_tests[i]);
-        if (VERBOSE) {
-            if (0 == matches[i]) {
-                cout << "passed" << endl;
-            } else {
-                cout << "failed" << endl;
-            }
-            result |= matches[i];
-        }
-    }
-
-    cout << endl;
-    cout << "=============================================" << endl;
-    cout << "options_test summary" << endl;
-    cout << "=============================================" << endl;
-
-    if (!result) {
-        cout << "passed" << endl;
-    } else {
-        cout << "failed the following tests:" << endl;
-        for (int i=0; i<count; i++) {
-            if (matches[i]) {
-                cout << "   ";
-                const char* const* p = g_tests[i].argv;
-                while (*p) {
-                    cout << " " << *p;
-                    p++;
-                }
-                cout << endl;
-            }
-        }
-    }
-
-    return result;
-}
-
diff --git a/tools/aidl/options_unittest.cpp b/tools/aidl/options_unittest.cpp
new file mode 100644
index 0000000..fec7f87
--- /dev/null
+++ b/tools/aidl/options_unittest.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include "options.h"
+
+using std::vector;
+using std::string;
+
+const char kPreprocessCommandOutputFile[] = "output_file_name";
+const char kPreprocessCommandInput1[] = "input1";
+const char kPreprocessCommandInput2[] = "input2";
+const char kPreprocessCommandInput3[] = "input3";
+const char* kPreprocessCommand[] = {
+    "aidl", "--preprocess",
+    kPreprocessCommandOutputFile,
+    kPreprocessCommandInput1,
+    kPreprocessCommandInput2,
+    kPreprocessCommandInput3,
+};
+
+TEST(OptionsTests, ParsesPreprocess) {
+  Options options;
+  const int argc = sizeof(kPreprocessCommand) / sizeof(*kPreprocessCommand);
+  EXPECT_EQ(parse_options(argc, kPreprocessCommand, &options), 0);
+  EXPECT_EQ(options.task, PREPROCESS_AIDL);
+  EXPECT_EQ(options.failOnParcelable, false);
+  EXPECT_EQ(options.importPaths.size(), 0u);
+  EXPECT_EQ(options.preprocessedFiles.size(), 0u);
+  EXPECT_EQ(options.inputFileName, string{""});
+  EXPECT_EQ(options.outputFileName, string{kPreprocessCommandOutputFile});
+  EXPECT_EQ(options.autoDepFile, false);
+  const vector<string> expected_input{kPreprocessCommandInput1,
+                                      kPreprocessCommandInput2,
+                                      kPreprocessCommandInput3};
+  EXPECT_EQ(options.filesToPreprocess, expected_input);
+}
diff --git a/tools/aidl/os.h b/tools/aidl/os.h
new file mode 100644
index 0000000..752ed47
--- /dev/null
+++ b/tools/aidl/os.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AIDL_OS_H_
+#define AIDL_OS_H_
+
+#if defined(_WIN32)
+#define OS_PATH_SEPARATOR '\\'
+#else
+#define OS_PATH_SEPARATOR '/'
+#endif
+
+#endif  // AIDL_OS_H_
diff --git a/tools/aidl/search_path.cpp b/tools/aidl/search_path.cpp
index ffb6cb2..029e216 100644
--- a/tools/aidl/search_path.cpp
+++ b/tools/aidl/search_path.cpp
@@ -1,9 +1,10 @@
 #include <unistd.h>
 #include "search_path.h"
 #include "options.h"
+#include "os.h"
 #include <string.h>
 
-#ifdef HAVE_MS_C_RUNTIME
+#ifdef _WIN32
 #include <io.h>
 #endif
 
@@ -41,7 +42,7 @@
         }
         f.append(expected);
 
-#ifdef HAVE_MS_C_RUNTIME
+#ifdef _WIN32
         /* check that the file exists and is not write-only */
         if (0 == _access(f.c_str(), 0) &&  /* mode 0=exist */
             0 == _access(f.c_str(), 4) ) { /* mode 4=readable */
diff --git a/tools/aidl/search_path.h b/tools/aidl/search_path.h
index 2bf94b1..4fec257 100644
--- a/tools/aidl/search_path.h
+++ b/tools/aidl/search_path.h
@@ -1,5 +1,5 @@
-#ifndef DEVICE_TOOLS_AIDL_SEARCH_PATH_H
-#define DEVICE_TOOLS_AIDL_SEARCH_PATH_H
+#ifndef AIDL_SEARCH_PATH_H_
+#define AIDL_SEARCH_PATH_H_
 
 #include <stdio.h>
 
@@ -19,5 +19,4 @@
 void set_import_paths(const vector<string>& importPaths);
 #endif
 
-#endif // DEVICE_TOOLS_AIDL_SEARCH_PATH_H
-
+#endif // AIDL_SEARCH_PATH_H_
diff --git a/tools/aidl/test_main.cpp b/tools/aidl/test_main.cpp
new file mode 100644
index 0000000..4d820af
--- /dev/null
+++ b/tools/aidl/test_main.cpp
@@ -0,0 +1,6 @@
+#include <gtest/gtest.h>
+
+int main(int argc, char **argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/tools/aidl/tests/end_to_end_tests.cpp b/tools/aidl/tests/end_to_end_tests.cpp
new file mode 100644
index 0000000..54ca603
--- /dev/null
+++ b/tools/aidl/tests/end_to_end_tests.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <base/logging.h>
+#include <base/files/file_path.h>
+#include <base/files/file_util.h>
+#include <gtest/gtest.h>
+
+#include "aidl.h"
+#include "options.h"
+#include "tests/test_data.h"
+
+using base::FilePath;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+using namespace aidl::test_data;
+
+namespace {
+
+const char kDiffTemplate[] = "diff %s %s";
+const char kStubInterfaceTemplate[] = "package %s;\ninterface %s { }";
+const char kStubParcelableTemplate[] = "package %s;\nparcelable %s;";
+
+FilePath GetPathForPackageClass(const char* package_class,
+                                const char* extension) {
+  string rel_path{package_class};
+  for (char& c : rel_path) {
+    if (c == '.') {
+      c = FilePath::kSeparators[0];
+    }
+  }
+  rel_path += extension;
+  return FilePath(rel_path);
+}
+
+void SplitPackageClass(const string& package_class,
+                       FilePath* rel_path,
+                       string* package,
+                       string* class_name) {
+  *package = string{package_class, 0, package_class.rfind('.')};
+  *class_name = string{package_class, package_class.rfind('.') + 1};
+  *rel_path = GetPathForPackageClass(package_class.c_str(), ".aidl");
+}
+
+}  // namespace
+
+class EndToEndTest : public ::testing::Test {
+ protected:
+  virtual void SetUp() {
+    ASSERT_TRUE(base::CreateNewTempDirectory(
+        string{"end_to_end_testsyyyy"}, &tmpDir_));
+    inputDir_ = tmpDir_.Append("input");
+    outputDir_ = tmpDir_.Append("output");
+    ASSERT_TRUE(base::CreateDirectory(inputDir_));
+    ASSERT_TRUE(base::CreateDirectory(outputDir_));
+  }
+
+  virtual void TearDown() {
+    ASSERT_TRUE(DeleteFile(tmpDir_, true))
+        << "Failed to remove temp directory: " << tmpDir_.value();
+  }
+
+  FilePath CreateInputFile(const FilePath& relative_path,
+                           const char contents[],
+                           int size) {
+    const FilePath created_file = inputDir_.Append(relative_path);
+    EXPECT_TRUE(base::CreateDirectory(created_file.DirName()));
+    EXPECT_TRUE(base::WriteFile(created_file, contents, size));
+    return created_file;
+  }
+
+  void CreateStubAidlFile(const string& package_class,
+                          const char* file_template) {
+    string package, class_name;
+    FilePath rel_path;
+    SplitPackageClass(package_class, &rel_path, &package, &class_name);
+    const size_t buf_len =
+        strlen(file_template) + package.length() + class_name.length() + 1;
+    unique_ptr<char[]> contents(new char[buf_len]);
+    const int written = snprintf(contents.get(), buf_len, file_template,
+                                 package.c_str(), class_name.c_str());
+    EXPECT_GT(written, 0);
+    CreateInputFile(rel_path, contents.get(), written);
+  }
+
+  void WriteStubAidls(const char** parcelables, const char** interfaces) {
+    while (*parcelables) {
+      CreateStubAidlFile(string{*parcelables}, kStubParcelableTemplate);
+      ++parcelables;
+    }
+    while (*interfaces) {
+      CreateStubAidlFile(string{*interfaces}, kStubInterfaceTemplate);
+      ++interfaces;
+    }
+  }
+
+  void CheckFileContents(const FilePath& rel_path,
+                         const string& expected_content) {
+    string actual_contents;
+    FilePath actual_path = outputDir_.Append(rel_path);
+    if (!ReadFileToString(actual_path, &actual_contents)) {
+      FAIL() << "Failed to read expected output file: " << rel_path.value();
+    }
+    // Generated .java files mention the "original" file as part of their
+    // comment header.  Thus we look for expected_content being a substring.
+    if (actual_contents.find(expected_content) == string::npos) {
+      // When the match fails, display a diff of what's wrong.  This greatly
+      // aids in debugging.
+      FilePath expected_path;
+      EXPECT_TRUE(CreateTemporaryFileInDir(tmpDir_, &expected_path));
+      base::WriteFile(expected_path, expected_content.c_str(),
+                      expected_content.length());
+      const size_t buf_len =
+          strlen(kDiffTemplate) + actual_path.value().length() +
+          expected_path.value().length() + 1;
+      unique_ptr<char[]> diff_cmd(new char[buf_len]);
+      EXPECT_GT(snprintf(diff_cmd.get(), buf_len, kDiffTemplate,
+                         expected_path.value().c_str(),
+                         actual_path.value().c_str()), 0);
+      system(diff_cmd.get());
+      FAIL() << "Actual contents of " << rel_path.value()
+             << " did not match expected content";
+    }
+  }
+
+  FilePath tmpDir_;
+  FilePath inputDir_;
+  FilePath outputDir_;
+};
+
+TEST_F(EndToEndTest, IExampleInterface) {
+  Options options;
+  options.failOnParcelable = true;
+  options.importPaths.push_back(inputDir_.value());
+  options.inputFileName =
+      CreateInputFile(GetPathForPackageClass(kIExampleInterfaceClass, ".aidl"),
+                      kIExampleInterfaceContents,
+                      strlen(kIExampleInterfaceContents)).value();
+  options.autoDepFile = true;
+  options.outputBaseFolder = outputDir_.value();
+  WriteStubAidls(kIExampleInterfaceParcelables, kIExampleInterfaceInterfaces);
+  EXPECT_EQ(compile_aidl(options), 0);
+  CheckFileContents(GetPathForPackageClass(kIExampleInterfaceClass, ".java"),
+                    kIExampleInterfaceJava);
+  // We'd like to check the depends file, but it mentions unique file paths.
+}
diff --git a/tools/aidl/tests/example_interface_test_data.cpp b/tools/aidl/tests/example_interface_test_data.cpp
new file mode 100644
index 0000000..b17a800
--- /dev/null
+++ b/tools/aidl/tests/example_interface_test_data.cpp
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tests/test_data.h"
+
+namespace aidl {
+namespace test_data {
+
+const char kIExampleInterfaceClass[] = "android.test.IExampleInterface";
+
+const char* kIExampleInterfaceParcelables[] = {
+  "android.foo.ExampleParcelable",
+  "android.test.ExampleParcelable2",
+  nullptr,
+};
+
+const char* kIExampleInterfaceInterfaces[] = {
+  "android.bar.IAuxInterface",
+  "android.test.IAuxInterface2",
+  nullptr,
+};
+
+const char kIExampleInterfaceContents[] = R"(
+package android.test;
+
+import android.foo.ExampleParcelable;
+import android.test.ExampleParcelable2;
+import android.bar.IAuxInterface;
+import android.test.IAuxInterface2;
+
+interface IExampleInterface {
+    boolean isEnabled();
+    int getState();
+    String getAddress();
+
+    ExampleParcelable[] getParcelables();
+
+    boolean setScanMode(int mode, int duration);
+
+    void registerBinder(IAuxInterface foo);
+    IExampleInterface getRecursiveBinder();
+
+    int takesAnInterface(in IAuxInterface2 arg);
+    int takesAParcelable(in ExampleParcelable2 arg);
+}
+)";
+
+const char kIExampleInterfaceDeps[] =
+R"(/tmp/.org.chromium.Chromium.Cdq7YZ/output/android/test/IExampleInterface.java: \
+  /tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IExampleInterface.aidl \
+  /tmp/.org.chromium.Chromium.Cdq7YZ/input/android/foo/ExampleParcelable.aidl \
+  /tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/ExampleParcelable2.aidl \
+  /tmp/.org.chromium.Chromium.Cdq7YZ/input/android/bar/IAuxInterface.aidl \
+  /tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IAuxInterface2.aidl 
+
+/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IExampleInterface.aidl :
+/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/foo/ExampleParcelable.aidl :
+/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/ExampleParcelable2.aidl :
+/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/bar/IAuxInterface.aidl :
+/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IAuxInterface2.aidl :)";
+
+const char kIExampleInterfaceJava[] =
+R"(package android.test;
+public interface IExampleInterface extends android.os.IInterface
+{
+/** Local-side IPC implementation stub class. */
+public static abstract class Stub extends android.os.Binder implements android.test.IExampleInterface
+{
+private static final java.lang.String DESCRIPTOR = "android.test.IExampleInterface";
+/** Construct the stub at attach it to the interface. */
+public Stub()
+{
+this.attachInterface(this, DESCRIPTOR);
+}
+/**
+ * Cast an IBinder object into an android.test.IExampleInterface interface,
+ * generating a proxy if needed.
+ */
+public static android.test.IExampleInterface asInterface(android.os.IBinder obj)
+{
+if ((obj==null)) {
+return null;
+}
+android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
+if (((iin!=null)&&(iin instanceof android.test.IExampleInterface))) {
+return ((android.test.IExampleInterface)iin);
+}
+return new android.test.IExampleInterface.Stub.Proxy(obj);
+}
+@Override public android.os.IBinder asBinder()
+{
+return this;
+}
+@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
+{
+switch (code)
+{
+case INTERFACE_TRANSACTION:
+{
+reply.writeString(DESCRIPTOR);
+return true;
+}
+case TRANSACTION_isEnabled:
+{
+data.enforceInterface(DESCRIPTOR);
+boolean _result = this.isEnabled();
+reply.writeNoException();
+reply.writeInt(((_result)?(1):(0)));
+return true;
+}
+case TRANSACTION_getState:
+{
+data.enforceInterface(DESCRIPTOR);
+int _result = this.getState();
+reply.writeNoException();
+reply.writeInt(_result);
+return true;
+}
+case TRANSACTION_getAddress:
+{
+data.enforceInterface(DESCRIPTOR);
+java.lang.String _result = this.getAddress();
+reply.writeNoException();
+reply.writeString(_result);
+return true;
+}
+case TRANSACTION_getParcelables:
+{
+data.enforceInterface(DESCRIPTOR);
+android.foo.ExampleParcelable[] _result = this.getParcelables();
+reply.writeNoException();
+reply.writeTypedArray(_result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+return true;
+}
+case TRANSACTION_setScanMode:
+{
+data.enforceInterface(DESCRIPTOR);
+int _arg0;
+_arg0 = data.readInt();
+int _arg1;
+_arg1 = data.readInt();
+boolean _result = this.setScanMode(_arg0, _arg1);
+reply.writeNoException();
+reply.writeInt(((_result)?(1):(0)));
+return true;
+}
+case TRANSACTION_registerBinder:
+{
+data.enforceInterface(DESCRIPTOR);
+android.bar.IAuxInterface _arg0;
+_arg0 = android.bar.IAuxInterface.Stub.asInterface(data.readStrongBinder());
+this.registerBinder(_arg0);
+reply.writeNoException();
+return true;
+}
+case TRANSACTION_getRecursiveBinder:
+{
+data.enforceInterface(DESCRIPTOR);
+android.test.IExampleInterface _result = this.getRecursiveBinder();
+reply.writeNoException();
+reply.writeStrongBinder((((_result!=null))?(_result.asBinder()):(null)));
+return true;
+}
+case TRANSACTION_takesAnInterface:
+{
+data.enforceInterface(DESCRIPTOR);
+android.test.IAuxInterface2 _arg0;
+_arg0 = android.test.IAuxInterface2.Stub.asInterface(data.readStrongBinder());
+int _result = this.takesAnInterface(_arg0);
+reply.writeNoException();
+reply.writeInt(_result);
+return true;
+}
+case TRANSACTION_takesAParcelable:
+{
+data.enforceInterface(DESCRIPTOR);
+android.test.ExampleParcelable2 _arg0;
+if ((0!=data.readInt())) {
+_arg0 = android.test.ExampleParcelable2.CREATOR.createFromParcel(data);
+}
+else {
+_arg0 = null;
+}
+int _result = this.takesAParcelable(_arg0);
+reply.writeNoException();
+reply.writeInt(_result);
+return true;
+}
+}
+return super.onTransact(code, data, reply, flags);
+}
+private static class Proxy implements android.test.IExampleInterface
+{
+private android.os.IBinder mRemote;
+Proxy(android.os.IBinder remote)
+{
+mRemote = remote;
+}
+@Override public android.os.IBinder asBinder()
+{
+return mRemote;
+}
+public java.lang.String getInterfaceDescriptor()
+{
+return DESCRIPTOR;
+}
+@Override public boolean isEnabled() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+boolean _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_isEnabled, _data, _reply, 0);
+_reply.readException();
+_result = (0!=_reply.readInt());
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public int getState() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+int _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getState, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readInt();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public java.lang.String getAddress() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+java.lang.String _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getAddress, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readString();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+android.foo.ExampleParcelable[] _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getParcelables, _data, _reply, 0);
+_reply.readException();
+_result = _reply.createTypedArray(android.foo.ExampleParcelable.CREATOR);
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public boolean setScanMode(int mode, int duration) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+boolean _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+_data.writeInt(mode);
+_data.writeInt(duration);
+mRemote.transact(Stub.TRANSACTION_setScanMode, _data, _reply, 0);
+_reply.readException();
+_result = (0!=_reply.readInt());
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public void registerBinder(android.bar.IAuxInterface foo) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+_data.writeStrongBinder((((foo!=null))?(foo.asBinder()):(null)));
+mRemote.transact(Stub.TRANSACTION_registerBinder, _data, _reply, 0);
+_reply.readException();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+}
+@Override public android.test.IExampleInterface getRecursiveBinder() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+android.test.IExampleInterface _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getRecursiveBinder, _data, _reply, 0);
+_reply.readException();
+_result = android.test.IExampleInterface.Stub.asInterface(_reply.readStrongBinder());
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public int takesAnInterface(android.test.IAuxInterface2 arg) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+int _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+_data.writeStrongBinder((((arg!=null))?(arg.asBinder()):(null)));
+mRemote.transact(Stub.TRANSACTION_takesAnInterface, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readInt();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public int takesAParcelable(android.test.ExampleParcelable2 arg) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+int _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+if ((arg!=null)) {
+_data.writeInt(1);
+arg.writeToParcel(_data, 0);
+}
+else {
+_data.writeInt(0);
+}
+mRemote.transact(Stub.TRANSACTION_takesAParcelable, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readInt();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+}
+static final int TRANSACTION_isEnabled = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
+static final int TRANSACTION_getState = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
+static final int TRANSACTION_getAddress = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
+static final int TRANSACTION_getParcelables = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
+static final int TRANSACTION_setScanMode = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
+static final int TRANSACTION_registerBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
+static final int TRANSACTION_getRecursiveBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
+static final int TRANSACTION_takesAnInterface = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
+static final int TRANSACTION_takesAParcelable = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
+}
+public boolean isEnabled() throws android.os.RemoteException;
+public int getState() throws android.os.RemoteException;
+public java.lang.String getAddress() throws android.os.RemoteException;
+public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException;
+public boolean setScanMode(int mode, int duration) throws android.os.RemoteException;
+public void registerBinder(android.bar.IAuxInterface foo) throws android.os.RemoteException;
+public android.test.IExampleInterface getRecursiveBinder() throws android.os.RemoteException;
+public int takesAnInterface(android.test.IAuxInterface2 arg) throws android.os.RemoteException;
+public int takesAParcelable(android.test.ExampleParcelable2 arg) throws android.os.RemoteException;
+})";
+
+}  // namespace test_data
+}  // namespace aidl
diff --git a/tools/aidl/tests/test_data.h b/tools/aidl/tests/test_data.h
new file mode 100644
index 0000000..cd8887f
--- /dev/null
+++ b/tools/aidl/tests/test_data.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AIDL_TESTS_TEST_DATA_H_
+#define AIDL_TESTS_TEST_DATA_H_
+
+namespace aidl {
+namespace test_data {
+
+extern const char kIExampleInterfaceClass[];
+extern const char kIExampleInterfaceContents[];
+extern const char* kIExampleInterfaceParcelables[];
+extern const char* kIExampleInterfaceInterfaces[];
+
+extern const char kIExampleInterfaceDeps[];
+extern const char kIExampleInterfaceJava[];
+
+}  // namespace test_data
+}  // namespace aidl
+#endif // AIDL_TESTS_TEST_DATA_H_
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 895f9c9..a410c53 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -86,7 +86,7 @@
     }
 
     @Override
-    public void shutdown(boolean confirm, boolean wait) {
+    public void shutdown(boolean confirm, String reason, boolean wait) {
         // pass for now.
     }
 
diff --git a/tools/split-select/Android.mk b/tools/split-select/Android.mk
index d9ddf08..239bed5 100644
--- a/tools/split-select/Android.mk
+++ b/tools/split-select/Android.mk
@@ -43,7 +43,6 @@
     external/zlib \
     frameworks/base/tools
 
-hostLdLibs :=
 hostStaticLibs := \
     libaapt \
     libandroidfw \
@@ -57,17 +56,13 @@
 
 cFlags := -Wall -Werror
 
-ifeq ($(HOST_OS),linux)
-    hostLdLibs += -lrt -ldl -lpthread
-endif
+hostLdLibs_linux := -lrt -ldl -lpthread
 
 # Statically link libz for MinGW (Win SDK under Linux),
 # and dynamically link for all others.
-ifneq ($(strip $(USE_MINGW)),)
-    hostStaticLibs += libz
-else
-    hostLdLibs += -lz
-endif
+hostStaticLibs_windows := libz
+hostLdLibs_darwin := -lz
+hostLdLibs_linux += -lz
 
 
 # ==========================================================
@@ -75,11 +70,12 @@
 # ==========================================================
 include $(CLEAR_VARS)
 LOCAL_MODULE := libsplit-select
+LOCAL_MODULE_HOST_OS := darwin linux windows
 
 LOCAL_SRC_FILES := $(sources)
 
-LOCAL_C_INCLUDES += $(cIncludes)
-LOCAL_CFLAGS += $(cFlags) -D_DARWIN_UNLIMITED_STREAMS
+LOCAL_C_INCLUDES := $(cIncludes)
+LOCAL_CFLAGS := $(cFlags) -D_DARWIN_UNLIMITED_STREAMS
 
 include $(BUILD_HOST_STATIC_LIBRARY)
 
@@ -93,10 +89,12 @@
 
 LOCAL_SRC_FILES := $(testSources)
 
-LOCAL_C_INCLUDES += $(cIncludes)
-LOCAL_STATIC_LIBRARIES += libsplit-select $(hostStaticLibs)
-LOCAL_LDLIBS += $(hostLdLibs)
-LOCAL_CFLAGS += $(cFlags)
+LOCAL_C_INCLUDES := $(cIncludes)
+LOCAL_STATIC_LIBRARIES := libsplit-select $(hostStaticLibs)
+LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
+LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
+LOCAL_LDLIBS_linux := $(hostLdLibs_linux)
+LOCAL_CFLAGS := $(cFlags)
 
 include $(BUILD_HOST_NATIVE_TEST)
 
@@ -105,13 +103,16 @@
 # ==========================================================
 include $(CLEAR_VARS)
 LOCAL_MODULE := split-select
+LOCAL_MODULE_HOST_OS := darwin linux windows
 
 LOCAL_SRC_FILES := $(main)
 
-LOCAL_C_INCLUDES += $(cIncludes)
-LOCAL_STATIC_LIBRARIES += libsplit-select $(hostStaticLibs)
-LOCAL_LDLIBS += $(hostLdLibs)
-LOCAL_CFLAGS += $(cFlags)
+LOCAL_C_INCLUDES := $(cIncludes)
+LOCAL_STATIC_LIBRARIES := libsplit-select $(hostStaticLibs)
+LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
+LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
+LOCAL_LDLIBS_linux := $(hostLdLibs_linux)
+LOCAL_CFLAGS := $(cFlags)
 
 include $(BUILD_HOST_EXECUTABLE)