Merge "add libmedia as dependency of invoke_mock_media_player."
diff --git a/Android.mk b/Android.mk
index 5fef91e..db63739 100644
--- a/Android.mk
+++ b/Android.mk
@@ -128,6 +128,7 @@
 	core/java/android/bluetooth/IBluetoothGattCallback.aidl \
 	core/java/android/bluetooth/IBluetoothGattServerCallback.aidl \
 	core/java/android/bluetooth/le/IAdvertiserCallback.aidl \
+	core/java/android/bluetooth/le/IScannerCallback.aidl \
 	core/java/android/content/IClipboard.aidl \
 	core/java/android/content/IContentService.aidl \
 	core/java/android/content/IIntentReceiver.aidl \
@@ -241,6 +242,10 @@
 	core/java/android/os/IUpdateLock.aidl \
 	core/java/android/os/IUserManager.aidl \
 	core/java/android/os/IVibratorService.aidl \
+	core/java/android/os/storage/IMountService.aidl \
+	core/java/android/os/storage/IMountServiceListener.aidl \
+	core/java/android/os/storage/IMountShutdownObserver.aidl \
+	core/java/android/os/storage/IObbActionListener.aidl \
 	core/java/android/security/IKeystoreService.aidl \
 	core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl \
 	core/java/android/service/carrier/ICarrierService.aidl \
@@ -294,6 +299,8 @@
 	core/java/android/view/IInputFilter.aidl \
 	core/java/android/view/IInputFilterHost.aidl \
 	core/java/android/view/IOnKeyguardExitResult.aidl \
+	core/java/android/view/IPinnedStackController.aidl \
+	core/java/android/view/IPinnedStackListener.aidl \
 	core/java/android/view/IRotationWatcher.aidl \
 	core/java/android/view/IWindow.aidl \
 	core/java/android/view/IWindowFocusObserver.aidl \
@@ -503,7 +510,10 @@
 
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVA_LIBRARIES := core-oj core-libart conscrypt okhttp core-junit bouncycastle ext
-LOCAL_STATIC_JAVA_LIBRARIES := framework-protos
+
+LOCAL_STATIC_JAVA_LIBRARIES :=                          \
+    framework-protos                                    \
+    android.hardware.thermal@1.0-java-constants         \
 
 LOCAL_MODULE := framework
 
@@ -575,6 +585,7 @@
 	frameworks/base/core/java/android/accounts/AuthenticatorDescription.aidl \
 	frameworks/base/core/java/android/accounts/Account.aidl \
 	frameworks/base/core/java/android/app/admin/SystemUpdatePolicy.aidl \
+	frameworks/base/core/java/android/app/admin/PasswordMetrics.aidl \
 	frameworks/base/core/java/android/print/PrintDocumentInfo.aidl \
 	frameworks/base/core/java/android/print/PageRange.aidl \
 	frameworks/base/core/java/android/print/PrintAttributes.aidl \
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index f5bd945..c28db57 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,7 +1,16 @@
 [Hook Scripts]
 checkstyle_hook = ../../development/tools/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
                   -fw core/java/android/animation/
+                      core/java/android/hardware/usb/
+                      core/java/android/print/
+                      core/java/android/printservice/
                       core/java/android/text/
-                      core/java/android/view/
                       core/java/android/transition/
+                      core/java/android/view/
                       core/java/android/widget/
+                      core/tests/coretests/src/android/print/
+                      packages/PrintRecommendationService/
+                      packages/PrintSpooler/
+                      services/print/
+                      services/usb/
+
diff --git a/api/current.txt b/api/current.txt
index 58d3341..47968de 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1041,6 +1041,7 @@
     field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
     field public static final int ringtoneType = 16843257; // 0x10101f9
     field public static final int rotation = 16843558; // 0x1010326
+    field public static final int rotationAnimation = 16843688; // 0x10103a8
     field public static final int rotationX = 16843559; // 0x1010327
     field public static final int rotationY = 16843560; // 0x1010328
     field public static final int roundIcon = 16844076; // 0x101052c
@@ -4489,6 +4490,7 @@
     method public void onTrimMemory(int);
     method public void onViewCreated(android.view.View, android.os.Bundle);
     method public void onViewStateRestored(android.os.Bundle);
+    method public void postponeEnterTransition();
     method public void registerForContextMenu(android.view.View);
     method public final void requestPermissions(java.lang.String[], int);
     method public void setAllowEnterTransitionOverlap(boolean);
@@ -4514,6 +4516,7 @@
     method public void startActivityForResult(android.content.Intent, int);
     method public void startActivityForResult(android.content.Intent, int, android.os.Bundle);
     method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+    method public void startPostponedEnterTransition();
     method public void unregisterForContextMenu(android.view.View);
   }
 
@@ -4630,8 +4633,10 @@
     method public abstract boolean popBackStackImmediate(java.lang.String, int);
     method public abstract boolean popBackStackImmediate(int, int);
     method public abstract void putFragment(android.os.Bundle, java.lang.String, android.app.Fragment);
+    method public abstract void registerFragmentLifecycleCallbacks(android.app.FragmentManager.FragmentLifecycleCallbacks, boolean);
     method public abstract void removeOnBackStackChangedListener(android.app.FragmentManager.OnBackStackChangedListener);
     method public abstract android.app.Fragment.SavedState saveFragmentInstanceState(android.app.Fragment);
+    method public abstract void unregisterFragmentLifecycleCallbacks(android.app.FragmentManager.FragmentLifecycleCallbacks);
     field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
   }
 
@@ -4644,6 +4649,23 @@
     method public abstract java.lang.String getName();
   }
 
+  public abstract class FragmentManager.FragmentLifecycleCallbacks {
+    ctor public FragmentManager.FragmentLifecycleCallbacks();
+    method public void onFragmentActivityCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
+    method public void onFragmentAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
+    method public void onFragmentCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
+    method public void onFragmentDestroyed(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentDetached(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentPaused(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentPreAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
+    method public void onFragmentResumed(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentSaveInstanceState(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
+    method public void onFragmentStarted(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentStopped(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentViewCreated(android.app.FragmentManager, android.app.Fragment, android.view.View, android.os.Bundle);
+    method public void onFragmentViewDestroyed(android.app.FragmentManager, android.app.Fragment);
+  }
+
   public static abstract interface FragmentManager.OnBackStackChangedListener {
     method public abstract void onBackStackChanged();
   }
@@ -4671,6 +4693,7 @@
     method public abstract android.app.FragmentTransaction remove(android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment, java.lang.String);
+    method public abstract android.app.FragmentTransaction setAllowOptimization(boolean);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(int);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(java.lang.CharSequence);
     method public abstract android.app.FragmentTransaction setBreadCrumbTitle(int);
@@ -6498,6 +6521,7 @@
   public static class NetworkStats.Bucket {
     ctor public NetworkStats.Bucket();
     method public long getEndTimeStamp();
+    method public int getMetered();
     method public int getRoaming();
     method public long getRxBytes();
     method public long getRxPackets();
@@ -6507,6 +6531,9 @@
     method public long getTxBytes();
     method public long getTxPackets();
     method public int getUid();
+    field public static final int METERED_ALL = -1; // 0xffffffff
+    field public static final int METERED_NO = 1; // 0x1
+    field public static final int METERED_YES = 2; // 0x2
     field public static final int ROAMING_ALL = -1; // 0xffffffff
     field public static final int ROAMING_NO = 1; // 0x1
     field public static final int ROAMING_YES = 2; // 0x2
@@ -10035,7 +10062,7 @@
     field public static final deprecated int PROTECTION_FLAG_SYSTEM = 16; // 0x10
     field public static final int PROTECTION_FLAG_VERIFIER = 512; // 0x200
     field public static final int PROTECTION_MASK_BASE = 15; // 0xf
-    field public static final int PROTECTION_MASK_FLAGS = 4080; // 0xff0
+    field public static final int PROTECTION_MASK_FLAGS = 65520; // 0xfff0
     field public static final int PROTECTION_NORMAL = 0; // 0x0
     field public static final int PROTECTION_SIGNATURE = 2; // 0x2
     field public static final deprecated int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3
@@ -11770,14 +11797,14 @@
     method public deprecated boolean clipRegion(android.graphics.Region);
     method public void concat(android.graphics.Matrix);
     method public void drawARGB(int, int, int, int);
-    method public void drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint);
     method public void drawArc(float, float, float, float, float, float, boolean, android.graphics.Paint);
+    method public void drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint);
     method public void drawBitmap(android.graphics.Bitmap, float, float, android.graphics.Paint);
-    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.RectF, android.graphics.Paint);
+    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Matrix, android.graphics.Paint);
     method public void drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.Rect, android.graphics.Paint);
+    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.RectF, android.graphics.Paint);
     method public deprecated void drawBitmap(int[], int, int, float, float, int, int, boolean, android.graphics.Paint);
     method public deprecated void drawBitmap(int[], int, int, int, int, int, int, boolean, android.graphics.Paint);
-    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Matrix, android.graphics.Paint);
     method public void drawBitmapMesh(android.graphics.Bitmap, int, int, float[], int, int[], int, android.graphics.Paint);
     method public void drawCircle(float, float, float, android.graphics.Paint);
     method public void drawColor(int);
@@ -11785,28 +11812,28 @@
     method public void drawLine(float, float, float, float, android.graphics.Paint);
     method public void drawLines(float[], int, int, android.graphics.Paint);
     method public void drawLines(float[], android.graphics.Paint);
-    method public void drawOval(android.graphics.RectF, android.graphics.Paint);
     method public void drawOval(float, float, float, float, android.graphics.Paint);
+    method public void drawOval(android.graphics.RectF, android.graphics.Paint);
     method public void drawPaint(android.graphics.Paint);
     method public void drawPath(android.graphics.Path, android.graphics.Paint);
     method public void drawPicture(android.graphics.Picture);
-    method public void drawPicture(android.graphics.Picture, android.graphics.RectF);
     method public void drawPicture(android.graphics.Picture, android.graphics.Rect);
+    method public void drawPicture(android.graphics.Picture, android.graphics.RectF);
     method public void drawPoint(float, float, android.graphics.Paint);
     method public void drawPoints(float[], int, int, android.graphics.Paint);
     method public void drawPoints(float[], android.graphics.Paint);
     method public deprecated void drawPosText(char[], int, int, float[], android.graphics.Paint);
     method public deprecated void drawPosText(java.lang.String, float[], android.graphics.Paint);
     method public void drawRGB(int, int, int);
-    method public void drawRect(android.graphics.RectF, android.graphics.Paint);
-    method public void drawRect(android.graphics.Rect, android.graphics.Paint);
     method public void drawRect(float, float, float, float, android.graphics.Paint);
-    method public void drawRoundRect(android.graphics.RectF, float, float, android.graphics.Paint);
+    method public void drawRect(android.graphics.Rect, android.graphics.Paint);
+    method public void drawRect(android.graphics.RectF, android.graphics.Paint);
     method public void drawRoundRect(float, float, float, float, float, float, android.graphics.Paint);
+    method public void drawRoundRect(android.graphics.RectF, float, float, android.graphics.Paint);
     method public void drawText(char[], int, int, float, float, android.graphics.Paint);
+    method public void drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint);
     method public void drawText(java.lang.String, float, float, android.graphics.Paint);
     method public void drawText(java.lang.String, int, int, float, float, android.graphics.Paint);
-    method public void drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint);
     method public void drawTextOnPath(char[], int, int, android.graphics.Path, float, float, android.graphics.Paint);
     method public void drawTextOnPath(java.lang.String, android.graphics.Path, float, float, android.graphics.Paint);
     method public void drawTextRun(char[], int, int, int, int, float, float, boolean, android.graphics.Paint);
@@ -13899,6 +13926,7 @@
   public static abstract class CameraCaptureSession.StateCallback {
     ctor public CameraCaptureSession.StateCallback();
     method public void onActive(android.hardware.camera2.CameraCaptureSession);
+    method public void onCaptureQueueEmpty(android.hardware.camera2.CameraCaptureSession);
     method public void onClosed(android.hardware.camera2.CameraCaptureSession);
     method public abstract void onConfigureFailed(android.hardware.camera2.CameraCaptureSession);
     method public abstract void onConfigured(android.hardware.camera2.CameraCaptureSession);
@@ -14777,6 +14805,7 @@
     method public java.lang.String getSerial();
     method public boolean releaseInterface(android.hardware.usb.UsbInterface);
     method public android.hardware.usb.UsbRequest requestWait();
+    method public android.hardware.usb.UsbRequest requestWait(int);
     method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
     method public boolean setInterface(android.hardware.usb.UsbInterface);
   }
@@ -14830,10 +14859,11 @@
     ctor public UsbRequest();
     method public boolean cancel();
     method public void close();
+    method public boolean enqueue(java.nio.ByteBuffer);
     method public java.lang.Object getClientData();
     method public android.hardware.usb.UsbEndpoint getEndpoint();
     method public boolean initialize(android.hardware.usb.UsbDeviceConnection, android.hardware.usb.UsbEndpoint);
-    method public boolean queue(java.nio.ByteBuffer, int);
+    method public deprecated boolean queue(java.nio.ByteBuffer, int);
     method public void setClientData(java.lang.Object);
   }
 
@@ -42337,6 +42367,7 @@
     method public abstract boolean isCreating();
     method public abstract android.graphics.Canvas lockCanvas();
     method public abstract android.graphics.Canvas lockCanvas(android.graphics.Rect);
+    method public default android.graphics.Canvas lockHardwareCanvas();
     method public abstract void removeCallback(android.view.SurfaceHolder.Callback);
     method public abstract void setFixedSize(int, int);
     method public abstract void setFormat(int);
@@ -44023,8 +44054,8 @@
     field public static final int ROTATION_ANIMATION_CHANGED = 4096; // 0x1000
     field public static final int ROTATION_ANIMATION_CROSSFADE = 1; // 0x1
     field public static final int ROTATION_ANIMATION_JUMPCUT = 2; // 0x2
-    field public static final int ROTATION_ANIMATION_SEAMLESS = 3; // 0x3
     field public static final int ROTATION_ANIMATION_ROTATE = 0; // 0x0
+    field public static final int ROTATION_ANIMATION_SEAMLESS = 3; // 0x3
     field public static final int SCREEN_BRIGHTNESS_CHANGED = 2048; // 0x800
     field public static final int SCREEN_ORIENTATION_CHANGED = 1024; // 0x400
     field public static final int SOFT_INPUT_ADJUST_NOTHING = 48; // 0x30
@@ -63010,6 +63041,7 @@
     method public void update(int);
     method public void update(byte[], int, int);
     method public void update(byte[]);
+    method public void update(java.nio.ByteBuffer);
   }
 
   public class CRC32 implements java.util.zip.Checksum {
@@ -63019,6 +63051,7 @@
     method public void update(int);
     method public void update(byte[], int, int);
     method public void update(byte[]);
+    method public void update(java.nio.ByteBuffer);
   }
 
   public class CheckedInputStream extends java.io.FilterInputStream {
diff --git a/api/system-current.txt b/api/system-current.txt
index 573b1f2..ff5e8735 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -103,7 +103,6 @@
     field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
     field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
     field public static final java.lang.String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS";
-    field public static final java.lang.String GET_PACKAGE_IMPORTANCE = "android.permission.GET_PACKAGE_IMPORTANCE";
     field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
     field public static final java.lang.String GET_PROCESS_STATE_AND_OOM_SCORE = "android.permission.GET_PROCESS_STATE_AND_OOM_SCORE";
     field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
@@ -1148,6 +1147,7 @@
     field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
     field public static final int ringtoneType = 16843257; // 0x10101f9
     field public static final int rotation = 16843558; // 0x1010326
+    field public static final int rotationAnimation = 16843688; // 0x10103a8
     field public static final int rotationX = 16843559; // 0x1010327
     field public static final int rotationY = 16843560; // 0x1010328
     field public static final int roundIcon = 16844076; // 0x101052c
@@ -4634,6 +4634,7 @@
     method public void onTrimMemory(int);
     method public void onViewCreated(android.view.View, android.os.Bundle);
     method public void onViewStateRestored(android.os.Bundle);
+    method public void postponeEnterTransition();
     method public void registerForContextMenu(android.view.View);
     method public final void requestPermissions(java.lang.String[], int);
     method public void setAllowEnterTransitionOverlap(boolean);
@@ -4659,6 +4660,7 @@
     method public void startActivityForResult(android.content.Intent, int);
     method public void startActivityForResult(android.content.Intent, int, android.os.Bundle);
     method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+    method public void startPostponedEnterTransition();
     method public void unregisterForContextMenu(android.view.View);
   }
 
@@ -4775,8 +4777,10 @@
     method public abstract boolean popBackStackImmediate(java.lang.String, int);
     method public abstract boolean popBackStackImmediate(int, int);
     method public abstract void putFragment(android.os.Bundle, java.lang.String, android.app.Fragment);
+    method public abstract void registerFragmentLifecycleCallbacks(android.app.FragmentManager.FragmentLifecycleCallbacks, boolean);
     method public abstract void removeOnBackStackChangedListener(android.app.FragmentManager.OnBackStackChangedListener);
     method public abstract android.app.Fragment.SavedState saveFragmentInstanceState(android.app.Fragment);
+    method public abstract void unregisterFragmentLifecycleCallbacks(android.app.FragmentManager.FragmentLifecycleCallbacks);
     field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
   }
 
@@ -4789,6 +4793,23 @@
     method public abstract java.lang.String getName();
   }
 
+  public abstract class FragmentManager.FragmentLifecycleCallbacks {
+    ctor public FragmentManager.FragmentLifecycleCallbacks();
+    method public void onFragmentActivityCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
+    method public void onFragmentAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
+    method public void onFragmentCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
+    method public void onFragmentDestroyed(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentDetached(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentPaused(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentPreAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
+    method public void onFragmentResumed(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentSaveInstanceState(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
+    method public void onFragmentStarted(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentStopped(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentViewCreated(android.app.FragmentManager, android.app.Fragment, android.view.View, android.os.Bundle);
+    method public void onFragmentViewDestroyed(android.app.FragmentManager, android.app.Fragment);
+  }
+
   public static abstract interface FragmentManager.OnBackStackChangedListener {
     method public abstract void onBackStackChanged();
   }
@@ -4816,6 +4837,7 @@
     method public abstract android.app.FragmentTransaction remove(android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment, java.lang.String);
+    method public abstract android.app.FragmentTransaction setAllowOptimization(boolean);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(int);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(java.lang.CharSequence);
     method public abstract android.app.FragmentTransaction setBreadCrumbTitle(int);
@@ -6788,6 +6810,7 @@
   public static class NetworkStats.Bucket {
     ctor public NetworkStats.Bucket();
     method public long getEndTimeStamp();
+    method public int getMetered();
     method public int getRoaming();
     method public long getRxBytes();
     method public long getRxPackets();
@@ -6797,6 +6820,9 @@
     method public long getTxBytes();
     method public long getTxPackets();
     method public int getUid();
+    field public static final int METERED_ALL = -1; // 0xffffffff
+    field public static final int METERED_NO = 1; // 0x1
+    field public static final int METERED_YES = 2; // 0x2
     field public static final int ROAMING_ALL = -1; // 0xffffffff
     field public static final int ROAMING_NO = 1; // 0x1
     field public static final int ROAMING_YES = 2; // 0x2
@@ -10461,6 +10487,7 @@
     field public static final int PROTECTION_DANGEROUS = 1; // 0x1
     field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40
     field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
+    field public static final int PROTECTION_FLAG_EPHEMERAL = 4096; // 0x1000
     field public static final int PROTECTION_FLAG_INSTALLER = 256; // 0x100
     field public static final int PROTECTION_FLAG_PRE23 = 128; // 0x80
     field public static final int PROTECTION_FLAG_PREINSTALLED = 1024; // 0x400
@@ -10469,7 +10496,7 @@
     field public static final deprecated int PROTECTION_FLAG_SYSTEM = 16; // 0x10
     field public static final int PROTECTION_FLAG_VERIFIER = 512; // 0x200
     field public static final int PROTECTION_MASK_BASE = 15; // 0xf
-    field public static final int PROTECTION_MASK_FLAGS = 4080; // 0xff0
+    field public static final int PROTECTION_MASK_FLAGS = 65520; // 0xfff0
     field public static final int PROTECTION_NORMAL = 0; // 0x0
     field public static final int PROTECTION_SIGNATURE = 2; // 0x2
     field public static final deprecated int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3
@@ -12218,14 +12245,14 @@
     method public deprecated boolean clipRegion(android.graphics.Region);
     method public void concat(android.graphics.Matrix);
     method public void drawARGB(int, int, int, int);
-    method public void drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint);
     method public void drawArc(float, float, float, float, float, float, boolean, android.graphics.Paint);
+    method public void drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint);
     method public void drawBitmap(android.graphics.Bitmap, float, float, android.graphics.Paint);
-    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.RectF, android.graphics.Paint);
+    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Matrix, android.graphics.Paint);
     method public void drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.Rect, android.graphics.Paint);
+    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.RectF, android.graphics.Paint);
     method public deprecated void drawBitmap(int[], int, int, float, float, int, int, boolean, android.graphics.Paint);
     method public deprecated void drawBitmap(int[], int, int, int, int, int, int, boolean, android.graphics.Paint);
-    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Matrix, android.graphics.Paint);
     method public void drawBitmapMesh(android.graphics.Bitmap, int, int, float[], int, int[], int, android.graphics.Paint);
     method public void drawCircle(float, float, float, android.graphics.Paint);
     method public void drawColor(int);
@@ -12233,28 +12260,28 @@
     method public void drawLine(float, float, float, float, android.graphics.Paint);
     method public void drawLines(float[], int, int, android.graphics.Paint);
     method public void drawLines(float[], android.graphics.Paint);
-    method public void drawOval(android.graphics.RectF, android.graphics.Paint);
     method public void drawOval(float, float, float, float, android.graphics.Paint);
+    method public void drawOval(android.graphics.RectF, android.graphics.Paint);
     method public void drawPaint(android.graphics.Paint);
     method public void drawPath(android.graphics.Path, android.graphics.Paint);
     method public void drawPicture(android.graphics.Picture);
-    method public void drawPicture(android.graphics.Picture, android.graphics.RectF);
     method public void drawPicture(android.graphics.Picture, android.graphics.Rect);
+    method public void drawPicture(android.graphics.Picture, android.graphics.RectF);
     method public void drawPoint(float, float, android.graphics.Paint);
     method public void drawPoints(float[], int, int, android.graphics.Paint);
     method public void drawPoints(float[], android.graphics.Paint);
     method public deprecated void drawPosText(char[], int, int, float[], android.graphics.Paint);
     method public deprecated void drawPosText(java.lang.String, float[], android.graphics.Paint);
     method public void drawRGB(int, int, int);
-    method public void drawRect(android.graphics.RectF, android.graphics.Paint);
-    method public void drawRect(android.graphics.Rect, android.graphics.Paint);
     method public void drawRect(float, float, float, float, android.graphics.Paint);
-    method public void drawRoundRect(android.graphics.RectF, float, float, android.graphics.Paint);
+    method public void drawRect(android.graphics.Rect, android.graphics.Paint);
+    method public void drawRect(android.graphics.RectF, android.graphics.Paint);
     method public void drawRoundRect(float, float, float, float, float, float, android.graphics.Paint);
+    method public void drawRoundRect(android.graphics.RectF, float, float, android.graphics.Paint);
     method public void drawText(char[], int, int, float, float, android.graphics.Paint);
+    method public void drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint);
     method public void drawText(java.lang.String, float, float, android.graphics.Paint);
     method public void drawText(java.lang.String, int, int, float, float, android.graphics.Paint);
-    method public void drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint);
     method public void drawTextOnPath(char[], int, int, android.graphics.Path, float, float, android.graphics.Paint);
     method public void drawTextOnPath(java.lang.String, android.graphics.Path, float, float, android.graphics.Paint);
     method public void drawTextRun(char[], int, int, int, int, float, float, boolean, android.graphics.Paint);
@@ -14355,6 +14382,7 @@
   public static abstract class CameraCaptureSession.StateCallback {
     ctor public CameraCaptureSession.StateCallback();
     method public void onActive(android.hardware.camera2.CameraCaptureSession);
+    method public void onCaptureQueueEmpty(android.hardware.camera2.CameraCaptureSession);
     method public void onClosed(android.hardware.camera2.CameraCaptureSession);
     method public abstract void onConfigureFailed(android.hardware.camera2.CameraCaptureSession);
     method public abstract void onConfigured(android.hardware.camera2.CameraCaptureSession);
@@ -15987,6 +16015,7 @@
     method public java.lang.String getSerial();
     method public boolean releaseInterface(android.hardware.usb.UsbInterface);
     method public android.hardware.usb.UsbRequest requestWait();
+    method public android.hardware.usb.UsbRequest requestWait(int);
     method public boolean resetDevice();
     method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
     method public boolean setInterface(android.hardware.usb.UsbInterface);
@@ -16041,10 +16070,11 @@
     ctor public UsbRequest();
     method public boolean cancel();
     method public void close();
+    method public boolean enqueue(java.nio.ByteBuffer);
     method public java.lang.Object getClientData();
     method public android.hardware.usb.UsbEndpoint getEndpoint();
     method public boolean initialize(android.hardware.usb.UsbDeviceConnection, android.hardware.usb.UsbEndpoint);
-    method public boolean queue(java.nio.ByteBuffer, int);
+    method public deprecated boolean queue(java.nio.ByteBuffer, int);
     method public void setClientData(java.lang.Object);
   }
 
@@ -45516,6 +45546,7 @@
     method public abstract boolean isCreating();
     method public abstract android.graphics.Canvas lockCanvas();
     method public abstract android.graphics.Canvas lockCanvas(android.graphics.Rect);
+    method public default android.graphics.Canvas lockHardwareCanvas();
     method public abstract void removeCallback(android.view.SurfaceHolder.Callback);
     method public abstract void setFixedSize(int, int);
     method public abstract void setFormat(int);
@@ -47205,8 +47236,8 @@
     field public static final int ROTATION_ANIMATION_CHANGED = 4096; // 0x1000
     field public static final int ROTATION_ANIMATION_CROSSFADE = 1; // 0x1
     field public static final int ROTATION_ANIMATION_JUMPCUT = 2; // 0x2
-    field public static final int ROTATION_ANIMATION_SEAMLESS = 3; // 0x3
     field public static final int ROTATION_ANIMATION_ROTATE = 0; // 0x0
+    field public static final int ROTATION_ANIMATION_SEAMLESS = 3; // 0x3
     field public static final int SCREEN_BRIGHTNESS_CHANGED = 2048; // 0x800
     field public static final int SCREEN_ORIENTATION_CHANGED = 1024; // 0x400
     field public static final int SOFT_INPUT_ADJUST_NOTHING = 48; // 0x30
@@ -66548,6 +66579,7 @@
     method public void update(int);
     method public void update(byte[], int, int);
     method public void update(byte[]);
+    method public void update(java.nio.ByteBuffer);
   }
 
   public class CRC32 implements java.util.zip.Checksum {
@@ -66557,6 +66589,7 @@
     method public void update(int);
     method public void update(byte[], int, int);
     method public void update(byte[]);
+    method public void update(java.nio.ByteBuffer);
   }
 
   public class CheckedInputStream extends java.io.FilterInputStream {
diff --git a/api/test-current.txt b/api/test-current.txt
index bde0e41..907f9a4 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1041,6 +1041,7 @@
     field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
     field public static final int ringtoneType = 16843257; // 0x10101f9
     field public static final int rotation = 16843558; // 0x1010326
+    field public static final int rotationAnimation = 16843688; // 0x10103a8
     field public static final int rotationX = 16843559; // 0x1010327
     field public static final int rotationY = 16843560; // 0x1010328
     field public static final int roundIcon = 16844076; // 0x101052c
@@ -4492,6 +4493,7 @@
     method public void onTrimMemory(int);
     method public void onViewCreated(android.view.View, android.os.Bundle);
     method public void onViewStateRestored(android.os.Bundle);
+    method public void postponeEnterTransition();
     method public void registerForContextMenu(android.view.View);
     method public final void requestPermissions(java.lang.String[], int);
     method public void setAllowEnterTransitionOverlap(boolean);
@@ -4517,6 +4519,7 @@
     method public void startActivityForResult(android.content.Intent, int);
     method public void startActivityForResult(android.content.Intent, int, android.os.Bundle);
     method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+    method public void startPostponedEnterTransition();
     method public void unregisterForContextMenu(android.view.View);
   }
 
@@ -4633,8 +4636,10 @@
     method public abstract boolean popBackStackImmediate(java.lang.String, int);
     method public abstract boolean popBackStackImmediate(int, int);
     method public abstract void putFragment(android.os.Bundle, java.lang.String, android.app.Fragment);
+    method public abstract void registerFragmentLifecycleCallbacks(android.app.FragmentManager.FragmentLifecycleCallbacks, boolean);
     method public abstract void removeOnBackStackChangedListener(android.app.FragmentManager.OnBackStackChangedListener);
     method public abstract android.app.Fragment.SavedState saveFragmentInstanceState(android.app.Fragment);
+    method public abstract void unregisterFragmentLifecycleCallbacks(android.app.FragmentManager.FragmentLifecycleCallbacks);
     field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
   }
 
@@ -4647,6 +4652,23 @@
     method public abstract java.lang.String getName();
   }
 
+  public abstract class FragmentManager.FragmentLifecycleCallbacks {
+    ctor public FragmentManager.FragmentLifecycleCallbacks();
+    method public void onFragmentActivityCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
+    method public void onFragmentAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
+    method public void onFragmentCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
+    method public void onFragmentDestroyed(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentDetached(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentPaused(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentPreAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
+    method public void onFragmentResumed(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentSaveInstanceState(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
+    method public void onFragmentStarted(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentStopped(android.app.FragmentManager, android.app.Fragment);
+    method public void onFragmentViewCreated(android.app.FragmentManager, android.app.Fragment, android.view.View, android.os.Bundle);
+    method public void onFragmentViewDestroyed(android.app.FragmentManager, android.app.Fragment);
+  }
+
   public static abstract interface FragmentManager.OnBackStackChangedListener {
     method public abstract void onBackStackChanged();
   }
@@ -4674,6 +4696,7 @@
     method public abstract android.app.FragmentTransaction remove(android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment);
     method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment, java.lang.String);
+    method public abstract android.app.FragmentTransaction setAllowOptimization(boolean);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(int);
     method public abstract android.app.FragmentTransaction setBreadCrumbShortTitle(java.lang.CharSequence);
     method public abstract android.app.FragmentTransaction setBreadCrumbTitle(int);
@@ -6507,6 +6530,7 @@
   public static class NetworkStats.Bucket {
     ctor public NetworkStats.Bucket();
     method public long getEndTimeStamp();
+    method public int getMetered();
     method public int getRoaming();
     method public long getRxBytes();
     method public long getRxPackets();
@@ -6516,6 +6540,9 @@
     method public long getTxBytes();
     method public long getTxPackets();
     method public int getUid();
+    field public static final int METERED_ALL = -1; // 0xffffffff
+    field public static final int METERED_NO = 1; // 0x1
+    field public static final int METERED_YES = 2; // 0x2
     field public static final int ROAMING_ALL = -1; // 0xffffffff
     field public static final int ROAMING_NO = 1; // 0x1
     field public static final int ROAMING_YES = 2; // 0x2
@@ -10043,6 +10070,7 @@
     field public static final int PROTECTION_DANGEROUS = 1; // 0x1
     field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40
     field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
+    field public static final int PROTECTION_FLAG_EPHEMERAL = 4096; // 0x1000
     field public static final int PROTECTION_FLAG_INSTALLER = 256; // 0x100
     field public static final int PROTECTION_FLAG_PRE23 = 128; // 0x80
     field public static final int PROTECTION_FLAG_PREINSTALLED = 1024; // 0x400
@@ -10051,7 +10079,7 @@
     field public static final deprecated int PROTECTION_FLAG_SYSTEM = 16; // 0x10
     field public static final int PROTECTION_FLAG_VERIFIER = 512; // 0x200
     field public static final int PROTECTION_MASK_BASE = 15; // 0xf
-    field public static final int PROTECTION_MASK_FLAGS = 4080; // 0xff0
+    field public static final int PROTECTION_MASK_FLAGS = 65520; // 0xfff0
     field public static final int PROTECTION_NORMAL = 0; // 0x0
     field public static final int PROTECTION_SIGNATURE = 2; // 0x2
     field public static final deprecated int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3
@@ -11787,14 +11815,14 @@
     method public deprecated boolean clipRegion(android.graphics.Region);
     method public void concat(android.graphics.Matrix);
     method public void drawARGB(int, int, int, int);
-    method public void drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint);
     method public void drawArc(float, float, float, float, float, float, boolean, android.graphics.Paint);
+    method public void drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint);
     method public void drawBitmap(android.graphics.Bitmap, float, float, android.graphics.Paint);
-    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.RectF, android.graphics.Paint);
+    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Matrix, android.graphics.Paint);
     method public void drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.Rect, android.graphics.Paint);
+    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.RectF, android.graphics.Paint);
     method public deprecated void drawBitmap(int[], int, int, float, float, int, int, boolean, android.graphics.Paint);
     method public deprecated void drawBitmap(int[], int, int, int, int, int, int, boolean, android.graphics.Paint);
-    method public void drawBitmap(android.graphics.Bitmap, android.graphics.Matrix, android.graphics.Paint);
     method public void drawBitmapMesh(android.graphics.Bitmap, int, int, float[], int, int[], int, android.graphics.Paint);
     method public void drawCircle(float, float, float, android.graphics.Paint);
     method public void drawColor(int);
@@ -11802,28 +11830,28 @@
     method public void drawLine(float, float, float, float, android.graphics.Paint);
     method public void drawLines(float[], int, int, android.graphics.Paint);
     method public void drawLines(float[], android.graphics.Paint);
-    method public void drawOval(android.graphics.RectF, android.graphics.Paint);
     method public void drawOval(float, float, float, float, android.graphics.Paint);
+    method public void drawOval(android.graphics.RectF, android.graphics.Paint);
     method public void drawPaint(android.graphics.Paint);
     method public void drawPath(android.graphics.Path, android.graphics.Paint);
     method public void drawPicture(android.graphics.Picture);
-    method public void drawPicture(android.graphics.Picture, android.graphics.RectF);
     method public void drawPicture(android.graphics.Picture, android.graphics.Rect);
+    method public void drawPicture(android.graphics.Picture, android.graphics.RectF);
     method public void drawPoint(float, float, android.graphics.Paint);
     method public void drawPoints(float[], int, int, android.graphics.Paint);
     method public void drawPoints(float[], android.graphics.Paint);
     method public deprecated void drawPosText(char[], int, int, float[], android.graphics.Paint);
     method public deprecated void drawPosText(java.lang.String, float[], android.graphics.Paint);
     method public void drawRGB(int, int, int);
-    method public void drawRect(android.graphics.RectF, android.graphics.Paint);
-    method public void drawRect(android.graphics.Rect, android.graphics.Paint);
     method public void drawRect(float, float, float, float, android.graphics.Paint);
-    method public void drawRoundRect(android.graphics.RectF, float, float, android.graphics.Paint);
+    method public void drawRect(android.graphics.Rect, android.graphics.Paint);
+    method public void drawRect(android.graphics.RectF, android.graphics.Paint);
     method public void drawRoundRect(float, float, float, float, float, float, android.graphics.Paint);
+    method public void drawRoundRect(android.graphics.RectF, float, float, android.graphics.Paint);
     method public void drawText(char[], int, int, float, float, android.graphics.Paint);
+    method public void drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint);
     method public void drawText(java.lang.String, float, float, android.graphics.Paint);
     method public void drawText(java.lang.String, int, int, float, float, android.graphics.Paint);
-    method public void drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint);
     method public void drawTextOnPath(char[], int, int, android.graphics.Path, float, float, android.graphics.Paint);
     method public void drawTextOnPath(java.lang.String, android.graphics.Path, float, float, android.graphics.Paint);
     method public void drawTextRun(char[], int, int, int, int, float, float, boolean, android.graphics.Paint);
@@ -13916,6 +13944,7 @@
   public static abstract class CameraCaptureSession.StateCallback {
     ctor public CameraCaptureSession.StateCallback();
     method public void onActive(android.hardware.camera2.CameraCaptureSession);
+    method public void onCaptureQueueEmpty(android.hardware.camera2.CameraCaptureSession);
     method public void onClosed(android.hardware.camera2.CameraCaptureSession);
     method public abstract void onConfigureFailed(android.hardware.camera2.CameraCaptureSession);
     method public abstract void onConfigured(android.hardware.camera2.CameraCaptureSession);
@@ -14794,6 +14823,7 @@
     method public java.lang.String getSerial();
     method public boolean releaseInterface(android.hardware.usb.UsbInterface);
     method public android.hardware.usb.UsbRequest requestWait();
+    method public android.hardware.usb.UsbRequest requestWait(int);
     method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
     method public boolean setInterface(android.hardware.usb.UsbInterface);
   }
@@ -14847,10 +14877,11 @@
     ctor public UsbRequest();
     method public boolean cancel();
     method public void close();
+    method public boolean enqueue(java.nio.ByteBuffer);
     method public java.lang.Object getClientData();
     method public android.hardware.usb.UsbEndpoint getEndpoint();
     method public boolean initialize(android.hardware.usb.UsbDeviceConnection, android.hardware.usb.UsbEndpoint);
-    method public boolean queue(java.nio.ByteBuffer, int);
+    method public deprecated boolean queue(java.nio.ByteBuffer, int);
     method public void setClientData(java.lang.Object);
   }
 
@@ -42573,6 +42604,7 @@
     method public abstract boolean isCreating();
     method public abstract android.graphics.Canvas lockCanvas();
     method public abstract android.graphics.Canvas lockCanvas(android.graphics.Rect);
+    method public default android.graphics.Canvas lockHardwareCanvas();
     method public abstract void removeCallback(android.view.SurfaceHolder.Callback);
     method public abstract void setFixedSize(int, int);
     method public abstract void setFormat(int);
@@ -44259,8 +44291,8 @@
     field public static final int ROTATION_ANIMATION_CHANGED = 4096; // 0x1000
     field public static final int ROTATION_ANIMATION_CROSSFADE = 1; // 0x1
     field public static final int ROTATION_ANIMATION_JUMPCUT = 2; // 0x2
-    field public static final int ROTATION_ANIMATION_SEAMLESS = 3; // 0x3
     field public static final int ROTATION_ANIMATION_ROTATE = 0; // 0x0
+    field public static final int ROTATION_ANIMATION_SEAMLESS = 3; // 0x3
     field public static final int SCREEN_BRIGHTNESS_CHANGED = 2048; // 0x800
     field public static final int SCREEN_ORIENTATION_CHANGED = 1024; // 0x400
     field public static final int SOFT_INPUT_ADJUST_NOTHING = 48; // 0x30
@@ -63262,6 +63294,7 @@
     method public void update(int);
     method public void update(byte[], int, int);
     method public void update(byte[]);
+    method public void update(java.nio.ByteBuffer);
   }
 
   public class CRC32 implements java.util.zip.Checksum {
@@ -63271,6 +63304,7 @@
     method public void update(int);
     method public void update(byte[], int, int);
     method public void update(byte[]);
+    method public void update(java.nio.ByteBuffer);
   }
 
   public class CheckedInputStream extends java.io.FilterInputStream {
diff --git a/cmds/am/Android.mk b/cmds/am/Android.mk
index f8350dc..5586dd4 100644
--- a/cmds/am/Android.mk
+++ b/cmds/am/Android.mk
@@ -3,8 +3,11 @@
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src) \
+    $(call all-proto-files-under, proto)
 LOCAL_MODULE := am
+LOCAL_PROTOC_OPTIMIZE_TYPE := stream
 include $(BUILD_JAVA_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -13,3 +16,14 @@
 LOCAL_MODULE_CLASS := EXECUTABLES
 LOCAL_MODULE_TAGS := optional
 include $(BUILD_PREBUILT)
+
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+    $(call all-proto-files-under, proto)
+LOCAL_MODULE := libinstrumentation
+LOCAL_PROTOC_OPTIMIZE_TYPE := full
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+    $(call intermediates-dir-for,STATIC_LIBRARIES,libinstrumentation,HOST,,,)/proto/$(LOCAL_PATH)/proto
+include $(BUILD_HOST_STATIC_LIBRARY)
+
diff --git a/cmds/am/proto/instrumentation_data.proto b/cmds/am/proto/instrumentation_data.proto
new file mode 100644
index 0000000..12a18a2
--- /dev/null
+++ b/cmds/am/proto/instrumentation_data.proto
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+syntax = "proto2";
+package android.am;
+
+option java_package = "com.android.commands.am";
+
+message ResultsBundleEntry {
+    optional string key = 1;
+
+    optional string value_string = 2;
+    optional sint32 value_int = 3;
+    optional float value_float = 4;
+    optional double value_double = 5;
+    optional sint64 value_long = 6;
+    optional ResultsBundle value_bundle = 7;
+}
+
+message ResultsBundle {
+    repeated ResultsBundleEntry entries = 1;
+}
+
+message TestStatus {
+    optional sint32 result_code = 3;
+    optional ResultsBundle results = 4;
+}
+
+enum SessionStatusCode {
+    /**
+     * The command ran successfully. This does not imply that the tests passed.
+     */
+    SESSION_FINISHED = 0;
+
+    /**
+     * There was an unrecoverable error running the tests.
+     */
+    SESSION_ABORTED = 1;
+}
+
+message SessionStatus {
+    optional SessionStatusCode status_code = 1;
+    optional string error_text = 2;
+    optional sint32 result_code = 3;
+    optional ResultsBundle results = 4;
+}
+
+message Session {
+    repeated TestStatus test_status = 1;
+    optional SessionStatus session_status = 2;
+}
+
+
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index e197bfc..91a4549 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -1,20 +1,18 @@
 /*
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package com.android.commands.am;
 
@@ -235,6 +233,7 @@
                 "    -e <NAME> <VALUE>: set argument <NAME> to <VALUE>.  For test runners a\n" +
                 "        common form is [-e <testrunner_flag> <value>[,<value>...]].\n" +
                 "    -p <FILE>: write profiling data to <FILE>\n" +
+                "    -m: Write output as protobuf (machine readable)\n" +
                 "    -w: wait for instrumentation to finish before returning.  Required for\n" +
                 "        test runners.\n" +
                 "    --user <USER_ID> | current: Specify user instrumentation runs in;\n" +
@@ -543,208 +542,43 @@
         receiver.waitForFinish();
     }
 
-    private void runInstrument() throws Exception {
-        String profileFile = null;
-        boolean wait = false;
-        boolean rawMode = false;
-        boolean no_window_animation = false;
-        int userId = UserHandle.USER_CURRENT;
-        Bundle args = new Bundle();
-        String argKey = null, argValue = null;
-        IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
-        String abi = null;
+    public void runInstrument() throws Exception {
+        Instrument instrument = new Instrument(mAm, mPm);
 
         String opt;
         while ((opt=nextOption()) != null) {
             if (opt.equals("-p")) {
-                profileFile = nextArgRequired();
+                instrument.profileFile = nextArgRequired();
             } else if (opt.equals("-w")) {
-                wait = true;
+                instrument.wait = true;
             } else if (opt.equals("-r")) {
-                rawMode = true;
+                instrument.rawMode = true;
+            } else if (opt.equals("-m")) {
+                instrument.proto = true;
             } else if (opt.equals("-e")) {
-                argKey = nextArgRequired();
-                argValue = nextArgRequired();
-                args.putString(argKey, argValue);
+                final String argKey = nextArgRequired();
+                final String argValue = nextArgRequired();
+                instrument.args.putString(argKey, argValue);
             } else if (opt.equals("--no_window_animation")
                     || opt.equals("--no-window-animation")) {
-                no_window_animation = true;
+                instrument.noWindowAnimation = true;
             } else if (opt.equals("--user")) {
-                userId = parseUserArg(nextArgRequired());
+                instrument.userId = parseUserArg(nextArgRequired());
             } else if (opt.equals("--abi")) {
-                abi = nextArgRequired();
+                instrument.abi = nextArgRequired();
             } else {
                 System.err.println("Error: Unknown option: " + opt);
                 return;
             }
         }
 
-        if (userId == UserHandle.USER_ALL) {
+        if (instrument.userId == UserHandle.USER_ALL) {
             System.err.println("Error: Can't start instrumentation with user 'all'");
             return;
         }
 
-        String cnArg = nextArgRequired();
+        instrument.componentNameArg = nextArgRequired();
 
-        ComponentName cn;
-        if (cnArg.contains("/")) {
-            cn = ComponentName.unflattenFromString(cnArg);
-            if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
-        } else {
-            List<InstrumentationInfo> infos = mPm.queryInstrumentation(null, 0).getList();
-
-            final int numInfos = infos == null ? 0: infos.size();
-            List<ComponentName> cns = new ArrayList<>();
-            for (int i = 0; i < numInfos; i++) {
-                InstrumentationInfo info = infos.get(i);
-
-                ComponentName c = new ComponentName(info.packageName, info.name);
-                if (cnArg.equals(info.packageName)) {
-                    cns.add(c);
-                }
-            }
-
-            if (cns.size() == 0) {
-                throw new IllegalArgumentException("No instrumentation found for: " + cnArg);
-            } else if (cns.size() == 1) {
-                cn = cns.get(0);
-            } else {
-                StringBuilder cnsStr = new StringBuilder();
-                final int numCns = cns.size();
-                for (int i = 0; i < numCns; i++) {
-                    cnsStr.append(cns.get(i).flattenToString());
-                    cnsStr.append(", ");
-                }
-
-                // Remove last ", "
-                cnsStr.setLength(cnsStr.length() - 2);
-
-                throw new IllegalArgumentException("Found multiple instrumentations: "
-                        + cnsStr.toString());
-            }
-        }
-
-        InstrumentationWatcher watcher = null;
-        UiAutomationConnection connection = null;
-        if (wait) {
-            watcher = new InstrumentationWatcher();
-            watcher.setRawOutput(rawMode);
-            connection = new UiAutomationConnection();
-        }
-
-        float[] oldAnims = null;
-        if (no_window_animation) {
-            oldAnims = wm.getAnimationScales();
-            wm.setAnimationScale(0, 0.0f);
-            wm.setAnimationScale(1, 0.0f);
-        }
-
-        if (abi != null) {
-            final String[] supportedAbis = Build.SUPPORTED_ABIS;
-            boolean matched = false;
-            for (String supportedAbi : supportedAbis) {
-                if (supportedAbi.equals(abi)) {
-                    matched = true;
-                    break;
-                }
-            }
-
-            if (!matched) {
-                throw new AndroidException(
-                        "INSTRUMENTATION_FAILED: Unsupported instruction set " + abi);
-            }
-        }
-
-        if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId, abi)) {
-            throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
-        }
-
-        if (watcher != null) {
-            if (!watcher.waitForFinish()) {
-                System.out.println("INSTRUMENTATION_ABORTED: System has crashed.");
-            }
-        }
-
-        if (oldAnims != null) {
-            wm.setAnimationScales(oldAnims);
-        }
-    }
-
-    private class InstrumentationWatcher extends IInstrumentationWatcher.Stub {
-        private boolean mFinished = false;
-        private boolean mRawMode = false;
-
-        /**
-         * Set or reset "raw mode".  In "raw mode", all bundles are dumped.  In "pretty mode",
-         * if a bundle includes Instrumentation.REPORT_KEY_STREAMRESULT, just print that.
-         * @param rawMode true for raw mode, false for pretty mode.
-         */
-        public void setRawOutput(boolean rawMode) {
-            mRawMode = rawMode;
-        }
-
-        @Override
-        public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) {
-            synchronized (this) {
-                // pretty printer mode?
-                String pretty = null;
-                if (!mRawMode && results != null) {
-                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
-                }
-                if (pretty != null) {
-                    System.out.print(pretty);
-                } else {
-                    if (results != null) {
-                        for (String key : results.keySet()) {
-                            System.out.println(
-                                    "INSTRUMENTATION_STATUS: " + key + "=" + results.get(key));
-                        }
-                    }
-                    System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode);
-                }
-                notifyAll();
-            }
-        }
-
-        @Override
-        public void instrumentationFinished(ComponentName name, int resultCode,
-                Bundle results) {
-            synchronized (this) {
-                // pretty printer mode?
-                String pretty = null;
-                if (!mRawMode && results != null) {
-                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
-                }
-                if (pretty != null) {
-                    System.out.println(pretty);
-                } else {
-                    if (results != null) {
-                        for (String key : results.keySet()) {
-                            System.out.println(
-                                    "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key));
-                        }
-                    }
-                    System.out.println("INSTRUMENTATION_CODE: " + resultCode);
-                }
-                mFinished = true;
-                notifyAll();
-            }
-        }
-
-        public boolean waitForFinish() {
-            synchronized (this) {
-                while (!mFinished) {
-                    try {
-                        if (!mAm.asBinder().pingBinder()) {
-                            return false;
-                        }
-                        wait(1000);
-                    } catch (InterruptedException e) {
-                        throw new IllegalStateException(e);
-                    }
-                }
-            }
-            return true;
-        }
+        instrument.run();
     }
 }
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
new file mode 100644
index 0000000..8eefd25
--- /dev/null
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.commands.am;
+
+import android.app.IActivityManager;
+import android.app.IInstrumentationWatcher;
+import android.app.Instrumentation;
+import android.app.UiAutomationConnection;
+import android.content.ComponentName;
+import android.content.pm.IPackageManager;
+import android.content.pm.InstrumentationInfo;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.AndroidException;
+import android.util.proto.ProtoOutputStream;
+import android.view.IWindowManager;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Runs the am instrument command
+ */
+public class Instrument {
+    private final IActivityManager mAm;
+    private final IPackageManager mPm;
+    private final IWindowManager mWm;
+
+    // Command line arguments
+    public String profileFile = null;
+    public boolean wait = false;
+    public boolean rawMode = false;
+    public boolean proto = false;
+    public boolean noWindowAnimation = false;
+    public String abi = null;
+    public int userId = UserHandle.USER_CURRENT;
+    public Bundle args = new Bundle();
+    // Required
+    public String componentNameArg;
+
+    /**
+     * Construct the instrument command runner.
+     */
+    public Instrument(IActivityManager am, IPackageManager pm) {
+        mAm = am;
+        mPm = pm;
+        mWm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+    }
+
+    /**
+     * Base class for status reporting.
+     *
+     * All the methods on this interface are called within the synchronized block
+     * of the InstrumentationWatcher, so calls are in order.  However, that means
+     * you must be careful not to do blocking operations because you don't know
+     * exactly the locking dependencies.
+     */
+    private interface StatusReporter {
+        /**
+         * Status update for tests.
+         */
+        public void onInstrumentationStatusLocked(ComponentName name, int resultCode,
+                Bundle results);
+
+        /**
+         * The tests finished.
+         */
+        public void onInstrumentationFinishedLocked(ComponentName name, int resultCode,
+                Bundle results);
+
+        /**
+         * @param errorText a description of the error
+         * @param commandError True if the error is related to the commandline, as opposed
+         *      to a test failing.
+         */
+        public void onError(String errorText, boolean commandError);
+    }
+
+    /**
+     * Printer for the 'classic' text based status reporting.
+     */
+    private class TextStatusReporter implements StatusReporter {
+        private boolean mRawMode;
+
+        /**
+         * Human-ish readable output.
+         *
+         * @param rawMode   In "raw mode" (true), all bundles are dumped.
+         *                  In "pretty mode" (false), if a bundle includes
+         *                  Instrumentation.REPORT_KEY_STREAMRESULT, just print that.
+         */
+        public TextStatusReporter(boolean rawMode) {
+            mRawMode = rawMode;
+        }
+
+        @Override
+        public void onInstrumentationStatusLocked(ComponentName name, int resultCode,
+                Bundle results) {
+            // pretty printer mode?
+            String pretty = null;
+            if (!mRawMode && results != null) {
+                pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
+            }
+            if (pretty != null) {
+                System.out.print(pretty);
+            } else {
+                if (results != null) {
+                    for (String key : results.keySet()) {
+                        System.out.println(
+                                "INSTRUMENTATION_STATUS: " + key + "=" + results.get(key));
+                    }
+                }
+                System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode);
+            }
+        }
+
+        @Override
+        public void onInstrumentationFinishedLocked(ComponentName name, int resultCode,
+                Bundle results) {
+            // pretty printer mode?
+            String pretty = null;
+            if (!mRawMode && results != null) {
+                pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
+            }
+            if (pretty != null) {
+                System.out.println(pretty);
+            } else {
+                if (results != null) {
+                    for (String key : results.keySet()) {
+                        System.out.println(
+                                "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key));
+                    }
+                }
+                System.out.println("INSTRUMENTATION_CODE: " + resultCode);
+            }
+        }
+
+        @Override
+        public void onError(String errorText, boolean commandError) {
+            // The regular BaseCommand error printing will print the commandErrors.
+            if (!commandError) {
+                System.out.println(errorText);
+            }
+        }
+    }
+
+    /**
+     * Printer for the protobuf based status reporting.
+     */
+    private class ProtoStatusReporter implements StatusReporter {
+        @Override
+        public void onInstrumentationStatusLocked(ComponentName name, int resultCode,
+                Bundle results) {
+            final ProtoOutputStream proto = new ProtoOutputStream();
+
+            final long token = proto.startRepeatedObject(InstrumentationData.Session.TEST_STATUS);
+
+            proto.writeSInt32(InstrumentationData.TestStatus.RESULT_CODE, resultCode);
+            writeBundle(proto, InstrumentationData.TestStatus.RESULTS, results);
+
+            proto.endRepeatedObject(token);
+            writeProtoToStdout(proto);
+        }
+
+        @Override
+        public void onInstrumentationFinishedLocked(ComponentName name, int resultCode,
+                Bundle results) {
+            final ProtoOutputStream proto = new ProtoOutputStream();
+
+            final long token = proto.startObject(InstrumentationData.Session.SESSION_STATUS);
+
+            proto.writeEnum(InstrumentationData.SessionStatus.STATUS_CODE,
+                    InstrumentationData.SESSION_FINISHED);
+            proto.writeSInt32(InstrumentationData.SessionStatus.RESULT_CODE, resultCode);
+            writeBundle(proto, InstrumentationData.SessionStatus.RESULTS, results);
+
+            proto.endObject(token);
+            writeProtoToStdout(proto);
+        }
+
+        @Override
+        public void onError(String errorText, boolean commandError) {
+            final ProtoOutputStream proto = new ProtoOutputStream();
+
+            final long token = proto.startObject(InstrumentationData.Session.SESSION_STATUS);
+
+            proto.writeEnum(InstrumentationData.SessionStatus.STATUS_CODE,
+                    InstrumentationData.SESSION_ABORTED);
+            proto.writeString(InstrumentationData.SessionStatus.ERROR_TEXT, errorText);
+
+            proto.endObject(token);
+            writeProtoToStdout(proto);
+        }
+
+        private void writeBundle(ProtoOutputStream proto, long fieldId, Bundle bundle) {
+            final long bundleToken = proto.startObject(fieldId);
+
+            for (final String key: bundle.keySet()) {
+                final long entryToken = proto.startRepeatedObject(
+                        InstrumentationData.ResultsBundle.ENTRIES);
+
+                proto.writeString(InstrumentationData.ResultsBundleEntry.KEY, key);
+
+                final Object val = bundle.get(key);
+                if (val instanceof String) {
+                    proto.writeString(InstrumentationData.ResultsBundleEntry.VALUE_STRING,
+                            (String)val);
+                } else if (val instanceof Byte) {
+                    proto.writeSInt32(InstrumentationData.ResultsBundleEntry.VALUE_INT,
+                            ((Byte)val).intValue());
+                } else if (val instanceof Double) {
+                    proto.writeDouble(InstrumentationData.ResultsBundleEntry.VALUE_DOUBLE,
+                            ((Double)val).doubleValue());
+                } else if (val instanceof Float) {
+                    proto.writeFloat(InstrumentationData.ResultsBundleEntry.VALUE_FLOAT,
+                            ((Float)val).floatValue());
+                } else if (val instanceof Integer) {
+                    proto.writeSInt32(InstrumentationData.ResultsBundleEntry.VALUE_INT,
+                            ((Integer)val).intValue());
+                } else if (val instanceof Long) {
+                    proto.writeSInt64(InstrumentationData.ResultsBundleEntry.VALUE_LONG,
+                            ((Long)val).longValue());
+                } else if (val instanceof Short) {
+                    proto.writeSInt32(InstrumentationData.ResultsBundleEntry.VALUE_INT,
+                            ((Short)val).intValue());
+                } else if (val instanceof Bundle) {
+                    writeBundle(proto, InstrumentationData.ResultsBundleEntry.VALUE_BUNDLE,
+                            (Bundle)val);
+                }
+
+                proto.endRepeatedObject(entryToken);
+            }
+
+            proto.endObject(bundleToken);
+        }
+
+        private void writeProtoToStdout(ProtoOutputStream proto) {
+            try {
+                System.out.write(proto.getBytes());
+                System.out.flush();
+            } catch (IOException ex) {
+                System.err.println("Error writing finished response: ");
+                ex.printStackTrace(System.err);
+            }
+        }
+    }
+
+
+    /**
+     * Callbacks from the remote instrumentation instance.
+     */
+    private class InstrumentationWatcher extends IInstrumentationWatcher.Stub {
+        private final StatusReporter mReporter;
+
+        private boolean mFinished = false;
+
+        public InstrumentationWatcher(StatusReporter reporter) {
+            mReporter = reporter;
+        }
+
+        @Override
+        public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) {
+            synchronized (this) {
+                mReporter.onInstrumentationStatusLocked(name, resultCode, results);
+                notifyAll();
+            }
+        }
+
+        @Override
+        public void instrumentationFinished(ComponentName name, int resultCode, Bundle results) {
+            synchronized (this) {
+                mReporter.onInstrumentationFinishedLocked(name, resultCode, results);
+                mFinished = true;
+                notifyAll();
+            }
+        }
+
+        public boolean waitForFinish() {
+            synchronized (this) {
+                while (!mFinished) {
+                    try {
+                        if (!mAm.asBinder().pingBinder()) {
+                            return false;
+                        }
+                        wait(1000);
+                    } catch (InterruptedException e) {
+                        throw new IllegalStateException(e);
+                    }
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Figure out which component they really meant.
+     */
+    private ComponentName parseComponentName(String cnArg) throws Exception {
+        if (cnArg.contains("/")) {
+            ComponentName cn = ComponentName.unflattenFromString(cnArg);
+            if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
+            return cn;
+        } else {
+            List<InstrumentationInfo> infos = mPm.queryInstrumentation(null, 0).getList();
+
+            final int numInfos = infos == null ? 0: infos.size();
+            ArrayList<ComponentName> cns = new ArrayList<>();
+            for (int i = 0; i < numInfos; i++) {
+                InstrumentationInfo info = infos.get(i);
+
+                ComponentName c = new ComponentName(info.packageName, info.name);
+                if (cnArg.equals(info.packageName)) {
+                    cns.add(c);
+                }
+            }
+
+            if (cns.size() == 0) {
+                throw new IllegalArgumentException("No instrumentation found for: " + cnArg);
+            } else if (cns.size() == 1) {
+                return cns.get(0);
+            } else {
+                StringBuilder cnsStr = new StringBuilder();
+                final int numCns = cns.size();
+                for (int i = 0; i < numCns; i++) {
+                    cnsStr.append(cns.get(i).flattenToString());
+                    cnsStr.append(", ");
+                }
+
+                // Remove last ", "
+                cnsStr.setLength(cnsStr.length() - 2);
+
+                throw new IllegalArgumentException("Found multiple instrumentations: "
+                        + cnsStr.toString());
+            }
+        }
+    }
+
+    /**
+     * Run the instrumentation.
+     */
+    public void run() throws Exception {
+        StatusReporter reporter = null;
+        float[] oldAnims = null;
+
+        try {
+            // Choose which output we will do.
+            if (proto) {
+                reporter = new ProtoStatusReporter();
+            } else if (wait) {
+                reporter = new TextStatusReporter(rawMode);
+            }
+
+            // Choose whether we have to wait for the results.
+            InstrumentationWatcher watcher = null;
+            UiAutomationConnection connection = null;
+            if (reporter != null) {
+                watcher = new InstrumentationWatcher(reporter);
+                connection = new UiAutomationConnection();
+            }
+
+            // Set the window animation if necessary
+            if (noWindowAnimation) {
+                oldAnims = mWm.getAnimationScales();
+                mWm.setAnimationScale(0, 0.0f);
+                mWm.setAnimationScale(1, 0.0f);
+            }
+
+            // Figure out which component we are tring to do.
+            final ComponentName cn = parseComponentName(componentNameArg);
+
+            // Choose an ABI if necessary
+            if (abi != null) {
+                final String[] supportedAbis = Build.SUPPORTED_ABIS;
+                boolean matched = false;
+                for (String supportedAbi : supportedAbis) {
+                    if (supportedAbi.equals(abi)) {
+                        matched = true;
+                        break;
+                    }
+                }
+                if (!matched) {
+                    throw new AndroidException(
+                            "INSTRUMENTATION_FAILED: Unsupported instruction set " + abi);
+                }
+            }
+
+            // Start the instrumentation
+            if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId,
+                        abi)) {
+                throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
+            }
+
+            // If we have been requested to wait, do so until the instrumentation is finished.
+            if (watcher != null) {
+                if (!watcher.waitForFinish()) {
+                    reporter.onError("INSTRUMENTATION_ABORTED: System has crashed.", false);
+                    return;
+                }
+            }
+        } catch (Exception ex) {
+            // Report failures
+            if (reporter != null) {
+                reporter.onError(ex.getMessage(), true);
+            }
+
+            // And re-throw the exception
+            throw ex;
+        } finally {
+            // Clean up
+            if (oldAnims != null) {
+                mWm.setAnimationScales(oldAnims);
+            }
+        }
+    }
+}
+
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 18ad43e..d5580ac 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -188,6 +188,16 @@
         LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
     }
 
+    if (!LOG_NDEBUG) {
+      String8 argv_String;
+      for (int i = 0; i < argc; ++i) {
+        argv_String.append("\"");
+        argv_String.append(argv[i]);
+        argv_String.append("\" ");
+      }
+      ALOGV("app_process main with argv: %s", argv_String.string());
+    }
+
     AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
     // Process command line arguments
     // ignore argv[0]
@@ -216,9 +226,31 @@
     //
     // Note that we must copy argument string values since we will rewrite the
     // entire argument block when we apply the nice name to argv0.
+    //
+    // As an exception to the above rule, anything in "spaced commands"
+    // goes to the vm even though it has a space in it.
+    const char* spaced_commands[] = { "-cp", "-classpath" };
+    // Allow "spaced commands" to be succeeded by exactly 1 argument (regardless of -s).
+    bool known_command = false;
 
     int i;
     for (i = 0; i < argc; i++) {
+        if (known_command == true) {
+          runtime.addOption(strdup(argv[i]));
+          ALOGV("app_process main add known option '%s'", argv[i]);
+          known_command = false;
+          continue;
+        }
+
+        for (int j = 0;
+             j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
+             ++j) {
+          if (strcmp(argv[i], spaced_commands[j]) == 0) {
+            known_command = true;
+            ALOGV("app_process main found known command '%s'", argv[i]);
+          }
+        }
+
         if (argv[i][0] != '-') {
             break;
         }
@@ -226,7 +258,9 @@
             ++i; // Skip --.
             break;
         }
+
         runtime.addOption(strdup(argv[i]));
+        ALOGV("app_process main add option '%s'", argv[i]);
     }
 
     // Parse runtime arguments.  Stop at first unrecognized option.
@@ -266,6 +300,18 @@
         // copies of them before we overwrite them with the process name.
         args.add(application ? String8("application") : String8("tool"));
         runtime.setClassNameAndArgs(className, argc - i, argv + i);
+
+        if (!LOG_NDEBUG) {
+          String8 restOfArgs;
+          char* const* argv_new = argv + i;
+          int argc_new = argc - i;
+          for (int k = 0; k < argc_new; ++k) {
+            restOfArgs.append("\"");
+            restOfArgs.append(argv_new[k]);
+            restOfArgs.append("\" ");
+          }
+          ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
+        }
     } else {
         // We're in zygote mode.
         maybeCreateDalvikCache();
diff --git a/cmds/idmap/inspect.cpp b/cmds/idmap/inspect.cpp
index f6afc85..154cb25 100644
--- a/cmds/idmap/inspect.cpp
+++ b/cmds/idmap/inspect.cpp
@@ -2,6 +2,7 @@
 
 #include <androidfw/AssetManager.h>
 #include <androidfw/ResourceTypes.h>
+#include <utils/ByteOrder.h>
 #include <utils/String8.h>
 
 #include <fcntl.h>
diff --git a/cmds/webview_zygote/Android.mk b/cmds/webview_zygote/Android.mk
new file mode 100644
index 0000000..66e762c
--- /dev/null
+++ b/cmds/webview_zygote/Android.mk
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2016 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := webview_zygote
+
+LOCAL_SRC_FILES := webview_zygote.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libandroid_runtime \
+	libbinder \
+	liblog \
+	libcutils \
+	libutils
+
+LOCAL_LDFLAGS_32 := -Wl,--version-script,art/sigchainlib/version-script32.txt -Wl,--export-dynamic
+LOCAL_LDFLAGS_64 := -Wl,--version-script,art/sigchainlib/version-script64.txt -Wl,--export-dynamic
+
+LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
+
+LOCAL_INIT_RC := webview_zygote32.rc
+
+# Always include the 32-bit version of webview_zygote. If the target is 64-bit,
+# also include the 64-bit webview_zygote.
+ifeq ($(TARGET_SUPPORTS_64_BIT_APPS),true)
+	LOCAL_INIT_RC += webview_zygote64.rc
+endif
+
+LOCAL_MULTILIB := both
+
+LOCAL_MODULE_STEM_32 := webview_zygote32
+LOCAL_MODULE_STEM_64 := webview_zygote64
+
+include $(BUILD_EXECUTABLE)
diff --git a/cmds/webview_zygote/webview_zygote.cpp b/cmds/webview_zygote/webview_zygote.cpp
new file mode 100644
index 0000000..88fee64
--- /dev/null
+++ b/cmds/webview_zygote/webview_zygote.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#define LOG_TAG "WebViewZygote"
+
+#include <sys/prctl.h>
+
+#include <android_runtime/AndroidRuntime.h>
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class WebViewRuntime : public AndroidRuntime {
+public:
+    WebViewRuntime(char* argBlockStart, size_t argBlockSize)
+        : AndroidRuntime(argBlockStart, argBlockSize) {}
+
+    ~WebViewRuntime() override {}
+
+    void onStarted() override {
+        // Nothing to do since this is a zygote server.
+    }
+
+    void onVmCreated(JNIEnv*) override {
+        // Nothing to do when the VM is created in the zygote.
+    }
+
+    void onZygoteInit() override {
+        // Called after a new process is forked.
+        sp<ProcessState> proc = ProcessState::self();
+        proc->startThreadPool();
+    }
+
+    void onExit(int code) override {
+        IPCThreadState::self()->stopProcess();
+        AndroidRuntime::onExit(code);
+    }
+};
+
+}  // namespace android
+
+int main(int argc, char* const argv[]) {
+    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
+        LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
+        return 12;
+    }
+
+    size_t argBlockSize = 0;
+    for (int i = 0; i < argc; ++i) {
+        argBlockSize += strlen(argv[i]) + 1;
+    }
+
+    android::WebViewRuntime runtime(argv[0], argBlockSize);
+    runtime.addOption("-Xzygote");
+
+    android::Vector<android::String8> args;
+    runtime.start("com.android.internal.os.WebViewZygoteInit", args, /*zygote=*/ true);
+}
diff --git a/cmds/webview_zygote/webview_zygote32.rc b/cmds/webview_zygote/webview_zygote32.rc
new file mode 100644
index 0000000..b7decc8
--- /dev/null
+++ b/cmds/webview_zygote/webview_zygote32.rc
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2016 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.
+#
+
+service webview_zygote32 /system/bin/webview_zygote32
+    user webview_zygote
+    socket webview_zygote stream 660 webview_zygote system
+
+on property:init.svc.zygote=stopped
+    stop webview_zygote32
diff --git a/cmds/webview_zygote/webview_zygote64.rc b/cmds/webview_zygote/webview_zygote64.rc
new file mode 100644
index 0000000..2935b28
--- /dev/null
+++ b/cmds/webview_zygote/webview_zygote64.rc
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2016 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.
+#
+
+service webview_zygote64 /system/bin/webview_zygote64
+    user webview_zygote
+    socket webview_zygote stream 660 webview_zygote system
+
+on property:init.svc.zygote=stopped
+    stop webview_zygote64
diff --git a/compiled-classes-phone b/compiled-classes-phone
index 6214306..661ff95 100644
--- a/compiled-classes-phone
+++ b/compiled-classes-phone
@@ -237,7 +237,6 @@
 android.app.ApplicationPackageManager$MoveCallbackDelegate
 android.app.ApplicationPackageManager$OnPermissionsChangeListenerDelegate
 android.app.ApplicationPackageManager$ResourceName
-android.app.ApplicationThreadNative
 android.app.ApplicationThreadProxy
 android.app.AutomaticZenRule
 android.app.BackStackRecord
@@ -313,6 +312,8 @@
 android.app.IAppTask$Stub
 android.app.IAppTask$Stub$Proxy
 android.app.IApplicationThread
+android.app.IApplicationThread$Stub
+android.app.IApplicationThread$Stub$Proxy
 android.app.IInstrumentationWatcher
 android.app.IInstrumentationWatcher$Stub
 android.app.INotificationManager
diff --git a/core/java/android/app/ActivityManager.aidl b/core/java/android/app/ActivityManager.aidl
index 92350da..fa6481b 100644
--- a/core/java/android/app/ActivityManager.aidl
+++ b/core/java/android/app/ActivityManager.aidl
@@ -17,3 +17,4 @@
 package android.app;
 
 parcelable ActivityManager.RecentTaskInfo;
+parcelable ActivityManager.TaskDescription;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 0d9be5f..4066f1c 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -3045,6 +3045,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
     public int getPackageImportance(String packageName) {
         try {
             int procState = ActivityManagerNative.getDefault().getPackageProcessState(packageName,
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 112b614b..623a11d 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -964,6 +964,14 @@
             return true;
         }
 
+        case UNREGISTER_TASK_STACK_LISTENER_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            unregisterTaskStackListener(ITaskStackListener.Stub.asInterface(token));
+            reply.writeNoException();
+            return true;
+        }
+
         case GET_TASK_FOR_ACTIVITY_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -1235,6 +1243,16 @@
             return true;
         }
 
+        case UPDATE_DISPLAY_OVERRIDE_CONFIGURATION_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final Configuration config = Configuration.CREATOR.createFromParcel(data);
+            final int displayId = data.readInt();
+            final boolean updated = updateDisplayOverrideConfiguration(config, displayId);
+            reply.writeNoException();
+            reply.writeInt(updated ? 1 : 0);
+            return true;
+        }
+
         case SET_REQUESTED_ORIENTATION_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -2547,15 +2565,6 @@
             return true;
         }
 
-        case DELETE_ACTIVITY_CONTAINER_TRANSACTION:  {
-            data.enforceInterface(IActivityManager.descriptor);
-            IActivityContainer activityContainer =
-                    IActivityContainer.Stub.asInterface(data.readStrongBinder());
-            deleteActivityContainer(activityContainer);
-            reply.writeNoException();
-            return true;
-        }
-
         case CREATE_STACK_ON_DISPLAY: {
             data.enforceInterface(IActivityManager.descriptor);
             int displayId = data.readInt();
@@ -4191,6 +4200,18 @@
         data.recycle();
         reply.recycle();
     }
+    @Override
+    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(listener.asBinder());
+        mRemote.transact(UNREGISTER_TASK_STACK_LISTENER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
     public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -4594,8 +4615,7 @@
         data.recycle();
         return res;
     }
-    public boolean updateConfiguration(Configuration values) throws RemoteException
-    {
+    public boolean updateConfiguration(Configuration values) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -4607,6 +4627,20 @@
         reply.recycle();
         return updated;
     }
+    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        values.writeToParcel(data, 0);
+        data.writeInt(displayId);
+        mRemote.transact(UPDATE_DISPLAY_OVERRIDE_CONFIGURATION_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean updated = reply.readInt() == 1;
+        data.recycle();
+        reply.recycle();
+        return updated;
+    }
     public void setRequestedOrientation(IBinder token, int requestedOrientation)
             throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -6359,18 +6393,6 @@
         return res;
     }
 
-    public void deleteActivityContainer(IActivityContainer activityContainer)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(activityContainer.asBinder());
-        mRemote.transact(DELETE_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
     public boolean startBinderTracking() throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index fbbfec3..e9a200f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -978,6 +978,10 @@
             sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/);
         }
 
+        public void attachAgent(String agent) {
+            sendMessage(H.ATTACH_AGENT, agent);
+        }
+
         public void setSchedulingGroup(int group) {
             // Note: do this immediately, since going into the foreground
             // should happen regardless of what pending work we have to do
@@ -1429,6 +1433,7 @@
         public static final int MULTI_WINDOW_MODE_CHANGED = 152;
         public static final int PICTURE_IN_PICTURE_MODE_CHANGED = 153;
         public static final int LOCAL_VOICE_INTERACTION_STARTED = 154;
+        public static final int ATTACH_AGENT = 155;
 
         String codeToString(int code) {
             if (DEBUG_MESSAGES) {
@@ -1485,6 +1490,7 @@
                     case MULTI_WINDOW_MODE_CHANGED: return "MULTI_WINDOW_MODE_CHANGED";
                     case PICTURE_IN_PICTURE_MODE_CHANGED: return "PICTURE_IN_PICTURE_MODE_CHANGED";
                     case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED";
+                    case ATTACH_AGENT: return "ATTACH_AGENT";
                 }
             }
             return Integer.toString(code);
@@ -1739,6 +1745,8 @@
                 case LOCAL_VOICE_INTERACTION_STARTED:
                     handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
                             (IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
+                case ATTACH_AGENT:
+                    handleAttachAgent((String) msg.obj);
                     break;
             }
             Object obj = msg.obj;
@@ -3008,6 +3016,14 @@
         }
     }
 
+    static final void handleAttachAgent(String agent) {
+        try {
+            VMDebug.attachAgent(agent);
+        } catch (IOException e) {
+            Slog.e(TAG, "Attaching agent failed: " + agent);
+        }
+    }
+
     private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
 
     /**
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 6458d6f..ec21882 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -206,6 +206,7 @@
     private ArrayList<Matrix> mSharedElementParentMatrices;
     private boolean mSharedElementTransitionComplete;
     private boolean mViewsTransitionComplete;
+    private ArrayList<View> mStrippedTransitioningViews = new ArrayList<>();
 
     public ActivityTransitionCoordinator(Window window,
             ArrayList<String> allSharedElementNames,
@@ -287,7 +288,7 @@
             View view = mTransitioningViews.get(i);
             if (!view.getGlobalVisibleRect(r)) {
                 mTransitioningViews.remove(i);
-                showView(view, true);
+                mStrippedTransitioningViews.add(view);
             }
         }
     }
@@ -360,6 +361,12 @@
                 }
             }
         }
+        if (mStrippedTransitioningViews != null) {
+            for (int i = mStrippedTransitioningViews.size() - 1; i >= 0; i--) {
+                View view = mStrippedTransitioningViews.get(i);
+                set.excludeTarget(view, true);
+            }
+        }
         // By adding the transition after addTarget, we prevent addTarget from
         // affecting transition.
         set.addTransition(transition);
@@ -679,6 +686,7 @@
         mWindow = null;
         mSharedElements.clear();
         mTransitioningViews = null;
+        mStrippedTransitioningViews = null;
         mOriginalAlphas.clear();
         mResultReceiver = null;
         mPendingTransition = null;
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index a4b1a1f..cf794c5 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -16,21 +16,13 @@
 
 package android.app;
 
-import android.graphics.Rect;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
-import android.transition.Transition;
-import android.transition.TransitionManager;
-import android.transition.TransitionSet;
-import android.util.ArrayMap;
 import android.util.Log;
 import android.util.LogWriter;
-import android.util.SparseArray;
 import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
 
 import com.android.internal.util.FastPrintWriter;
 
@@ -38,7 +30,6 @@
 import java.io.PrintWriter;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
-import java.util.List;
 
 final class BackStackState implements Parcelable {
     final int[] mOps;
@@ -52,6 +43,7 @@
     final CharSequence mBreadCrumbShortTitleText;
     final ArrayList<String> mSharedElementSourceNames;
     final ArrayList<String> mSharedElementTargetNames;
+    final boolean mAllowOptimization;
 
     public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
         final int numOps = bse.mOps.size();
@@ -81,6 +73,7 @@
         mBreadCrumbShortTitleText = bse.mBreadCrumbShortTitleText;
         mSharedElementSourceNames = bse.mSharedElementSourceNames;
         mSharedElementTargetNames = bse.mSharedElementTargetNames;
+        mAllowOptimization = bse.mAllowOptimization;
     }
 
     public BackStackState(Parcel in) {
@@ -95,6 +88,7 @@
         mBreadCrumbShortTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mSharedElementSourceNames = in.createStringArrayList();
         mSharedElementTargetNames = in.createStringArrayList();
+        mAllowOptimization = in.readInt() != 0;
     }
 
     public BackStackRecord instantiate(FragmentManagerImpl fm) {
@@ -137,6 +131,7 @@
         bse.mBreadCrumbShortTitleText = mBreadCrumbShortTitleText;
         bse.mSharedElementSourceNames = mSharedElementSourceNames;
         bse.mSharedElementTargetNames = mSharedElementTargetNames;
+        bse.mAllowOptimization = mAllowOptimization;
         bse.bumpBackStackNesting(1);
         return bse;
     }
@@ -157,6 +152,7 @@
         TextUtils.writeToParcel(mBreadCrumbShortTitleText, dest, 0);
         dest.writeStringList(mSharedElementSourceNames);
         dest.writeStringList(mSharedElementTargetNames);
+        dest.writeInt(mAllowOptimization ? 1 : 0);
     }
 
     public static final Parcelable.Creator<BackStackState> CREATOR
@@ -175,7 +171,7 @@
  * @hide Entry of an operation on the fragment back stack.
  */
 final class BackStackRecord extends FragmentTransaction implements
-        FragmentManager.BackStackEntry, Runnable {
+        FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
     static final String TAG = FragmentManagerImpl.TAG;
 
     final FragmentManagerImpl mManager;
@@ -210,6 +206,7 @@
     String mName;
     boolean mCommitted;
     int mIndex = -1;
+    boolean mAllowOptimization;
 
     int mBreadCrumbTitleRes;
     CharSequence mBreadCrumbTitleText;
@@ -352,6 +349,7 @@
 
     public BackStackRecord(FragmentManagerImpl manager) {
         mManager = manager;
+        mAllowOptimization = Build.isAtLeastO();
     }
 
     public int getId() {
@@ -633,6 +631,12 @@
         mManager.execSingleAction(this, true);
     }
 
+    @Override
+    public FragmentTransaction setAllowOptimization(boolean allowOptimization) {
+        mAllowOptimization = allowOptimization;
+        return this;
+    }
+
     int commitInternal(boolean allowStateLoss) {
         if (mCommitted) {
             throw new IllegalStateException("commit already called");
@@ -654,94 +658,177 @@
         return mIndex;
     }
 
-    public void run() {
+    /**
+     * Implementation of {@link android.app.FragmentManagerImpl.OpGenerator}.
+     * This operation is added to the list of pending actions during {@link #commit()}, and
+     * will be executed on the UI thread to run this FragmentTransaction.
+     *
+     * @param records Modified to add this BackStackRecord
+     * @param isRecordPop Modified to add a false (this isn't a pop)
+     * @return true always because the records and isRecordPop will always be changed
+     */
+    @Override
+    public boolean generateOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop) {
         if (FragmentManagerImpl.DEBUG) {
             Log.v(TAG, "Run: " + this);
         }
 
+        records.add(this);
+        isRecordPop.add(false);
         if (mAddToBackStack) {
-            if (mIndex < 0) {
-                throw new IllegalStateException("addToBackStack() called after commit()");
-            }
+            mManager.addBackStackState(this);
         }
+        return true;
+    }
 
-        expandReplaceOps();
-        bumpBackStackNesting(1);
-
-        if (mManager.mCurState >= Fragment.CREATED) {
-            SparseArray<FragmentContainerTransition> transitioningFragments = new SparseArray<>();
-            calculateFragments(transitioningFragments);
-            beginTransition(transitioningFragments);
-        }
-
+    boolean interactsWith(int containerId) {
         final int numOps = mOps.size();
         for (int opNum = 0; opNum < numOps; opNum++) {
             final Op op = mOps.get(opNum);
-            Fragment f = op.fragment;
+            if (op.fragment.mContainerId == containerId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean interactsWith(ArrayList<BackStackRecord> records, int startIndex, int endIndex) {
+        if (endIndex == startIndex) {
+            return false;
+        }
+        final int numOps = mOps.size();
+        int lastContainer = -1;
+        for (int opNum = 0; opNum < numOps; opNum++) {
+            final Op op = mOps.get(opNum);
+            final int container = op.fragment.mContainerId;
+            if (container != 0 && container != lastContainer) {
+                lastContainer = container;
+                for (int i = startIndex; i < endIndex; i++) {
+                    BackStackRecord record = records.get(i);
+                    final int numThoseOps = record.mOps.size();
+                    for (int thoseOpIndex = 0; thoseOpIndex < numThoseOps; thoseOpIndex++) {
+                        final Op thatOp = record.mOps.get(thoseOpIndex);
+                        if (thatOp.fragment.mContainerId == container) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Executes the operations contained within this transaction. The Fragment states will only
+     * be modified if optimizations are not allowed.
+     */
+    void executeOps() {
+        final int numOps = mOps.size();
+        for (int opNum = 0; opNum < numOps; opNum++) {
+            final Op op = mOps.get(opNum);
+            final Fragment f = op.fragment;
+            f.setNextTransition(mTransition, mTransitionStyle);
             switch (op.cmd) {
                 case OP_ADD:
-                    f.mNextAnim = op.enterAnim;
+                    f.setNextAnim(op.enterAnim);
                     mManager.addFragment(f, false);
                     break;
                 case OP_REMOVE:
-                    f.mNextAnim = op.exitAnim;
-                    mManager.removeFragment(f, mTransition, mTransitionStyle);
+                    f.setNextAnim(op.exitAnim);
+                    mManager.removeFragment(f);
                     break;
                 case OP_HIDE:
-                    f.mNextAnim = op.exitAnim;
-                    mManager.hideFragment(f, mTransition, mTransitionStyle);
+                    f.setNextAnim(op.exitAnim);
+                    mManager.hideFragment(f);
                     break;
                 case OP_SHOW:
-                    f.mNextAnim = op.enterAnim;
-                    mManager.showFragment(f, mTransition, mTransitionStyle);
+                    f.setNextAnim(op.enterAnim);
+                    mManager.showFragment(f);
                     break;
                 case OP_DETACH:
-                    f.mNextAnim = op.exitAnim;
-                    mManager.detachFragment(f, mTransition, mTransitionStyle);
+                    f.setNextAnim(op.exitAnim);
+                    mManager.detachFragment(f);
                     break;
                 case OP_ATTACH:
-                    f.mNextAnim = op.enterAnim;
-                    mManager.attachFragment(f, mTransition, mTransitionStyle);
+                    f.setNextAnim(op.enterAnim);
+                    mManager.attachFragment(f);
                     break;
                 default:
                     throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
             }
+            if (!mAllowOptimization && op.cmd != OP_ADD) {
+                mManager.moveFragmentToExpectedState(f);
+            }
         }
-
-        mManager.moveToState(mManager.mCurState, mTransition,
-                mTransitionStyle, true);
-
-        if (mAddToBackStack) {
-            mManager.addBackStackState(this);
+        if (!mAllowOptimization) {
+            // Added fragments are added at the end to comply with prior behavior.
+            mManager.moveToState(mManager.mCurState);
         }
     }
 
-    private void expandReplaceOps() {
-        final int numOps = mOps.size();
-
-        boolean hasReplace = false;
-        // Before we do anything, check to see if any replace operations exist:
-        for (int opNum = 0; opNum < numOps; opNum++) {
+    /**
+     * Reverses the execution of the operations within this transaction. The Fragment states will
+     * only be modified if optimizations are not allowed.
+     */
+    void executePopOps() {
+        for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
             final Op op = mOps.get(opNum);
-            if (op.cmd == OP_REPLACE) {
-                hasReplace = true;
-                break;
+            Fragment f = op.fragment;
+            f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
+            switch (op.cmd) {
+                case OP_ADD:
+                    f.setNextAnim(op.popExitAnim);
+                    mManager.removeFragment(f);
+                    break;
+                case OP_REMOVE:
+                    f.setNextAnim(op.popEnterAnim);
+                    mManager.addFragment(f, false);
+                    break;
+                case OP_HIDE:
+                    f.setNextAnim(op.popEnterAnim);
+                    mManager.showFragment(f);
+                    break;
+                case OP_SHOW:
+                    f.setNextAnim(op.popExitAnim);
+                    mManager.hideFragment(f);
+                    break;
+                case OP_DETACH:
+                    f.setNextAnim(op.popEnterAnim);
+                    mManager.attachFragment(f);
+                    break;
+                case OP_ATTACH:
+                    f.setNextAnim(op.popExitAnim);
+                    mManager.detachFragment(f);
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
+            }
+            if (!mAllowOptimization && op.cmd != OP_ADD) {
+                mManager.moveFragmentToExpectedState(f);
             }
         }
-
-        if (!hasReplace) {
-            return; // nothing to expand
+        if (!mAllowOptimization) {
+            mManager.moveToState(mManager.mCurState);
         }
+    }
 
-        ArrayList<Fragment> added = (mManager.mAdded == null) ? new ArrayList<Fragment>() :
-                new ArrayList<>(mManager.mAdded);
+    /**
+     * Removes all OP_REPLACE ops and replaces them with the proper add and remove
+     * operations that are equivalent to the replace. This must be called prior to
+     * {@link #executeOps()} or any other call that operations on mOps.
+     *
+     * @param added Initialized to the fragments that are in the mManager.mAdded, this
+     *              will be modified to contain the fragments that will be in mAdded
+     *              after the execution ({@link #executeOps()}.
+     */
+    void expandReplaceOps(ArrayList<Fragment> added) {
         for (int opNum = 0; opNum < mOps.size(); opNum++) {
             final Op op = mOps.get(opNum);
             switch (op.cmd) {
                 case OP_ADD:
                 case OP_ATTACH:
                     added.add(op.fragment);
-                break;
+                    break;
                 case OP_REMOVE:
                 case OP_DETACH:
                     added.remove(op.fragment);
@@ -782,920 +869,29 @@
         }
     }
 
-    private static void setFirstOut(SparseArray<FragmentContainerTransition> transitioningFragments,
-                            Fragment fragment, boolean isPop) {
-        if (fragment != null) {
-            int containerId = fragment.mContainerId;
-            if (containerId != 0 && !fragment.isHidden()) {
-                FragmentContainerTransition fragments = transitioningFragments.get(containerId);
-                if (fragment.isAdded() && fragment.getView() != null && (fragments == null ||
-                        fragments.firstOut == null)) {
-                    if (fragments == null) {
-                        fragments = new FragmentContainerTransition();
-                        transitioningFragments.put(containerId, fragments);
-                    }
-                    fragments.firstOut = fragment;
-                    fragments.firstOutIsPop = isPop;
-                }
-                if (fragments != null && fragments.lastIn == fragment) {
-                    fragments.lastIn = null;
-                }
-            }
-        }
-    }
-
-    private void setLastIn(SparseArray<FragmentContainerTransition> transitioningFragments,
-            Fragment fragment, boolean isPop) {
-        if (fragment != null) {
-            int containerId = fragment.mContainerId;
-            if (containerId != 0) {
-                FragmentContainerTransition fragments = transitioningFragments.get(containerId);
-                if (!fragment.isAdded()) {
-                    if (fragments == null) {
-                        fragments = new FragmentContainerTransition();
-                        transitioningFragments.put(containerId, fragments);
-                    }
-                    fragments.lastIn = fragment;
-                    fragments.lastInIsPop = isPop;
-                }
-                if (fragments != null && fragments.firstOut == fragment) {
-                    fragments.firstOut = null;
-                }
-            }
-            /**
-             * Ensure that fragments that are entering are at least at the CREATED state
-             * so that they may load Transitions using TransitionInflater.
-             */
-            if (fragment.mState < Fragment.CREATED && mManager.mCurState >= Fragment.CREATED &&
-                    mManager.mHost.getContext().getApplicationInfo().targetSdkVersion >=
-                    Build.VERSION_CODES.N) {
-                mManager.makeActive(fragment);
-                mManager.moveToState(fragment, Fragment.CREATED, 0, 0, false);
-            }
-        }
-    }
-
-    /**
-     * Finds the first removed fragment and last added fragments when going forward.
-     * If none of the fragments have transitions, then both lists will be empty.
-     *
-     * @param transitioningFragments Keyed on the container ID, the first fragments to be removed,
-     *                               and last fragments to be added. This will be modified by
-     *                               this method.
-     */
-    private void calculateFragments(
-            SparseArray<FragmentContainerTransition> transitioningFragments) {
-        if (!mManager.mContainer.onHasView()) {
-            return; // nothing to see, so no transitions
-        }
-        final int numOps = mOps.size();
-        for (int opNum = 0; opNum < numOps; opNum++) {
+    boolean isPostponed() {
+        for (int opNum = 0; opNum < mOps.size(); opNum++) {
             final Op op = mOps.get(opNum);
-            switch (op.cmd) {
-                case OP_ADD:
-                case OP_SHOW:
-                case OP_ATTACH:
-                    setLastIn(transitioningFragments, op.fragment, false);
-                    break;
-                case OP_REMOVE:
-                case OP_HIDE:
-                case OP_DETACH:
-                    setFirstOut(transitioningFragments, op.fragment, false);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Finds the first removed fragment and last added fragments when popping the back stack.
-     * If none of the fragments have transitions, then both lists will be empty.
-     *
-     * @param transitioningFragments Keyed on the container ID, the first fragments to be removed,
-     *                               and last fragments to be added. This will be modified by
-     *                               this method.
-     */
-    public void calculateBackFragments(
-            SparseArray<FragmentContainerTransition> transitioningFragments) {
-        if (!mManager.mContainer.onHasView()) {
-            return; // nothing to see, so no transitions
-        }
-        final int numOps = mOps.size();
-        for (int opNum = numOps - 1; opNum >= 0; opNum--) {
-            final Op op = mOps.get(opNum);
-            switch (op.cmd) {
-                case OP_ADD:
-                case OP_SHOW:
-                case OP_ATTACH:
-                    setFirstOut(transitioningFragments, op.fragment, true);
-                    break;
-                case OP_REMOVE:
-                case OP_HIDE:
-                case OP_DETACH:
-                    setLastIn(transitioningFragments, op.fragment, true);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * When custom fragment transitions are used, this sets up the state for each transition
-     * and begins the transition. A different transition is started for each fragment container
-     * and consists of up to 3 different transitions: the exit transition, a shared element
-     * transition and an enter transition.
-     *
-     * <p>The exit transition operates against the leaf nodes of the first fragment
-     * with a view that was removed. If no such fragment was removed, then no exit
-     * transition is executed. The exit transition comes from the outgoing fragment.</p>
-     *
-     * <p>The enter transition operates against the last fragment that was added. If
-     * that fragment does not have a view or no fragment was added, then no enter
-     * transition is executed. The enter transition comes from the incoming fragment.</p>
-     *
-     * <p>The shared element transition operates against all views and comes either
-     * from the outgoing fragment or the incoming fragment, depending on whether this
-     * is going forward or popping the back stack. When going forward, the incoming
-     * fragment's enter shared element transition is used, but when going back, the
-     * outgoing fragment's return shared element transition is used. Shared element
-     * transitions only operate if there is both an incoming and outgoing fragment.</p>
-     *
-     * @param containers The first in and last out fragments that are transitioning.
-     * @return The TransitionState used to complete the operation of the transition
-     * in {@link #setNameOverrides(android.app.BackStackRecord.TransitionState, java.util.ArrayList,
-     * java.util.ArrayList)}.
-     */
-    private TransitionState beginTransition(SparseArray<FragmentContainerTransition> containers) {
-        TransitionState state = new TransitionState();
-
-        // Adding a non-existent target view makes sure that the transitions don't target
-        // any views by default. They'll only target the views we tell add. If we don't
-        // add any, then no views will be targeted.
-        state.nonExistentView = new View(mManager.mHost.getContext());
-
-        final int numContainers = containers.size();
-        for (int i = 0; i < numContainers; i++) {
-            int containerId = containers.keyAt(i);
-            FragmentContainerTransition containerTransition = containers.valueAt(i);
-            configureTransitions(containerId, state, containerTransition);
-        }
-        return state;
-    }
-
-    private static Transition cloneTransition(Transition transition) {
-        if (transition != null) {
-            transition = transition.clone();
-        }
-        return transition;
-    }
-
-    private static Transition getEnterTransition(Fragment inFragment, boolean isBack) {
-        if (inFragment == null) {
-            return null;
-        }
-        return cloneTransition(isBack ? inFragment.getReenterTransition() :
-                inFragment.getEnterTransition());
-    }
-
-    private static Transition getExitTransition(Fragment outFragment, boolean isBack) {
-        if (outFragment == null) {
-            return null;
-        }
-        return cloneTransition(isBack ? outFragment.getReturnTransition() :
-                outFragment.getExitTransition());
-    }
-
-    private static TransitionSet getSharedElementTransition(Fragment inFragment,
-            Fragment outFragment, boolean isBack) {
-        if (inFragment == null || outFragment == null) {
-            return null;
-        }
-        Transition transition = cloneTransition(isBack
-                ? outFragment.getSharedElementReturnTransition()
-                : inFragment.getSharedElementEnterTransition());
-        if (transition == null) {
-            return null;
-        }
-        TransitionSet transitionSet = new TransitionSet();
-        transitionSet.addTransition(transition);
-        return transitionSet;
-    }
-
-    private static ArrayList<View> captureExitingViews(Transition exitTransition,
-            Fragment outFragment, ArrayMap<String, View> namedViews, View nonExistentView) {
-        ArrayList<View> viewList = null;
-        if (exitTransition != null) {
-            viewList = new ArrayList<View>();
-            View root = outFragment.getView();
-            root.captureTransitioningViews(viewList);
-            if (namedViews != null) {
-                viewList.removeAll(namedViews.values());
-            }
-            if (!viewList.isEmpty()) {
-                viewList.add(nonExistentView);
-                addTargets(exitTransition, viewList);
-            }
-        }
-        return viewList;
-    }
-
-    private ArrayMap<String, View> remapSharedElements(TransitionState state, Fragment outFragment,
-            boolean isBack) {
-        ArrayMap<String, View> namedViews = new ArrayMap<String, View>();
-        if (mSharedElementSourceNames != null) {
-            outFragment.getView().findNamedViews(namedViews);
-            if (isBack) {
-                namedViews.retainAll(mSharedElementTargetNames);
-            } else {
-                namedViews = remapNames(mSharedElementSourceNames, mSharedElementTargetNames,
-                        namedViews);
-            }
-        }
-
-        if (isBack) {
-            outFragment.mEnterTransitionCallback.onMapSharedElements(
-                    mSharedElementTargetNames, namedViews);
-            setBackNameOverrides(state, namedViews, false);
-        } else {
-            outFragment.mExitTransitionCallback.onMapSharedElements(
-                    mSharedElementTargetNames, namedViews);
-            setNameOverrides(state, namedViews, false);
-        }
-
-        return namedViews;
-    }
-
-    /**
-     * Prepares the enter transition by adding a non-existent view to the transition's target list
-     * and setting it epicenter callback. By adding a non-existent view to the target list,
-     * we can prevent any view from being targeted at the beginning of the transition.
-     * We will add to the views before the end state of the transition is captured so that the
-     * views will appear. At the start of the transition, we clear the list of targets so that
-     * we can restore the state of the transition and use it again.
-     *
-     * <p>The shared element transition maps its shared elements immediately prior to
-     * capturing the final state of the Transition.</p>
-     */
-    private ArrayList<View> addTransitionTargets(final TransitionState state,
-            final Transition enterTransition, final TransitionSet sharedElementTransition,
-            final Transition exitTransition, final Transition overallTransition,
-            final View container, final Fragment inFragment, final Fragment outFragment,
-            final ArrayList<View> hiddenFragmentViews, final boolean isBack,
-            final ArrayList<View> sharedElementTargets) {
-        if (enterTransition == null && sharedElementTransition == null &&
-                overallTransition == null) {
-            return null;
-        }
-        final ArrayList<View> enteringViews = new ArrayList<View>();
-        container.getViewTreeObserver().addOnPreDrawListener(
-                new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        container.getViewTreeObserver().removeOnPreDrawListener(this);
-
-                        // Don't include any newly-hidden fragments in the transition.
-                        if (inFragment != null) {
-                            excludeHiddenFragments(hiddenFragmentViews, inFragment.mContainerId,
-                                    overallTransition);
-                        }
-
-                        ArrayMap<String, View> namedViews = null;
-                        if (sharedElementTransition != null) {
-                            namedViews = mapSharedElementsIn(state, isBack, inFragment);
-                            removeTargets(sharedElementTransition, sharedElementTargets);
-                            // keep the nonExistentView as excluded so the list doesn't get emptied
-                            sharedElementTargets.remove(state.nonExistentView);
-                            excludeViews(exitTransition, sharedElementTransition,
-                                    sharedElementTargets, false);
-                            excludeViews(enterTransition, sharedElementTransition,
-                                    sharedElementTargets, false);
-
-                            setSharedElementTargets(sharedElementTransition,
-                                    state.nonExistentView, namedViews, sharedElementTargets);
-
-                            setEpicenterIn(namedViews, state);
-
-                            callSharedElementEnd(state, inFragment, outFragment, isBack,
-                                    namedViews);
-                        }
-
-                        if (enterTransition != null) {
-                            enterTransition.removeTarget(state.nonExistentView);
-                            View view = inFragment.getView();
-                            if (view != null) {
-                                view.captureTransitioningViews(enteringViews);
-                                if (namedViews != null) {
-                                    enteringViews.removeAll(namedViews.values());
-                                }
-                                enteringViews.add(state.nonExistentView);
-                                // We added this earlier to prevent any views being targeted.
-                                addTargets(enterTransition, enteringViews);
-                            }
-                            setSharedElementEpicenter(enterTransition, state);
-                        }
-
-                        excludeViews(exitTransition, enterTransition, enteringViews, true);
-                        excludeViews(exitTransition, sharedElementTransition, sharedElementTargets,
-                                true);
-                        excludeViews(enterTransition, sharedElementTransition, sharedElementTargets,
-                                true);
-                        return true;
-                    }
-                });
-        return enteringViews;
-    }
-
-    private void callSharedElementEnd(TransitionState state, Fragment inFragment,
-            Fragment outFragment, boolean isBack, ArrayMap<String, View> namedViews) {
-        SharedElementCallback sharedElementCallback = isBack ?
-                outFragment.mEnterTransitionCallback :
-                inFragment.mEnterTransitionCallback;
-        ArrayList<String> names = new ArrayList<String>(namedViews.keySet());
-        ArrayList<View> views = new ArrayList<View>(namedViews.values());
-        sharedElementCallback.onSharedElementEnd(names, views, null);
-    }
-
-    private void setEpicenterIn(ArrayMap<String, View> namedViews, TransitionState state) {
-        if (mSharedElementTargetNames != null && !namedViews.isEmpty()) {
-            // now we know the epicenter of the entering transition.
-            View epicenter = namedViews
-                    .get(mSharedElementTargetNames.get(0));
-            if (epicenter != null) {
-                state.enteringEpicenterView = epicenter;
-            }
-        }
-    }
-
-    private ArrayMap<String, View> mapSharedElementsIn(TransitionState state,
-            boolean isBack, Fragment inFragment) {
-        // Now map the shared elements in the incoming fragment
-        ArrayMap<String, View> namedViews = mapEnteringSharedElements(state, inFragment, isBack);
-
-        // remap shared elements and set the name mapping used
-        // in the shared element transition.
-        if (isBack) {
-            inFragment.mExitTransitionCallback.onMapSharedElements(
-                    mSharedElementTargetNames, namedViews);
-            setBackNameOverrides(state, namedViews, true);
-        } else {
-            inFragment.mEnterTransitionCallback.onMapSharedElements(
-                    mSharedElementTargetNames, namedViews);
-            setNameOverrides(state, namedViews, true);
-        }
-        return namedViews;
-    }
-
-    private static Transition mergeTransitions(Transition enterTransition,
-            Transition exitTransition, Transition sharedElementTransition, Fragment inFragment,
-            boolean isBack) {
-        boolean overlap = true;
-        if (enterTransition != null && exitTransition != null && inFragment != null) {
-            overlap = isBack ? inFragment.getAllowReturnTransitionOverlap() :
-                    inFragment.getAllowEnterTransitionOverlap();
-        }
-
-        // Wrap the transitions. Explicit targets like in enter and exit will cause the
-        // views to be targeted regardless of excluded views. If that happens, then the
-        // excluded fragments views (hidden fragments) will still be in the transition.
-
-        Transition transition;
-        if (overlap) {
-            // Regular transition -- do it all together
-            TransitionSet transitionSet = new TransitionSet();
-            if (enterTransition != null) {
-                transitionSet.addTransition(enterTransition);
-            }
-            if (exitTransition != null) {
-                transitionSet.addTransition(exitTransition);
-            }
-            if (sharedElementTransition != null) {
-                transitionSet.addTransition(sharedElementTransition);
-            }
-            transition = transitionSet;
-        } else {
-            // First do exit, then enter, but allow shared element transition to happen
-            // during both.
-            Transition staggered = null;
-            if (exitTransition != null && enterTransition != null) {
-                staggered = new TransitionSet()
-                        .addTransition(exitTransition)
-                        .addTransition(enterTransition)
-                        .setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
-            } else if (exitTransition != null) {
-                staggered = exitTransition;
-            } else if (enterTransition != null) {
-                staggered = enterTransition;
-            }
-            if (sharedElementTransition != null) {
-                TransitionSet together = new TransitionSet();
-                if (staggered != null) {
-                    together.addTransition(staggered);
-                }
-                together.addTransition(sharedElementTransition);
-                transition = together;
-            } else {
-                transition = staggered;
-            }
-        }
-        return transition;
-    }
-
-    /**
-     * Configures custom transitions for a specific fragment container.
-     *
-     * @param containerId The container ID of the fragments to configure the transition for.
-     * @param state The Transition State keeping track of the executing transitions.
-     * @param transitioningFragments The first out and last in fragments for the fragment container.
-     */
-    private void configureTransitions(int containerId, TransitionState state,
-            FragmentContainerTransition transitioningFragments) {
-        ViewGroup sceneRoot = (ViewGroup) mManager.mContainer.onFindViewById(containerId);
-        if (sceneRoot != null) {
-            final Fragment inFragment = transitioningFragments.lastIn;
-            final Fragment outFragment = transitioningFragments.firstOut;
-
-            Transition enterTransition =
-                    getEnterTransition(inFragment, transitioningFragments.lastInIsPop);
-            TransitionSet sharedElementTransition = getSharedElementTransition(inFragment,
-                    outFragment, transitioningFragments.lastInIsPop);
-            Transition exitTransition =
-                    getExitTransition(outFragment, transitioningFragments.firstOutIsPop);
-
-            if (enterTransition == null && sharedElementTransition == null &&
-                    exitTransition == null) {
-                return; // no transitions!
-            }
-            if (enterTransition != null) {
-                enterTransition.addTarget(state.nonExistentView);
-            }
-            ArrayMap<String, View> namedViews = null;
-            ArrayList<View> sharedElementTargets = new ArrayList<View>();
-            if (sharedElementTransition != null) {
-                namedViews = remapSharedElements(state, outFragment,
-                        transitioningFragments.firstOutIsPop);
-                setSharedElementTargets(sharedElementTransition,
-                        state.nonExistentView, namedViews, sharedElementTargets);
-
-                // Notify the start of the transition.
-                SharedElementCallback callback = transitioningFragments.lastInIsPop ?
-                        outFragment.mEnterTransitionCallback :
-                        inFragment.mEnterTransitionCallback;
-                ArrayList<String> names = new ArrayList<String>(namedViews.keySet());
-                ArrayList<View> views = new ArrayList<View>(namedViews.values());
-                callback.onSharedElementStart(names, views, null);
-            }
-
-            ArrayList<View> exitingViews = captureExitingViews(exitTransition, outFragment,
-                    namedViews, state.nonExistentView);
-            if (exitingViews == null || exitingViews.isEmpty()) {
-                exitTransition = null;
-            }
-            excludeViews(enterTransition, exitTransition, exitingViews, true);
-            excludeViews(enterTransition, sharedElementTransition, sharedElementTargets, true);
-            excludeViews(exitTransition, sharedElementTransition, sharedElementTargets, true);
-
-            // Set the epicenter of the exit transition
-            if (mSharedElementTargetNames != null && namedViews != null) {
-                View epicenterView = namedViews.get(mSharedElementTargetNames.get(0));
-                if (epicenterView != null) {
-                    if (exitTransition != null) {
-                        setEpicenter(exitTransition, epicenterView);
-                    }
-                    if (sharedElementTransition != null) {
-                        setEpicenter(sharedElementTransition, epicenterView);
-                    }
-                }
-            }
-
-            Transition transition = mergeTransitions(enterTransition, exitTransition,
-                    sharedElementTransition, inFragment, transitioningFragments.lastInIsPop);
-
-            if (transition != null) {
-                ArrayList<View> hiddenFragments = new ArrayList<View>();
-                ArrayList<View> enteringViews = addTransitionTargets(state, enterTransition,
-                        sharedElementTransition, exitTransition, transition, sceneRoot, inFragment,
-                        outFragment, hiddenFragments, transitioningFragments.lastInIsPop,
-                        sharedElementTargets);
-
-                transition.setNameOverrides(state.nameOverrides);
-                // We want to exclude hidden views later, so we need a non-null list in the
-                // transition now.
-                transition.excludeTarget(state.nonExistentView, true);
-                // Now exclude all currently hidden fragments.
-                excludeHiddenFragments(hiddenFragments, containerId, transition);
-                TransitionManager.beginDelayedTransition(sceneRoot, transition);
-                // Remove the view targeting after the transition starts
-                removeTargetedViewsFromTransitions(sceneRoot, state.nonExistentView,
-                        enterTransition, enteringViews, exitTransition, exitingViews,
-                        sharedElementTransition, sharedElementTargets, transition,
-                        hiddenFragments);
-            }
-        }
-    }
-
-    /**
-     * Finds all children of the shared elements and sets the wrapping TransitionSet
-     * targets to point to those. It also limits transitions that have no targets to the
-     * specific shared elements. This allows developers to target child views of the
-     * shared elements specifically, but this doesn't happen by default.
-     */
-    private static void setSharedElementTargets(TransitionSet transition,
-            View nonExistentView, ArrayMap<String, View> namedViews,
-            ArrayList<View> sharedElementTargets) {
-        sharedElementTargets.clear();
-        sharedElementTargets.addAll(namedViews.values());
-
-        final List<View> views = transition.getTargets();
-        views.clear();
-        final int count = sharedElementTargets.size();
-        for (int i = 0; i < count; i++) {
-            final View view = sharedElementTargets.get(i);
-            bfsAddViewChildren(views, view);
-        }
-        sharedElementTargets.add(nonExistentView);
-        addTargets(transition, sharedElementTargets);
-    }
-
-    /**
-     * Uses a breadth-first scheme to add startView and all of its children to views.
-     * It won't add a child if it is already in views.
-     */
-    private static void bfsAddViewChildren(final List<View> views, final View startView) {
-        final int startIndex = views.size();
-        if (containedBeforeIndex(views, startView, startIndex)) {
-            return; // This child is already in the list, so all its children are also.
-        }
-        views.add(startView);
-        for (int index = startIndex; index < views.size(); index++) {
-            final View view = views.get(index);
-            if (view instanceof ViewGroup) {
-                ViewGroup viewGroup = (ViewGroup) view;
-                final int childCount =  viewGroup.getChildCount();
-                for (int childIndex = 0; childIndex < childCount; childIndex++) {
-                    final View child = viewGroup.getChildAt(childIndex);
-                    if (!containedBeforeIndex(views, child, startIndex)) {
-                        views.add(child);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Does a linear search through views for view, limited to maxIndex.
-     */
-    private static boolean containedBeforeIndex(final List<View> views, final View view,
-            final int maxIndex) {
-        for (int i = 0; i < maxIndex; i++) {
-            if (views.get(i) == view) {
+            if (isFragmentPostponed(op)) {
                 return true;
             }
         }
         return false;
     }
 
-    private static void excludeViews(Transition transition, Transition fromTransition,
-            ArrayList<View> views, boolean exclude) {
-        if (transition != null) {
-            final int viewCount = fromTransition == null ? 0 : views.size();
-            for (int i = 0; i < viewCount; i++) {
-                transition.excludeTarget(views.get(i), exclude);
-            }
-        }
-    }
-
-    /**
-     * After the transition has started, remove all targets that we added to the transitions
-     * so that the transitions are left in a clean state.
-     */
-    private void removeTargetedViewsFromTransitions(
-            final ViewGroup sceneRoot, final View nonExistingView,
-            final Transition enterTransition, final ArrayList<View> enteringViews,
-            final Transition exitTransition, final ArrayList<View> exitingViews,
-            final Transition sharedElementTransition, final ArrayList<View> sharedElementTargets,
-            final Transition overallTransition, final ArrayList<View> hiddenViews) {
-        if (overallTransition != null) {
-            sceneRoot.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
-                @Override
-                public boolean onPreDraw() {
-                    sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
-                    if (enterTransition != null) {
-                        removeTargets(enterTransition, enteringViews);
-                        excludeViews(enterTransition, exitTransition, exitingViews, false);
-                        excludeViews(enterTransition, sharedElementTransition, sharedElementTargets,
-                                false);
-                    }
-                    if (exitTransition != null) {
-                        removeTargets(exitTransition, exitingViews);
-                        excludeViews(exitTransition, enterTransition, enteringViews, false);
-                        excludeViews(exitTransition, sharedElementTransition, sharedElementTargets,
-                                false);
-                    }
-                    if (sharedElementTransition != null) {
-                        removeTargets(sharedElementTransition, sharedElementTargets);
-                    }
-                    int numViews = hiddenViews.size();
-                    for (int i = 0; i < numViews; i++) {
-                        overallTransition.excludeTarget(hiddenViews.get(i), false);
-                    }
-                    overallTransition.excludeTarget(nonExistingView, false);
-                    return true;
-                }
-            });
-        }
-    }
-
-    /**
-     * This method removes the views from transitions that target ONLY those views.
-     * The views list should match those added in addTargets and should contain
-     * one view that is not in the view hierarchy (state.nonExistentView).
-     */
-    public static void removeTargets(Transition transition, ArrayList<View> views) {
-        if (transition instanceof TransitionSet) {
-            TransitionSet set = (TransitionSet) transition;
-            int numTransitions = set.getTransitionCount();
-            for (int i = 0; i < numTransitions; i++) {
-                Transition child = set.getTransitionAt(i);
-                removeTargets(child, views);
-            }
-        } else if (!hasSimpleTarget(transition)) {
-            List<View> targets = transition.getTargets();
-            if (targets != null && targets.size() == views.size() &&
-                    targets.containsAll(views)) {
-                // We have an exact match. We must have added these earlier in addTargets
-                for (int i = views.size() - 1; i >= 0; i--) {
-                    transition.removeTarget(views.get(i));
-                }
-            }
-        }
-    }
-
-    /**
-     * This method adds views as targets to the transition, but only if the transition
-     * doesn't already have a target. It is best for views to contain one View object
-     * that does not exist in the view hierarchy (state.nonExistentView) so that
-     * when they are removed later, a list match will suffice to remove the targets.
-     * Otherwise, if you happened to have targeted the exact views for the transition,
-     * the removeTargets call will remove them unexpectedly.
-     */
-    public static void addTargets(Transition transition, ArrayList<View> views) {
-        if (transition instanceof TransitionSet) {
-            TransitionSet set = (TransitionSet) transition;
-            int numTransitions = set.getTransitionCount();
-            for (int i = 0; i < numTransitions; i++) {
-                Transition child = set.getTransitionAt(i);
-                addTargets(child, views);
-            }
-        } else if (!hasSimpleTarget(transition)) {
-            List<View> targets = transition.getTargets();
-            if (isNullOrEmpty(targets)) {
-                // We can just add the target views
-                int numViews = views.size();
-                for (int i = 0; i < numViews; i++) {
-                    transition.addTarget(views.get(i));
-                }
-            }
-        }
-    }
-
-    private static boolean hasSimpleTarget(Transition transition) {
-        return !isNullOrEmpty(transition.getTargetIds()) ||
-                !isNullOrEmpty(transition.getTargetNames()) ||
-                !isNullOrEmpty(transition.getTargetTypes());
-    }
-
-    private static boolean isNullOrEmpty(List list) {
-        return list == null || list.isEmpty();
-    }
-
-    /**
-     * Remaps a name-to-View map, substituting different names for keys.
-     *
-     * @param inMap A list of keys found in the map, in the order in toGoInMap
-     * @param toGoInMap A list of keys to use for the new map, in the order of inMap
-     * @param namedViews The current mapping
-     * @return a new Map after it has been mapped with the new names as keys.
-     */
-    private static ArrayMap<String, View> remapNames(ArrayList<String> inMap,
-            ArrayList<String> toGoInMap, ArrayMap<String, View> namedViews) {
-        ArrayMap<String, View> remappedViews = new ArrayMap<String, View>();
-        if (!namedViews.isEmpty()) {
-            int numKeys = inMap.size();
-            for (int i = 0; i < numKeys; i++) {
-                View view = namedViews.get(inMap.get(i));
-
-                if (view != null) {
-                    remappedViews.put(toGoInMap.get(i), view);
-                }
-            }
-        }
-        return remappedViews;
-    }
-
-    /**
-     * Maps shared elements to views in the entering fragment.
-     *
-     * @param state The transition State as returned from {@link #beginTransition(
-     * android.util.SparseArray, android.util.SparseArray, boolean)}.
-     * @param inFragment The last fragment to be added.
-     * @param isBack true if this is popping the back stack or false if this is a
-     *               forward operation.
-     */
-    private ArrayMap<String, View> mapEnteringSharedElements(TransitionState state,
-            Fragment inFragment, boolean isBack) {
-        ArrayMap<String, View> namedViews = new ArrayMap<String, View>();
-        View root = inFragment.getView();
-        if (root != null) {
-            if (mSharedElementSourceNames != null) {
-                root.findNamedViews(namedViews);
-                if (isBack) {
-                    namedViews = remapNames(mSharedElementSourceNames,
-                            mSharedElementTargetNames, namedViews);
-                } else {
-                    namedViews.retainAll(mSharedElementTargetNames);
-                }
-            }
-        }
-        return namedViews;
-    }
-
-    private void excludeHiddenFragments(final ArrayList<View> hiddenFragmentViews, int containerId,
-            Transition transition) {
-        if (mManager.mAdded != null) {
-            for (int i = 0; i < mManager.mAdded.size(); i++) {
-                Fragment fragment = mManager.mAdded.get(i);
-                if (fragment.mView != null && fragment.mContainer != null &&
-                        fragment.mContainerId == containerId) {
-                    if (fragment.mHidden) {
-                        if (!hiddenFragmentViews.contains(fragment.mView)) {
-                            transition.excludeTarget(fragment.mView, true);
-                            hiddenFragmentViews.add(fragment.mView);
-                        }
-                    } else {
-                        transition.excludeTarget(fragment.mView, false);
-                        hiddenFragmentViews.remove(fragment.mView);
-                    }
-                }
-            }
-        }
-    }
-
-    private static void setEpicenter(Transition transition, View view) {
-        final Rect epicenter = new Rect();
-        view.getBoundsOnScreen(epicenter);
-
-        transition.setEpicenterCallback(new Transition.EpicenterCallback() {
-            @Override
-            public Rect onGetEpicenter(Transition transition) {
-                return epicenter;
-            }
-        });
-    }
-
-    private void setSharedElementEpicenter(Transition transition, final TransitionState state) {
-        transition.setEpicenterCallback(new Transition.EpicenterCallback() {
-            private Rect mEpicenter;
-
-            @Override
-            public Rect onGetEpicenter(Transition transition) {
-                if (mEpicenter == null && state.enteringEpicenterView != null) {
-                    mEpicenter = new Rect();
-                    state.enteringEpicenterView.getBoundsOnScreen(mEpicenter);
-                }
-                return mEpicenter;
-            }
-        });
-    }
-
-    public TransitionState popFromBackStack(boolean doStateMove, TransitionState state,
-            SparseArray<FragmentContainerTransition> transitioningFragments) {
-        if (FragmentManagerImpl.DEBUG) {
-            Log.v(TAG, "popFromBackStack: " + this);
-            LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
-            PrintWriter pw = new FastPrintWriter(logw, false, 1024);
-            dump("  ", null, pw, null);
-            pw.flush();
-        }
-
-        if (mManager.mCurState >= Fragment.CREATED) {
-            if (state == null) {
-                if (transitioningFragments.size() != 0) {
-                    state = beginTransition(transitioningFragments);
-                }
-            } else if (!doStateMove) {
-                setNameOverrides(state, mSharedElementTargetNames, mSharedElementSourceNames);
-            }
-        }
-
-        bumpBackStackNesting(-1);
-
-        final int numOps = mOps.size();
-        for (int opNum = numOps - 1; opNum >= 0; opNum--) {
+    void setOnStartPostponedListener(Fragment.OnStartEnterTransitionListener listener) {
+        for (int opNum = 0; opNum < mOps.size(); opNum++) {
             final Op op = mOps.get(opNum);
-            Fragment f = op.fragment;
-            switch (op.cmd) {
-                case OP_ADD:
-                    f.mNextAnim = op.popExitAnim;
-                    mManager.removeFragment(f,
-                            FragmentManagerImpl.reverseTransit(mTransition),
-                            mTransitionStyle);
-                    break;
-                case OP_REMOVE:
-                    f.mNextAnim = op.popEnterAnim;
-                    mManager.addFragment(f, false);
-                    break;
-                case OP_HIDE:
-                    f.mNextAnim = op.popEnterAnim;
-                    mManager.showFragment(f,
-                            FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
-                    break;
-                case OP_SHOW:
-                    f.mNextAnim = op.popExitAnim;
-                    mManager.hideFragment(f,
-                            FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
-                    break;
-                case OP_DETACH:
-                    f.mNextAnim = op.popEnterAnim;
-                    mManager.attachFragment(f,
-                            FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
-                    break;
-                case OP_ATTACH:
-                    f.mNextAnim = op.popExitAnim;
-                    mManager.detachFragment(f,
-                            FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
-                    break;
-                default:
-                    throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
-            }
-        }
-
-        if (doStateMove) {
-            mManager.moveToState(mManager.mCurState,
-                    FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle, true);
-            state = null;
-        }
-
-        if (mIndex >= 0) {
-            mManager.freeBackStackIndex(mIndex);
-            mIndex = -1;
-        }
-        return state;
-    }
-
-    private static void setNameOverride(ArrayMap<String, String> overrides,
-            String source, String target) {
-        if (source != null && target != null && !source.equals(target)) {
-            for (int index = 0; index < overrides.size(); index++) {
-                if (source.equals(overrides.valueAt(index))) {
-                    overrides.setValueAt(index, target);
-                    return;
-                }
-            }
-            overrides.put(source, target);
-        }
-    }
-
-    private static void setNameOverrides(TransitionState state, ArrayList<String> sourceNames,
-            ArrayList<String> targetNames) {
-        if (sourceNames != null && targetNames != null) {
-            for (int i = 0; i < sourceNames.size(); i++) {
-                String source = sourceNames.get(i);
-                String target = targetNames.get(i);
-                setNameOverride(state.nameOverrides, source, target);
+            if (isFragmentPostponed(op)) {
+                op.fragment.setOnStartEnterTransitionListener(listener);
             }
         }
     }
 
-    private void setBackNameOverrides(TransitionState state, ArrayMap<String, View> namedViews,
-            boolean isEnd) {
-        int targetCount = mSharedElementTargetNames == null ? 0 : mSharedElementTargetNames.size();
-        int sourceCount = mSharedElementSourceNames == null ? 0 : mSharedElementSourceNames.size();
-        final int count = Math.min(targetCount, sourceCount);
-        for (int i = 0; i < count; i++) {
-            String source = mSharedElementSourceNames.get(i);
-            String originalTarget = mSharedElementTargetNames.get(i);
-            View view = namedViews.get(originalTarget);
-            if (view != null) {
-                String target = view.getTransitionName();
-                if (isEnd) {
-                    setNameOverride(state.nameOverrides, source, target);
-                } else {
-                    setNameOverride(state.nameOverrides, target, source);
-                }
-            }
-        }
-    }
-
-    private void setNameOverrides(TransitionState state, ArrayMap<String, View> namedViews,
-            boolean isEnd) {
-        int count = namedViews == null ? 0 : namedViews.size();
-        for (int i = 0; i < count; i++) {
-            String source = namedViews.keyAt(i);
-            String target = namedViews.valueAt(i).getTransitionName();
-            if (isEnd) {
-                setNameOverride(state.nameOverrides, source, target);
-            } else {
-                setNameOverride(state.nameOverrides, target, source);
-            }
-        }
+    private static boolean isFragmentPostponed(Op op) {
+        final Fragment fragment = op.fragment;
+        return (fragment.mAdded && fragment.mView != null && !fragment.mDetached &&
+                !fragment.mHidden && fragment.isPostponed());
     }
 
     public String getName() {
@@ -1713,36 +909,4 @@
     public boolean isEmpty() {
         return mOps.isEmpty();
     }
-
-    public class TransitionState {
-        public ArrayMap<String, String> nameOverrides = new ArrayMap<String, String>();
-        public View enteringEpicenterView;
-        public View nonExistentView;
-    }
-
-    /**
-     * Tracks the last fragment added and first fragment removed for fragment transitions.
-     * This also tracks which fragments are changed by push or pop transactions.
-     */
-    public static class FragmentContainerTransition {
-        /**
-         * The last fragment added/attached/shown in its container
-         */
-        public Fragment lastIn;
-
-        /**
-         * true when lastIn was added during a pop transaction or false if added with a push
-         */
-        public boolean lastInIsPop;
-
-        /**
-         * The first fragment with a View that was removed/detached/hidden in its container.
-         */
-        public Fragment firstOut;
-
-        /**
-         * true when firstOut was removed during a pop transaction or false otherwise
-         */
-        public boolean firstOutIsPop;
-    }
 }
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index c6736eef..27a0200 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -123,6 +123,7 @@
         mIsReadyForTransition = true;
         hideViews(mSharedElements);
         if (getViewsTransition() != null && mTransitioningViews != null) {
+            stripOffscreenViews();
             hideViews(mTransitioningViews);
         }
         if (mIsReturning) {
@@ -518,9 +519,6 @@
             mIsViewsTransitionStarted = true;
             if (mTransitioningViews != null && !mTransitioningViews.isEmpty()) {
                 viewsTransition = configureTransition(getViewsTransition(), true);
-                if (viewsTransition != null && !mIsReturning) {
-                    stripOffscreenViews();
-                }
             }
             if (viewsTransition == null) {
                 viewsTransitionComplete();
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 6ea170e..8124232 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -31,6 +31,8 @@
 import android.os.Build;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.transition.Transition;
@@ -375,15 +377,6 @@
 
     int mState = INITIALIZING;
 
-    // Non-null if the fragment's view hierarchy is currently animating away,
-    // meaning we need to wait a bit on completely destroying it.  This is the
-    // animation that is running.
-    Animator mAnimatingAway;
-
-    // If mAnimatingAway != null, this is the state we should move to once the
-    // animation is done.
-    int mStateAfterAnimating;
-
     // When instantiated from saved state, this is the saved state.
     Bundle mSavedFragmentState;
     SparseArray<Parcelable> mSavedViewState;
@@ -478,9 +471,6 @@
     // Used to verify that subclasses call through to super class.
     boolean mCalled;
 
-    // If app has requested a specific animation, this is the one to use.
-    int mNextAnim;
-
     // The parent container of the fragment after dynamically added to UI.
     ViewGroup mContainer;
 
@@ -498,17 +488,18 @@
     boolean mLoadersStarted;
     boolean mCheckedForLoaderManager;
 
-    private Transition mEnterTransition = null;
-    private Transition mReturnTransition = USE_DEFAULT_TRANSITION;
-    private Transition mExitTransition = null;
-    private Transition mReenterTransition = USE_DEFAULT_TRANSITION;
-    private Transition mSharedElementEnterTransition = null;
-    private Transition mSharedElementReturnTransition = USE_DEFAULT_TRANSITION;
-    private Boolean mAllowReturnTransitionOverlap;
-    private Boolean mAllowEnterTransitionOverlap;
+    // The animation and transition information for the fragment. This will be null
+    // unless the elements are explicitly accessed and should remain null for Fragments
+    // without Views.
+    AnimationInfo mAnimationInfo;
 
-    SharedElementCallback mEnterTransitionCallback = SharedElementCallback.NULL_CALLBACK;
-    SharedElementCallback mExitTransitionCallback = SharedElementCallback.NULL_CALLBACK;
+    // True if the View was added, and its animation has yet to be run. This could
+    // also indicate that the fragment view hasn't been made visible, even if there is no
+    // animation for this fragment.
+    boolean mIsNewlyAdded;
+
+    // True if mHidden has been changed and the animation should be scheduled.
+    boolean mHiddenChanged;
 
     /**
      * State information that has been retrieved from a fragment instance
@@ -1390,26 +1381,41 @@
 
         TypedArray a = context.obtainStyledAttributes(attrs,
                 com.android.internal.R.styleable.Fragment);
-        mEnterTransition = loadTransition(context, a, mEnterTransition, null,
-                com.android.internal.R.styleable.Fragment_fragmentEnterTransition);
-        mReturnTransition = loadTransition(context, a, mReturnTransition, USE_DEFAULT_TRANSITION,
-                com.android.internal.R.styleable.Fragment_fragmentReturnTransition);
-        mExitTransition = loadTransition(context, a, mExitTransition, null,
-                com.android.internal.R.styleable.Fragment_fragmentExitTransition);
-        mReenterTransition = loadTransition(context, a, mReenterTransition, USE_DEFAULT_TRANSITION,
-                com.android.internal.R.styleable.Fragment_fragmentReenterTransition);
-        mSharedElementEnterTransition = loadTransition(context, a, mSharedElementEnterTransition,
-                null, com.android.internal.R.styleable.Fragment_fragmentSharedElementEnterTransition);
-        mSharedElementReturnTransition = loadTransition(context, a, mSharedElementReturnTransition,
+        setEnterTransition(loadTransition(context, a, getEnterTransition(), null,
+                com.android.internal.R.styleable.Fragment_fragmentEnterTransition));
+        setReturnTransition(loadTransition(context, a, getReturnTransition(),
                 USE_DEFAULT_TRANSITION,
-                com.android.internal.R.styleable.Fragment_fragmentSharedElementReturnTransition);
-        if (mAllowEnterTransitionOverlap == null) {
-            mAllowEnterTransitionOverlap = a.getBoolean(
-                    com.android.internal.R.styleable.Fragment_fragmentAllowEnterTransitionOverlap, true);
+                com.android.internal.R.styleable.Fragment_fragmentReturnTransition));
+        setExitTransition(loadTransition(context, a, getExitTransition(), null,
+                com.android.internal.R.styleable.Fragment_fragmentExitTransition));
+
+        setReenterTransition(loadTransition(context, a, getReenterTransition(),
+                USE_DEFAULT_TRANSITION,
+                com.android.internal.R.styleable.Fragment_fragmentReenterTransition));
+        setSharedElementEnterTransition(loadTransition(context, a,
+                getSharedElementEnterTransition(), null,
+                com.android.internal.R.styleable.Fragment_fragmentSharedElementEnterTransition));
+        setSharedElementReturnTransition(loadTransition(context, a,
+                getSharedElementReturnTransition(), USE_DEFAULT_TRANSITION,
+                com.android.internal.R.styleable.Fragment_fragmentSharedElementReturnTransition));
+        boolean isEnterSet;
+        boolean isReturnSet;
+        if (mAnimationInfo == null) {
+            isEnterSet = false;
+            isReturnSet = false;
+        } else {
+            isEnterSet = mAnimationInfo.mAllowEnterTransitionOverlap != null;
+            isReturnSet = mAnimationInfo.mAllowReturnTransitionOverlap != null;
         }
-        if (mAllowReturnTransitionOverlap == null) {
-            mAllowReturnTransitionOverlap = a.getBoolean(
-                    com.android.internal.R.styleable.Fragment_fragmentAllowReturnTransitionOverlap, true);
+        if (!isEnterSet) {
+            setAllowEnterTransitionOverlap(a.getBoolean(
+                    com.android.internal.R.styleable.Fragment_fragmentAllowEnterTransitionOverlap,
+                    true));
+        }
+        if (!isReturnSet) {
+            setAllowReturnTransitionOverlap(a.getBoolean(
+                    com.android.internal.R.styleable.Fragment_fragmentAllowReturnTransitionOverlap,
+                    true));
         }
         a.recycle();
 
@@ -1934,16 +1940,12 @@
      */
     public void setEnterSharedElementCallback(SharedElementCallback callback) {
         if (callback == null) {
+            if (mAnimationInfo == null) {
+                return; // already a null callback
+            }
             callback = SharedElementCallback.NULL_CALLBACK;
         }
-        mEnterTransitionCallback = callback;
-    }
-
-    /**
-     * @hide
-     */
-    public void setEnterSharedElementTransitionCallback(SharedElementCallback callback) {
-        setEnterSharedElementCallback(callback);
+        ensureAnimationInfo().mEnterTransitionCallback = callback;
     }
 
     /**
@@ -1955,16 +1957,12 @@
      */
     public void setExitSharedElementCallback(SharedElementCallback callback) {
         if (callback == null) {
+            if (mAnimationInfo == null) {
+                return; // already a null callback
+            }
             callback = SharedElementCallback.NULL_CALLBACK;
         }
-        mExitTransitionCallback = callback;
-    }
-
-    /**
-     * @hide
-     */
-    public void setExitSharedElementTransitionCallback(SharedElementCallback callback) {
-        setExitSharedElementCallback(callback);
+        ensureAnimationInfo().mExitTransitionCallback = callback;
     }
 
     /**
@@ -1979,7 +1977,9 @@
      * @attr ref android.R.styleable#Fragment_fragmentEnterTransition
      */
     public void setEnterTransition(Transition transition) {
-        mEnterTransition = transition;
+        if (shouldChangeTransition(transition, null)) {
+            ensureAnimationInfo().mEnterTransition = transition;
+        }
     }
 
     /**
@@ -1993,7 +1993,10 @@
      * @attr ref android.R.styleable#Fragment_fragmentEnterTransition
      */
     public Transition getEnterTransition() {
-        return mEnterTransition;
+        if (mAnimationInfo == null) {
+            return null;
+        }
+        return mAnimationInfo.mEnterTransition;
     }
 
     /**
@@ -2011,7 +2014,9 @@
      * @attr ref android.R.styleable#Fragment_fragmentExitTransition
      */
     public void setReturnTransition(Transition transition) {
-        mReturnTransition = transition;
+        if (shouldChangeTransition(transition, USE_DEFAULT_TRANSITION)) {
+            ensureAnimationInfo().mReturnTransition = transition;
+        }
     }
 
     /**
@@ -2028,8 +2033,11 @@
      * @attr ref android.R.styleable#Fragment_fragmentExitTransition
      */
     public Transition getReturnTransition() {
-        return mReturnTransition == USE_DEFAULT_TRANSITION ? getEnterTransition()
-                : mReturnTransition;
+        if (mAnimationInfo == null) {
+            return null;
+        }
+        return mAnimationInfo.mReturnTransition == USE_DEFAULT_TRANSITION ? getEnterTransition()
+                : mAnimationInfo.mReturnTransition;
     }
 
     /**
@@ -2046,7 +2054,9 @@
      * @attr ref android.R.styleable#Fragment_fragmentExitTransition
      */
     public void setExitTransition(Transition transition) {
-        mExitTransition = transition;
+        if (shouldChangeTransition(transition, null)) {
+            ensureAnimationInfo().mExitTransition = transition;
+        }
     }
 
     /**
@@ -2063,7 +2073,10 @@
      * @attr ref android.R.styleable#Fragment_fragmentExitTransition
      */
     public Transition getExitTransition() {
-        return mExitTransition;
+        if (mAnimationInfo == null) {
+            return null;
+        }
+        return mAnimationInfo.mExitTransition;
     }
 
     /**
@@ -2080,7 +2093,9 @@
      * @attr ref android.R.styleable#Fragment_fragmentReenterTransition
      */
     public void setReenterTransition(Transition transition) {
-        mReenterTransition = transition;
+        if (shouldChangeTransition(transition, USE_DEFAULT_TRANSITION)) {
+            ensureAnimationInfo().mReenterTransition = transition;
+        }
     }
 
     /**
@@ -2097,8 +2112,11 @@
      * @attr ref android.R.styleable#Fragment_fragmentReenterTransition
      */
     public Transition getReenterTransition() {
-        return mReenterTransition == USE_DEFAULT_TRANSITION ? getExitTransition()
-                : mReenterTransition;
+        if (mAnimationInfo == null) {
+            return null;
+        }
+        return mAnimationInfo.mReenterTransition == USE_DEFAULT_TRANSITION ? getExitTransition()
+                : mAnimationInfo.mReenterTransition;
     }
 
     /**
@@ -2112,7 +2130,9 @@
      * @attr ref android.R.styleable#Fragment_fragmentSharedElementEnterTransition
      */
     public void setSharedElementEnterTransition(Transition transition) {
-        mSharedElementEnterTransition = transition;
+        if (shouldChangeTransition(transition, null)) {
+            ensureAnimationInfo().mSharedElementEnterTransition = transition;
+        }
     }
 
     /**
@@ -2126,7 +2146,10 @@
      * @attr ref android.R.styleable#Fragment_fragmentSharedElementEnterTransition
      */
     public Transition getSharedElementEnterTransition() {
-        return mSharedElementEnterTransition;
+        if (mAnimationInfo == null) {
+            return null;
+        }
+        return mAnimationInfo.mSharedElementEnterTransition;
     }
 
     /**
@@ -2143,7 +2166,9 @@
      * @attr ref android.R.styleable#Fragment_fragmentSharedElementReturnTransition
      */
     public void setSharedElementReturnTransition(Transition transition) {
-        mSharedElementReturnTransition = transition;
+        if (shouldChangeTransition(transition, USE_DEFAULT_TRANSITION)) {
+            ensureAnimationInfo().mSharedElementReturnTransition = transition;
+        }
     }
 
     /**
@@ -2160,8 +2185,12 @@
      * @attr ref android.R.styleable#Fragment_fragmentSharedElementReturnTransition
      */
     public Transition getSharedElementReturnTransition() {
-        return mSharedElementReturnTransition == USE_DEFAULT_TRANSITION ?
-                getSharedElementEnterTransition() : mSharedElementReturnTransition;
+        if (mAnimationInfo == null) {
+            return null;
+        }
+        return mAnimationInfo.mSharedElementReturnTransition == USE_DEFAULT_TRANSITION
+                ? getSharedElementEnterTransition()
+                : mAnimationInfo.mSharedElementReturnTransition;
     }
 
     /**
@@ -2174,7 +2203,7 @@
      * @attr ref android.R.styleable#Fragment_fragmentAllowEnterTransitionOverlap
      */
     public void setAllowEnterTransitionOverlap(boolean allow) {
-        mAllowEnterTransitionOverlap = allow;
+        ensureAnimationInfo().mAllowEnterTransitionOverlap = allow;
     }
 
     /**
@@ -2187,7 +2216,8 @@
      * @attr ref android.R.styleable#Fragment_fragmentAllowEnterTransitionOverlap
      */
     public boolean getAllowEnterTransitionOverlap() {
-        return (mAllowEnterTransitionOverlap == null) ? true : mAllowEnterTransitionOverlap;
+        return (mAnimationInfo == null || mAnimationInfo.mAllowEnterTransitionOverlap == null)
+                ? true : mAnimationInfo.mAllowEnterTransitionOverlap;
     }
 
     /**
@@ -2200,7 +2230,7 @@
      * @attr ref android.R.styleable#Fragment_fragmentAllowReturnTransitionOverlap
      */
     public void setAllowReturnTransitionOverlap(boolean allow) {
-        mAllowReturnTransitionOverlap = allow;
+        ensureAnimationInfo().mAllowReturnTransitionOverlap = allow;
     }
 
     /**
@@ -2213,7 +2243,90 @@
      * @attr ref android.R.styleable#Fragment_fragmentAllowReturnTransitionOverlap
      */
     public boolean getAllowReturnTransitionOverlap() {
-        return (mAllowReturnTransitionOverlap == null) ? true : mAllowReturnTransitionOverlap;
+        return (mAnimationInfo == null || mAnimationInfo.mAllowReturnTransitionOverlap == null)
+                ? true : mAnimationInfo.mAllowReturnTransitionOverlap;
+    }
+
+    /**
+     * Postpone the entering Fragment transition until {@link #startPostponedEnterTransition()}
+     * or {@link FragmentManager#executePendingTransactions()} has been called.
+     * <p>
+     * This method gives the Fragment the ability to delay Fragment animations
+     * until all data is loaded. Until then, the added, shown, and
+     * attached Fragments will be INVISIBLE and removed, hidden, and detached Fragments won't
+     * be have their Views removed. The transaction runs when all postponed added Fragments in the
+     * transaction have called {@link #startPostponedEnterTransition()}.
+     * <p>
+     * This method should be called before being added to the FragmentTransaction or
+     * in {@link #onCreate(Bundle), {@link #onAttach(Context)}, or
+     * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}}.
+     * {@link #startPostponedEnterTransition()} must be called to allow the Fragment to
+     * start the transitions.
+     * <p>
+     * When a FragmentTransaction is started that may affect a postponed FragmentTransaction,
+     * based on which containers are in their operations, the postponed FragmentTransaction
+     * will have its start triggered. The early triggering may result in faulty or nonexistent
+     * animations in the postponed transaction. FragmentTransactions that operate only on
+     * independent containers will not interfere with each other's postponement.
+     * <p>
+     * Calling postponeEnterTransition on Fragments with a null View will not postpone the
+     * transition. Likewise, postponement only works if FragmentTransaction optimizations are
+     * enabled.
+     *
+     * @see Activity#postponeEnterTransition()
+     * @see FragmentTransaction#setAllowOptimization(boolean)
+     */
+    public void postponeEnterTransition() {
+        ensureAnimationInfo().mEnterTransitionPostponed = true;
+    }
+
+    /**
+     * Begin postponed transitions after {@link #postponeEnterTransition()} was called.
+     * If postponeEnterTransition() was called, you must call startPostponedEnterTransition()
+     * or {@link FragmentManager#executePendingTransactions()} to complete the FragmentTransaction.
+     * If postponement was interrupted with {@link FragmentManager#executePendingTransactions()},
+     * before {@code startPostponedEnterTransition()}, animations may not run or may execute
+     * improperly.
+     *
+     * @see Activity#startPostponedEnterTransition()
+     */
+    public void startPostponedEnterTransition() {
+        if (mFragmentManager == null || mFragmentManager.mHost == null) {
+                ensureAnimationInfo().mEnterTransitionPostponed = false;
+        } else if (Looper.myLooper() != mFragmentManager.mHost.getHandler().getLooper()) {
+            mFragmentManager.mHost.getHandler().
+                    postAtFrontOfQueue(this::callStartTransitionListener);
+        } else {
+            callStartTransitionListener();
+        }
+    }
+
+    /**
+     * Calls the start transition listener. This must be called on the UI thread.
+     */
+    private void callStartTransitionListener() {
+        final OnStartEnterTransitionListener listener;
+        if (mAnimationInfo == null) {
+            listener = null;
+        } else {
+            mAnimationInfo.mEnterTransitionPostponed = false;
+            listener = mAnimationInfo.mStartEnterTransitionListener;
+            mAnimationInfo.mStartEnterTransitionListener = null;
+        }
+        if (listener != null) {
+            listener.onStartEnterTransition();
+        }
+    }
+
+    /**
+     * Returns true if mAnimationInfo is not null or the transition differs from the default value.
+     * This is broken out to ensure mAnimationInfo is properly locked when checking.
+     */
+    private boolean shouldChangeTransition(Transition transition, Transition defaultValue) {
+        if (transition == defaultValue) {
+            return mAnimationInfo != null;
+        }
+        return true;
     }
 
     /**
@@ -2274,8 +2387,8 @@
             writer.print(" mTargetRequestCode=");
             writer.println(mTargetRequestCode);
         }
-        if (mNextAnim != 0) {
-            writer.print(prefix); writer.print("mNextAnim="); writer.println(mNextAnim);
+        if (getNextAnim() != 0) {
+            writer.print(prefix); writer.print("mNextAnim="); writer.println(getNextAnim());
         }
         if (mContainer != null) {
             writer.print(prefix); writer.print("mContainer="); writer.println(mContainer);
@@ -2283,10 +2396,11 @@
         if (mView != null) {
             writer.print(prefix); writer.print("mView="); writer.println(mView);
         }
-        if (mAnimatingAway != null) {
-            writer.print(prefix); writer.print("mAnimatingAway="); writer.println(mAnimatingAway);
+        if (getAnimatingAway() != null) {
+            writer.print(prefix); writer.print("mAnimatingAway=");
+            writer.println(getAnimatingAway());
             writer.print(prefix); writer.print("mStateAfterAnimating=");
-            writer.println(mStateAfterAnimating);
+            writer.println(getStateAfterAnimating());
         }
         if (mLoaderManager != null) {
             writer.print(prefix); writer.println("Loader Manager:");
@@ -2613,6 +2727,23 @@
         }
     }
 
+    void setOnStartEnterTransitionListener(OnStartEnterTransitionListener listener) {
+        ensureAnimationInfo();
+        if (listener == mAnimationInfo.mStartEnterTransitionListener) {
+            return;
+        }
+        if (listener != null && mAnimationInfo.mStartEnterTransitionListener != null) {
+            throw new IllegalStateException("Trying to set a replacement " +
+                    "startPostponedEnterTransition on " + this);
+        }
+        if (mAnimationInfo.mEnterTransitionPostponed) {
+            mAnimationInfo.mStartEnterTransitionListener = listener;
+        }
+        if (listener != null) {
+            listener.startListening();
+        }
+    }
+
     private static Transition loadTransition(Context context, TypedArray typedArray,
             Transition currentValue, Transition defaultValue, int id) {
         if (currentValue != defaultValue) {
@@ -2631,4 +2762,158 @@
         return transition;
     }
 
+    private AnimationInfo ensureAnimationInfo() {
+        if (mAnimationInfo == null) {
+            mAnimationInfo = new AnimationInfo();
+        }
+        return mAnimationInfo;
+    }
+
+    int getNextAnim() {
+        if (mAnimationInfo == null) {
+            return 0;
+        }
+        return mAnimationInfo.mNextAnim;
+    }
+
+    void setNextAnim(int animResourceId) {
+        if (mAnimationInfo == null && animResourceId == 0) {
+            return; // no change!
+        }
+        ensureAnimationInfo().mNextAnim = animResourceId;
+    }
+
+    int getNextTransition() {
+        if (mAnimationInfo == null) {
+            return 0;
+        }
+        return mAnimationInfo.mNextTransition;
+    }
+
+    void setNextTransition(int nextTransition, int nextTransitionStyle) {
+        if (mAnimationInfo == null && nextTransition == 0 && nextTransitionStyle == 0) {
+            return; // no change!
+        }
+        ensureAnimationInfo();
+        mAnimationInfo.mNextTransition = nextTransition;
+        mAnimationInfo.mNextTransitionStyle = nextTransitionStyle;
+    }
+
+    int getNextTransitionStyle() {
+        if (mAnimationInfo == null) {
+            return 0;
+        }
+        return mAnimationInfo.mNextTransitionStyle;
+    }
+
+    SharedElementCallback getEnterTransitionCallback() {
+        if (mAnimationInfo == null) {
+            return SharedElementCallback.NULL_CALLBACK;
+        }
+        return mAnimationInfo.mEnterTransitionCallback;
+    }
+
+    SharedElementCallback getExitTransitionCallback() {
+        if (mAnimationInfo == null) {
+            return SharedElementCallback.NULL_CALLBACK;
+        }
+        return mAnimationInfo.mExitTransitionCallback;
+    }
+
+    Animator getAnimatingAway() {
+        if (mAnimationInfo == null) {
+            return null;
+        }
+        return mAnimationInfo.mAnimatingAway;
+    }
+
+    void setAnimatingAway(Animator animator) {
+        ensureAnimationInfo().mAnimatingAway = animator;
+    }
+
+    int getStateAfterAnimating() {
+        if (mAnimationInfo == null) {
+            return 0;
+        }
+        return mAnimationInfo.mStateAfterAnimating;
+    }
+
+    void setStateAfterAnimating(int state) {
+        ensureAnimationInfo().mStateAfterAnimating = state;
+    }
+
+    boolean isPostponed() {
+        if (mAnimationInfo == null) {
+            return false;
+        }
+        return mAnimationInfo.mEnterTransitionPostponed;
+    }
+
+    boolean isHideReplaced() {
+        if (mAnimationInfo == null) {
+            return false;
+        }
+        return mAnimationInfo.mIsHideReplaced;
+    }
+
+    void setHideReplaced(boolean replaced) {
+        ensureAnimationInfo().mIsHideReplaced = replaced;
+    }
+
+    /**
+     * Used internally to be notified when {@link #startPostponedEnterTransition()} has
+     * been called. This listener will only be called once and then be removed from the
+     * listeners.
+     */
+    interface OnStartEnterTransitionListener {
+        void onStartEnterTransition();
+        void startListening();
+    }
+
+    /**
+     * Contains all the animation and transition information for a fragment. This will only
+     * be instantiated for Fragments that have Views.
+     */
+    static class AnimationInfo {
+        // Non-null if the fragment's view hierarchy is currently animating away,
+        // meaning we need to wait a bit on completely destroying it.  This is the
+        // animation that is running.
+        Animator mAnimatingAway;
+
+        // If mAnimatingAway != null, this is the state we should move to once the
+        // animation is done.
+        int mStateAfterAnimating;
+
+        // If app has requested a specific animation, this is the one to use.
+        int mNextAnim;
+
+        // If app has requested a specific transition, this is the one to use.
+        int mNextTransition;
+
+        // If app has requested a specific transition style, this is the one to use.
+        int mNextTransitionStyle;
+
+        private Transition mEnterTransition = null;
+        private Transition mReturnTransition = USE_DEFAULT_TRANSITION;
+        private Transition mExitTransition = null;
+        private Transition mReenterTransition = USE_DEFAULT_TRANSITION;
+        private Transition mSharedElementEnterTransition = null;
+        private Transition mSharedElementReturnTransition = USE_DEFAULT_TRANSITION;
+        private Boolean mAllowReturnTransitionOverlap;
+        private Boolean mAllowEnterTransitionOverlap;
+
+        SharedElementCallback mEnterTransitionCallback = SharedElementCallback.NULL_CALLBACK;
+        SharedElementCallback mExitTransitionCallback = SharedElementCallback.NULL_CALLBACK;
+
+        // True when postponeEnterTransition has been called and startPostponeEnterTransition
+        // hasn't been called yet.
+        boolean mEnterTransitionPostponed;
+
+        // Listener to wait for startPostponeEnterTransition. After being called, it will
+        // be set to null
+        OnStartEnterTransitionListener mStartEnterTransitionListener;
+
+        // True if the View was hidden, but the transition is handling the hide
+        boolean mIsHideReplaced;
+    }
 }
diff --git a/core/java/android/app/FragmentHostCallback.java b/core/java/android/app/FragmentHostCallback.java
index d869168..7e415e9 100644
--- a/core/java/android/app/FragmentHostCallback.java
+++ b/core/java/android/app/FragmentHostCallback.java
@@ -54,7 +54,8 @@
     private boolean mLoadersStarted;
 
     public FragmentHostCallback(Context context, Handler handler, int windowAnimations) {
-        this(null /*activity*/, context, handler, windowAnimations);
+        this((context instanceof Activity) ? (Activity)context : null, context,
+                chooseHandler(context, handler), windowAnimations);
     }
 
     FragmentHostCallback(Activity activity) {
@@ -70,6 +71,19 @@
     }
 
     /**
+     * Used internally in {@link #FragmentHostCallback(Context, Handler, int)} to choose
+     * the Activity's handler or the provided handler.
+     */
+    private static Handler chooseHandler(Context context, Handler handler) {
+        if (handler == null && context instanceof Activity) {
+            Activity activity = (Activity) context;
+            return activity.mHandler;
+        } else {
+            return handler;
+        }
+    }
+
+    /**
      * Print internal state into the given stream.
      *
      * @param prefix Desired prefix to prepend at each line of output.
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 674c3f7..5a2c5e7 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -28,7 +28,6 @@
 import android.content.res.TypedArray;
 import android.os.Bundle;
 import android.os.Debug;
-import android.os.Handler;
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -36,6 +35,7 @@
 import android.util.DebugUtils;
 import android.util.Log;
 import android.util.LogWriter;
+import android.util.Pair;
 import android.util.SparseArray;
 import android.util.SuperNotCalledException;
 import android.view.LayoutInflater;
@@ -44,6 +44,7 @@
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
+
 import com.android.internal.util.FastPrintWriter;
 
 import java.io.FileDescriptor;
@@ -51,6 +52,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * Interface for interacting with {@link Fragment} objects inside of an
@@ -160,6 +162,9 @@
      * can call this function (only from the main thread) to do so.  Note that
      * all callbacks and other related behavior will be done from within this
      * call, so be careful about where this is called from.
+     * <p>
+     * This also forces the start of any postponed Transactions where
+     * {@link Fragment#postponeEnterTransition()} has been called.
      *
      * @return Returns true if there were any pending transactions to be
      * executed.
@@ -206,7 +211,7 @@
     /**
      * Like {@link #popBackStack()}, but performs the operation immediately
      * inside of the call.  This is like calling {@link #executePendingTransactions()}
-     * afterwards.
+     * afterwards without forcing the start of postponed Transactions.
      * @return Returns true if there was something popped, else false.
      */
     public abstract boolean popBackStackImmediate();
@@ -229,7 +234,7 @@
     /**
      * Like {@link #popBackStack(String, int)}, but performs the operation immediately
      * inside of the call.  This is like calling {@link #executePendingTransactions()}
-     * afterwards.
+     * afterwards without forcing the start of postponed Transactions.
      * @return Returns true if there was something popped, else false.
      */
     public abstract boolean popBackStackImmediate(String name, int flags);
@@ -253,7 +258,7 @@
     /**
      * Like {@link #popBackStack(int, int)}, but performs the operation immediately
      * inside of the call.  This is like calling {@link #executePendingTransactions()}
-     * afterwards.
+     * afterwards without forcing the start of postponed Transactions.
      * @return Returns true if there was something popped, else false.
      */
     public abstract boolean popBackStackImmediate(int id, int flags);
@@ -334,6 +339,26 @@
     public abstract boolean isDestroyed();
 
     /**
+     * Registers a {@link FragmentLifecycleCallbacks} to listen to fragment lifecycle events
+     * happening in this FragmentManager. All registered callbacks will be automatically
+     * unregistered when this FragmentManager is destroyed.
+     *
+     * @param cb Callbacks to register
+     * @param recursive true to automatically register this callback for all child FragmentManagers
+     */
+    public abstract void registerFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb,
+            boolean recursive);
+
+    /**
+     * Unregisters a previously registered {@link FragmentLifecycleCallbacks}. If the callback
+     * was not previously registered this call has no effect. All registered callbacks will be
+     * automatically unregistered when this FragmentManager is destroyed.
+     *
+     * @param cb Callbacks to unregister
+     */
+    public abstract void unregisterFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb);
+
+    /**
      * Print the FragmentManager's state into the given stream.
      *
      * @param prefix Text to print at the front of each line.
@@ -357,6 +382,141 @@
      * This may end up being deferred until we move to the resumed state.
      */
     public void invalidateOptionsMenu() { }
+
+    /**
+     * Callback interface for listening to fragment state changes that happen
+     * within a given FragmentManager.
+     */
+    public abstract class FragmentLifecycleCallbacks {
+        /**
+         * Called right before the fragment's {@link Fragment#onAttach(Context)} method is called.
+         * This is a good time to inject any required dependencies for the fragment before any of
+         * the fragment's lifecycle methods are invoked.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         * @param context Context that the Fragment is being attached to
+         */
+        public void onFragmentPreAttached(FragmentManager fm, Fragment f, Context context) {}
+
+        /**
+         * Called after the fragment has been attached to its host. Its host will have had
+         * <code>onAttachFragment</code> called before this call happens.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         * @param context Context that the Fragment was attached to
+         */
+        public void onFragmentAttached(FragmentManager fm, Fragment f, Context context) {}
+
+        /**
+         * Called after the fragment has returned from the FragmentManager's call to
+         * {@link Fragment#onCreate(Bundle)}. This will only happen once for any given
+         * fragment instance, though the fragment may be attached and detached multiple times.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         * @param savedInstanceState Saved instance bundle from a previous instance
+         */
+        public void onFragmentCreated(FragmentManager fm, Fragment f, Bundle savedInstanceState) {}
+
+        /**
+         * Called after the fragment has returned from the FragmentManager's call to
+         * {@link Fragment#onActivityCreated(Bundle)}. This will only happen once for any given
+         * fragment instance, though the fragment may be attached and detached multiple times.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         * @param savedInstanceState Saved instance bundle from a previous instance
+         */
+        public void onFragmentActivityCreated(FragmentManager fm, Fragment f,
+                Bundle savedInstanceState) {}
+
+        /**
+         * Called after the fragment has returned a non-null view from the FragmentManager's
+         * request to {@link Fragment#onCreateView(LayoutInflater, ViewGroup, Bundle)}.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment that created and owns the view
+         * @param v View returned by the fragment
+         * @param savedInstanceState Saved instance bundle from a previous instance
+         */
+        public void onFragmentViewCreated(FragmentManager fm, Fragment f, View v,
+                Bundle savedInstanceState) {}
+
+        /**
+         * Called after the fragment has returned from the FragmentManager's call to
+         * {@link Fragment#onStart()}.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         */
+        public void onFragmentStarted(FragmentManager fm, Fragment f) {}
+
+        /**
+         * Called after the fragment has returned from the FragmentManager's call to
+         * {@link Fragment#onResume()}.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         */
+        public void onFragmentResumed(FragmentManager fm, Fragment f) {}
+
+        /**
+         * Called after the fragment has returned from the FragmentManager's call to
+         * {@link Fragment#onPause()}.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         */
+        public void onFragmentPaused(FragmentManager fm, Fragment f) {}
+
+        /**
+         * Called after the fragment has returned from the FragmentManager's call to
+         * {@link Fragment#onStop()}.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         */
+        public void onFragmentStopped(FragmentManager fm, Fragment f) {}
+
+        /**
+         * Called after the fragment has returned from the FragmentManager's call to
+         * {@link Fragment#onSaveInstanceState(Bundle)}.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         * @param outState Saved state bundle for the fragment
+         */
+        public void onFragmentSaveInstanceState(FragmentManager fm, Fragment f, Bundle outState) {}
+
+        /**
+         * Called after the fragment has returned from the FragmentManager's call to
+         * {@link Fragment#onDestroyView()}.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         */
+        public void onFragmentViewDestroyed(FragmentManager fm, Fragment f) {}
+
+        /**
+         * Called after the fragment has returned from the FragmentManager's call to
+         * {@link Fragment#onDestroy()}.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         */
+        public void onFragmentDestroyed(FragmentManager fm, Fragment f) {}
+
+        /**
+         * Called after the fragment has returned from the FragmentManager's call to
+         * {@link Fragment#onDetach()}.
+         *
+         * @param fm Host FragmentManager
+         * @param f Fragment changing state
+         */
+        public void onFragmentDetached(FragmentManager fm, Fragment f) {}
+    }
 }
 
 final class FragmentManagerState implements Parcelable {
@@ -445,8 +605,7 @@
         }
     }
 
-    ArrayList<Runnable> mPendingActions;
-    Runnable[] mTmpActions;
+    ArrayList<OpGenerator> mPendingActions;
     boolean mExecutingActions;
     
     ArrayList<Fragment> mActive;
@@ -460,10 +619,10 @@
     ArrayList<Integer> mAvailBackStackIndices;
 
     ArrayList<OnBackStackChangedListener> mBackStackChangeListeners;
+    CopyOnWriteArrayList<Pair<FragmentLifecycleCallbacks, Boolean>> mLifecycleCallbacks;
 
     int mCurState = Fragment.INITIALIZING;
     FragmentHostCallback<?> mHost;
-    FragmentController mController;
     FragmentContainer mContainer;
     Fragment mParent;
     
@@ -473,10 +632,18 @@
     String mNoTransactionsBecause;
     boolean mHavePendingDeferredStart;
 
+    // Temporary vars for optimizing execution of BackStackRecords:
+    ArrayList<BackStackRecord> mTmpRecords;
+    ArrayList<Boolean> mTmpIsPop;
+    ArrayList<Fragment> mTmpAddedFragments;
+
     // Temporary vars for state save and restore.
     Bundle mStateBundle = null;
     SparseArray<Parcelable> mStateArray = null;
-    
+
+    // Postponed transactions.
+    ArrayList<StartEnterTransitionListener> mPostponedTransactions;
+
     Runnable mExecCommit = new Runnable() {
         @Override
         public void run() {
@@ -560,61 +727,73 @@
 
     @Override
     public boolean executePendingTransactions() {
-        return execPendingActions();
+        boolean updates = execPendingActions();
+        forcePostponedTransactions();
+        return updates;
     }
 
     @Override
     public void popBackStack() {
-        enqueueAction(new Runnable() {
-            @Override public void run() {
-                popBackStackState(mHost.getHandler(), null, -1, 0);
-            }
-        }, false);
+        enqueueAction(new PopBackStackState(null, -1, 0), false);
     }
 
     @Override
     public boolean popBackStackImmediate() {
         checkStateLoss();
-        executePendingTransactions();
-        return popBackStackState(mHost.getHandler(), null, -1, 0);
+        return popBackStackImmediate(null, -1, 0);
     }
 
     @Override
-    public void popBackStack(final String name, final int flags) {
-        enqueueAction(new Runnable() {
-            @Override public void run() {
-                popBackStackState(mHost.getHandler(), name, -1, flags);
-            }
-        }, false);
+    public void popBackStack(String name, int flags) {
+        enqueueAction(new PopBackStackState(name, -1, flags), false);
     }
 
     @Override
     public boolean popBackStackImmediate(String name, int flags) {
         checkStateLoss();
-        executePendingTransactions();
-        return popBackStackState(mHost.getHandler(), name, -1, flags);
+        return popBackStackImmediate(name, -1, flags);
     }
 
     @Override
-    public void popBackStack(final int id, final int flags) {
+    public void popBackStack(int id, int flags) {
         if (id < 0) {
             throw new IllegalArgumentException("Bad id: " + id);
         }
-        enqueueAction(new Runnable() {
-            @Override public void run() {
-                popBackStackState(mHost.getHandler(), null, id, flags);
-            }
-        }, false);
+        enqueueAction(new PopBackStackState(null, id, flags), false);
     }
 
     @Override
     public boolean popBackStackImmediate(int id, int flags) {
         checkStateLoss();
-        executePendingTransactions();
         if (id < 0) {
             throw new IllegalArgumentException("Bad id: " + id);
         }
-        return popBackStackState(mHost.getHandler(), null, id, flags);
+        return popBackStackImmediate(null, id, flags);
+    }
+
+    /**
+     * Used by all public popBackStackImmediate methods, this executes pending transactions and
+     * returns true if the pop action did anything, regardless of what other pending
+     * transactions did.
+     *
+     * @return true if the pop operation did anything or false otherwise.
+     */
+    private boolean popBackStackImmediate(String name, int id, int flags) {
+        execPendingActions();
+        ensureExecReady(true);
+
+        boolean executePop = popBackStackState(mTmpRecords, mTmpIsPop, name, id, flags);
+        if (executePop) {
+            mExecutingActions = true;
+            try {
+                optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);
+            } finally {
+                cleanupExec();
+            }
+        }
+
+        doPendingDeferredStart();
+        return executePop;
     }
 
     @Override
@@ -785,7 +964,7 @@
             if (N > 0) {
                 writer.print(prefix); writer.println("Pending Actions:");
                 for (int i=0; i<N; i++) {
-                    Runnable r = mPendingActions.get(i);
+                    OpGenerator r = mPendingActions.get(i);
                     writer.print(prefix); writer.print("  #"); writer.print(i);
                             writer.print(": "); writer.println(r);
                 }
@@ -817,14 +996,14 @@
 
     Animator loadAnimator(Fragment fragment, int transit, boolean enter,
             int transitionStyle) {
-        Animator animObj = fragment.onCreateAnimator(transit, enter,
-                fragment.mNextAnim);
+        Animator animObj = fragment.onCreateAnimator(transit, enter, fragment.getNextAnim());
         if (animObj != null) {
             return animObj;
         }
         
-        if (fragment.mNextAnim != 0) {
-            Animator anim = AnimatorInflater.loadAnimator(mHost.getContext(), fragment.mNextAnim);
+        if (fragment.getNextAnim() != 0) {
+            Animator anim = AnimatorInflater.loadAnimator(mHost.getContext(),
+                    fragment.getNextAnim());
             if (anim != null) {
                 return anim;
             }
@@ -900,13 +1079,13 @@
             if (f.mFromLayout && !f.mInLayout) {
                 return;
             }
-            if (f.mAnimatingAway != null) {
+            if (f.getAnimatingAway() != null) {
                 // The fragment is currently being animated...  but!  Now we
                 // want to move our state back up.  Give up on waiting for the
                 // animation, move to whatever the final state should be once
                 // the animation is done, and then we can proceed from there.
-                f.mAnimatingAway = null;
-                moveToState(f, f.mStateAfterAnimating, 0, 0, true);
+                f.setAnimatingAway(null);
+                moveToState(f, f.getStateAfterAnimating(), 0, 0, true);
             }
             switch (f.mState) {
                 case Fragment.INITIALIZING:
@@ -933,6 +1112,7 @@
                     f.mParentFragment = mParent;
                     f.mFragmentManager = mParent != null
                             ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
+                    dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
                     f.mCalled = false;
                     f.onAttach(mHost.getContext());
                     if (!f.mCalled) {
@@ -944,9 +1124,11 @@
                     } else {
                         f.mParentFragment.onAttachFragment(f);
                     }
+                    dispatchOnFragmentAttached(f, mHost.getContext(), false);
 
                     if (!f.mRetaining) {
                         f.performCreate(f.mSavedFragmentState);
+                        dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
                     } else {
                         f.restoreChildFragmentState(f.mSavedFragmentState, true);
                         f.mState = Fragment.CREATED;
@@ -962,6 +1144,7 @@
                             f.mView.setSaveFromParentEnabled(false);
                             if (f.mHidden) f.mView.setVisibility(View.GONE);
                             f.onViewCreated(f.mView, f.mSavedFragmentState);
+                            dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
                         }
                     }
                 case Fragment.CREATED:
@@ -997,21 +1180,21 @@
                             if (f.mView != null) {
                                 f.mView.setSaveFromParentEnabled(false);
                                 if (container != null) {
-                                    Animator anim = loadAnimator(f, transit, true,
-                                            transitionStyle);
-                                    if (anim != null) {
-                                        anim.setTarget(f.mView);
-                                        setHWLayerAnimListenerIfAlpha(f.mView, anim);
-                                        anim.start();
-                                    }
                                     container.addView(f.mView);
+                                    f.mIsNewlyAdded = true;
                                 }
-                                if (f.mHidden) f.mView.setVisibility(View.GONE);
+                                if (f.mHidden) {
+                                    f.mView.setVisibility(View.GONE);
+                                    f.mIsNewlyAdded = false; // No animation required
+                                }
                                 f.onViewCreated(f.mView, f.mSavedFragmentState);
+                                dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
+                                        false);
                             }
                         }
 
                         f.performActivityCreated(f.mSavedFragmentState);
+                        dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
                         if (f.mView != null) {
                             f.restoreViewState(f.mSavedFragmentState);
                         }
@@ -1025,11 +1208,13 @@
                     if (newState > Fragment.STOPPED) {
                         if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
                         f.performStart();
+                        dispatchOnFragmentStarted(f, false);
                     }
                 case Fragment.STARTED:
                     if (newState > Fragment.STARTED) {
                         if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
                         f.performResume();
+                        dispatchOnFragmentResumed(f, false);
                         // Get rid of this in case we saved it and never needed it.
                         f.mSavedFragmentState = null;
                         f.mSavedViewState = null;
@@ -1041,11 +1226,13 @@
                     if (newState < Fragment.RESUMED) {
                         if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
                         f.performPause();
+                        dispatchOnFragmentPaused(f, false);
                     }
                 case Fragment.STARTED:
                     if (newState < Fragment.STARTED) {
                         if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
                         f.performStop();
+                        dispatchOnFragmentStopped(f, false);
                     }
                 case Fragment.STOPPED:
                 case Fragment.ACTIVITY_CREATED:
@@ -1059,9 +1246,11 @@
                             }
                         }
                         f.performDestroyView();
+                        dispatchOnFragmentViewDestroyed(f, false);
                         if (f.mView != null && f.mContainer != null) {
                             Animator anim = null;
-                            if (mCurState > Fragment.INITIALIZING && !mDestroyed) {
+                            if (mCurState > Fragment.INITIALIZING && !mDestroyed &&
+                                    f.mView.getVisibility() == View.VISIBLE) {
                                 anim = loadAnimator(f, transit, false,
                                         transitionStyle);
                             }
@@ -1070,15 +1259,15 @@
                                 final View view = f.mView;
                                 final Fragment fragment = f;
                                 container.startViewTransition(view);
-                                f.mAnimatingAway = anim;
-                                f.mStateAfterAnimating = newState;
+                                f.setAnimatingAway(anim);
+                                f.setStateAfterAnimating(newState);
                                 anim.addListener(new AnimatorListenerAdapter() {
                                     @Override
                                     public void onAnimationEnd(Animator anim) {
                                         container.endViewTransition(view);
-                                        if (fragment.mAnimatingAway != null) {
-                                            fragment.mAnimatingAway = null;
-                                            moveToState(fragment, fragment.mStateAfterAnimating,
+                                        if (fragment.getAnimatingAway() != null) {
+                                            fragment.setAnimatingAway(null);
+                                            moveToState(fragment, fragment.getStateAfterAnimating(),
                                                     0, 0, false);
                                         }
                                     }
@@ -1096,34 +1285,36 @@
                 case Fragment.CREATED:
                     if (newState < Fragment.CREATED) {
                         if (mDestroyed) {
-                            if (f.mAnimatingAway != null) {
+                            if (f.getAnimatingAway() != null) {
                                 // The fragment's containing activity is
                                 // being destroyed, but this fragment is
                                 // currently animating away.  Stop the
                                 // animation right now -- it is not needed,
                                 // and we can't wait any more on destroying
                                 // the fragment.
-                                Animator anim = f.mAnimatingAway;
-                                f.mAnimatingAway = null;
+                                Animator anim = f.getAnimatingAway();
+                                f.setAnimatingAway(null);
                                 anim.cancel();
                             }
                         }
-                        if (f.mAnimatingAway != null) {
+                        if (f.getAnimatingAway() != null) {
                             // We are waiting for the fragment's view to finish
                             // animating away.  Just make a note of the state
                             // the fragment now should move to once the animation
                             // is done.
-                            f.mStateAfterAnimating = newState;
+                            f.setStateAfterAnimating(newState);
                             newState = Fragment.CREATED;
                         } else {
                             if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
                             if (!f.mRetaining) {
                                 f.performDestroy();
+                                dispatchOnFragmentDestroyed(f, false);
                             } else {
                                 f.mState = Fragment.INITIALIZING;
                             }
 
                             f.performDetach();
+                            dispatchOnFragmentDetached(f, false);
                             if (!keepActive) {
                                 if (!f.mRetaining) {
                                     makeInactive(f);
@@ -1149,26 +1340,138 @@
         moveToState(f, mCurState, 0, 0, false);
     }
 
-    void moveToState(int newState, boolean always) {
-        moveToState(newState, 0, 0, always);
+    /**
+     * Fragments that have been shown or hidden don't have their visibility changed or
+     * animations run during the {@link #showFragment(Fragment)} or {@link #hideFragment(Fragment)}
+     * calls. After fragments are brought to their final state in
+     * {@link #moveFragmentToExpectedState(Fragment)} the fragments that have been shown or
+     * hidden must have their visibility changed and their animations started here.
+     *
+     * @param fragment The fragment with mHiddenChanged = true that should change its View's
+     *                 visibility and start the show or hide animation.
+     */
+    void completeShowHideFragment(final Fragment fragment) {
+        if (fragment.mView != null) {
+            Animator anim = loadAnimator(fragment, fragment.getNextTransition(), !fragment.mHidden,
+                    fragment.getNextTransitionStyle());
+            if (anim != null) {
+                anim.setTarget(fragment.mView);
+                if (fragment.mHidden) {
+                    if (fragment.isHideReplaced()) {
+                        fragment.setHideReplaced(false);
+                    } else {
+                        // Delay the actual hide operation until the animation finishes, otherwise
+                        // the fragment will just immediately disappear
+                        anim.addListener(new AnimatorListenerAdapter() {
+                            @Override
+                            public void onAnimationEnd(Animator animation) {
+                                animation.removeListener(this);
+                                if (fragment.mView != null) {
+                                    fragment.mView.setVisibility(View.GONE);
+                                }
+                            }
+                        });
+                    }
+                }
+                setHWLayerAnimListenerIfAlpha(fragment.mView, anim);
+                anim.start();
+            } else {
+                final int visibility = fragment.mHidden && !fragment.isHideReplaced()
+                        ? View.GONE
+                        : View.VISIBLE;
+                fragment.mView.setVisibility(visibility);
+                if (fragment.isHideReplaced()) {
+                    fragment.setHideReplaced(false);
+                }
+            }
+        }
+        if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
+            mNeedMenuInvalidate = true;
+        }
+        fragment.mHiddenChanged = false;
+        fragment.onHiddenChanged(fragment.mHidden);
     }
-    
-    void moveToState(int newState, int transit, int transitStyle, boolean always) {
+
+    /**
+     * Moves a fragment to its expected final state or the fragment manager's state, depending
+     * on whether the fragment manager's state is raised properly.
+     *
+     * @param f The fragment to change.
+     */
+    void moveFragmentToExpectedState(final Fragment f) {
+        if (f == null) {
+            return;
+        }
+        int nextState = mCurState;
+        if (f.mRemoving) {
+            if (f.isInBackStack()) {
+                nextState = Math.min(nextState, Fragment.CREATED);
+            } else {
+                nextState = Math.min(nextState, Fragment.INITIALIZING);
+            }
+        }
+
+        moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);
+
+        if (f.mView != null) {
+            // Move the view if it is out of order
+            Fragment underFragment = findFragmentUnder(f);
+            if (underFragment != null) {
+                final View underView = underFragment.mView;
+                // make sure this fragment is in the right order.
+                final ViewGroup container = f.mContainer;
+                int underIndex = container.indexOfChild(underView);
+                int viewIndex = container.indexOfChild(f.mView);
+                if (viewIndex < underIndex) {
+                    container.removeViewAt(viewIndex);
+                    container.addView(f.mView, underIndex);
+                }
+            }
+            if (f.mIsNewlyAdded && f.mContainer != null) {
+                // Make it visible and run the animations
+                f.mView.setVisibility(View.VISIBLE);
+                f.mIsNewlyAdded = false;
+                // run animations:
+                Animator anim = loadAnimator(f, f.getNextTransition(), true, f.getNextTransitionStyle());
+                if (anim != null) {
+                    anim.setTarget(f.mView);
+                    setHWLayerAnimListenerIfAlpha(f.mView, anim);
+                    anim.start();
+                }
+            }
+        }
+        if (f.mHiddenChanged) {
+            completeShowHideFragment(f);
+        }
+    }
+
+    void moveToState(int newState) {
         if (mHost == null && newState != Fragment.INITIALIZING) {
             throw new IllegalStateException("No activity");
         }
 
-        if (!always && mCurState == newState) {
-            return;
-        }
-
         mCurState = newState;
+
         if (mActive != null) {
             boolean loadersRunning = false;
-            for (int i=0; i<mActive.size(); i++) {
+
+            // Must add them in the proper order. mActive fragments may be out of order
+            final int numAdded = mAdded.size();
+            for (int i = 0; i < numAdded; i++) {
+                Fragment f = mAdded.get(i);
+                moveFragmentToExpectedState(f);
+                if (f.mLoaderManager != null) {
+                    loadersRunning |= f.mLoaderManager.hasRunningLoaders();
+                }
+            }
+
+            // Now iterate through all active fragments. These will include those that are removed
+            // and detached.
+            final int numActive = mActive.size();
+            for (int i = 0; i < numActive; i++) {
                 Fragment f = mActive.get(i);
-                if (f != null) {
-                    moveToState(f, newState, transit, transitStyle, false);
+                if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
+                    moveFragmentToExpectedState(f);
                     if (f.mLoaderManager != null) {
                         loadersRunning |= f.mLoaderManager.hasRunningLoaders();
                     }
@@ -1185,7 +1488,7 @@
             }
         }
     }
-    
+
     void startPendingDeferredFragments() {
         if (mActive == null) return;
 
@@ -1244,6 +1547,9 @@
             mAdded.add(fragment);
             fragment.mAdded = true;
             fragment.mRemoving = false;
+            if (fragment.mView == null) {
+                fragment.mHiddenChanged = false;
+            }
             if (fragment.mHasMenu && fragment.mMenuVisible) {
                 mNeedMenuInvalidate = true;
             }
@@ -1252,8 +1558,8 @@
             }
         }
     }
-    
-    public void removeFragment(Fragment fragment, int transition, int transitionStyle) {
+
+    public void removeFragment(Fragment fragment) {
         if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting);
         final boolean inactive = !fragment.isInBackStack();
         if (!fragment.mDetached || inactive) {
@@ -1273,66 +1579,42 @@
             }
             fragment.mAdded = false;
             fragment.mRemoving = true;
-            moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED,
-                    transition, transitionStyle, false);
         }
     }
-    
-    public void hideFragment(Fragment fragment, int transition, int transitionStyle) {
+
+    /**
+     * Marks a fragment as hidden to be later animated in with
+     * {@link #completeShowHideFragment(Fragment)}.
+     *
+     * @param fragment The fragment to be shown.
+     */
+    public void hideFragment(Fragment fragment) {
         if (DEBUG) Log.v(TAG, "hide: " + fragment);
         if (!fragment.mHidden) {
             fragment.mHidden = true;
-            if (fragment.mView != null) {
-                Animator anim = loadAnimator(fragment, transition, false,
-                        transitionStyle);
-                if (anim != null) {
-                    anim.setTarget(fragment.mView);
-                    // Delay the actual hide operation until the animation finishes, otherwise
-                    // the fragment will just immediately disappear
-                    final Fragment finalFragment = fragment;
-                    anim.addListener(new AnimatorListenerAdapter() {
-                        @Override
-                        public void onAnimationEnd(Animator animation) {
-                            if (finalFragment.mView != null) {
-                                finalFragment.mView.setVisibility(View.GONE);
-                            }
-                        }
-                    });
-                    setHWLayerAnimListenerIfAlpha(finalFragment.mView, anim);
-                    anim.start();
-                } else {
-                    fragment.mView.setVisibility(View.GONE);
-                }
-            }
-            if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
-                mNeedMenuInvalidate = true;
-            }
-            fragment.onHiddenChanged(true);
+            // Toggle hidden changed so that if a fragment goes through show/hide/show
+            // it doesn't go through the animation.
+            fragment.mHiddenChanged = !fragment.mHiddenChanged;
         }
     }
-    
-    public void showFragment(Fragment fragment, int transition, int transitionStyle) {
+
+    /**
+     * Marks a fragment as shown to be later animated in with
+     * {@link #completeShowHideFragment(Fragment)}.
+     *
+     * @param fragment The fragment to be shown.
+     */
+    public void showFragment(Fragment fragment) {
         if (DEBUG) Log.v(TAG, "show: " + fragment);
         if (fragment.mHidden) {
             fragment.mHidden = false;
-            if (fragment.mView != null) {
-                Animator anim = loadAnimator(fragment, transition, true,
-                        transitionStyle);
-                if (anim != null) {
-                    anim.setTarget(fragment.mView);
-                    setHWLayerAnimListenerIfAlpha(fragment.mView, anim);
-                    anim.start();
-                }
-                fragment.mView.setVisibility(View.VISIBLE);
-            }
-            if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
-                mNeedMenuInvalidate = true;
-            }
-            fragment.onHiddenChanged(false);
+            // Toggle hidden changed so that if a fragment goes through show/hide/show
+            // it doesn't go through the animation.
+            fragment.mHiddenChanged = !fragment.mHiddenChanged;
         }
     }
-    
-    public void detachFragment(Fragment fragment, int transition, int transitionStyle) {
+
+    public void detachFragment(Fragment fragment) {
         if (DEBUG) Log.v(TAG, "detach: " + fragment);
         if (!fragment.mDetached) {
             fragment.mDetached = true;
@@ -1346,12 +1628,11 @@
                     mNeedMenuInvalidate = true;
                 }
                 fragment.mAdded = false;
-                moveToState(fragment, Fragment.CREATED, transition, transitionStyle, false);
             }
         }
     }
 
-    public void attachFragment(Fragment fragment, int transition, int transitionStyle) {
+    public void attachFragment(Fragment fragment) {
         if (DEBUG) Log.v(TAG, "attach: " + fragment);
         if (fragment.mDetached) {
             fragment.mDetached = false;
@@ -1368,7 +1649,6 @@
                 if (fragment.mHasMenu && fragment.mMenuVisible) {
                     mNeedMenuInvalidate = true;
                 }
-                moveToState(fragment, mCurState, transition, transitionStyle, false);
             }
         }
     }
@@ -1447,7 +1727,7 @@
      * @param allowStateLoss whether to allow loss of state information
      * @throws IllegalStateException if the activity has been destroyed
      */
-    public void enqueueAction(Runnable action, boolean allowStateLoss) {
+    public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
         if (!allowStateLoss) {
             checkStateLoss();
         }
@@ -1456,10 +1736,25 @@
                 throw new IllegalStateException("Activity has been destroyed");
             }
             if (mPendingActions == null) {
-                mPendingActions = new ArrayList<Runnable>();
+                mPendingActions = new ArrayList<>();
             }
             mPendingActions.add(action);
-            if (mPendingActions.size() == 1) {
+            scheduleCommit();
+        }
+    }
+
+    /**
+     * Schedules the execution when one hasn't been scheduled already. This should happen
+     * the first time {@link #enqueueAction(OpGenerator, boolean)} is called or when
+     * a postponed transaction has been started with
+     * {@link Fragment#startPostponedEnterTransition()}
+     */
+    private void scheduleCommit() {
+        synchronized (this) {
+            boolean postponeReady =
+                    mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
+            boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
+            if (postponeReady || pendingReady) {
                 mHost.getHandler().removeCallbacks(mExecCommit);
                 mHost.getHandler().post(mExecCommit);
             }
@@ -1522,7 +1817,13 @@
         }
     }
 
-    public void execSingleAction(Runnable action, boolean allowStateLoss) {
+    /**
+     * Broken out from exec*, this prepares for gathering and executing operations.
+     *
+     * @param allowStateLoss true if state loss should be ignored or false if it should be
+     *                       checked.
+     */
+    private void ensureExecReady(boolean allowStateLoss) {
         if (mExecutingActions) {
             throw new IllegalStateException("FragmentManager is already executing transactions");
         }
@@ -1535,55 +1836,50 @@
             checkStateLoss();
         }
 
-        mExecutingActions = true;
-        try {
-            action.run();
-        } finally {
-            mExecutingActions = false;
+        if (mTmpRecords == null) {
+            mTmpRecords = new ArrayList<>();
+            mTmpIsPop = new ArrayList<>();
+        }
+        executePostponedTransaction(null, null);
+    }
+
+    public void execSingleAction(OpGenerator action, boolean allowStateLoss) {
+        ensureExecReady(allowStateLoss);
+        if (action.generateOps(mTmpRecords, mTmpIsPop)) {
+            mExecutingActions = true;
+            try {
+                optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);
+            } finally {
+                cleanupExec();
+            }
         }
 
         doPendingDeferredStart();
     }
 
     /**
+     * Broken out of exec*, this cleans up the mExecutingActions and the temporary structures
+     * used in executing operations.
+     */
+    private void cleanupExec() {
+        mExecutingActions = false;
+        mTmpIsPop.clear();
+        mTmpRecords.clear();
+    }
+
+    /**
      * Only call from main thread!
      */
     public boolean execPendingActions() {
-        if (mExecutingActions) {
-            throw new IllegalStateException("Recursive entry to executePendingTransactions");
-        }
-        
-        if (Looper.myLooper() != mHost.getHandler().getLooper()) {
-            throw new IllegalStateException("Must be called from main thread of process");
-        }
+        ensureExecReady(true);
 
         boolean didSomething = false;
-
-        while (true) {
-            int numActions;
-            
-            synchronized (this) {
-                if (mPendingActions == null || mPendingActions.size() == 0) {
-                    break;
-                }
-                
-                numActions = mPendingActions.size();
-                if (mTmpActions == null || mTmpActions.length < numActions) {
-                    mTmpActions = new Runnable[numActions];
-                }
-                mPendingActions.toArray(mTmpActions);
-                mPendingActions.clear();
-                mHost.getHandler().removeCallbacks(mExecCommit);
-            }
-            
+        while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
             mExecutingActions = true;
             try {
-                for (int i = 0; i < numActions; i++) {
-                    mTmpActions[i].run();
-                    mTmpActions[i] = null;
-                }
+                optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);
             } finally {
-                mExecutingActions = false;
+                cleanupExec();
             }
             didSomething = true;
         }
@@ -1593,6 +1889,382 @@
         return didSomething;
     }
 
+    /**
+     * Complete the execution of transactions that have previously been postponed, but are
+     * now ready.
+     */
+    private void executePostponedTransaction(ArrayList<BackStackRecord> records,
+            ArrayList<Boolean> isRecordPop) {
+        int numPostponed = mPostponedTransactions == null ? 0 : mPostponedTransactions.size();
+        for (int i = 0; i < numPostponed; i++) {
+            StartEnterTransitionListener listener = mPostponedTransactions.get(i);
+            if (records != null && !listener.mIsBack) {
+                int index = records.indexOf(listener.mRecord);
+                if (index != -1 && isRecordPop.get(index)) {
+                    listener.cancelTransaction();
+                    continue;
+                }
+            }
+            if (listener.isReady() || (records != null &&
+                    listener.mRecord.interactsWith(records, 0, records.size()))) {
+                mPostponedTransactions.remove(i);
+                i--;
+                numPostponed--;
+                int index;
+                if (records != null && !listener.mIsBack &&
+                        (index = records.indexOf(listener.mRecord)) != -1 &&
+                        isRecordPop.get(index)) {
+                    // This is popping a postponed transaction
+                    listener.cancelTransaction();
+                } else {
+                    listener.completeTransaction();
+                }
+            }
+        }
+    }
+
+    /**
+     * Optimizes BackStackRecord operations. This method merges operations of proximate records
+     * that allow optimization. See {@link FragmentTransaction#setAllowOptimization(boolean)}.
+     * <p>
+     * For example, a transaction that adds to the back stack and then another that pops that
+     * back stack record will be optimized.
+     * <p>
+     * Likewise, two transactions committed that are executed at the same time will be optimized
+     * as well as two pop operations executed together.
+     *
+     * @param records The records pending execution
+     * @param isRecordPop The direction that these records are being run.
+     */
+    private void optimizeAndExecuteOps(ArrayList<BackStackRecord> records,
+            ArrayList<Boolean> isRecordPop) {
+        if (records == null || records.isEmpty()) {
+            return;
+        }
+
+        if (isRecordPop == null || records.size() != isRecordPop.size()) {
+            throw new IllegalStateException("Internal error with the back stack records");
+        }
+
+        // Force start of any postponed transactions that interact with scheduled transactions:
+        executePostponedTransaction(records, isRecordPop);
+
+        final int numRecords = records.size();
+        int startIndex = 0;
+        for (int recordNum = 0; recordNum < numRecords; recordNum++) {
+            final boolean canOptimize = records.get(recordNum).mAllowOptimization;
+            if (!canOptimize) {
+                // execute all previous transactions
+                if (startIndex != recordNum) {
+                    executeOpsTogether(records, isRecordPop, startIndex, recordNum);
+                }
+                // execute all unoptimized together
+                int optimizeEnd;
+                for (optimizeEnd = recordNum + 1; optimizeEnd < numRecords; optimizeEnd++) {
+                    if (records.get(optimizeEnd).mAllowOptimization) {
+                        break;
+                    }
+                }
+                executeOpsTogether(records, isRecordPop, recordNum, optimizeEnd);
+                startIndex = optimizeEnd;
+                recordNum = optimizeEnd - 1;
+            }
+        }
+        if (startIndex != numRecords) {
+            executeOpsTogether(records, isRecordPop, startIndex, numRecords);
+        }
+    }
+
+    /**
+     * Optimizes a subset of a list of BackStackRecords, all of which either allow optimization or
+     * do not allow optimization.
+     * @param records A list of BackStackRecords that are to be optimized
+     * @param isRecordPop The direction that these records are being run.
+     * @param startIndex The index of the first record in <code>records</code> to be optimized
+     * @param endIndex One more than the final record index in <code>records</code> to optimize.
+     */
+    private void executeOpsTogether(ArrayList<BackStackRecord> records,
+            ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
+        final boolean allowOptimization = records.get(startIndex).mAllowOptimization;
+        boolean addToBackStack = false;
+        if (mTmpAddedFragments == null) {
+            mTmpAddedFragments = new ArrayList<>();
+        } else {
+            mTmpAddedFragments.clear();
+        }
+        if (mAdded != null) {
+            mTmpAddedFragments.addAll(mAdded);
+        }
+        for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
+            final BackStackRecord record = records.get(recordNum);
+            final boolean isPop = isRecordPop.get(recordNum);
+            if (!isPop) {
+                record.expandReplaceOps(mTmpAddedFragments);
+            }
+            final int bumpAmount = isPop ? -1 : 1;
+            record.bumpBackStackNesting(bumpAmount);
+            addToBackStack = addToBackStack || record.mAddToBackStack;
+        }
+        mTmpAddedFragments.clear();
+
+        if (!allowOptimization) {
+            FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex,
+                    false);
+        }
+        executeOps(records, isRecordPop, startIndex, endIndex);
+
+        int postponeIndex = endIndex;
+        if (allowOptimization) {
+            moveFragmentsToInvisible();
+            postponeIndex = postponePostponableTransactions(records, isRecordPop,
+                    startIndex, endIndex);
+        }
+
+        if (postponeIndex != startIndex && allowOptimization) {
+            // need to run something now
+            FragmentTransition.startTransitions(this, records, isRecordPop, startIndex,
+                    postponeIndex, true);
+            moveToState(mCurState);
+        }
+
+        for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
+            final BackStackRecord record = records.get(recordNum);
+            final boolean isPop = isRecordPop.get(recordNum);
+            if (isPop && record.mIndex >= 0) {
+                freeBackStackIndex(record.mIndex);
+                record.mIndex = -1;
+            }
+        }
+
+        if (addToBackStack) {
+            reportBackStackChanged();
+        }
+    }
+
+    /**
+     * Examine all transactions and determine which ones are marked as postponed. Those will
+     * have their operations rolled back and moved to the end of the record list (up to endIndex).
+     * It will also add the postponed transaction to the queue.
+     *
+     * @param records A list of BackStackRecords that should be checked.
+     * @param isRecordPop The direction that these records are being run.
+     * @param startIndex The index of the first record in <code>records</code> to be checked
+     * @param endIndex One more than the final record index in <code>records</code> to be checked.
+     * @return The index of the first postponed transaction or endIndex if no transaction was
+     * postponed.
+     */
+    private int postponePostponableTransactions(ArrayList<BackStackRecord> records,
+            ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
+        int postponeIndex = endIndex;
+        for (int i = endIndex - 1; i >= startIndex; i--) {
+            final BackStackRecord record = records.get(i);
+            final boolean isPop = isRecordPop.get(i);
+            boolean isPostponed = record.isPostponed() &&
+                    !record.interactsWith(records, i + 1, endIndex);
+            if (isPostponed) {
+                if (mPostponedTransactions == null) {
+                    mPostponedTransactions = new ArrayList<>();
+                }
+                StartEnterTransitionListener listener =
+                        new StartEnterTransitionListener(record, isPop);
+                mPostponedTransactions.add(listener);
+                record.setOnStartPostponedListener(listener);
+
+                // roll back the transaction
+                if (isPop) {
+                    record.executeOps();
+                } else {
+                    record.executePopOps();
+                }
+
+                // move to the end
+                postponeIndex--;
+                if (i != postponeIndex) {
+                    records.remove(i);
+                    records.add(postponeIndex, record);
+                }
+
+                // different views may be visible now
+                moveFragmentsToInvisible();
+            }
+        }
+        return postponeIndex;
+    }
+
+    /**
+     * When a postponed transaction is ready to be started, this completes the transaction,
+     * removing, hiding, or showing views as well as starting the animations and transitions.
+     * <p>
+     * {@code runtransitions} is set to false when the transaction postponement was interrupted
+     * abnormally -- normally by a new transaction being started that affects the postponed
+     * transaction.
+     *
+     * @param record The transaction to run
+     * @param isPop true if record is popping or false if it is adding
+     * @param runTransitions true if the fragment transition should be run or false otherwise.
+     * @param moveToState true if the state should be changed after executing the operations.
+     *                    This is false when the transaction is canceled when a postponed
+     *                    transaction is popped.
+     */
+    private void completeExecute(BackStackRecord record, boolean isPop, boolean runTransitions,
+            boolean moveToState) {
+        ArrayList<BackStackRecord> records = new ArrayList<>(1);
+        ArrayList<Boolean> isRecordPop = new ArrayList<>(1);
+        records.add(record);
+        isRecordPop.add(isPop);
+        executeOps(records, isRecordPop, 0, 1);
+        if (runTransitions) {
+            FragmentTransition.startTransitions(this, records, isRecordPop, 0, 1, true);
+        }
+        if (moveToState) {
+            moveToState(mCurState);
+        } else if (mActive != null) {
+            final int numActive = mActive.size();
+            for (int i = 0; i < numActive; i++) {
+                // Allow added fragments to be removed during the pop since we aren't going
+                // to move them to the final state with moveToState(mCurState).
+                Fragment fragment = mActive.get(i);
+                if (fragment.mView != null && fragment.mIsNewlyAdded &&
+                        record.interactsWith(fragment.mContainerId)) {
+                    fragment.mIsNewlyAdded = false;
+                }
+            }
+        }
+    }
+
+    /**
+     * Find a fragment within the fragment's container whose View should be below the passed
+     * fragment. {@code null} is returned when the fragment has no View or if there should be
+     * no fragment with a View below the given fragment.
+     *
+     * As an example, if mAdded has two Fragments with Views sharing the same container:
+     * FragmentA
+     * FragmentB
+     *
+     * Then, when processing FragmentB, FragmentA will be returned. If, however, FragmentA
+     * had no View, null would be returned.
+     *
+     * @param f The fragment that may be on top of another fragment.
+     * @return The fragment with a View under f, if one exists or null if f has no View or
+     * there are no fragments with Views in the same container.
+     */
+    private Fragment findFragmentUnder(Fragment f) {
+        final ViewGroup container = f.mContainer;
+        final View view = f.mView;
+
+        if (container == null || view == null) {
+            return null;
+        }
+
+        final int fragmentIndex = mAdded.indexOf(f);
+        for (int i = fragmentIndex - 1; i >= 0; i--) {
+            Fragment underFragment = mAdded.get(i);
+            if (underFragment.mContainer == container && underFragment.mView != null) {
+                // Found the fragment under this one
+                return underFragment;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Run the operations in the BackStackRecords, either to push or pop.
+     *
+     * @param records The list of records whose operations should be run.
+     * @param isRecordPop The direction that these records are being run.
+     * @param startIndex The index of the first entry in records to run.
+     * @param endIndex One past the index of the final entry in records to run.
+     */
+    private static void executeOps(ArrayList<BackStackRecord> records,
+            ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
+        for (int i = startIndex; i < endIndex; i++) {
+            final BackStackRecord record = records.get(i);
+            final boolean isPop = isRecordPop.get(i);
+            if (isPop) {
+                record.executePopOps();
+            } else {
+                record.executeOps();
+            }
+        }
+    }
+
+    /**
+     * Ensure that fragments that are added are moved to at least the CREATED state.
+     * Any newly-added Views are made INVISIBLE so that the Transaction can be postponed
+     * with {@link Fragment#postponeEnterTransition()}.
+     */
+    private void moveFragmentsToInvisible() {
+        if (mCurState < Fragment.CREATED) {
+            return;
+        }
+        // We want to leave the fragment in the started state
+        final int state = Math.min(mCurState, Fragment.STARTED);
+        final int numAdded = mAdded == null ? 0 : mAdded.size();
+        for (int i = 0; i < numAdded; i++) {
+            Fragment fragment = mAdded.get(i);
+            if (fragment.mState < state) {
+                moveToState(fragment, state, fragment.getNextAnim(), fragment.getNextTransition(), false);
+                if (fragment.mView != null && !fragment.mHidden && fragment.mIsNewlyAdded) {
+                    fragment.mView.setVisibility(View.INVISIBLE);
+                }
+            }
+        }
+    }
+
+    /**
+     * Starts all postponed transactions regardless of whether they are ready or not.
+     */
+    private void forcePostponedTransactions() {
+        if (mPostponedTransactions != null) {
+            while (!mPostponedTransactions.isEmpty()) {
+                mPostponedTransactions.remove(0).completeTransaction();
+            }
+        }
+    }
+
+    /**
+     * Ends the animations of fragments so that they immediately reach the end state.
+     * This is used prior to saving the state so that the correct state is saved.
+     */
+    private void endAnimatingAwayFragments() {
+        final int numFragments = mActive == null ? 0 : mActive.size();
+        for (int i = 0; i < numFragments; i++) {
+            Fragment fragment = mActive.get(i);
+            if (fragment != null && fragment.getAnimatingAway() != null) {
+                // Give up waiting for the animation and just end it.
+                fragment.getAnimatingAway().end();
+            }
+        }
+    }
+
+    /**
+     * Adds all records in the pending actions to records and whether they are add or pop
+     * operations to isPop. After executing, the pending actions will be empty.
+     *
+     * @param records All pending actions will generate BackStackRecords added to this.
+     *                This contains the transactions, in order, to execute.
+     * @param isPop All pending actions will generate booleans to add to this. This contains
+     *              an entry for each entry in records to indicate whether or not it is a
+     *              pop action.
+     */
+    private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records,
+            ArrayList<Boolean> isPop) {
+        int numActions;
+        synchronized (this) {
+            if (mPendingActions == null || mPendingActions.size() == 0) {
+                return false;
+            }
+
+            numActions = mPendingActions.size();
+            for (int i = 0; i < numActions; i++) {
+                mPendingActions.get(i).generateOps(records, isPop);
+            }
+            mPendingActions.clear();
+            mHost.getHandler().removeCallbacks(mExecCommit);
+        }
+        return numActions > 0;
+    }
+
     void doPendingDeferredStart() {
         if (mHavePendingDeferredStart) {
             boolean loadersRunning = false;
@@ -1624,24 +2296,19 @@
         mBackStack.add(state);
         reportBackStackChanged();
     }
-    
-    boolean popBackStackState(Handler handler, String name, int id, int flags) {
+
+    boolean popBackStackState(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop,
+            String name, int id, int flags) {
         if (mBackStack == null) {
             return false;
         }
-        if (name == null && id < 0 && (flags&POP_BACK_STACK_INCLUSIVE) == 0) {
-            int last = mBackStack.size()-1;
+        if (name == null && id < 0 && (flags & POP_BACK_STACK_INCLUSIVE) == 0) {
+            int last = mBackStack.size() - 1;
             if (last < 0) {
                 return false;
             }
-            final BackStackRecord bss = mBackStack.remove(last);
-            SparseArray<BackStackRecord.FragmentContainerTransition> transitioningFragments =
-                    new SparseArray<>();
-            if (mCurState >= Fragment.CREATED) {
-                bss.calculateBackFragments(transitioningFragments);
-            }
-            bss.popFromBackStack(true, null, transitioningFragments);
-            reportBackStackChanged();
+            records.add(mBackStack.remove(last));
+            isRecordPop.add(true);
         } else {
             int index = -1;
             if (name != null || id >= 0) {
@@ -1678,25 +2345,10 @@
             if (index == mBackStack.size()-1) {
                 return false;
             }
-            final ArrayList<BackStackRecord> states
-                    = new ArrayList<BackStackRecord>();
-            for (int i=mBackStack.size()-1; i>index; i--) {
-                states.add(mBackStack.remove(i));
+            for (int i = mBackStack.size() - 1; i > index; i--) {
+                records.add(mBackStack.remove(i));
+                isRecordPop.add(true);
             }
-            final int LAST = states.size()-1;
-            SparseArray<BackStackRecord.FragmentContainerTransition> transitioningFragments =
-                    new SparseArray<>();
-            if (mCurState >= Fragment.CREATED) {
-                for (int i = 0; i <= LAST; i++) {
-                    states.get(i).calculateBackFragments(transitioningFragments);
-                }
-            }
-            BackStackRecord.TransitionState state = null;
-            for (int i=0; i<=LAST; i++) {
-                if (DEBUG) Log.v(TAG, "Popping back stack state: " + states.get(i));
-                state = states.get(i).popFromBackStack(i == LAST, state, transitioningFragments);
-            }
-            reportBackStackChanged();
         }
         return true;
     }
@@ -1766,6 +2418,7 @@
             mStateBundle = new Bundle();
         }
         f.performSaveInstanceState(mStateBundle);
+        dispatchOnFragmentSaveInstanceState(f, mStateBundle, false);
         if (!mStateBundle.isEmpty()) {
             result = mStateBundle;
             mStateBundle = null;
@@ -1795,6 +2448,8 @@
     Parcelable saveAllState() {
         // Make sure all pending operations have now been executed to get
         // our state update-to-date.
+        forcePostponedTransactions();
+        endAnimatingAwayFragments();
         execPendingActions();
 
         mStateSaved = true;
@@ -2036,40 +2691,40 @@
     
     public void dispatchCreate() {
         mStateSaved = false;
-        moveToState(Fragment.CREATED, false);
+        moveToState(Fragment.CREATED);
     }
     
     public void dispatchActivityCreated() {
         mStateSaved = false;
-        moveToState(Fragment.ACTIVITY_CREATED, false);
+        moveToState(Fragment.ACTIVITY_CREATED);
     }
     
     public void dispatchStart() {
         mStateSaved = false;
-        moveToState(Fragment.STARTED, false);
+        moveToState(Fragment.STARTED);
     }
     
     public void dispatchResume() {
         mStateSaved = false;
-        moveToState(Fragment.RESUMED, false);
+        moveToState(Fragment.RESUMED);
     }
     
     public void dispatchPause() {
-        moveToState(Fragment.STARTED, false);
+        moveToState(Fragment.STARTED);
     }
     
     public void dispatchStop() {
-        moveToState(Fragment.STOPPED, false);
+        moveToState(Fragment.STOPPED);
     }
     
     public void dispatchDestroyView() {
-        moveToState(Fragment.CREATED, false);
+        moveToState(Fragment.CREATED);
     }
 
     public void dispatchDestroy() {
         mDestroyed = true;
         execPendingActions();
-        moveToState(Fragment.INITIALIZING, false);
+        moveToState(Fragment.INITIALIZING);
         mHost = null;
         mContainer = null;
         mParent = null;
@@ -2218,6 +2873,265 @@
         }
     }
 
+    public void registerFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb,
+            boolean recursive) {
+        if (mLifecycleCallbacks == null) {
+            mLifecycleCallbacks = new CopyOnWriteArrayList<>();
+        }
+        mLifecycleCallbacks.add(new Pair(cb, recursive));
+    }
+
+    public void unregisterFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb) {
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+
+        synchronized (mLifecycleCallbacks) {
+            for (int i = 0, N = mLifecycleCallbacks.size(); i < N; i++) {
+                if (mLifecycleCallbacks.get(i).first == cb) {
+                    mLifecycleCallbacks.remove(i);
+                    break;
+                }
+            }
+        }
+    }
+
+    void dispatchOnFragmentPreAttached(Fragment f, Context context, boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentPreAttached(f, context, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentPreAttached(this, f, context);
+            }
+        }
+    }
+
+    void dispatchOnFragmentAttached(Fragment f, Context context, boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentAttached(f, context, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentAttached(this, f, context);
+            }
+        }
+    }
+
+    void dispatchOnFragmentCreated(Fragment f, Bundle savedInstanceState, boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentCreated(f, savedInstanceState, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentCreated(this, f, savedInstanceState);
+            }
+        }
+    }
+
+    void dispatchOnFragmentActivityCreated(Fragment f, Bundle savedInstanceState,
+            boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentActivityCreated(f, savedInstanceState, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentActivityCreated(this, f, savedInstanceState);
+            }
+        }
+    }
+
+    void dispatchOnFragmentViewCreated(Fragment f, View v, Bundle savedInstanceState,
+            boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentViewCreated(f, v, savedInstanceState, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentViewCreated(this, f, v, savedInstanceState);
+            }
+        }
+    }
+
+    void dispatchOnFragmentStarted(Fragment f, boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentStarted(f, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentStarted(this, f);
+            }
+        }
+    }
+
+    void dispatchOnFragmentResumed(Fragment f, boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentResumed(f, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentResumed(this, f);
+            }
+        }
+    }
+
+    void dispatchOnFragmentPaused(Fragment f, boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentPaused(f, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentPaused(this, f);
+            }
+        }
+    }
+
+    void dispatchOnFragmentStopped(Fragment f, boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentStopped(f, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentStopped(this, f);
+            }
+        }
+    }
+
+    void dispatchOnFragmentSaveInstanceState(Fragment f, Bundle outState, boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentSaveInstanceState(f, outState, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentSaveInstanceState(this, f, outState);
+            }
+        }
+    }
+
+    void dispatchOnFragmentViewDestroyed(Fragment f, boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentViewDestroyed(f, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentViewDestroyed(this, f);
+            }
+        }
+    }
+
+    void dispatchOnFragmentDestroyed(Fragment f, boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentDestroyed(f, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentDestroyed(this, f);
+            }
+        }
+    }
+
+    void dispatchOnFragmentDetached(Fragment f, boolean onlyRecursive) {
+        if (mParent != null) {
+            FragmentManager parentManager = mParent.getFragmentManager();
+            if (parentManager instanceof FragmentManagerImpl) {
+                ((FragmentManagerImpl) parentManager)
+                        .dispatchOnFragmentDetached(f, true);
+            }
+        }
+        if (mLifecycleCallbacks == null) {
+            return;
+        }
+        for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) {
+            if (!onlyRecursive || p.second) {
+                p.first.onFragmentDetached(this, f);
+            }
+        }
+    }
+
     @Override
     public void invalidateOptionsMenu() {
         if (mHost != null && mCurState == Fragment.RESUMED) {
@@ -2363,4 +3277,121 @@
     LayoutInflater.Factory2 getLayoutInflaterFactory() {
         return this;
     }
+
+    /**
+     * An add or pop transaction to be scheduled for the UI thread.
+     */
+    interface OpGenerator {
+        /**
+         * Generate transactions to add to {@code records} and whether or not the transaction is
+         * an add or pop to {@code isRecordPop}.
+         *
+         * records and isRecordPop must be added equally so that each transaction in records
+         * matches the boolean for whether or not it is a pop in isRecordPop.
+         *
+         * @param records A list to add transactions to.
+         * @param isRecordPop A list to add whether or not the transactions added to records is
+         *                    a pop transaction.
+         * @return true if something was added or false otherwise.
+         */
+        boolean generateOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop);
+    }
+
+    /**
+     * A pop operation OpGenerator. This will be run on the UI thread and will generate the
+     * transactions that will be popped if anything can be popped.
+     */
+    private class PopBackStackState implements OpGenerator {
+        final String mName;
+        final int mId;
+        final int mFlags;
+
+        public PopBackStackState(String name, int id, int flags) {
+            mName = name;
+            mId = id;
+            mFlags = flags;
+        }
+
+        @Override
+        public boolean generateOps(ArrayList<BackStackRecord> records,
+                ArrayList<Boolean> isRecordPop) {
+            return popBackStackState(records, isRecordPop, mName, mId, mFlags);
+        }
+    }
+
+    /**
+     * A listener for a postponed transaction. This waits until
+     * {@link Fragment#startPostponedEnterTransition()} is called or a transaction is started
+     * that interacts with this one, based on interactions with the fragment container.
+     */
+    static class StartEnterTransitionListener
+            implements Fragment.OnStartEnterTransitionListener {
+        private final boolean mIsBack;
+        private final BackStackRecord mRecord;
+        private int mNumPostponed;
+
+        public StartEnterTransitionListener(BackStackRecord record, boolean isBack) {
+            mIsBack = isBack;
+            mRecord = record;
+        }
+
+        /**
+         * Called from {@link Fragment#startPostponedEnterTransition()}, this decreases the
+         * number of Fragments that are postponed. This may cause the transaction to schedule
+         * to finish running and run transitions and animations.
+         */
+        @Override
+        public void onStartEnterTransition() {
+            mNumPostponed--;
+            if (mNumPostponed != 0) {
+                return;
+            }
+            mRecord.mManager.scheduleCommit();
+        }
+
+        /**
+         * Called from {@link Fragment#
+         * setOnStartEnterTransitionListener(Fragment.OnStartEnterTransitionListener)}, this
+         * increases the number of fragments that are postponed as part of this transaction.
+         */
+        @Override
+        public void startListening() {
+            mNumPostponed++;
+        }
+
+        /**
+         * @return true if there are no more postponed fragments as part of the transaction.
+         */
+        public boolean isReady() {
+            return mNumPostponed == 0;
+        }
+
+        /**
+         * Completes the transaction and start the animations and transitions. This may skip
+         * the transitions if this is called before all fragments have called
+         * {@link Fragment#startPostponedEnterTransition()}.
+         */
+        public void completeTransaction() {
+            final boolean canceled;
+            canceled = mNumPostponed > 0;
+            FragmentManagerImpl manager = mRecord.mManager;
+            final int numAdded = manager.mAdded.size();
+            for (int i = 0; i < numAdded; i++) {
+                final Fragment fragment = manager.mAdded.get(i);
+                fragment.setOnStartEnterTransitionListener(null);
+                if (canceled && fragment.isPostponed()) {
+                    fragment.startPostponedEnterTransition();
+                }
+            }
+            mRecord.mManager.completeExecute(mRecord, mIsBack, !canceled, true);
+        }
+
+        /**
+         * Cancels this transaction instead of completing it. That means that the state isn't
+         * changed, so the pop results in no change to the state.
+         */
+        public void cancelTransaction() {
+            mRecord.mManager.completeExecute(mRecord, mIsBack, false, false);
+        }
+    }
 }
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index 633e85b..25a7839 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -260,6 +260,32 @@
     public abstract FragmentTransaction setBreadCrumbShortTitle(CharSequence text);
 
     /**
+     * Sets whether or not to allow optimizing operations within and across
+     * transactions. Optimizing fragment transaction's operations can eliminate
+     * operations that cancel. For example, if two transactions are executed
+     * together, one that adds a fragment A and the next replaces it with fragment B,
+     * the operations will cancel and only fragment B will be added. That means that
+     * fragment A may not go through the creation/destruction lifecycle.
+     * <p>
+     * The side effect of optimization is that fragments may have state changes
+     * out of the expected order. For example, one transaction adds fragment A,
+     * a second adds fragment B, then a third removes fragment A. Without optimization,
+     * fragment B could expect that while it is being created, fragment A will also
+     * exist because fragment A will be removed after fragment B was added.
+     * With optimization, fragment B cannot expect fragment A to exist when
+     * it has been created because fragment A's add/remove will be optimized out.
+     * <p>
+     * The default is {@code false} for applications targeting version
+     * versions prior to O and {@code true} for applications targeting O and
+     * later.
+     *
+     * @param allowOptimization {@code true} to enable optimizing operations
+     *                          or {@code false} to disable optimizing
+     *                          operations on this transaction.
+     */
+    public abstract FragmentTransaction setAllowOptimization(boolean allowOptimization);
+
+    /**
      * Schedules a commit of this transaction.  The commit does
      * not happen immediately; it will be scheduled as work on the main thread
      * to be done the next time that thread is ready.
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
new file mode 100644
index 0000000..d27dff5
--- /dev/null
+++ b/core/java/android/app/FragmentTransition.java
@@ -0,0 +1,1363 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app;
+
+import android.graphics.Rect;
+import android.os.Build;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+import android.transition.TransitionSet;
+import android.util.ArrayMap;
+import android.util.SparseArray;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Contains the Fragment Transition functionality for both optimized and unoptimized
+ * Fragment Transactions. With optimized fragment transactions, all Views have been
+ * added to the View hierarchy prior to calling startTransitions. With
+ */
+class FragmentTransition {
+    /**
+     * The inverse of all BackStackRecord operation commands. This assumes that
+     * REPLACE operations have already been replaced by add/remove operations.
+     */
+    private static final int[] INVERSE_OPS = {
+            BackStackRecord.OP_NULL,   // inverse of OP_NULL (error)
+            BackStackRecord.OP_REMOVE, // inverse of OP_ADD
+            BackStackRecord.OP_NULL,   // inverse of OP_REPLACE (error)
+            BackStackRecord.OP_ADD,    // inverse of OP_REMOVE
+            BackStackRecord.OP_SHOW,   // inverse of OP_HIDE
+            BackStackRecord.OP_HIDE,   // inverse of OP_SHOW
+            BackStackRecord.OP_ATTACH, // inverse of OP_DETACH
+            BackStackRecord.OP_DETACH, // inverse of OP_ATTACH
+    };
+
+    /**
+     * The main entry point for Fragment Transitions, this starts the transitions
+     * set on the leaving Fragment's {@link Fragment#getExitTransition()}, the
+     * entering Fragment's {@link Fragment#getEnterTransition()} and
+     * {@link Fragment#getSharedElementEnterTransition()}. When popping,
+     * the leaving Fragment's {@link Fragment#getReturnTransition()} and
+     * {@link Fragment#getSharedElementReturnTransition()} and the entering
+     * {@link Fragment#getReenterTransition()} will be run.
+     * <p>
+     * With optimized Fragment Transitions, all Views have been added to the
+     * View hierarchy prior to calling this method. The incoming Fragment's Views
+     * will be INVISIBLE. With unoptimized Fragment Transitions, this method
+     * is called before any change has been made to the hierarchy. That means
+     * that the added Fragments have not created their Views yet and the hierarchy
+     * is unknown.
+     *
+     * @param fragmentManager The executing FragmentManagerImpl
+     * @param records The list of transactions being executed.
+     * @param isRecordPop For each transaction, whether it is a pop transaction or not.
+     * @param startIndex The first index into records and isRecordPop to execute as
+     *                   part of this transition.
+     * @param endIndex One past the last index into records and isRecordPop to execute
+     *                 as part of this transition.
+     * @param isOptimized true if this is an optimized transaction, meaning that the
+     *                    Views of incoming fragments have been added. false if the
+     *                    transaction has yet to be run and Views haven't been created.
+     */
+    static void startTransitions(FragmentManagerImpl fragmentManager,
+            ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop,
+            int startIndex, int endIndex, boolean isOptimized) {
+        if (fragmentManager.mCurState < Fragment.CREATED) {
+            return;
+        }
+        SparseArray<FragmentContainerTransition> transitioningFragments =
+                new SparseArray<>();
+        for (int i = startIndex; i < endIndex; i++) {
+            final BackStackRecord record = records.get(i);
+            final boolean isPop = isRecordPop.get(i);
+            if (isPop) {
+                calculatePopFragments(record, transitioningFragments, isOptimized);
+            } else {
+                calculateFragments(record, transitioningFragments, isOptimized);
+            }
+        }
+
+        if (transitioningFragments.size() != 0) {
+            final View nonExistentView = new View(fragmentManager.mHost.getContext());
+            final int numContainers = transitioningFragments.size();
+            for (int i = 0; i < numContainers; i++) {
+                int containerId = transitioningFragments.keyAt(i);
+                ArrayMap<String, String> nameOverrides = calculateNameOverrides(containerId,
+                        records, isRecordPop, startIndex, endIndex);
+
+                FragmentContainerTransition containerTransition = transitioningFragments.valueAt(i);
+
+                if (isOptimized) {
+                    configureTransitionsOptimized(fragmentManager, containerId,
+                            containerTransition, nonExistentView, nameOverrides);
+                } else {
+                    configureTransitionsUnoptimized(fragmentManager, containerId,
+                            containerTransition, nonExistentView, nameOverrides);
+                }
+            }
+        }
+    }
+
+    /**
+     * Iterates through the transactions that affect a given fragment container
+     * and tracks the shared element names across transactions. This is most useful
+     * in pop transactions where the names of shared elements are known.
+     *
+     * @param containerId The container ID that is executing the transition.
+     * @param records The list of transactions being executed.
+     * @param isRecordPop For each transaction, whether it is a pop transaction or not.
+     * @param startIndex The first index into records and isRecordPop to execute as
+     *                   part of this transition.
+     * @param endIndex One past the last index into records and isRecordPop to execute
+     *                 as part of this transition.
+     * @return A map from the initial shared element name to the final shared element name
+     * before any onMapSharedElements is run.
+     */
+    private static ArrayMap<String, String> calculateNameOverrides(int containerId,
+            ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop,
+            int startIndex, int endIndex) {
+        ArrayMap<String, String> nameOverrides = new ArrayMap<>();
+        for (int recordNum = endIndex - 1; recordNum >= startIndex; recordNum--) {
+            final BackStackRecord record = records.get(recordNum);
+            if (!record.interactsWith(containerId)) {
+                continue;
+            }
+            final boolean isPop = isRecordPop.get(recordNum);
+            if (record.mSharedElementSourceNames != null) {
+                final int numSharedElements = record.mSharedElementSourceNames.size();
+                final ArrayList<String> sources;
+                final ArrayList<String> targets;
+                if (isPop) {
+                    targets = record.mSharedElementSourceNames;
+                    sources = record.mSharedElementTargetNames;
+                } else {
+                    sources = record.mSharedElementSourceNames;
+                    targets = record.mSharedElementTargetNames;
+                }
+                for (int i = 0; i < numSharedElements; i++) {
+                    String sourceName = sources.get(i);
+                    String targetName = targets.get(i);
+                    String previousTarget = nameOverrides.remove(targetName);
+                    if (previousTarget != null) {
+                        nameOverrides.put(sourceName, previousTarget);
+                    } else {
+                        nameOverrides.put(sourceName, targetName);
+                    }
+                }
+            }
+        }
+        return nameOverrides;
+    }
+
+    /**
+     * Configures a transition for a single fragment container for which the transaction was
+     * optimized. That means that all Fragment Views have been added and incoming fragment
+     * Views are marked invisible.
+     *
+     * @param fragmentManager The executing FragmentManagerImpl
+     * @param containerId The container ID that is executing the transition.
+     * @param fragments A structure holding the transitioning fragments in this container.
+     * @param nonExistentView A View that does not exist in the hierarchy. This is used to
+     *                        prevent transitions from acting on other Views when there is no
+     *                        other target.
+     * @param nameOverrides A map of the shared element names from the starting fragment to
+     *                      the final fragment's Views as given in
+     *                      {@link FragmentTransaction#addSharedElement(View, String)}.
+     */
+    private static void configureTransitionsOptimized(FragmentManagerImpl fragmentManager,
+            int containerId, FragmentContainerTransition fragments,
+            View nonExistentView, ArrayMap<String, String> nameOverrides) {
+        ViewGroup sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+        if (sceneRoot == null) {
+            return;
+        }
+        final Fragment inFragment = fragments.lastIn;
+        final Fragment outFragment = fragments.firstOut;
+        final boolean inIsPop = fragments.lastInIsPop;
+        final boolean outIsPop = fragments.firstOutIsPop;
+
+        ArrayList<View> sharedElementsIn = new ArrayList<>();
+        ArrayList<View> sharedElementsOut = new ArrayList<>();
+        Transition enterTransition = getEnterTransition(inFragment, inIsPop);
+        Transition exitTransition = getExitTransition(outFragment, outIsPop);
+
+        TransitionSet sharedElementTransition = configureSharedElementsOptimized(sceneRoot,
+                nonExistentView, nameOverrides, fragments, sharedElementsOut, sharedElementsIn,
+                enterTransition, exitTransition);
+
+        if (enterTransition == null && sharedElementTransition == null &&
+                exitTransition == null) {
+            return; // no transitions!
+        }
+
+        ArrayList<View> exitingViews = configureEnteringExitingViews(exitTransition,
+                outFragment, sharedElementsOut, nonExistentView);
+
+        ArrayList<View> enteringViews = configureEnteringExitingViews(enterTransition,
+                inFragment, sharedElementsIn, nonExistentView);
+
+        setViewVisibility(enteringViews, View.INVISIBLE);
+
+        Transition transition = mergeTransitions(enterTransition, exitTransition,
+                sharedElementTransition, inFragment, inIsPop);
+
+        if (transition != null) {
+            replaceHide(exitTransition, outFragment, exitingViews);
+            transition.setNameOverrides(nameOverrides);
+            scheduleRemoveTargets(transition,
+                    enterTransition, enteringViews, exitTransition, exitingViews,
+                    sharedElementTransition, sharedElementsIn);
+            TransitionManager.beginDelayedTransition(sceneRoot, transition);
+            setViewVisibility(enteringViews, View.VISIBLE);
+            // Swap the shared element targets
+            if (sharedElementTransition != null) {
+                sharedElementTransition.getTargets().clear();
+                sharedElementTransition.getTargets().addAll(sharedElementsIn);
+                replaceTargets(sharedElementTransition, sharedElementsOut, sharedElementsIn);
+            }
+        }
+    }
+
+    /**
+     * Configures a transition for a single fragment container for which the transaction was
+     * not optimized. That means that the transaction has not been executed yet, so incoming
+     * Views are not yet known.
+     *
+     * @param fragmentManager The executing FragmentManagerImpl
+     * @param containerId The container ID that is executing the transition.
+     * @param fragments A structure holding the transitioning fragments in this container.
+     * @param nonExistentView A View that does not exist in the hierarchy. This is used to
+     *                        prevent transitions from acting on other Views when there is no
+     *                        other target.
+     * @param nameOverrides A map of the shared element names from the starting fragment to
+     *                      the final fragment's Views as given in
+     *                      {@link FragmentTransaction#addSharedElement(View, String)}.
+     */
+    private static void configureTransitionsUnoptimized(FragmentManagerImpl fragmentManager,
+            int containerId, FragmentContainerTransition fragments,
+            View nonExistentView, ArrayMap<String, String> nameOverrides) {
+        ViewGroup sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+        if (sceneRoot == null) {
+            return;
+        }
+        final Fragment inFragment = fragments.lastIn;
+        final Fragment outFragment = fragments.firstOut;
+        final boolean inIsPop = fragments.lastInIsPop;
+        final boolean outIsPop = fragments.firstOutIsPop;
+
+        Transition enterTransition = getEnterTransition(inFragment, inIsPop);
+        Transition exitTransition = getExitTransition(outFragment, outIsPop);
+
+        ArrayList<View> sharedElementsOut = new ArrayList<>();
+        ArrayList<View> sharedElementsIn = new ArrayList<>();
+
+        TransitionSet sharedElementTransition = configureSharedElementsUnoptimized(sceneRoot,
+                nonExistentView, nameOverrides, fragments, sharedElementsOut, sharedElementsIn,
+                enterTransition, exitTransition);
+
+        if (enterTransition == null && sharedElementTransition == null &&
+                exitTransition == null) {
+            return; // no transitions!
+        }
+
+        ArrayList<View> exitingViews = configureEnteringExitingViews(exitTransition,
+                outFragment, sharedElementsOut, nonExistentView);
+
+        if (exitingViews == null || exitingViews.isEmpty()) {
+            exitTransition = null;
+        }
+
+        if (enterTransition != null) {
+            // Ensure the entering transition doesn't target anything until the views are made
+            // visible
+            enterTransition.addTarget(nonExistentView);
+        }
+
+        Transition transition = mergeTransitions(enterTransition, exitTransition,
+                sharedElementTransition, inFragment, fragments.lastInIsPop);
+
+        if (transition != null) {
+            transition.setNameOverrides(nameOverrides);
+            final ArrayList<View> enteringViews = new ArrayList<>();
+            scheduleRemoveTargets(transition,
+                    enterTransition, enteringViews, exitTransition, exitingViews,
+                    sharedElementTransition, sharedElementsIn);
+            scheduleTargetChange(sceneRoot, inFragment, nonExistentView, sharedElementsIn,
+                    enterTransition, enteringViews, exitTransition, exitingViews);
+
+            TransitionManager.beginDelayedTransition(sceneRoot, transition);
+        }
+    }
+
+    /**
+     * Replace hide operations with visibility changes on the exiting views. Instead of making
+     * the entire fragment's view GONE, make each exiting view INVISIBLE. At the end of the
+     * transition, make the fragment's view GONE.
+     */
+    private static void replaceHide(Transition exitTransition, Fragment exitingFragment,
+            final ArrayList<View> exitingViews) {
+        if (exitingFragment != null && exitTransition != null && exitingFragment.mAdded
+                && exitingFragment.mHidden && exitingFragment.mHiddenChanged) {
+            exitingFragment.setHideReplaced(true);
+            final View fragmentView = exitingFragment.getView();
+            final ViewGroup container = exitingFragment.mContainer;
+            container.getViewTreeObserver().addOnPreDrawListener(
+                    new ViewTreeObserver.OnPreDrawListener() {
+                        @Override
+                        public boolean onPreDraw() {
+                            container.getViewTreeObserver().removeOnPreDrawListener(this);
+                            setViewVisibility(exitingViews, View.INVISIBLE);
+                            return true;
+                        }
+                    });
+            exitTransition.addListener(new Transition.TransitionListenerAdapter() {
+                @Override
+                public void onTransitionEnd(Transition transition) {
+                    transition.removeListener(this);
+                    fragmentView.setVisibility(View.GONE);
+                    setViewVisibility(exitingViews, View.VISIBLE);
+                }
+            });
+        }
+    }
+
+    /**
+     * This method is used for fragment transitions for unoptimized transactions to change the
+     * enter and exit transition targets after the call to
+     * {@link TransitionManager#beginDelayedTransition(ViewGroup, Transition)}. The exit transition
+     * must ensure that it does not target any Views and the enter transition must start targeting
+     * the Views of the incoming Fragment.
+     *
+     * @param sceneRoot The fragment container View
+     * @param inFragment The last fragment that is entering
+     * @param nonExistentView A view that does not exist in the hierarchy that is used as a
+     *                        transition target to ensure no View is targeted.
+     * @param sharedElementsIn The shared element Views of the incoming fragment
+     * @param enterTransition The enter transition of the incoming fragment
+     * @param enteringViews The entering Views of the incoming fragment
+     * @param exitTransition The exit transition of the outgoing fragment
+     * @param exitingViews The exiting views of the outgoing fragment
+     */
+    private static void scheduleTargetChange(final ViewGroup sceneRoot,
+            final Fragment inFragment, final View nonExistentView,
+            final ArrayList<View> sharedElementsIn,
+            final Transition enterTransition, final ArrayList<View> enteringViews,
+            final Transition exitTransition, final ArrayList<View> exitingViews) {
+
+        sceneRoot.getViewTreeObserver().addOnPreDrawListener(
+                new ViewTreeObserver.OnPreDrawListener() {
+                    @Override
+                    public boolean onPreDraw() {
+                        sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+
+                        if (enterTransition != null) {
+                            enterTransition.removeTarget(nonExistentView);
+                            ArrayList<View> views = configureEnteringExitingViews(
+                                    enterTransition, inFragment, sharedElementsIn, nonExistentView);
+                            enteringViews.addAll(views);
+                        }
+
+                        if (exitingViews != null) {
+                            ArrayList<View> tempExiting = new ArrayList<>();
+                            tempExiting.add(nonExistentView);
+                            replaceTargets(exitTransition, exitingViews, tempExiting);
+                            exitingViews.clear();
+                            exitingViews.add(nonExistentView);
+                        }
+
+                        return true;
+                    }
+                });
+    }
+
+    /**
+     * Returns a TransitionSet containing the shared element transition. The wrapping TransitionSet
+     * targets all shared elements to ensure that no other Views are targeted. The shared element
+     * transition can then target any or all shared elements without worrying about accidentally
+     * targeting entering or exiting Views.
+     *
+     * @param inFragment The incoming fragment
+     * @param outFragment the outgoing fragment
+     * @param isPop True if this is a pop transaction or false if it is a normal (add) transaction.
+     * @return A TransitionSet wrapping the shared element transition or null if no such transition
+     * exists.
+     */
+    private static TransitionSet getSharedElementTransition(Fragment inFragment,
+            Fragment outFragment, boolean isPop) {
+        if (inFragment == null || outFragment == null) {
+            return null;
+        }
+        Transition transition = cloneTransition(isPop
+                ? outFragment.getSharedElementReturnTransition()
+                : inFragment.getSharedElementEnterTransition());
+        if (transition == null) {
+            return null;
+        }
+        TransitionSet transitionSet = new TransitionSet();
+        transitionSet.addTransition(transition);
+        return transitionSet;
+    }
+
+    /**
+     * Returns a clone of the enter transition or null if no such transition exists.
+     */
+    private static Transition getEnterTransition(Fragment inFragment, boolean isPop) {
+        if (inFragment == null) {
+            return null;
+        }
+        return cloneTransition(isPop ? inFragment.getReenterTransition() :
+                inFragment.getEnterTransition());
+    }
+
+    /**
+     * Returns a clone of the exit transition or null if no such transition exists.
+     */
+    private static Transition getExitTransition(Fragment outFragment, boolean isPop) {
+        if (outFragment == null) {
+            return null;
+        }
+        return cloneTransition(isPop ? outFragment.getReturnTransition() :
+                outFragment.getExitTransition());
+    }
+
+    /**
+     * Returns a clone of a transition or null if it is null
+     */
+    private static Transition cloneTransition(Transition transition) {
+        if (transition != null) {
+            transition = transition.clone();
+        }
+        return transition;
+    }
+
+    /**
+     * Configures the shared elements of an optimized fragment transaction's transition.
+     * This retrieves the shared elements of the outgoing and incoming fragments, maps the
+     * views, and sets up the epicenter on the transitions.
+     * <p>
+     * The epicenter of exit and shared element transitions is the first shared element
+     * in the outgoing fragment. The epicenter of the entering transition is the first shared
+     * element in the incoming fragment.
+     *
+     * @param sceneRoot The fragment container View
+     * @param nonExistentView A View that does not exist in the hierarchy. This is used to
+     *                        prevent transitions from acting on other Views when there is no
+     *                        other target.
+     * @param nameOverrides A map of the shared element names from the starting fragment to
+     *                      the final fragment's Views as given in
+     *                      {@link FragmentTransaction#addSharedElement(View, String)}.
+     * @param fragments A structure holding the transitioning fragments in this container.
+     * @param sharedElementsOut A list modified to contain the shared elements in the outgoing
+     *                          fragment
+     * @param sharedElementsIn A list modified to contain the shared elements in the incoming
+     *                         fragment
+     * @param enterTransition The transition used for entering Views, modified by applying the
+     *                        epicenter
+     * @param exitTransition The transition used for exiting Views, modified by applying the
+     *                       epicenter
+     * @return The shared element transition or null if no shared elements exist
+     */
+    private static TransitionSet configureSharedElementsOptimized(final ViewGroup sceneRoot,
+            final View nonExistentView, ArrayMap<String, String> nameOverrides,
+            final FragmentContainerTransition fragments,
+            final ArrayList<View> sharedElementsOut,
+            final ArrayList<View> sharedElementsIn,
+            final Transition enterTransition, final Transition exitTransition) {
+        final Fragment inFragment = fragments.lastIn;
+        final Fragment outFragment = fragments.firstOut;
+        if (inFragment != null) {
+            inFragment.getView().setVisibility(View.VISIBLE);
+        }
+        if (inFragment == null || outFragment == null) {
+            return null; // no shared element without a fragment
+        }
+
+        final boolean inIsPop = fragments.lastInIsPop;
+        TransitionSet sharedElementTransition = nameOverrides.isEmpty() ? null
+                : getSharedElementTransition(inFragment, outFragment, inIsPop);
+
+        ArrayMap<String, View> outSharedElements = captureOutSharedElements(nameOverrides,
+                sharedElementTransition, fragments);
+
+        ArrayMap<String, View> inSharedElements = captureInSharedElements(nameOverrides,
+                sharedElementTransition, fragments);
+
+        if (nameOverrides.isEmpty()) {
+            sharedElementTransition = null;
+        } else {
+            sharedElementsOut.addAll(outSharedElements.values());
+            sharedElementsIn.addAll(inSharedElements.values());
+        }
+
+        if (enterTransition == null && exitTransition == null && sharedElementTransition == null) {
+            // don't call onSharedElementStart/End since there is no transition
+            return null;
+        }
+
+        callSharedElementStartEnd(inFragment, outFragment, inIsPop, outSharedElements, true);
+
+        final Rect epicenter;
+        final View epicenterView;
+        if (sharedElementTransition != null) {
+            sharedElementsIn.add(nonExistentView);
+            setSharedElementTargets(sharedElementTransition, nonExistentView, sharedElementsOut);
+            final boolean outIsPop = fragments.firstOutIsPop;
+            final BackStackRecord outTransaction = fragments.firstOutTransaction;
+            setOutEpicenter(sharedElementTransition, exitTransition, outSharedElements, outIsPop,
+                    outTransaction);
+            epicenter = new Rect();
+            epicenterView = getInEpicenterView(inSharedElements, fragments,
+                    enterTransition, inIsPop);
+            if (epicenterView != null) {
+                enterTransition.setEpicenterCallback(new Transition.EpicenterCallback() {
+                    @Override
+                    public Rect onGetEpicenter(Transition transition) {
+                        return epicenter;
+                    }
+                });
+            }
+        } else {
+            epicenter = null;
+            epicenterView = null;
+        }
+
+        sceneRoot.getViewTreeObserver().addOnPreDrawListener(
+                new ViewTreeObserver.OnPreDrawListener() {
+                    @Override
+                    public boolean onPreDraw() {
+                        sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+                        callSharedElementStartEnd(inFragment, outFragment, inIsPop,
+                                inSharedElements, false);
+                        if (epicenterView != null) {
+                            epicenterView.getBoundsOnScreen(epicenter);
+                        }
+                        return true;
+                    }
+                });
+        return sharedElementTransition;
+    }
+
+    /**
+     * Configures the shared elements of an unoptimized fragment transaction's transition.
+     * This retrieves the shared elements of the incoming fragments, and schedules capturing
+     * the incoming fragment's shared elements. It also maps the views, and sets up the epicenter
+     * on the transitions.
+     * <p>
+     * The epicenter of exit and shared element transitions is the first shared element
+     * in the outgoing fragment. The epicenter of the entering transition is the first shared
+     * element in the incoming fragment.
+     *
+     * @param sceneRoot The fragment container View
+     * @param nonExistentView A View that does not exist in the hierarchy. This is used to
+     *                        prevent transitions from acting on other Views when there is no
+     *                        other target.
+     * @param nameOverrides A map of the shared element names from the starting fragment to
+     *                      the final fragment's Views as given in
+     *                      {@link FragmentTransaction#addSharedElement(View, String)}.
+     * @param fragments A structure holding the transitioning fragments in this container.
+     * @param sharedElementsOut A list modified to contain the shared elements in the outgoing
+     *                          fragment
+     * @param sharedElementsIn A list modified to contain the shared elements in the incoming
+     *                         fragment
+     * @param enterTransition The transition used for entering Views, modified by applying the
+     *                        epicenter
+     * @param exitTransition The transition used for exiting Views, modified by applying the
+     *                       epicenter
+     * @return The shared element transition or null if no shared elements exist
+     */
+    private static TransitionSet configureSharedElementsUnoptimized(final ViewGroup sceneRoot,
+            final View nonExistentView, ArrayMap<String, String> nameOverrides,
+            final FragmentContainerTransition fragments,
+            final ArrayList<View> sharedElementsOut,
+            final ArrayList<View> sharedElementsIn,
+            final Transition enterTransition, final Transition exitTransition) {
+        final Fragment inFragment = fragments.lastIn;
+        final Fragment outFragment = fragments.firstOut;
+
+        if (inFragment == null || outFragment == null) {
+            return null; // no transition
+        }
+
+        final boolean inIsPop = fragments.lastInIsPop;
+        TransitionSet sharedElementTransition = nameOverrides.isEmpty() ? null
+                : getSharedElementTransition(inFragment, outFragment, inIsPop);
+
+        ArrayMap<String, View> outSharedElements = captureOutSharedElements(nameOverrides,
+                sharedElementTransition, fragments);
+
+        if (nameOverrides.isEmpty()) {
+            sharedElementTransition = null;
+        } else {
+            sharedElementsOut.addAll(outSharedElements.values());
+        }
+
+        if (enterTransition == null && exitTransition == null && sharedElementTransition == null) {
+            // don't call onSharedElementStart/End since there is no transition
+            return null;
+        }
+
+        callSharedElementStartEnd(inFragment, outFragment, inIsPop, outSharedElements, true);
+
+        final Rect inEpicenter;
+        if (sharedElementTransition != null) {
+            inEpicenter = new Rect();
+            setSharedElementTargets(sharedElementTransition, nonExistentView, sharedElementsOut);
+            final boolean outIsPop = fragments.firstOutIsPop;
+            final BackStackRecord outTransaction = fragments.firstOutTransaction;
+            setOutEpicenter(sharedElementTransition, exitTransition, outSharedElements, outIsPop,
+                    outTransaction);
+            if (enterTransition != null) {
+                enterTransition.setEpicenterCallback(new Transition.EpicenterCallback() {
+                    @Override
+                    public Rect onGetEpicenter(Transition transition) {
+                        if (inEpicenter.isEmpty()) {
+                            return null;
+                        }
+                        return inEpicenter;
+                    }
+                });
+            }
+        } else {
+            inEpicenter = null;
+        }
+
+        TransitionSet finalSharedElementTransition = sharedElementTransition;
+
+        sceneRoot.getViewTreeObserver().addOnPreDrawListener(
+                new ViewTreeObserver.OnPreDrawListener() {
+                    @Override
+                    public boolean onPreDraw() {
+                        sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+                        ArrayMap<String, View> inSharedElements = captureInSharedElements(
+                                nameOverrides, finalSharedElementTransition, fragments);
+
+                        if (inSharedElements != null) {
+                            sharedElementsIn.addAll(inSharedElements.values());
+                            sharedElementsIn.add(nonExistentView);
+                        }
+
+                        callSharedElementStartEnd(inFragment, outFragment, inIsPop,
+                                inSharedElements, false);
+                        if (finalSharedElementTransition != null) {
+                            finalSharedElementTransition.getTargets().clear();
+                            finalSharedElementTransition.getTargets().addAll(sharedElementsIn);
+                            replaceTargets(finalSharedElementTransition, sharedElementsOut,
+                                    sharedElementsIn);
+
+                            final View inEpicenterView = getInEpicenterView(inSharedElements,
+                                    fragments, enterTransition, inIsPop);
+                            if (inEpicenterView != null) {
+                                inEpicenterView.getBoundsOnScreen(inEpicenter);
+                            }
+                        }
+                        return true;
+                    }
+                });
+        return sharedElementTransition;
+    }
+
+    /**
+     * Finds the shared elements in the outgoing fragment. It also calls
+     * {@link SharedElementCallback#onMapSharedElements(List, Map)} to allow more control
+     * of the shared element mapping. {@code nameOverrides} is updated to match the
+     * actual transition name of the mapped shared elements.
+     *
+     * @param nameOverrides A map of the shared element names from the starting fragment to
+     *                      the final fragment's Views as given in
+     *                      {@link FragmentTransaction#addSharedElement(View, String)}.
+     * @param sharedElementTransition The shared element transition
+     * @param fragments A structure holding the transitioning fragments in this container.
+     * @return The mapping of shared element names to the Views in the hierarchy or null
+     * if there is no shared element transition.
+     */
+    private static ArrayMap<String, View> captureOutSharedElements(
+            ArrayMap<String, String> nameOverrides, TransitionSet sharedElementTransition,
+            FragmentContainerTransition fragments) {
+        if (nameOverrides.isEmpty() || sharedElementTransition == null) {
+            nameOverrides.clear();
+            return null;
+        }
+        final Fragment outFragment = fragments.firstOut;
+        final ArrayMap<String, View> outSharedElements = new ArrayMap<>();
+        outFragment.getView().findNamedViews(outSharedElements);
+
+        final SharedElementCallback sharedElementCallback;
+        final ArrayList<String> names;
+        final BackStackRecord outTransaction = fragments.firstOutTransaction;
+        if (fragments.firstOutIsPop) {
+            sharedElementCallback = outFragment.getEnterTransitionCallback();
+            names = outTransaction.mSharedElementTargetNames;
+        } else {
+            sharedElementCallback = outFragment.getExitTransitionCallback();
+            names = outTransaction.mSharedElementSourceNames;
+        }
+
+        outSharedElements.retainAll(names);
+        if (sharedElementCallback != null) {
+            sharedElementCallback.onMapSharedElements(names, outSharedElements);
+            for (int i = names.size() - 1; i >= 0; i--) {
+                String name = names.get(i);
+                View view = outSharedElements.get(name);
+                if (view == null) {
+                    nameOverrides.remove(name);
+                } else if (!name.equals(view.getTransitionName())) {
+                    String targetValue = nameOverrides.remove(name);
+                    nameOverrides.put(view.getTransitionName(), targetValue);
+                }
+            }
+        } else {
+            nameOverrides.retainAll(outSharedElements.keySet());
+        }
+        return outSharedElements;
+    }
+
+    /**
+     * Finds the shared elements in the incoming fragment. It also calls
+     * {@link SharedElementCallback#onMapSharedElements(List, Map)} to allow more control
+     * of the shared element mapping. {@code nameOverrides} is updated to match the
+     * actual transition name of the mapped shared elements.
+     *
+     * @param nameOverrides A map of the shared element names from the starting fragment to
+     *                      the final fragment's Views as given in
+     *                      {@link FragmentTransaction#addSharedElement(View, String)}.
+     * @param sharedElementTransition The shared element transition
+     * @param fragments A structure holding the transitioning fragments in this container.
+     * @return The mapping of shared element names to the Views in the hierarchy or null
+     * if there is no shared element transition.
+     */
+    private static ArrayMap<String, View> captureInSharedElements(
+            ArrayMap<String, String> nameOverrides, TransitionSet sharedElementTransition,
+            FragmentContainerTransition fragments) {
+        Fragment inFragment = fragments.lastIn;
+        final View fragmentView = inFragment.getView();
+        if (nameOverrides.isEmpty() || sharedElementTransition == null || fragmentView == null) {
+            nameOverrides.clear();
+            return null;
+        }
+        final ArrayMap<String, View> inSharedElements = new ArrayMap<>();
+        fragmentView.findNamedViews(inSharedElements);
+
+        final SharedElementCallback sharedElementCallback;
+        final ArrayList<String> names;
+        final BackStackRecord inTransaction = fragments.lastInTransaction;
+        if (fragments.lastInIsPop) {
+            sharedElementCallback = inFragment.getExitTransitionCallback();
+            names = inTransaction.mSharedElementSourceNames;
+        } else {
+            sharedElementCallback = inFragment.getEnterTransitionCallback();
+            names = inTransaction.mSharedElementTargetNames;
+        }
+
+        inSharedElements.retainAll(names);
+        if (sharedElementCallback != null) {
+            sharedElementCallback.onMapSharedElements(names, inSharedElements);
+            for (int i = names.size() - 1; i >= 0; i--) {
+                String name = names.get(i);
+                View view = inSharedElements.get(name);
+                if (view == null) {
+                    String key = findKeyForValue(nameOverrides, name);
+                    if (key != null) {
+                        nameOverrides.remove(key);
+                    }
+                } else if (!name.equals(view.getTransitionName())) {
+                    String key = findKeyForValue(nameOverrides, name);
+                    if (key != null) {
+                        nameOverrides.put(key, view.getTransitionName());
+                    }
+                }
+            }
+        } else {
+            retainValues(nameOverrides, inSharedElements);
+        }
+        return inSharedElements;
+    }
+
+    /**
+     * Utility to find the String key in {@code map} that maps to {@code value}.
+     */
+    private static String findKeyForValue(ArrayMap<String, String> map, String value) {
+        final int numElements = map.size();
+        for (int i = 0; i < numElements; i++) {
+            if (value.equals(map.valueAt(i))) {
+                return map.keyAt(i);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the View in the incoming Fragment that should be used as the epicenter.
+     *
+     * @param inSharedElements The mapping of shared element names to Views in the
+     *                         incoming fragment.
+     * @param fragments A structure holding the transitioning fragments in this container.
+     * @param enterTransition The transition used for the incoming Fragment's views
+     * @param inIsPop Is the incoming fragment being added as a pop transaction?
+     */
+    private static View getInEpicenterView(ArrayMap<String, View> inSharedElements,
+            FragmentContainerTransition fragments,
+            Transition enterTransition, boolean inIsPop) {
+        BackStackRecord inTransaction = fragments.lastInTransaction;
+        if (enterTransition != null && inTransaction.mSharedElementSourceNames != null &&
+                !inTransaction.mSharedElementSourceNames.isEmpty()) {
+            final String targetName = inIsPop
+                    ? inTransaction.mSharedElementSourceNames.get(0)
+                    : inTransaction.mSharedElementTargetNames.get(0);
+            return inSharedElements.get(targetName);
+        }
+        return null;
+    }
+
+    /**
+     * Sets the epicenter for the exit transition.
+     *
+     * @param sharedElementTransition The shared element transition
+     * @param exitTransition The transition for the outgoing fragment's views
+     * @param outSharedElements Shared elements in the outgoing fragment
+     * @param outIsPop Is the outgoing fragment being removed as a pop transaction?
+     * @param outTransaction The transaction that caused the fragment to be removed.
+     */
+    private static void setOutEpicenter(TransitionSet sharedElementTransition,
+            Transition exitTransition, ArrayMap<String, View> outSharedElements, boolean outIsPop,
+            BackStackRecord outTransaction) {
+        if (outTransaction.mSharedElementSourceNames != null &&
+                !outTransaction.mSharedElementSourceNames.isEmpty()) {
+            final String sourceName = outIsPop
+                    ? outTransaction.mSharedElementTargetNames.get(0)
+                    : outTransaction.mSharedElementSourceNames.get(0);
+            final View outEpicenterView = outSharedElements.get(sourceName);
+            setEpicenter(sharedElementTransition, outEpicenterView);
+
+            if (exitTransition != null) {
+                setEpicenter(exitTransition, outEpicenterView);
+            }
+        }
+    }
+
+    /**
+     * Sets a transition epicenter to the rectangle of a given View.
+     */
+    private static void setEpicenter(Transition transition, View view) {
+        if (view != null) {
+            final Rect epicenter = new Rect();
+            view.getBoundsOnScreen(epicenter);
+
+            transition.setEpicenterCallback(new Transition.EpicenterCallback() {
+                @Override
+                public Rect onGetEpicenter(Transition transition) {
+                    return epicenter;
+                }
+            });
+        }
+    }
+
+    /**
+     * A utility to retain only the mappings in {@code nameOverrides} that have a value
+     * that has a key in {@code namedViews}. This is a useful equivalent to
+     * {@link ArrayMap#retainAll(Collection)} for values.
+     */
+    private static void retainValues(ArrayMap<String, String> nameOverrides,
+            ArrayMap<String, View> namedViews) {
+        for (int i = nameOverrides.size() - 1; i >= 0; i--) {
+            final String targetName = nameOverrides.valueAt(i);
+            if (!namedViews.containsKey(targetName)) {
+                nameOverrides.removeAt(i);
+            }
+        }
+    }
+
+    /**
+     * Calls the {@link SharedElementCallback#onSharedElementStart(List, List, List)} or
+     * {@link SharedElementCallback#onSharedElementEnd(List, List, List)} on the appropriate
+     * incoming or outgoing fragment.
+     *
+     * @param inFragment The incoming fragment
+     * @param outFragment The outgoing fragment
+     * @param isPop Is the incoming fragment part of a pop transaction?
+     * @param sharedElements The shared element Views
+     * @param isStart Call the start or end call on the SharedElementCallback
+     */
+    private static void callSharedElementStartEnd(Fragment inFragment, Fragment outFragment,
+            boolean isPop, ArrayMap<String, View> sharedElements, boolean isStart) {
+        SharedElementCallback sharedElementCallback = isPop
+                ? outFragment.getEnterTransitionCallback()
+                : inFragment.getEnterTransitionCallback();
+        if (sharedElementCallback != null) {
+            ArrayList<View> views = new ArrayList<>();
+            ArrayList<String> names = new ArrayList<>();
+            final int count = sharedElements == null ? 0 : sharedElements.size();
+            for (int i = 0; i < count; i++) {
+                names.add(sharedElements.keyAt(i));
+                views.add(sharedElements.valueAt(i));
+            }
+            if (isStart) {
+                sharedElementCallback.onSharedElementStart(names, views, null);
+            } else {
+                sharedElementCallback.onSharedElementEnd(names, views, null);
+            }
+        }
+    }
+
+    /**
+     * Finds all children of the shared elements and sets the wrapping TransitionSet
+     * targets to point to those. It also limits transitions that have no targets to the
+     * specific shared elements. This allows developers to target child views of the
+     * shared elements specifically, but this doesn't happen by default.
+     */
+    private static void setSharedElementTargets(TransitionSet transition,
+            View nonExistentView, ArrayList<View> sharedViews) {
+        final List<View> views = transition.getTargets();
+        views.clear();
+        final int count = sharedViews.size();
+        for (int i = 0; i < count; i++) {
+            final View view = sharedViews.get(i);
+            bfsAddViewChildren(views, view);
+        }
+        views.add(nonExistentView);
+        sharedViews.add(nonExistentView);
+        addTargets(transition, sharedViews);
+    }
+
+    /**
+     * Uses a breadth-first scheme to add startView and all of its children to views.
+     * It won't add a child if it is already in views.
+     */
+    private static void bfsAddViewChildren(final List<View> views, final View startView) {
+        final int startIndex = views.size();
+        if (containedBeforeIndex(views, startView, startIndex)) {
+            return; // This child is already in the list, so all its children are also.
+        }
+        views.add(startView);
+        for (int index = startIndex; index < views.size(); index++) {
+            final View view = views.get(index);
+            if (view instanceof ViewGroup) {
+                ViewGroup viewGroup = (ViewGroup) view;
+                final int childCount =  viewGroup.getChildCount();
+                for (int childIndex = 0; childIndex < childCount; childIndex++) {
+                    final View child = viewGroup.getChildAt(childIndex);
+                    if (!containedBeforeIndex(views, child, startIndex)) {
+                        views.add(child);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Does a linear search through views for view, limited to maxIndex.
+     */
+    private static boolean containedBeforeIndex(final List<View> views, final View view,
+            final int maxIndex) {
+        for (int i = 0; i < maxIndex; i++) {
+            if (views.get(i) == view) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * After the transition has started, remove all targets that we added to the transitions
+     * so that the transitions are left in a clean state.
+     */
+    private static void scheduleRemoveTargets(final Transition overalTransition,
+            final Transition enterTransition, final ArrayList<View> enteringViews,
+            final Transition exitTransition, final ArrayList<View> exitingViews,
+            final TransitionSet sharedElementTransition, final ArrayList<View> sharedElementsIn) {
+        overalTransition.addListener(new Transition.TransitionListenerAdapter() {
+            @Override
+            public void onTransitionStart(Transition transition) {
+                if (enterTransition != null) {
+                    replaceTargets(enterTransition, enteringViews, null);
+                }
+                if (exitTransition != null) {
+                    replaceTargets(exitTransition, exitingViews, null);
+                }
+                if (sharedElementTransition != null) {
+                    replaceTargets(sharedElementTransition, sharedElementsIn, null);
+                }
+            }
+        });
+    }
+
+    /**
+     * This method removes the views from transitions that target ONLY those views and
+     * replaces them with the new targets list.
+     * The views list should match those added in addTargets and should contain
+     * one view that is not in the view hierarchy (state.nonExistentView).
+     */
+    public static void replaceTargets(Transition transition, ArrayList<View> oldTargets,
+            ArrayList<View> newTargets) {
+        if (transition instanceof TransitionSet) {
+            TransitionSet set = (TransitionSet) transition;
+            int numTransitions = set.getTransitionCount();
+            for (int i = 0; i < numTransitions; i++) {
+                Transition child = set.getTransitionAt(i);
+                replaceTargets(child, oldTargets, newTargets);
+            }
+        } else if (!hasSimpleTarget(transition)) {
+            List<View> targets = transition.getTargets();
+            if (targets != null && targets.size() == oldTargets.size() &&
+                    targets.containsAll(oldTargets)) {
+                // We have an exact match. We must have added these earlier in addTargets
+                final int targetCount = newTargets == null ? 0 : newTargets.size();
+                for (int i = 0; i < targetCount; i++) {
+                    transition.addTarget(newTargets.get(i));
+                }
+                for (int i = oldTargets.size() - 1; i >= 0; i--) {
+                    transition.removeTarget(oldTargets.get(i));
+                }
+            }
+        }
+    }
+
+    /**
+     * This method adds views as targets to the transition, but only if the transition
+     * doesn't already have a target. It is best for views to contain one View object
+     * that does not exist in the view hierarchy (state.nonExistentView) so that
+     * when they are removed later, a list match will suffice to remove the targets.
+     * Otherwise, if you happened to have targeted the exact views for the transition,
+     * the replaceTargets call will remove them unexpectedly.
+     */
+    public static void addTargets(Transition transition, ArrayList<View> views) {
+        if (transition == null) {
+            return;
+        }
+        if (transition instanceof TransitionSet) {
+            TransitionSet set = (TransitionSet) transition;
+            int numTransitions = set.getTransitionCount();
+            for (int i = 0; i < numTransitions; i++) {
+                Transition child = set.getTransitionAt(i);
+                addTargets(child, views);
+            }
+        } else if (!hasSimpleTarget(transition)) {
+            List<View> targets = transition.getTargets();
+            if (isNullOrEmpty(targets)) {
+                // We can just add the target views
+                int numViews = views.size();
+                for (int i = 0; i < numViews; i++) {
+                    transition.addTarget(views.get(i));
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns true if there are any targets based on ID, transition or type.
+     */
+    private static boolean hasSimpleTarget(Transition transition) {
+        return !isNullOrEmpty(transition.getTargetIds()) ||
+                !isNullOrEmpty(transition.getTargetNames()) ||
+                !isNullOrEmpty(transition.getTargetTypes());
+    }
+
+    /**
+     * Simple utility to detect if a list is null or has no elements.
+     */
+    private static boolean isNullOrEmpty(List list) {
+        return list == null || list.isEmpty();
+    }
+
+    private static ArrayList<View> configureEnteringExitingViews(Transition transition,
+            Fragment fragment, ArrayList<View> sharedElements, View nonExistentView) {
+        ArrayList<View> viewList = null;
+        if (transition != null) {
+            viewList = new ArrayList<>();
+            View root = fragment.getView();
+            root.captureTransitioningViews(viewList);
+            if (sharedElements != null) {
+                viewList.removeAll(sharedElements);
+            }
+            if (!viewList.isEmpty()) {
+                viewList.add(nonExistentView);
+                addTargets(transition, viewList);
+            }
+        }
+        return viewList;
+    }
+
+    /**
+     * Sets the visibility of all Views in {@code views} to {@code visibility}.
+     */
+    private static void setViewVisibility(ArrayList<View> views, @View.Visibility int visibility) {
+        if (views == null) {
+            return;
+        }
+        for (int i = views.size() - 1; i >= 0; i--) {
+            final View view = views.get(i);
+            view.setVisibility(visibility);
+        }
+    }
+
+    /**
+     * Merges exit, shared element, and enter transitions so that they act together or
+     * sequentially as defined in the fragments.
+     */
+    private static Transition mergeTransitions(Transition enterTransition,
+            Transition exitTransition, Transition sharedElementTransition, Fragment inFragment,
+            boolean isPop) {
+        boolean overlap = true;
+        if (enterTransition != null && exitTransition != null && inFragment != null) {
+            overlap = isPop ? inFragment.getAllowReturnTransitionOverlap() :
+                    inFragment.getAllowEnterTransitionOverlap();
+        }
+
+        // Wrap the transitions. Explicit targets like in enter and exit will cause the
+        // views to be targeted regardless of excluded views. If that happens, then the
+        // excluded fragments views (hidden fragments) will still be in the transition.
+
+        Transition transition;
+        if (overlap) {
+            // Regular transition -- do it all together
+            TransitionSet transitionSet = new TransitionSet();
+            if (enterTransition != null) {
+                transitionSet.addTransition(enterTransition);
+            }
+            if (exitTransition != null) {
+                transitionSet.addTransition(exitTransition);
+            }
+            if (sharedElementTransition != null) {
+                transitionSet.addTransition(sharedElementTransition);
+            }
+            transition = transitionSet;
+        } else {
+            // First do exit, then enter, but allow shared element transition to happen
+            // during both.
+            Transition staggered = null;
+            if (exitTransition != null && enterTransition != null) {
+                staggered = new TransitionSet()
+                        .addTransition(exitTransition)
+                        .addTransition(enterTransition)
+                        .setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+            } else if (exitTransition != null) {
+                staggered = exitTransition;
+            } else if (enterTransition != null) {
+                staggered = enterTransition;
+            }
+            if (sharedElementTransition != null) {
+                TransitionSet together = new TransitionSet();
+                if (staggered != null) {
+                    together.addTransition(staggered);
+                }
+                together.addTransition(sharedElementTransition);
+                transition = together;
+            } else {
+                transition = staggered;
+            }
+        }
+        return transition;
+    }
+
+    /**
+     * Finds the first removed fragment and last added fragments when going forward.
+     * If none of the fragments have transitions, then both lists will be empty.
+     *
+     * @param transitioningFragments Keyed on the container ID, the first fragments to be removed,
+     *                               and last fragments to be added. This will be modified by
+     *                               this method.
+     */
+    public static void calculateFragments(BackStackRecord transaction,
+            SparseArray<FragmentContainerTransition> transitioningFragments,
+            boolean isOptimized) {
+        final int numOps = transaction.mOps.size();
+        for (int opNum = 0; opNum < numOps; opNum++) {
+            final BackStackRecord.Op op = transaction.mOps.get(opNum);
+            addToFirstInLastOut(transaction, op, transitioningFragments, false, isOptimized);
+        }
+    }
+
+    /**
+     * Finds the first removed fragment and last added fragments when popping the back stack.
+     * If none of the fragments have transitions, then both lists will be empty.
+     *
+     * @param transitioningFragments Keyed on the container ID, the first fragments to be removed,
+     *                               and last fragments to be added. This will be modified by
+     *                               this method.
+     */
+    public static void calculatePopFragments(BackStackRecord transaction,
+            SparseArray<FragmentContainerTransition> transitioningFragments, boolean isOptimized) {
+        if (!transaction.mManager.mContainer.onHasView()) {
+            return; // nothing to see, so no transitions
+        }
+        final int numOps = transaction.mOps.size();
+        for (int opNum = numOps - 1; opNum >= 0; opNum--) {
+            final BackStackRecord.Op op = transaction.mOps.get(opNum);
+            addToFirstInLastOut(transaction, op, transitioningFragments, true, isOptimized);
+        }
+    }
+
+    /**
+     * Examines the {@code command} and may set the first out or last in fragment for the fragment's
+     * container.
+     *
+     * @param transaction The executing transaction
+     * @param op The operation being run.
+     * @param transitioningFragments A structure holding the first in and last out fragments
+     *                               for each fragment container.
+     * @param isPop Is the operation a pop?
+     * @param isOptimizedTransaction True if the operations have been partially executed and the
+     *                               added fragments have Views in the hierarchy or false if the
+     *                               operations haven't been executed yet.
+     */
+    private static void addToFirstInLastOut(BackStackRecord transaction, BackStackRecord.Op op,
+            SparseArray<FragmentContainerTransition> transitioningFragments, boolean isPop,
+            boolean isOptimizedTransaction) {
+        final Fragment fragment = op.fragment;
+        final int containerId = fragment.mContainerId;
+        if (containerId == 0) {
+            return; // no container, no transition
+        }
+        final int command = isPop ? INVERSE_OPS[op.cmd] : op.cmd;
+        boolean setLastIn = false;
+        boolean wasRemoved = false;
+        boolean setFirstOut = false;
+        boolean wasAdded = false;
+        switch (command) {
+            case BackStackRecord.OP_SHOW:
+                if (isOptimizedTransaction) {
+                    setLastIn = fragment.mHiddenChanged && !fragment.mHidden &&
+                            fragment.mAdded;
+                } else {
+                    setLastIn = fragment.mHidden;
+                }
+                wasAdded = true;
+                break;
+            case BackStackRecord.OP_ADD:
+            case BackStackRecord.OP_ATTACH:
+                if (isOptimizedTransaction) {
+                    setLastIn = fragment.mIsNewlyAdded;
+                } else {
+                    setLastIn = !fragment.mAdded && !fragment.mHidden;
+                }
+                wasAdded = true;
+                break;
+            case BackStackRecord.OP_HIDE:
+                if (isOptimizedTransaction) {
+                    setFirstOut = fragment.mHiddenChanged && fragment.mAdded &&
+                            fragment.mHidden;
+                } else {
+                    setFirstOut = fragment.mAdded && !fragment.mHidden;
+                }
+                wasRemoved = true;
+                break;
+            case BackStackRecord.OP_REMOVE:
+            case BackStackRecord.OP_DETACH:
+                if (isOptimizedTransaction) {
+                    setFirstOut = !fragment.mAdded && fragment.mView != null &&
+                            fragment.mView.getVisibility() == View.VISIBLE;
+                } else {
+                    setFirstOut = fragment.mAdded && !fragment.mHidden;
+                }
+                wasRemoved = true;
+                break;
+        }
+        FragmentContainerTransition containerTransition = transitioningFragments.get(containerId);
+        if (setLastIn) {
+            containerTransition =
+                    ensureContainer(containerTransition, transitioningFragments, containerId);
+            containerTransition.lastIn = fragment;
+            containerTransition.lastInIsPop = isPop;
+            containerTransition.lastInTransaction = transaction;
+        }
+        if (!isOptimizedTransaction && wasAdded) {
+            if (containerTransition != null && containerTransition.firstOut == fragment) {
+                containerTransition.firstOut = null;
+            }
+
+            /**
+             * Ensure that fragments that are entering are at least at the CREATED state
+             * so that they may load Transitions using TransitionInflater.
+             */
+            FragmentManagerImpl manager = transaction.mManager;
+            if (fragment.mState < Fragment.CREATED && manager.mCurState >= Fragment.CREATED &&
+                    manager.mHost.getContext().getApplicationInfo().targetSdkVersion >=
+                            Build.VERSION_CODES.N && !transaction.mAllowOptimization) {
+                manager.makeActive(fragment);
+                manager.moveToState(fragment, Fragment.CREATED, 0, 0, false);
+            }
+        }
+        if (setFirstOut && (containerTransition == null || containerTransition.firstOut == null)) {
+            containerTransition =
+                    ensureContainer(containerTransition, transitioningFragments, containerId);
+            containerTransition.firstOut = fragment;
+            containerTransition.firstOutIsPop = isPop;
+            containerTransition.firstOutTransaction = transaction;
+        }
+
+        if (!isOptimizedTransaction && wasRemoved &&
+                (containerTransition != null && containerTransition.lastIn == fragment)) {
+            containerTransition.lastIn = null;
+        }
+    }
+
+    /**
+     * Ensures that a FragmentContainerTransition has been added to the SparseArray. If so,
+     * it returns the existing one. If not, one is created and added to the SparseArray and
+     * returned.
+     */
+    private static FragmentContainerTransition ensureContainer(
+            FragmentContainerTransition containerTransition,
+            SparseArray<FragmentContainerTransition> transitioningFragments, int containerId) {
+        if (containerTransition == null) {
+            containerTransition = new FragmentContainerTransition();
+            transitioningFragments.put(containerId, containerTransition);
+        }
+        return containerTransition;
+    }
+
+    /**
+     * Tracks the last fragment added and first fragment removed for fragment transitions.
+     * This also tracks which fragments are changed by push or pop transactions.
+     */
+    public static class FragmentContainerTransition {
+        /**
+         * The last fragment added/attached/shown in its container
+         */
+        public Fragment lastIn;
+
+        /**
+         * true when lastIn was added during a pop transaction or false if added with a push
+         */
+        public boolean lastInIsPop;
+
+        /**
+         * The transaction that included the last in fragment
+         */
+        public BackStackRecord lastInTransaction;
+
+        /**
+         * The first fragment with a View that was removed/detached/hidden in its container.
+         */
+        public Fragment firstOut;
+
+        /**
+         * true when firstOut was removed during a pop transaction or false otherwise
+         */
+        public boolean firstOutIsPop;
+
+        /**
+         * The transaction that included the first out fragment
+         */
+        public BackStackRecord firstOutTransaction;
+    }
+}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index c9d3682..7b25c76 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -214,6 +214,7 @@
     public int getFocusedStackId() throws RemoteException;
     public void setFocusedTask(int taskId) throws RemoteException;
     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException;
+    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException;
     public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
     public ContentProviderHolder getContentProvider(IApplicationThread caller,
             String name, int userId, boolean stable) throws RemoteException;
@@ -274,12 +275,24 @@
 
     /**
      * Updates global configuration and applies changes to the entire system.
-     * @param values Update values for global configuration.
+     * @param values Update values for global configuration. If null is passed it will request the
+     *               Window Manager to compute new config for the default display.
      * @throws RemoteException
      * @return Returns true if the configuration was updated.
      */
     public boolean updateConfiguration(Configuration values) throws RemoteException;
 
+    /**
+     * Updates override configuration applied to specific display.
+     * @param values Update values for display configuration. If null is passed it will request the
+     *               Window Manager to compute new config for the specified display.
+     * @param displayId Id of the display to apply the config to.
+     * @throws RemoteException
+     * @return Returns true if the configuration was updated.
+     */
+    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId)
+            throws RemoteException;
+
     public void setRequestedOrientation(IBinder token,
             int requestedOrientation) throws RemoteException;
     public int getRequestedOrientation(IBinder token) throws RemoteException;
@@ -568,8 +581,6 @@
 
     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException;
 
-    public void deleteActivityContainer(IActivityContainer container) throws RemoteException;
-
     public int getActivityDisplayId(IBinder activityToken) throws RemoteException;
 
     public void startSystemLockTaskMode(int taskId) throws RemoteException;
@@ -1091,4 +1102,6 @@
 
     // Start of O transactions
     int REQUEST_ACTIVITY_RELAUNCH = IBinder.FIRST_CALL_TRANSACTION+400;
+    int UPDATE_DISPLAY_OVERRIDE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 401;
+    int UNREGISTER_TASK_STACK_LISTENER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+402;
 }
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 2dd3b1a..e2f6fb5 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -155,6 +155,7 @@
     void scheduleLocalVoiceInteractionStarted(IBinder token,
             IVoiceInteractor voiceInteractor) = 61;
     void handleTrustStorageUpdate() = 62;
+    void attachAgent(String path) = 63;
     /**
      * Don't change the existing transaction Ids as they could be used in the native code.
      * When adding a new method, assign the next available transaction id.
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 496ca6f..e454ae1 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -16,6 +16,9 @@
 
 package android.app;
 
+import android.app.ActivityManager;
+import android.content.ComponentName;
+
 /** @hide */
 oneway interface ITaskStackListener {
     /** Called whenever there are changes to the state of tasks in a stack. */
@@ -45,4 +48,51 @@
      * Callen when we launched an activity that is dismissed the docked stack.
      */
     void onActivityDismissingDockedStack();
+
+    /**
+     * Called when a task is added.
+     *
+     * @param taskId id of the task.
+     * @param componentName of the activity that the task is being started with.
+    */
+    void onTaskCreated(int taskId, in ComponentName componentName);
+
+    /**
+     * Called when a task is removed.
+     *
+     * @param taskId id of the task.
+    */
+    void onTaskRemoved(int taskId);
+
+    /**
+     * Called when a task is moved to the front of its stack.
+     *
+     * @param taskId id of the task.
+    */
+    void onTaskMovedToFront(int taskId);
+
+    /**
+     * Called when a task’s description is changed due to an activity calling
+     * ActivityManagerService.setTaskDescription
+     *
+     * @param taskId id of the task.
+     * @param td the new TaskDescription.
+    */
+    void onTaskDescriptionChanged(int taskId, in ActivityManager.TaskDescription td);
+
+    /**
+     * Called when a activity’s orientation is changed due to it calling
+     * ActivityManagerService.setRequestedOrientation
+     *
+     * @param taskId id of the task that the activity is in.
+     * @param requestedOrientation the new requested orientation.
+    */
+    void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation);
+
+    /**
+     * Called when the task is about to be finished but before its surfaces are
+     * removed from the window manager. This allows interested parties to
+     * perform relevant animations before the window disappears.
+     */
+    void onTaskRemovalStarted(int taskId);
 }
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
new file mode 100644
index 0000000..0639552
--- /dev/null
+++ b/core/java/android/app/TaskStackListener.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.content.ComponentName;
+import android.os.RemoteException;
+
+/**
+ * Classes interested in observing only a subset of changes using ITaskStackListener can extend
+ * this class to avoid having to implement all the methods.
+ * @hide
+ */
+public abstract class TaskStackListener extends ITaskStackListener.Stub {
+    @Override
+    public void onTaskStackChanged() throws RemoteException {
+    }
+
+    @Override
+    public void onActivityPinned() throws RemoteException {
+    }
+
+    @Override
+    public void onPinnedActivityRestartAttempt() throws RemoteException {
+    }
+
+    @Override
+    public void onPinnedStackAnimationEnded() throws RemoteException {
+    }
+
+    @Override
+    public void onActivityForcedResizable(String packageName, int taskId) throws RemoteException {
+    }
+
+    @Override
+    public void onActivityDismissingDockedStack() throws RemoteException {
+    }
+
+    @Override
+    public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException {
+    }
+
+    @Override
+    public void onTaskRemoved(int taskId) throws RemoteException {
+    }
+
+    @Override
+    public void onTaskMovedToFront(int taskId) throws RemoteException {
+    }
+
+    @Override
+    public void onTaskRemovalStarted(int taskId) {
+    }
+
+    @Override
+    public void onTaskDescriptionChanged(int taskId, ActivityManager.TaskDescription td)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation)
+            throws RemoteException {
+    }
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 4ddcfe5..118e1f3 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -26,6 +26,7 @@
 import android.annotation.UserIdInt;
 import android.annotation.WorkerThread;
 import android.app.Activity;
+import android.app.admin.PasswordMetrics;
 import android.app.admin.SecurityLog.SecurityEvent;
 import android.content.ComponentName;
 import android.content.Context;
@@ -1094,7 +1095,7 @@
      * names.  If there are no administrators {@code null} may be
      * returned.
      */
-    public List<ComponentName> getActiveAdmins() {
+    public @Nullable List<ComponentName> getActiveAdmins() {
         throwIfParentInstance("getActiveAdmins");
         return getActiveAdminsAsUser(myUserId());
     }
@@ -1103,7 +1104,7 @@
      * @see #getActiveAdmins()
      * @hide
      */
-    public List<ComponentName> getActiveAdminsAsUser(int userId) {
+    public @Nullable List<ComponentName> getActiveAdminsAsUser(int userId) {
         if (mService != null) {
             try {
                 return mService.getActiveAdmins(userId);
@@ -2499,7 +2500,7 @@
      *            of the device admin that sets the proxy.
      * @hide
      */
-    public ComponentName setGlobalProxy(@NonNull ComponentName admin, Proxy proxySpec,
+    public @Nullable ComponentName setGlobalProxy(@NonNull ComponentName admin, Proxy proxySpec,
             List<String> exclusionList ) {
         throwIfParentInstance("setGlobalProxy");
         if (proxySpec == null) {
@@ -2583,7 +2584,7 @@
      *         if no admin has set the proxy.
      * @hide
      */
-    public ComponentName getGlobalProxyAdmin() {
+    public @Nullable ComponentName getGlobalProxyAdmin() {
         if (mService != null) {
             try {
                 return mService.getGlobalProxyAdmin(myUserId());
@@ -2893,8 +2894,8 @@
      * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
      *         owner.
      */
-    public List<byte[]> getInstalledCaCerts(@Nullable ComponentName admin) {
-        List<byte[]> certs = new ArrayList<byte[]>();
+    public @NonNull List<byte[]> getInstalledCaCerts(@Nullable ComponentName admin) {
+        final List<byte[]> certs = new ArrayList<byte[]>();
         throwIfParentInstance("getInstalledCaCerts");
         if (mService != null) {
             try {
@@ -3107,7 +3108,8 @@
      *         none is set.
      * @throws SecurityException if {@code admin} is not a device or a profile owner.
      */
-    public String getCertInstallerPackage(@NonNull ComponentName admin) throws SecurityException {
+    public @Nullable String getCertInstallerPackage(@NonNull ComponentName admin)
+            throws SecurityException {
         throwIfParentInstance("getCertInstallerPackage");
         if (mService != null) {
             try {
@@ -3176,7 +3178,7 @@
      *         is set.
      * @throws SecurityException if {@code admin} is not a device or a profile owner.
      */
-    public String getAlwaysOnVpnPackage(@NonNull ComponentName admin) {
+    public @Nullable String getAlwaysOnVpnPackage(@NonNull ComponentName admin) {
         throwIfParentInstance("getAlwaysOnVpnPackage");
         if (mService != null) {
             try {
@@ -3523,12 +3525,10 @@
     /**
      * @hide
      */
-    public void setActivePasswordState(int quality, int length, int letters, int uppercase,
-            int lowercase, int numbers, int symbols, int nonletter, int userHandle) {
+    public void setActivePasswordState(PasswordMetrics metrics, int userHandle) {
         if (mService != null) {
             try {
-                mService.setActivePasswordState(quality, length, letters, uppercase, lowercase,
-                        numbers, symbols, nonletter, userHandle);
+                mService.setActivePasswordState(metrics, userHandle);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -3799,7 +3799,7 @@
      * @hide
      */
     @SystemApi
-    public String getDeviceOwner() {
+    public @Nullable String getDeviceOwner() {
         throwIfParentInstance("getDeviceOwner");
         final ComponentName name = getDeviceOwnerComponentOnCallingUser();
         return name != null ? name.getPackageName() : null;
@@ -3844,7 +3844,7 @@
      */
     @Deprecated
     @SystemApi
-    public String getDeviceInitializerApp() {
+    public @Nullable String getDeviceInitializerApp() {
         return null;
     }
 
@@ -3855,7 +3855,7 @@
      */
     @Deprecated
     @SystemApi
-    public ComponentName getDeviceInitializerComponent() {
+    public @Nullable ComponentName getDeviceInitializerComponent() {
         return null;
     }
 
@@ -4021,8 +4021,8 @@
      *         this method.
      * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
-    public String[] setPackagesSuspended(@NonNull ComponentName admin, String[] packageNames,
-            boolean suspended) {
+    public @NonNull String[] setPackagesSuspended(@NonNull ComponentName admin,
+            @NonNull String[] packageNames, boolean suspended) {
         throwIfParentInstance("setPackagesSuspended");
         if (mService != null) {
             try {
@@ -4129,7 +4129,7 @@
      * @throws IllegalArgumentException if the userId is invalid.
      */
     @SystemApi
-    public ComponentName getProfileOwner() throws IllegalArgumentException {
+    public @Nullable ComponentName getProfileOwner() throws IllegalArgumentException {
         throwIfParentInstance("getProfileOwner");
         return getProfileOwnerAsUser(Process.myUserHandle().getIdentifier());
     }
@@ -4138,7 +4138,8 @@
      * @see #getProfileOwner()
      * @hide
      */
-    public ComponentName getProfileOwnerAsUser(final int userId) throws IllegalArgumentException {
+    public @Nullable ComponentName getProfileOwnerAsUser(final int userId)
+            throws IllegalArgumentException {
         if (mService != null) {
             try {
                 return mService.getProfileOwner(userId);
@@ -4155,7 +4156,7 @@
      *         if one is not set.
      * @throws IllegalArgumentException if the userId is invalid.
      */
-    public String getProfileOwnerName() throws IllegalArgumentException {
+    public @Nullable String getProfileOwnerName() throws IllegalArgumentException {
         if (mService != null) {
             try {
                 return mService.getProfileOwnerName(Process.myUserHandle().getIdentifier());
@@ -4174,7 +4175,7 @@
      * @throws IllegalArgumentException if the userId is invalid.
      */
     @SystemApi
-    public String getProfileOwnerNameAsUser(int userId) throws IllegalArgumentException {
+    public @Nullable String getProfileOwnerNameAsUser(int userId) throws IllegalArgumentException {
         throwIfParentInstance("getProfileOwnerNameAsUser");
         if (mService != null) {
             try {
@@ -4279,7 +4280,8 @@
      *         {@code null} if none is set.
      * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
-    public String getApplicationRestrictionsManagingPackage(@NonNull ComponentName admin) {
+    public @Nullable String getApplicationRestrictionsManagingPackage(
+            @NonNull ComponentName admin) {
         throwIfParentInstance("getApplicationRestrictionsManagingPackage");
         if (mService != null) {
             try {
@@ -4417,14 +4419,14 @@
      * @param agent Which component to get enabled features for.
      * @return configuration for the given trust agent.
      */
-    public List<PersistableBundle> getTrustAgentConfiguration(@Nullable ComponentName admin,
-            @NonNull ComponentName agent) {
+    public @Nullable List<PersistableBundle> getTrustAgentConfiguration(
+            @Nullable ComponentName admin, @NonNull ComponentName agent) {
         return getTrustAgentConfiguration(admin, agent, myUserId());
     }
 
     /** @hide per-user version */
-    public List<PersistableBundle> getTrustAgentConfiguration(@Nullable ComponentName admin,
-            @NonNull ComponentName agent, int userHandle) {
+    public @Nullable List<PersistableBundle> getTrustAgentConfiguration(
+            @Nullable ComponentName admin, @NonNull ComponentName agent, int userHandle) {
         if (mService != null) {
             try {
                 return mService.getTrustAgentConfiguration(admin, agent, userHandle,
@@ -4739,7 +4741,7 @@
      * @return List of accessiblity service package names.
      * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
-    public List<String> getPermittedAccessibilityServices(@NonNull ComponentName admin) {
+    public @Nullable List<String> getPermittedAccessibilityServices(@NonNull ComponentName admin) {
         throwIfParentInstance("getPermittedAccessibilityServices");
         if (mService != null) {
             try {
@@ -4787,7 +4789,7 @@
      * @hide
      */
      @SystemApi
-     public List<String> getPermittedAccessibilityServices(int userId) {
+     public @Nullable List<String> getPermittedAccessibilityServices(int userId) {
         throwIfParentInstance("getPermittedAccessibilityServices");
         if (mService != null) {
             try {
@@ -4841,7 +4843,7 @@
      * @return List of input method package names.
      * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
-    public List<String> getPermittedInputMethods(@NonNull ComponentName admin) {
+    public @Nullable List<String> getPermittedInputMethods(@NonNull ComponentName admin) {
         throwIfParentInstance("getPermittedInputMethods");
         if (mService != null) {
             try {
@@ -4887,7 +4889,7 @@
      * @hide
      */
     @SystemApi
-    public List<String> getPermittedInputMethodsForCurrentUser() {
+    public @Nullable List<String> getPermittedInputMethodsForCurrentUser() {
         throwIfParentInstance("getPermittedInputMethodsForCurrentUser");
         if (mService != null) {
             try {
@@ -4908,7 +4910,7 @@
      * @return List of package names to keep cached.
      * @hide
      */
-    public List<String> getKeepUninstalledPackages(@NonNull ComponentName admin) {
+    public @Nullable List<String> getKeepUninstalledPackages(@NonNull ComponentName admin) {
         throwIfParentInstance("getKeepUninstalledPackages");
         if (mService != null) {
             try {
@@ -4960,7 +4962,7 @@
      * @removed From {@link android.os.Build.VERSION_CODES#N}
      */
     @Deprecated
-    public UserHandle createUser(@NonNull ComponentName admin, String name) {
+    public @Nullable UserHandle createUser(@NonNull ComponentName admin, String name) {
         return null;
     }
 
@@ -4993,7 +4995,7 @@
      * @removed From {@link android.os.Build.VERSION_CODES#N}
      */
     @Deprecated
-    public UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name,
+    public @Nullable UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name,
             String ownerName, @NonNull ComponentName profileOwnerComponent, Bundle adminExtras) {
         return null;
     }
@@ -5038,7 +5040,8 @@
      *         user could not be created.
      * @throws SecurityException if {@code admin} is not a device owner.
      */
-    public UserHandle createAndManageUser(@NonNull ComponentName admin, @NonNull String name,
+    public @Nullable UserHandle createAndManageUser(@NonNull ComponentName admin,
+            @NonNull String name,
             @NonNull ComponentName profileOwner, @Nullable PersistableBundle adminExtras,
             int flags) {
         throwIfParentInstance("createAndManageUser");
@@ -5105,7 +5108,8 @@
      * @see {@link #setApplicationRestrictionsManagingPackage}
      */
     @WorkerThread
-    public Bundle getApplicationRestrictions(@Nullable ComponentName admin, String packageName) {
+    public @NonNull Bundle getApplicationRestrictions(
+            @Nullable ComponentName admin, String packageName) {
         throwIfParentInstance("getApplicationRestrictions");
         if (mService != null) {
             try {
@@ -5172,7 +5176,7 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
-    public Bundle getUserRestrictions(@NonNull ComponentName admin) {
+    public @NonNull Bundle getUserRestrictions(@NonNull ComponentName admin) {
         throwIfParentInstance("getUserRestrictions");
         Bundle ret = null;
         if (mService != null) {
@@ -5312,7 +5316,7 @@
      *
      * @see #setAccountManagementDisabled
      */
-    public String[] getAccountTypesWithManagementDisabled() {
+    public @Nullable String[] getAccountTypesWithManagementDisabled() {
         throwIfParentInstance("getAccountTypesWithManagementDisabled");
         return getAccountTypesWithManagementDisabledAsUser(myUserId());
     }
@@ -5321,7 +5325,7 @@
      * @see #getAccountTypesWithManagementDisabled()
      * @hide
      */
-    public String[] getAccountTypesWithManagementDisabledAsUser(int userId) {
+    public @Nullable String[] getAccountTypesWithManagementDisabledAsUser(int userId) {
         if (mService != null) {
             try {
                 return mService.getAccountTypesWithManagementDisabledAsUser(userId);
@@ -5367,7 +5371,7 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @hide
      */
-    public String[] getLockTaskPackages(@NonNull ComponentName admin) {
+    public @NonNull String[] getLockTaskPackages(@NonNull ComponentName admin) {
         throwIfParentInstance("getLockTaskPackages");
         if (mService != null) {
             try {
@@ -5652,7 +5656,7 @@
      * @see #removeCrossProfileWidgetProvider(android.content.ComponentName, String)
      * @throws SecurityException if {@code admin} is not a profile owner.
      */
-    public List<String> getCrossProfileWidgetProviders(@NonNull ComponentName admin) {
+    public @NonNull List<String> getCrossProfileWidgetProviders(@NonNull ComponentName admin) {
         throwIfParentInstance("getCrossProfileWidgetProviders");
         if (mService != null) {
             try {
@@ -5710,7 +5714,7 @@
      *
      * @return The current policy object, or {@code null} if no policy is set.
      */
-    public SystemUpdatePolicy getSystemUpdatePolicy() {
+    public @Nullable SystemUpdatePolicy getSystemUpdatePolicy() {
         throwIfParentInstance("getSystemUpdatePolicy");
         if (mService != null) {
             try {
@@ -5949,7 +5953,7 @@
      *         The address will be in the {@code XX:XX:XX:XX:XX:XX} format.
      * @throws SecurityException if {@code admin} is not a device owner.
      */
-    public String getWifiMacAddress(@NonNull ComponentName admin) {
+    public @Nullable String getWifiMacAddress(@NonNull ComponentName admin) {
         throwIfParentInstance("getWifiMacAddress");
         try {
             return mService.getWifiMacAddress(admin);
@@ -6058,7 +6062,7 @@
      *         null if no message has been set.
      * @throws SecurityException if {@code admin} is not an active administrator.
      */
-    public CharSequence getLongSupportMessage(@NonNull ComponentName admin) {
+    public @Nullable CharSequence getLongSupportMessage(@NonNull ComponentName admin) {
         throwIfParentInstance("getLongSupportMessage");
         if (mService != null) {
             try {
@@ -6079,7 +6083,7 @@
      *
      * @hide
      */
-    public CharSequence getShortSupportMessageForUser(@NonNull ComponentName admin,
+    public @Nullable CharSequence getShortSupportMessageForUser(@NonNull ComponentName admin,
             int userHandle) {
         if (mService != null) {
             try {
@@ -6101,7 +6105,8 @@
      *
      * @hide
      */
-    public CharSequence getLongSupportMessageForUser(@NonNull ComponentName admin, int userHandle) {
+    public @Nullable CharSequence getLongSupportMessageForUser(
+            @NonNull ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
                 return mService.getLongSupportMessageForUser(admin, userHandle);
@@ -6156,7 +6161,7 @@
      * @return a new instance of {@link DevicePolicyManager} that acts on the parent profile.
      * @throws SecurityException if {@code admin} is not a profile owner.
      */
-    public DevicePolicyManager getParentProfileInstance(@NonNull ComponentName admin) {
+    public @NonNull DevicePolicyManager getParentProfileInstance(@NonNull ComponentName admin) {
         throwIfParentInstance("getParentProfileInstance");
         try {
             if (!mService.isManagedProfile(admin)) {
@@ -6226,7 +6231,7 @@
      * or {@code null} if rate limitation is exceeded or if logging is currently disabled.
      * @throws SecurityException if {@code admin} is not a device owner.
      */
-    public List<SecurityEvent> retrieveSecurityLogs(@NonNull ComponentName admin) {
+    public @Nullable List<SecurityEvent> retrieveSecurityLogs(@NonNull ComponentName admin) {
         throwIfParentInstance("retrieveSecurityLogs");
         try {
             ParceledListSlice<SecurityEvent> list = mService.retrieveSecurityLogs(admin);
@@ -6247,7 +6252,7 @@
      *
      * @hide
      */
-    public DevicePolicyManager getParentProfileInstance(UserInfo uInfo) {
+    public @NonNull DevicePolicyManager getParentProfileInstance(UserInfo uInfo) {
         mContext.checkSelfPermission(
                 android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         if (!uInfo.isManagedProfile()) {
@@ -6273,7 +6278,8 @@
      *         is not supported on the device.
      * @throws SecurityException if {@code admin} is not a device owner.
      */
-    public List<SecurityEvent> retrievePreRebootSecurityLogs(@NonNull ComponentName admin) {
+    public @Nullable List<SecurityEvent> retrievePreRebootSecurityLogs(
+            @NonNull ComponentName admin) {
         throwIfParentInstance("retrievePreRebootSecurityLogs");
         try {
             ParceledListSlice<SecurityEvent> list = mService.retrievePreRebootSecurityLogs(admin);
@@ -6392,7 +6398,7 @@
      * @return The organization name or {@code null} if none is set.
      * @throws SecurityException if {@code admin} is not a profile owner.
      */
-    public CharSequence getOrganizationName(@NonNull ComponentName admin) {
+    public @Nullable CharSequence getOrganizationName(@NonNull ComponentName admin) {
         throwIfParentInstance("getOrganizationName");
         try {
             return mService.getOrganizationName(admin);
@@ -6409,7 +6415,7 @@
      *
      * @hide
      */
-    public CharSequence getOrganizationNameForUser(int userHandle) {
+    public @Nullable CharSequence getOrganizationNameForUser(int userHandle) {
         try {
             return mService.getOrganizationNameForUser(userHandle);
         } catch (RemoteException re) {
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 8c376bb..22219d7 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -18,6 +18,7 @@
 package android.app.admin;
 
 import android.app.admin.SystemUpdatePolicy;
+import android.app.admin.PasswordMetrics;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -29,6 +30,7 @@
 import android.os.PersistableBundle;
 import android.os.RemoteCallback;
 import android.os.UserHandle;
+
 import java.util.List;
 
 /**
@@ -117,8 +119,7 @@
     void forceRemoveActiveAdmin(in ComponentName policyReceiver, int userHandle);
     boolean hasGrantedPolicy(in ComponentName policyReceiver, int usesPolicy, int userHandle);
 
-    void setActivePasswordState(int quality, int length, int letters, int uppercase, int lowercase,
-        int numbers, int symbols, int nonletter, int userHandle);
+    void setActivePasswordState(in PasswordMetrics metrics, int userHandle);
     void reportFailedPasswordAttempt(int userHandle);
     void reportSuccessfulPasswordAttempt(int userHandle);
     void reportFailedFingerprintAttempt(int userHandle);
diff --git a/core/java/android/app/admin/PasswordMetrics.aidl b/core/java/android/app/admin/PasswordMetrics.aidl
new file mode 100644
index 0000000..90d7c69
--- /dev/null
+++ b/core/java/android/app/admin/PasswordMetrics.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.app.admin;
+
+parcelable PasswordMetrics;
diff --git a/core/java/android/app/admin/PasswordMetrics.java b/core/java/android/app/admin/PasswordMetrics.java
new file mode 100644
index 0000000..ea3f560
--- /dev/null
+++ b/core/java/android/app/admin/PasswordMetrics.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.app.admin.DevicePolicyManager;
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.io.IOException;
+
+/**
+ * A class that represents the metrics of a password that are used to decide whether or not a
+ * password meets the requirements.
+ *
+ * {@hide}
+ */
+public class PasswordMetrics implements Parcelable {
+    // Maximum allowed number of repeated or ordered characters in a sequence before we'll
+    // consider it a complex PIN/password.
+    public static final int MAX_ALLOWED_SEQUENCE = 3;
+
+    public int quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+    public int length = 0;
+    public int letters = 0;
+    public int upperCase = 0;
+    public int lowerCase = 0;
+    public int numeric = 0;
+    public int symbols = 0;
+    public int nonLetter = 0;
+
+    public PasswordMetrics() {}
+
+    public PasswordMetrics(int quality, int length) {
+        this.quality = quality;
+        this.length = length;
+    }
+
+    public PasswordMetrics(int quality, int length, int letters, int upperCase, int lowerCase,
+            int numeric, int symbols, int nonLetter) {
+        this(quality, length);
+        this.letters = letters;
+        this.upperCase = upperCase;
+        this.lowerCase = lowerCase;
+        this.numeric = numeric;
+        this.symbols = symbols;
+        this.nonLetter = nonLetter;
+    }
+
+    private PasswordMetrics(Parcel in) {
+        quality = in.readInt();
+        length = in.readInt();
+        letters = in.readInt();
+        upperCase = in.readInt();
+        lowerCase = in.readInt();
+        numeric = in.readInt();
+        symbols = in.readInt();
+        nonLetter = in.readInt();
+    }
+
+    public boolean isDefault() {
+        return quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
+                && length == 0 && letters == 0 && upperCase == 0 && lowerCase == 0
+                && numeric == 0 && symbols == 0 && nonLetter == 0;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(quality);
+        dest.writeInt(length);
+        dest.writeInt(letters);
+        dest.writeInt(upperCase);
+        dest.writeInt(lowerCase);
+        dest.writeInt(numeric);
+        dest.writeInt(symbols);
+        dest.writeInt(nonLetter);
+    }
+
+    public static final Parcelable.Creator<PasswordMetrics> CREATOR
+            = new Parcelable.Creator<PasswordMetrics>() {
+        public PasswordMetrics createFromParcel(Parcel in) {
+            return new PasswordMetrics(in);
+        }
+
+        public PasswordMetrics[] newArray(int size) {
+            return new PasswordMetrics[size];
+        }
+    };
+
+    public static PasswordMetrics computeForPassword(@NonNull String password) {
+        // Analyse the characters used
+        int letters = 0;
+        int upperCase = 0;
+        int lowerCase = 0;
+        int numeric = 0;
+        int symbols = 0;
+        int nonLetter = 0;
+        final int length = password.length();
+        for (int i = 0; i < length; i++) {
+            switch (categoryChar(password.charAt(i))) {
+                case CHAR_LOWER_CASE:
+                    letters++;
+                    lowerCase++;
+                    break;
+                case CHAR_UPPER_CASE:
+                    letters++;
+                    upperCase++;
+                    break;
+                case CHAR_DIGIT:
+                    numeric++;
+                    nonLetter++;
+                    break;
+                case CHAR_SYMBOL:
+                    symbols++;
+                    nonLetter++;
+                    break;
+            }
+        }
+
+        // Determine the quality of the password
+        final boolean hasNumeric = numeric > 0;
+        final boolean hasNonNumeric = (letters + symbols) > 0;
+        final int quality;
+        if (hasNonNumeric && hasNumeric) {
+            quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
+        } else if (hasNonNumeric) {
+            quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+        } else if (hasNumeric) {
+            quality = maxLengthSequence(password) > MAX_ALLOWED_SEQUENCE
+                    ? DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
+                    : DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
+        } else {
+            quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+        }
+
+        return new PasswordMetrics(
+                quality, length, letters, upperCase, lowerCase, numeric, symbols, nonLetter);
+    }
+
+    /*
+     * Returns the maximum length of a sequential characters. A sequence is defined as
+     * monotonically increasing characters with a constant interval or the same character repeated.
+     *
+     * For example:
+     * maxLengthSequence("1234") == 4
+     * maxLengthSequence("13579") == 5
+     * maxLengthSequence("1234abc") == 4
+     * maxLengthSequence("aabc") == 3
+     * maxLengthSequence("qwertyuio") == 1
+     * maxLengthSequence("@ABC") == 3
+     * maxLengthSequence(";;;;") == 4 (anything that repeats)
+     * maxLengthSequence(":;<=>") == 1  (ordered, but not composed of alphas or digits)
+     *
+     * @param string the pass
+     * @return the number of sequential letters or digits
+     */
+    public static int maxLengthSequence(@NonNull String string) {
+        if (string.length() == 0) return 0;
+        char previousChar = string.charAt(0);
+        @CharacterCatagory int category = categoryChar(previousChar); //current sequence category
+        int diff = 0; //difference between two consecutive characters
+        boolean hasDiff = false; //if we are currently targeting a sequence
+        int maxLength = 0; //maximum length of a sequence already found
+        int startSequence = 0; //where the current sequence started
+        for (int current = 1; current < string.length(); current++) {
+            char currentChar = string.charAt(current);
+            @CharacterCatagory int categoryCurrent = categoryChar(currentChar);
+            int currentDiff = (int) currentChar - (int) previousChar;
+            if (categoryCurrent != category || Math.abs(currentDiff) > maxDiffCategory(category)) {
+                maxLength = Math.max(maxLength, current - startSequence);
+                startSequence = current;
+                hasDiff = false;
+                category = categoryCurrent;
+            }
+            else {
+                if(hasDiff && currentDiff != diff) {
+                    maxLength = Math.max(maxLength, current - startSequence);
+                    startSequence = current - 1;
+                }
+                diff = currentDiff;
+                hasDiff = true;
+            }
+            previousChar = currentChar;
+        }
+        maxLength = Math.max(maxLength, string.length() - startSequence);
+        return maxLength;
+    }
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({CHAR_UPPER_CASE, CHAR_LOWER_CASE, CHAR_DIGIT, CHAR_SYMBOL})
+    private @interface CharacterCatagory {}
+    private static final int CHAR_LOWER_CASE = 0;
+    private static final int CHAR_UPPER_CASE = 1;
+    private static final int CHAR_DIGIT = 2;
+    private static final int CHAR_SYMBOL = 3;
+
+    @CharacterCatagory
+    private static int categoryChar(char c) {
+        if ('a' <= c && c <= 'z') return CHAR_LOWER_CASE;
+        if ('A' <= c && c <= 'Z') return CHAR_UPPER_CASE;
+        if ('0' <= c && c <= '9') return CHAR_DIGIT;
+        return CHAR_SYMBOL;
+    }
+
+    private static int maxDiffCategory(@CharacterCatagory int category) {
+        switch (category) {
+            case CHAR_LOWER_CASE:
+            case CHAR_UPPER_CASE:
+                return 1;
+            case CHAR_DIGIT:
+                return 10;
+            default:
+                return 0;
+        }
+    }
+}
diff --git a/core/java/android/app/usage/NetworkStats.java b/core/java/android/app/usage/NetworkStats.java
index 226aa8f..f64bec7 100644
--- a/core/java/android/app/usage/NetworkStats.java
+++ b/core/java/android/app/usage/NetworkStats.java
@@ -164,6 +164,29 @@
         public static final int UID_TETHERING = TrafficStats.UID_TETHERING;
 
         /** @hide */
+        @IntDef({METERED_ALL, METERED_NO, METERED_YES})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Metered {}
+
+        /**
+         * Combined usage across all metered states. Covers metered and unmetered usage.
+         */
+        public static final int METERED_ALL = -1;
+
+        /**
+         * Usage that occurs on an unmetered network.
+         */
+        public static final int METERED_NO = 0x1;
+
+        /**
+         * Usage that occurs on a metered network.
+         *
+         * <p>A network is classified as metered when the user is sensitive to heavy data usage on
+         * that connection.
+         */
+        public static final int METERED_YES = 0x2;
+
+        /** @hide */
         @IntDef({ROAMING_ALL, ROAMING_NO, ROAMING_YES})
         @Retention(RetentionPolicy.SOURCE)
         public @interface Roaming {}
@@ -200,6 +223,7 @@
         private int mUid;
         private int mTag;
         private int mState;
+        private int mMetered;
         private int mRoaming;
         private long mBeginTimeStamp;
         private long mEndTimeStamp;
@@ -279,6 +303,21 @@
         }
 
         /**
+         * Metered state. One of the following values:<p/>
+         * <ul>
+         * <li>{@link #METERED_ALL}</li>
+         * <li>{@link #METERED_NO}</li>
+         * <li>{@link #METERED_YES}</li>
+         * </ul>
+         * <p>A network is classified as metered when the user is sensitive to heavy data usage on
+         * that connection. Apps may warn before using these networks for large downloads. The
+         * metered state can be set by the user within data usage network restrictions.
+         */
+        public @Metered int getMetered() {
+            return mMetered;
+        }
+
+        /**
          * Roaming state. One of the following values:<p/>
          * <ul>
          * <li>{@link #ROAMING_ALL}</li>
@@ -491,6 +530,8 @@
         bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid);
         bucketOut.mTag = Bucket.convertTag(mRecycledSummaryEntry.tag);
         bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set);
+        // TODO: Implement metered tracking.
+        bucketOut.mMetered = Bucket.METERED_ALL;
         bucketOut.mRoaming = Bucket.convertRoaming(mRecycledSummaryEntry.roaming);
         bucketOut.mBeginTimeStamp = mStartTimeStamp;
         bucketOut.mEndTimeStamp = mEndTimeStamp;
@@ -539,6 +580,7 @@
                 bucketOut.mUid = Bucket.convertUid(getUid());
                 bucketOut.mTag = Bucket.convertTag(mTag);
                 bucketOut.mState = Bucket.STATE_ALL;
+                bucketOut.mMetered = Bucket.METERED_ALL;
                 bucketOut.mRoaming = Bucket.ROAMING_ALL;
                 bucketOut.mBeginTimeStamp = mRecycledHistoryEntry.bucketStart;
                 bucketOut.mEndTimeStamp = mRecycledHistoryEntry.bucketStart +
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index bb5f7a1..4c8360f 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -377,13 +377,13 @@
      * AppWidget provider. Will animate into these new views as needed
      */
     public void updateAppWidget(RemoteViews remoteViews) {
-        applyRemoteViews(remoteViews);
+        applyRemoteViews(remoteViews, true);
     }
 
     /**
      * @hide
      */
-    protected void applyRemoteViews(RemoteViews remoteViews) {
+    protected void applyRemoteViews(RemoteViews remoteViews, boolean useAsyncIfPossible) {
         if (LOGD) Log.d(TAG, "updateAppWidget called mOld=" + mOld);
 
         boolean recycled = false;
@@ -423,7 +423,7 @@
             mLayoutId = -1;
             mViewMode = VIEW_MODE_DEFAULT;
         } else {
-            if (mAsyncExecutor != null) {
+            if (mAsyncExecutor != null && useAsyncIfPossible) {
                 inflateAsync(remoteViews);
                 return;
             }
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 111085d..542b06b 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -789,19 +789,13 @@
     public boolean enableBLE() {
         if (!isBleScanAlwaysAvailable()) return false;
 
-        if (isLeEnabled() == true) {
-            if (DBG) Log.d(TAG, "enableBLE(): BT is already enabled..!");
-            try {
-                mManagerService.updateBleAppCount(mToken, true);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-            return true;
-        }
-
         try {
-            if (DBG) Log.d(TAG, "Calling enableBLE");
             mManagerService.updateBleAppCount(mToken, true);
+            if (isLeEnabled()) {
+                if (DBG) Log.d(TAG, "enableBLE(): Bluetooth already enabled");
+                return true;
+            }
+            if (DBG) Log.d(TAG, "enableBLE(): Calling enable");
             return mManagerService.enable(ActivityThread.currentPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 2bb9012..12ebdac 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -44,14 +44,18 @@
     private IBluetoothGatt mService;
     private BluetoothGattCallback mCallback;
     private int mClientIf;
-    private boolean mAuthRetry = false;
     private BluetoothDevice mDevice;
     private boolean mAutoConnect;
+    private int mAuthRetryState;
     private int mConnState;
     private final Object mStateLock = new Object();
     private Boolean mDeviceBusy = false;
     private int mTransport;
 
+    private static final int AUTH_RETRY_STATE_IDLE = 0;
+    private static final int AUTH_RETRY_STATE_NO_MITM = 1;
+    private static final int AUTH_RETRY_STATE_MITM = 2;
+
     private static final int CONN_STATE_IDLE = 0;
     private static final int CONN_STATE_CONNECTING = 1;
     private static final int CONN_STATE_CONNECTED = 2;
@@ -131,7 +135,7 @@
      * Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation.
      */
     private final IBluetoothGattCallback mBluetoothGattCallback =
-        new BluetoothGattCallbackWrapper() {
+        new IBluetoothGattCallback.Stub() {
             /**
              * Application interface registered - app is ready to go
              * @hide
@@ -259,17 +263,19 @@
 
                 if ((status == GATT_INSUFFICIENT_AUTHENTICATION
                   || status == GATT_INSUFFICIENT_ENCRYPTION)
-                  && mAuthRetry == false) {
+                  && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
                     try {
-                        mAuthRetry = true;
-                        mService.readCharacteristic(mClientIf, address, handle, AUTHENTICATION_MITM);
+                        final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ?
+                                AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
+                        mService.readCharacteristic(mClientIf, address, handle, authReq);
+                        mAuthRetryState++;
                         return;
                     } catch (RemoteException e) {
                         Log.e(TAG,"",e);
                     }
                 }
 
-                mAuthRetry = false;
+                mAuthRetryState = AUTH_RETRY_STATE_IDLE;
 
                 BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice, handle);
                 if (characteristic == null) {
@@ -308,19 +314,20 @@
 
                 if ((status == GATT_INSUFFICIENT_AUTHENTICATION
                   || status == GATT_INSUFFICIENT_ENCRYPTION)
-                  && mAuthRetry == false) {
+                  && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
                     try {
-                        mAuthRetry = true;
+                        final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ?
+                                AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
                         mService.writeCharacteristic(mClientIf, address, handle,
-                            characteristic.getWriteType(), AUTHENTICATION_MITM,
-                            characteristic.getValue());
+                            characteristic.getWriteType(), authReq, characteristic.getValue());
+                        mAuthRetryState++;
                         return;
                     } catch (RemoteException e) {
                         Log.e(TAG,"",e);
                     }
                 }
 
-                mAuthRetry = false;
+                mAuthRetryState = AUTH_RETRY_STATE_IDLE;
 
                 try {
                     mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status);
@@ -375,17 +382,19 @@
 
                 if ((status == GATT_INSUFFICIENT_AUTHENTICATION
                   || status == GATT_INSUFFICIENT_ENCRYPTION)
-                  && mAuthRetry == false) {
+                  && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
                     try {
-                        mAuthRetry = true;
-                        mService.readDescriptor(mClientIf, address, handle, AUTHENTICATION_MITM);
+                        final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ?
+                                AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
+                        mService.readDescriptor(mClientIf, address, handle, authReq);
+                        mAuthRetryState++;
                         return;
                     } catch (RemoteException e) {
                         Log.e(TAG,"",e);
                     }
                 }
 
-                mAuthRetry = true;
+                mAuthRetryState = AUTH_RETRY_STATE_IDLE;
 
                 try {
                     mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
@@ -414,18 +423,20 @@
 
                 if ((status == GATT_INSUFFICIENT_AUTHENTICATION
                   || status == GATT_INSUFFICIENT_ENCRYPTION)
-                  && mAuthRetry == false) {
+                  && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
                     try {
-                        mAuthRetry = true;
+                        final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE) ?
+                                AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
                         mService.writeDescriptor(mClientIf, address, handle,
-                            AUTHENTICATION_MITM, descriptor.getValue());
+                            authReq, descriptor.getValue());
+                        mAuthRetryState++;
                         return;
                     } catch (RemoteException e) {
                         Log.e(TAG,"",e);
                     }
                 }
 
-                mAuthRetry = false;
+                mAuthRetryState = AUTH_RETRY_STATE_IDLE;
 
                 try {
                     mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
@@ -499,6 +510,7 @@
         mServices = new ArrayList<BluetoothGattService>();
 
         mConnState = CONN_STATE_IDLE;
+        mAuthRetryState = AUTH_RETRY_STATE_IDLE;
     }
 
     /**
@@ -512,6 +524,7 @@
 
         unregisterApp();
         mConnState = CONN_STATE_CLOSED;
+        mAuthRetryState = AUTH_RETRY_STATE_IDLE;
     }
 
     /**
diff --git a/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java b/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
deleted file mode 100644
index da81569..0000000
--- a/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.le.AdvertiseSettings;
-import android.bluetooth.le.ScanResult;
-import android.bluetooth.BluetoothGattService;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-
-import java.util.List;
-
-/**
- * Wrapper class for default implementation of IBluetoothGattCallback.
- *
- * @hide
- */
-public class BluetoothGattCallbackWrapper extends IBluetoothGattCallback.Stub {
-
-    @Override
-    public void onClientRegistered(int status, int clientIf) throws RemoteException {
-    }
-
-    @Override
-    public void onClientConnectionState(int status, int clientIf, boolean connected, String address)
-            throws RemoteException {
-    }
-
-    @Override
-    public void onScanResult(ScanResult scanResult) throws RemoteException {
-    }
-
-    @Override
-    public void onBatchScanResults(List<ScanResult> batchResults) throws RemoteException {
-    }
-
-    @Override
-    public void onSearchComplete(String address, List<BluetoothGattService> services,
-            int status) throws RemoteException {
-    }
-
-    @Override
-    public void onCharacteristicRead(String address, int status, int handle, byte[] value)
-            throws RemoteException {
-    }
-
-    @Override
-    public void onCharacteristicWrite(String address, int status, int handle) throws RemoteException {
-    }
-
-    @Override
-    public void onExecuteWrite(String address, int status) throws RemoteException {
-    }
-
-    @Override
-    public void onDescriptorRead(String address, int status, int handle, byte[] value) throws RemoteException {
-    }
-
-    @Override
-    public void onDescriptorWrite(String address, int status, int handle) throws RemoteException {
-    }
-
-    @Override
-    public void onNotify(String address, int handle, byte[] value) throws RemoteException {
-    }
-
-    @Override
-    public void onReadRemoteRssi(String address, int rssi, int status) throws RemoteException {
-    }
-
-    @Override
-    public void onConfigureMTU(String address, int mtu, int status) throws RemoteException {
-    }
-
-    @Override
-    public void onFoundOrLost(boolean onFound, ScanResult scanResult) throws RemoteException {
-    }
-
-    @Override
-    public void onScanManagerErrorCallback(int errorCode) throws RemoteException {
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 2ded4c8..243579a 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -275,6 +275,48 @@
     }
 
     /**
+     * Parse UUID to bytes. The returned value is shortest representation, a 16-bit, 32-bit or 128-bit UUID,
+     * Note returned value is little endian (Bluetooth).
+     *
+     * @param uuid uuid to parse.
+     * @return shortest representation of {@code uuid} as bytes.
+     * @throws IllegalArgumentException If the {@code uuid} is null.
+     */
+    public static byte[] uuidToBytes(ParcelUuid uuid) {
+        if (uuid == null) {
+            throw new IllegalArgumentException("uuid cannot be null");
+        }
+
+        if (is16BitUuid(uuid)) {
+            byte[] uuidBytes = new byte[UUID_BYTES_16_BIT];
+            int uuidVal = getServiceIdentifierFromParcelUuid(uuid);
+            uuidBytes[0] = (byte)(uuidVal & 0xFF);
+            uuidBytes[1] = (byte)((uuidVal & 0xFF00) >> 8);
+            return uuidBytes;
+        }
+
+        if (is32BitUuid(uuid)) {
+            byte[] uuidBytes = new byte[UUID_BYTES_32_BIT];
+            int uuidVal = getServiceIdentifierFromParcelUuid(uuid);
+            uuidBytes[0] = (byte)(uuidVal & 0xFF);
+            uuidBytes[1] = (byte)((uuidVal & 0xFF00) >> 8);
+            uuidBytes[2] = (byte)((uuidVal & 0xFF0000) >> 16);
+            uuidBytes[3] = (byte)((uuidVal & 0xFF000000) >> 24);
+            return uuidBytes;
+        }
+
+        // Construct a 128 bit UUID.
+        long msb = uuid.getUuid().getMostSignificantBits();
+        long lsb = uuid.getUuid().getLeastSignificantBits();
+
+        byte[] uuidBytes = new byte[UUID_BYTES_128_BIT];
+        ByteBuffer buf = ByteBuffer.wrap(uuidBytes).order(ByteOrder.LITTLE_ENDIAN);
+        buf.putLong(8, msb);
+        buf.putLong(0, lsb);
+        return uuidBytes;
+    }
+
+    /**
      * Check whether the given parcelUuid can be converted to 16 bit bluetooth uuid.
      *
      * @param parcelUuid
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index f4ebcaf..aa2291e 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -29,6 +29,7 @@
 import android.bluetooth.IBluetoothGattCallback;
 import android.bluetooth.IBluetoothGattServerCallback;
 import android.bluetooth.le.IAdvertiserCallback;
+import android.bluetooth.le.IScannerCallback;
 
 /**
  * API for interacting with BLE / GATT
@@ -37,11 +38,12 @@
 interface IBluetoothGatt {
     List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
 
-    void startScan(in int appIf, in boolean isServer, in ScanSettings settings,
-                   in List<ScanFilter> filters, in WorkSource workSource, in List scanStorages,
-                   in String callingPackage);
-    void stopScan(in int appIf, in boolean isServer);
-    void flushPendingBatchResults(in int appIf, in boolean isServer);
+    void registerScanner(in IScannerCallback callback);
+    void unregisterScanner(in int scannerId);
+    void startScan(in int scannerId, in ScanSettings settings, in List<ScanFilter> filters,
+                   in WorkSource workSource, in List scanStorages, in String callingPackage);
+    void stopScan(in int scannerId);
+    void flushPendingBatchResults(in int scannerId);
 
     void registerAdvertiser(in IAdvertiserCallback callback);
     void unregisterAdvertiser(in int advertiserId);
diff --git a/core/java/android/bluetooth/IBluetoothGattCallback.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
index efda08e..72cb618 100644
--- a/core/java/android/bluetooth/IBluetoothGattCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
@@ -17,8 +17,6 @@
 
 import android.os.ParcelUuid;
 import android.bluetooth.BluetoothGattService;
-import android.bluetooth.le.AdvertiseSettings;
-import android.bluetooth.le.ScanResult;
 
 /**
  * Callback definitions for interacting with BLE / GATT
@@ -28,8 +26,6 @@
     void onClientRegistered(in int status, in int clientIf);
     void onClientConnectionState(in int status, in int clientIf,
                                  in boolean connected, in String address);
-    void onScanResult(in ScanResult scanResult);
-    void onBatchScanResults(in List<ScanResult> batchResults);
     void onSearchComplete(in String address, in List<BluetoothGattService> services, in int status);
     void onCharacteristicRead(in String address, in int status, in int handle, in byte[] value);
     void onCharacteristicWrite(in String address, in int status, in int handle);
@@ -38,7 +34,5 @@
     void onDescriptorWrite(in String address, in int status, in int handle);
     void onNotify(in String address, in int handle, in byte[] value);
     void onReadRemoteRssi(in String address, in int rssi, in int status);
-    void onScanManagerErrorCallback(in int errorCode);
     void onConfigureMTU(in String address, in int mtu, in int status);
-    void onFoundOrLost(in boolean onFound, in ScanResult scanResult);
 }
diff --git a/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
index 0bcb07b..1a924fb 100644
--- a/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
@@ -23,7 +23,6 @@
  */
 oneway interface IBluetoothGattServerCallback {
     void onServerRegistered(in int status, in int serverIf);
-    void onScanResult(in String address, in int rssi, in byte[] advData);
     void onServerConnectionState(in int status, in int serverIf,
                                  in boolean connected, in String address);
     void onServiceAdded(in int status, in BluetoothGattService service);
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 048f791..26f2dea 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -18,7 +18,6 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCallbackWrapper;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetoothGatt;
 import android.bluetooth.IBluetoothManager;
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 5715ff8..b63c614 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -22,9 +22,9 @@
 import android.app.ActivityThread;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCallbackWrapper;
 import android.bluetooth.IBluetoothGatt;
 import android.bluetooth.IBluetoothManager;
+import android.bluetooth.le.IScannerCallback;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.ParcelUuid;
@@ -267,7 +267,7 @@
     /**
      * Bluetooth GATT interface callbacks
      */
-    private class BleScanCallbackWrapper extends BluetoothGattCallbackWrapper {
+    private class BleScanCallbackWrapper extends IScannerCallback.Stub {
         private static final int REGISTRATION_CALLBACK_TIMEOUT_MILLIS = 2000;
 
         private final ScanCallback mScanCallback;
@@ -280,7 +280,7 @@
         // mLeHandle 0: not registered
         // -1: scan stopped or registration failed
         // > 0: registered and scan started
-        private int mClientIf;
+        private int mScannerId;
 
         public BleScanCallbackWrapper(IBluetoothGatt bluetoothGatt,
                 List<ScanFilter> filters, ScanSettings settings,
@@ -291,28 +291,27 @@
             mSettings = settings;
             mWorkSource = workSource;
             mScanCallback = scanCallback;
-            mClientIf = 0;
+            mScannerId = 0;
             mResultStorages = resultStorages;
         }
 
         public void startRegisteration() {
             synchronized (this) {
                 // Scan stopped.
-                if (mClientIf == -1) return;
+                if (mScannerId == -1) return;
                 try {
-                    UUID uuid = UUID.randomUUID();
-                    mBluetoothGatt.registerClient(new ParcelUuid(uuid), this);
+                    mBluetoothGatt.registerScanner(this);
                     wait(REGISTRATION_CALLBACK_TIMEOUT_MILLIS);
                 } catch (InterruptedException | RemoteException e) {
                     Log.e(TAG, "application registeration exception", e);
                     postCallbackError(mScanCallback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
                 }
-                if (mClientIf > 0) {
+                if (mScannerId > 0) {
                     mLeScanClients.put(mScanCallback, this);
                 } else {
-                    // Registration timed out or got exception, reset clientIf to -1 so no
+                    // Registration timed out or got exception, reset scannerId to -1 so no
                     // subsequent operations can proceed.
-                    if (mClientIf == 0) mClientIf = -1;
+                    if (mScannerId == 0) mScannerId = -1;
                     postCallbackError(mScanCallback,
                             ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED);
                 }
@@ -321,28 +320,28 @@
 
         public void stopLeScan() {
             synchronized (this) {
-                if (mClientIf <= 0) {
-                    Log.e(TAG, "Error state, mLeHandle: " + mClientIf);
+                if (mScannerId <= 0) {
+                    Log.e(TAG, "Error state, mLeHandle: " + mScannerId);
                     return;
                 }
                 try {
-                    mBluetoothGatt.stopScan(mClientIf, false);
-                    mBluetoothGatt.unregisterClient(mClientIf);
+                    mBluetoothGatt.stopScan(mScannerId);
+                    mBluetoothGatt.unregisterScanner(mScannerId);
                 } catch (RemoteException e) {
                     Log.e(TAG, "Failed to stop scan and unregister", e);
                 }
-                mClientIf = -1;
+                mScannerId = -1;
             }
         }
 
         void flushPendingBatchResults() {
             synchronized (this) {
-                if (mClientIf <= 0) {
-                    Log.e(TAG, "Error state, mLeHandle: " + mClientIf);
+                if (mScannerId <= 0) {
+                    Log.e(TAG, "Error state, mLeHandle: " + mScannerId);
                     return;
                 }
                 try {
-                    mBluetoothGatt.flushPendingBatchResults(mClientIf, false);
+                    mBluetoothGatt.flushPendingBatchResults(mScannerId);
                 } catch (RemoteException e) {
                     Log.e(TAG, "Failed to get pending scan results", e);
                 }
@@ -353,28 +352,28 @@
          * Application interface registered - app is ready to go
          */
         @Override
-        public void onClientRegistered(int status, int clientIf) {
-            Log.d(TAG, "onClientRegistered() - status=" + status +
-                    " clientIf=" + clientIf + " mClientIf=" + mClientIf);
+        public void onScannerRegistered(int status, int scannerId) {
+            Log.d(TAG, "onScannerRegistered() - status=" + status +
+                    " scannerId=" + scannerId + " mScannerId=" + mScannerId);
             synchronized (this) {
                 if (status == BluetoothGatt.GATT_SUCCESS) {
                     try {
-                        if (mClientIf == -1) {
+                        if (mScannerId == -1) {
                             // Registration succeeds after timeout, unregister client.
-                            mBluetoothGatt.unregisterClient(clientIf);
+                            mBluetoothGatt.unregisterClient(scannerId);
                         } else {
-                            mClientIf = clientIf;
-                            mBluetoothGatt.startScan(mClientIf, false, mSettings, mFilters,
+                            mScannerId = scannerId;
+                            mBluetoothGatt.startScan(mScannerId, mSettings, mFilters,
                                     mWorkSource, mResultStorages,
                                     ActivityThread.currentOpPackageName());
                         }
                     } catch (RemoteException e) {
                         Log.e(TAG, "fail to start le scan: " + e);
-                        mClientIf = -1;
+                        mScannerId = -1;
                     }
                 } else {
                     // registration failed
-                    mClientIf = -1;
+                    mScannerId = -1;
                 }
                 notifyAll();
             }
@@ -391,7 +390,7 @@
 
             // Check null in case the scan has been stopped
             synchronized (this) {
-                if (mClientIf <= 0) return;
+                if (mScannerId <= 0) return;
             }
             Handler handler = new Handler(Looper.getMainLooper());
             handler.post(new Runnable() {
@@ -423,7 +422,7 @@
 
             // Check null in case the scan has been stopped
             synchronized (this) {
-                if (mClientIf <= 0)
+                if (mScannerId <= 0)
                     return;
             }
             Handler handler = new Handler(Looper.getMainLooper());
@@ -447,7 +446,7 @@
                 Log.d(TAG, "onScanManagerErrorCallback() - errorCode = " + errorCode);
             }
             synchronized (this) {
-                if (mClientIf <= 0)
+                if (mScannerId <= 0)
                     return;
             }
             postCallbackError(mScanCallback, errorCode);
diff --git a/core/java/android/bluetooth/le/IScannerCallback.aidl b/core/java/android/bluetooth/le/IScannerCallback.aidl
new file mode 100644
index 0000000..8cbbaef
--- /dev/null
+++ b/core/java/android/bluetooth/le/IScannerCallback.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.bluetooth.le;
+
+import android.bluetooth.le.ScanResult;
+
+/**
+ * Callback definitions for interacting with Advertiser
+ * @hide
+ */
+oneway interface IScannerCallback {
+    void onScannerRegistered(in int status, in int scannerId);
+
+    void onScanResult(in ScanResult scanResult);
+    void onBatchScanResults(in List<ScanResult> batchResults);
+    void onFoundOrLost(in boolean onFound, in ScanResult scanResult);
+    void onScanManagerErrorCallback(in int errorCode);
+}
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 4cbff5f..e2ebd46 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -26,6 +26,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
+
 /**
  * Information you can retrieve about a particular application
  * activity or receiver. This corresponds to information collected
@@ -763,6 +765,13 @@
      */
     public String parentActivityName;
 
+    /**
+     * Screen rotation animation desired by the activity, with values as defined
+     * for {@link android.view.WindowManager.LayoutParams#rotationAnimation}.
+     * @hide
+     */
+    public int rotationAnimation = ROTATION_ANIMATION_ROTATE;
+
     /** @hide */
     public static final int LOCK_TASK_LAUNCH_MODE_DEFAULT = 0;
     /** @hide */
@@ -822,6 +831,7 @@
         windowLayout = orig.windowLayout;
         resizeMode = orig.resizeMode;
         requestedVrComponent = orig.requestedVrComponent;
+        rotationAnimation = orig.rotationAnimation;
     }
 
     /**
@@ -972,6 +982,7 @@
         }
         dest.writeInt(resizeMode);
         dest.writeString(requestedVrComponent);
+        dest.writeInt(rotationAnimation);
     }
 
     public static final Parcelable.Creator<ActivityInfo> CREATOR
@@ -1006,6 +1017,7 @@
         }
         resizeMode = source.readInt();
         requestedVrComponent = source.readString();
+        rotationAnimation = source.readInt();
     }
 
     /**
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 12e8d48..13c8ab1 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -98,6 +98,7 @@
 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
 
 /**
  * Parser for package files (APKs) on disk. This supports apps packaged either
@@ -2599,9 +2600,10 @@
         perm.info.protectionLevel = PermissionInfo.fixProtectionLevel(perm.info.protectionLevel);
 
         if ((perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_FLAGS) != 0) {
-            if ((perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) !=
+            if ( (perm.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_EPHEMERAL) == 0
+                    && (perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) !=
                     PermissionInfo.PROTECTION_SIGNATURE) {
-                outError[0] = "<permission>  protectionLevel specifies a flag but is "
+                outError[0] = "<permission>  protectionLevel specifies a non-ephemeral flag but is "
                         + "not based on signature type";
                 mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                 return null;
@@ -3572,6 +3574,9 @@
 
             a.info.requestedVrComponent =
                 sa.getString(R.styleable.AndroidManifestActivity_enableVrMode);
+
+            a.info.rotationAnimation =
+                sa.getInt(R.styleable.AndroidManifestActivity_rotationAnimation, ROTATION_ANIMATION_ROTATE);
         } else {
             a.info.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
             a.info.configChanges = 0;
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 65e0b92..6901ba1 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -17,6 +17,7 @@
 package android.content.pm;
 
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -119,6 +120,17 @@
      */
     public static final int PROTECTION_FLAG_SETUP = 0x800;
 
+
+    /**
+     * Additional flag for {@link #protectionLevel}, corresponding
+     * to the <code>ephemeral</code> value of
+     * {@link android.R.attr#protectionLevel}.
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    public static final int PROTECTION_FLAG_EPHEMERAL = 0x1000;
+
     /**
      * Mask for {@link #protectionLevel}: the basic protection type.
      */
@@ -127,7 +139,7 @@
     /**
      * Mask for {@link #protectionLevel}: additional flag bits.
      */
-    public static final int PROTECTION_MASK_FLAGS = 0xff0;
+    public static final int PROTECTION_MASK_FLAGS = 0xfff0;
 
     /**
      * The level of access this permission is protecting, as per
@@ -236,6 +248,9 @@
         if ((level&PermissionInfo.PROTECTION_FLAG_SETUP) != 0) {
             protLevel += "|setup";
         }
+        if ((level&PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0) {
+            protLevel += "|ephemeral";
+        }
         return protLevel;
     }
 
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index 1d85493..62b7f32 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -722,6 +722,36 @@
         }
 
         /**
+         * This method is called when camera device's input capture queue becomes empty,
+         * and is ready to accept the next request.
+         *
+         * <p>Pending capture requests exist in one of two queues: the in-flight queue where requests
+         * are already in different stages of processing pipeline, and an input queue where requests
+         * wait to enter the in-flight queue. The input queue is needed because more requests may be
+         * submitted than the current camera device pipeline depth.</p>
+         *
+         * <p>This callback is fired when the input queue becomes empty, and the camera device may
+         * have to fall back to the repeating request if set, or completely skip the next frame from
+         * the sensor. This can cause glitches to camera preview output, for example. This callback
+         * will only fire after requests queued by capture() or captureBurst(), not after a
+         * repeating request or burst enters the in-flight queue. For example, in the common case
+         * of a repeating request and a single-shot JPEG capture, this callback only fires when the
+         * JPEG request has entered the in-flight queue for capture.</p>
+         *
+         * <p>By only sending a new {@link #capture} or {@link #captureBurst} when the input
+         * queue is empty, pipeline latency can be minimized.</p>
+         *
+         * <p>This callback is not fired when the session is first created. It is different from
+         * {@link #onReady}, which is fired when all requests in both queues have been processed.</p>
+         *
+         * @param session
+         *            The session returned by {@link CameraDevice#createCaptureSession}
+         */
+        public void onCaptureQueueEmpty(@NonNull CameraCaptureSession session) {
+            // default empty implementation
+        }
+
+        /**
          * This method is called when the session is closed.
          *
          * <p>A session is closed when a new session is created by the parent camera device,
diff --git a/core/java/android/hardware/camera2/impl/CallbackProxies.java b/core/java/android/hardware/camera2/impl/CallbackProxies.java
index dac2ef8..e6e448e 100644
--- a/core/java/android/hardware/camera2/impl/CallbackProxies.java
+++ b/core/java/android/hardware/camera2/impl/CallbackProxies.java
@@ -173,6 +173,11 @@
         }
 
         @Override
+        public void onCaptureQueueEmpty(CameraCaptureSession session) {
+            mProxy.invoke("onCaptureQueueEmpty", session);
+        }
+
+        @Override
         public void onClosed(CameraCaptureSession session) {
             mProxy.invoke("onClosed", session);
         }
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index b10c341..5e9fd66 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -604,11 +604,16 @@
             }
 
             @Override
-            public void onSurfacePrepared(Surface surface) {
-                if (DEBUG) Log.v(TAG, mIdString + "onPrepared");
-                mStateCallback.onSurfacePrepared(session, surface);
+            public void onRequestQueueEmpty() {
+                if (DEBUG) Log.v(TAG, mIdString + "onRequestQueueEmpty");
+                mStateCallback.onCaptureQueueEmpty(session);
             }
 
+            @Override
+            public void onSurfacePrepared(Surface surface) {
+                if (DEBUG) Log.v(TAG, mIdString + "onSurfacePrepared");
+                mStateCallback.onSurfacePrepared(session, surface);
+            }
         };
 
     }
diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
index 1c8e124..4481a74 100644
--- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
@@ -291,6 +291,11 @@
         }
 
         @Override
+        public void onCaptureQueueEmpty(CameraCaptureSession session) {
+            mCallback.onCaptureQueueEmpty(CameraConstrainedHighSpeedCaptureSessionImpl.this);
+        }
+
+        @Override
         public void onClosed(CameraCaptureSession session) {
             mCallback.onClosed(CameraConstrainedHighSpeedCaptureSessionImpl.this);
         }
@@ -300,7 +305,5 @@
             mCallback.onSurfacePrepared(CameraConstrainedHighSpeedCaptureSessionImpl.this,
                     surface);
         }
-
-
     }
 }
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index ee8a6d7..97ca56ef 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -1204,6 +1204,14 @@
         }
 
         /**
+         * This method is called when camera device's non-repeating request queue is empty,
+         * and is ready to start capturing next image.
+         */
+        public void onRequestQueueEmpty() {
+            // Default empty implementation
+        }
+
+        /**
          * The method called when the camera device has finished preparing
          * an output Surface
          */
@@ -1906,6 +1914,23 @@
             sessionCallback.onSurfacePrepared(surface);
         }
 
+        @Override
+        public void onRequestQueueEmpty() {
+            final StateCallbackKK sessionCallback;
+
+            if (DEBUG) {
+                Log.v(TAG, "Request queue becomes empty");
+            }
+
+            synchronized(mInterfaceLock) {
+                sessionCallback = mSessionStateCallback;
+            }
+
+            if (sessionCallback == null) return;
+
+            sessionCallback.onRequestQueueEmpty();
+        }
+
         /**
          * Called by onDeviceError for handling single-capture failures.
          */
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index b9e75ee..2a9bf6b 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -206,6 +206,7 @@
         private static final int RESULT_RECEIVED = 3;
         private static final int PREPARED = 4;
         private static final int REPEATING_REQUEST_ERROR = 5;
+        private static final int REQUEST_QUEUE_EMPTY = 6;
 
         private final HandlerThread mHandlerThread;
         private Handler mHandler;
@@ -262,7 +263,6 @@
             getHandler().sendMessage(msg);
         }
 
-
         @Override
         public void onRepeatingRequestError(long lastFrameNumber) {
             Message msg = getHandler().obtainMessage(REPEATING_REQUEST_ERROR,
@@ -272,6 +272,13 @@
         }
 
         @Override
+        public void onRequestQueueEmpty() {
+            Message msg = getHandler().obtainMessage(REQUEST_QUEUE_EMPTY,
+                    /* arg1 */ 0, /* arg2 */ 0);
+            getHandler().sendMessage(msg);
+        }
+
+        @Override
         public IBinder asBinder() {
             // This is solely intended to be used for in-process binding.
             return null;
@@ -327,6 +334,10 @@
                             mCallbacks.onRepeatingRequestError(lastFrameNumber);
                             break;
                         }
+                        case REQUEST_QUEUE_EMPTY: {
+                            mCallbacks.onRequestQueueEmpty();
+                            break;
+                        }
                         default:
                             throw new IllegalArgumentException(
                                 "Unknown callback message " + msg.what);
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index e0d3905..a05a8ec 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -248,7 +248,8 @@
         return program;
     }
 
-    private void drawFrame(SurfaceTexture st, int width, int height, int flipType) {
+    private void drawFrame(SurfaceTexture st, int width, int height, int flipType)
+            throws LegacyExceptionUtils.BufferQueueAbandonedException {
         checkGlError("onDrawFrame start");
         st.getTransformMatrix(mSTMatrix);
 
@@ -343,7 +344,7 @@
                 /*offset*/ 0);
 
         GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, /*offset*/ 0, /*count*/ 4);
-        checkGlError("glDrawArrays");
+        checkGlDrawError("glDrawArrays");
     }
 
     /**
@@ -548,7 +549,29 @@
     private void checkGlError(String msg) {
         int error;
         while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
-            throw new IllegalStateException(msg + ": GLES20 error: 0x" + Integer.toHexString(error));
+            throw new IllegalStateException(
+                    msg + ": GLES20 error: 0x" + Integer.toHexString(error));
+        }
+    }
+
+    private void checkGlDrawError(String msg)
+            throws LegacyExceptionUtils.BufferQueueAbandonedException {
+        int error;
+        boolean surfaceAbandoned = false;
+        boolean glError = false;
+        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+            if (error == GLES20.GL_OUT_OF_MEMORY) {
+                surfaceAbandoned = true;
+            } else {
+                glError = true;
+            }
+        }
+        if (glError) {
+            throw new IllegalStateException(
+                    msg + ": GLES20 error: 0x" + Integer.toHexString(error));
+        }
+        if (surfaceAbandoned) {
+            throw new LegacyExceptionUtils.BufferQueueAbandonedException();
         }
     }
 
@@ -759,9 +782,14 @@
             if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) {
                 makeCurrent(holder.eglSurface);
                 // glReadPixels reads from the bottom of the buffer, so add an extra vertical flip
-                drawFrame(mSurfaceTexture, holder.width, holder.height,
-                        (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ?
-                                FLIP_TYPE_BOTH : FLIP_TYPE_VERTICAL);
+                try {
+                    drawFrame(mSurfaceTexture, holder.width, holder.height,
+                            (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ?
+                                    FLIP_TYPE_BOTH : FLIP_TYPE_VERTICAL);
+                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
+                    // Should never hit this.
+                    throw new IllegalStateException("Surface abandoned, skipping drawFrame...", e);
+                }
                 mPBufferPixels.clear();
                 GLES20.glReadPixels(/*x*/ 0, /*y*/ 0, holder.width, holder.height,
                         GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPBufferPixels);
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
index 160e261..ffd6ec3 100644
--- a/core/java/android/hardware/usb/UsbDeviceConnection.java
+++ b/core/java/android/hardware/usb/UsbDeviceConnection.java
@@ -21,6 +21,9 @@
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.os.ParcelFileDescriptor;
+
+import com.android.internal.util.Preconditions;
+
 import dalvik.system.CloseGuard;
 
 import java.io.FileDescriptor;
@@ -262,8 +265,6 @@
      * {@link android.hardware.usb.UsbRequest#getEndpoint} and {@link
      * android.hardware.usb.UsbRequest#getClientData} can be useful in determining how to process
      * the result of this function.</p>
-     * <p>Position and array offset of the request's buffer are ignored and assumed to be 0. The
-     * position will be set to the number of bytes read/written.</p>
      *
      * @return a completed USB request, or null if an error occurred
      *
@@ -273,7 +274,38 @@
      *                                  {@link UsbRequest#queue(ByteBuffer, int)}
      */
     public UsbRequest requestWait() {
-        UsbRequest request = native_request_wait();
+        // -1 is special value indicating infinite wait
+        UsbRequest request = native_request_wait(-1);
+        if (request != null) {
+            request.dequeue();
+        }
+        return request;
+    }
+
+    /**
+     * Waits for the result of a {@link android.hardware.usb.UsbRequest#queue} operation
+     * <p>Note that this may return requests queued on multiple
+     * {@link android.hardware.usb.UsbEndpoint}s. When multiple endpoints are in use,
+     * {@link android.hardware.usb.UsbRequest#getEndpoint} and {@link
+     * android.hardware.usb.UsbRequest#getClientData} can be useful in determining how to process
+     * the result of this function.</p>
+     * <p>Android processes {@link UsbRequest UsbRequests} asynchronously. Hence it is not
+     * guaranteed that {@link #requestWait(int) requestWait(0)} returns a request that has been
+     * queued right before even if the request could have been processed immediately.</p>
+     *
+     * @param timeout timeout in milliseconds. If 0 this method does not wait.
+     *
+     * @return a completed USB request, or {@code null} if an error or time out occurred
+     *
+     * @throws IllegalArgumentException if the number of bytes read or written is more than the
+     *                                  limit of the request's buffer. The number of bytes is
+     *                                  determined by the {@code length} parameter of
+     *                                  {@link UsbRequest#queue(ByteBuffer, int)}
+     */
+    public UsbRequest requestWait(int timeout) {
+        timeout = Preconditions.checkArgumentNonnegative(timeout, "timeout");
+
+        UsbRequest request = native_request_wait(timeout);
         if (request != null) {
             request.dequeue();
         }
@@ -318,7 +350,7 @@
             int index, byte[] buffer, int offset, int length, int timeout);
     private native int native_bulk_request(int endpoint, byte[] buffer,
             int offset, int length, int timeout);
-    private native UsbRequest native_request_wait();
+    private native UsbRequest native_request_wait(int timeout);
     private native String native_get_serial();
     private native boolean native_reset_device();
 }
diff --git a/core/java/android/hardware/usb/UsbRequest.java b/core/java/android/hardware/usb/UsbRequest.java
index 9f7592f..badb344 100644
--- a/core/java/android/hardware/usb/UsbRequest.java
+++ b/core/java/android/hardware/usb/UsbRequest.java
@@ -16,8 +16,10 @@
 
 package android.hardware.usb;
 
-import android.util.Log;
+import android.annotation.Nullable;
+
 import com.android.internal.util.Preconditions;
+
 import dalvik.system.CloseGuard;
 
 import java.nio.ByteBuffer;
@@ -38,13 +40,18 @@
 
     private static final String TAG = "UsbRequest";
 
+    // From drivers/usb/core/devio.c
+    private static final int MAX_USBFS_BUFFER_SIZE = 16384;
+
     // used by the JNI code
     private long mNativeContext;
 
     private UsbEndpoint mEndpoint;
 
-    // for temporarily saving current buffer across queue and dequeue
+    /** The buffer that is currently being read / written */
     private ByteBuffer mBuffer;
+
+    /** The amount of data to read / write when using {@link #queue} */
     private int mLength;
 
     // for client use
@@ -53,8 +60,21 @@
     // Prevent the connection from being finalized
     private UsbDeviceConnection mConnection;
 
+    /** Whether this buffer was {@link #enqueue enqueued (new behavior)} or {@link #queue queued
+     * (deprecared behavior)}. */
+    private boolean mIsUsingEnqueue;
+
+    /** Temporary buffer than might be used while buffer is enqueued */
+    private ByteBuffer mTempBuffer;
+
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
+    /**
+     * Lock for queue, enqueue and dequeue, so a queue operation can be finished by a dequeue
+     * operation on a different thread.
+     */
+    private final Object mLock = new Object();
+
     public UsbRequest() {
     }
 
@@ -67,7 +87,7 @@
      */
     public boolean initialize(UsbDeviceConnection connection, UsbEndpoint endpoint) {
         mEndpoint = endpoint;
-        mConnection = Preconditions.checkNotNull(connection);
+        mConnection = Preconditions.checkNotNull(connection, "connection");
 
         boolean wasInitialized = native_init(connection, endpoint.getAddress(),
                 endpoint.getAttributes(), endpoint.getMaxPacketSize(), endpoint.getInterval());
@@ -140,54 +160,164 @@
      * Queues the request to send or receive data on its endpoint.
      * <p>For OUT endpoints, the given buffer data will be sent on the endpoint. For IN endpoints,
      * the endpoint will attempt to read the given number of bytes into the specified buffer. If the
-     * queueing operation is successful, we return true and the result will be returned via {@link
-     * android.hardware.usb.UsbDeviceConnection#requestWait}</p>
+     * queueing operation is successful, return true. The result will be returned via
+     * {@link UsbDeviceConnection#requestWait}</p>
      *
      * @param buffer the buffer containing the bytes to write, or location to store the results of a
      *               read. Position and array offset will be ignored and assumed to be 0. Limit and
-     *               capacity will be ignored.
+     *               capacity will be ignored. Once the request
+     *               {@link UsbDeviceConnection#requestWait() is processed} the position will be set
+     *               to the number of bytes read/written.
      * @param length number of bytes to read or write.
      *
      * @return true if the queueing operation succeeded
+     *
+     * @deprecated Use {@link #enqueue(ByteBuffer)} instead.
      */
+    @Deprecated
     public boolean queue(ByteBuffer buffer, int length) {
         boolean out = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
-
-        // save our buffer for when the request has completed
-        mBuffer = buffer;
-        mLength = length;
-
-        // Note: On a buffer slice we lost the capacity information about the underlying buffer,
-        // hence we cannot check if the access would be a data leak/memory corruption.
-
         boolean result;
-        if (buffer.isDirect()) {
-            result = native_queue_direct(buffer, length, out);
-        } else if (buffer.hasArray()) {
-            result = native_queue_array(buffer.array(), length, out);
-        } else {
-            throw new IllegalArgumentException("buffer is not direct and has no array");
+
+        synchronized (mLock) {
+            // save our buffer for when the request has completed
+            mBuffer = buffer;
+            mLength = length;
+
+            // Note: On a buffer slice we lost the capacity information about the underlying buffer,
+            // hence we cannot check if the access would be a data leak/memory corruption.
+
+            if (buffer.isDirect()) {
+                result = native_queue_direct(buffer, length, out);
+            } else if (buffer.hasArray()) {
+                result = native_queue_array(buffer.array(), length, out);
+            } else {
+                throw new IllegalArgumentException("buffer is not direct and has no array");
+            }
+            if (!result) {
+                mBuffer = null;
+                mLength = 0;
+            }
         }
-        if (!result) {
-            mBuffer = null;
-            mLength = 0;
-        }
+
         return result;
     }
 
+    /**
+     * Queues the request to send or receive data on its endpoint.
+     *
+     * <p>For OUT endpoints, the remaining bytes of the buffer will be sent on the endpoint. For IN
+     * endpoints, the endpoint will attempt to fill the remaining bytes of the buffer. If the
+     * queueing operation is successful, return true. The result will be returned via
+     * {@link UsbDeviceConnection#requestWait}</p>
+     *
+     * @param buffer the buffer containing the bytes to send, or the buffer to fill. The state
+     *               of the buffer is undefined until the request is returned by
+     *               {@link UsbDeviceConnection#requestWait}. If the request failed the buffer
+     *               will be unchanged; if the request succeeded the position of the buffer is
+     *               incremented by the number of bytes sent/received.
+     *
+     * @return true if the queueing operation succeeded
+     */
+    public boolean enqueue(@Nullable ByteBuffer buffer) {
+        // Request need to be initialized
+        Preconditions.checkState(mNativeContext != 0, "request is not initialized");
+
+        // Request can not be currently enqueued
+        Preconditions.checkState(!mIsUsingEnqueue, "request is currently enqueued");
+
+        boolean isSend = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
+        boolean wasEnqueued;
+
+        synchronized (mLock) {
+            mBuffer = buffer;
+
+            if (buffer == null) {
+                // Null buffers enqueue empty USB requests which is supported
+                mIsUsingEnqueue = true;
+                wasEnqueued = native_enqueue(null, 0, 0);
+            } else {
+                // Can only send/receive MAX_USBFS_BUFFER_SIZE bytes at once
+                Preconditions.checkArgumentInRange(buffer.remaining(), 0, MAX_USBFS_BUFFER_SIZE,
+                        "number of remaining bytes");
+
+                // Can not receive into read-only buffers.
+                Preconditions.checkArgument(!(buffer.isReadOnly() && !isSend), "buffer can not be "
+                        + "read-only when receiving data");
+
+                if (!buffer.isDirect()) {
+                    mTempBuffer = ByteBuffer.allocateDirect(mBuffer.remaining());
+
+                    if (isSend) {
+                        // Copy buffer into temporary buffer
+                        mBuffer.mark();
+                        mTempBuffer.put(mBuffer);
+                        mTempBuffer.flip();
+                        mBuffer.reset();
+                    }
+
+                    // Send/Receive into the temp buffer instead
+                    buffer = mTempBuffer;
+                }
+
+                mIsUsingEnqueue = true;
+                wasEnqueued = native_enqueue(buffer, buffer.position(), buffer.remaining());
+            }
+        }
+
+        if (!wasEnqueued) {
+            mIsUsingEnqueue = false;
+            mTempBuffer = null;
+            mBuffer = null;
+        }
+
+        return wasEnqueued;
+    }
+
     /* package */ void dequeue() {
-        boolean out = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
-        int bytesRead;
-        if (mBuffer.isDirect()) {
-            bytesRead = native_dequeue_direct();
-        } else {
-            bytesRead = native_dequeue_array(mBuffer.array(), mLength, out);
+        boolean isSend = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
+        int bytesTransferred;
+
+        synchronized (mLock) {
+            if (mIsUsingEnqueue) {
+                bytesTransferred = native_dequeue_direct();
+                mIsUsingEnqueue = false;
+
+                if (mBuffer == null) {
+                    // Nothing to do
+                } else if (mTempBuffer == null) {
+                    mBuffer.position(mBuffer.position() + bytesTransferred);
+                } else {
+                    mTempBuffer.limit(bytesTransferred);
+
+                    // The user might have modified mBuffer which might make put/position fail.
+                    // Changing the buffer while a request is in flight is not supported. Still,
+                    // make sure to free mTempBuffer correctly.
+                    try {
+                        if (isSend) {
+                            mBuffer.position(mBuffer.position() + bytesTransferred);
+                        } else {
+                            // Copy temp buffer back into original buffer
+                            mBuffer.put(mTempBuffer);
+                        }
+                    } finally {
+                        mTempBuffer = null;
+                    }
+                }
+            } else {
+                if (mBuffer.isDirect()) {
+                    bytesTransferred = native_dequeue_direct();
+                } else {
+                    bytesTransferred = native_dequeue_array(mBuffer.array(), mLength, isSend);
+                }
+                if (bytesTransferred >= 0) {
+                    mBuffer.position(Math.min(bytesTransferred, mLength));
+                }
+            }
+
+            mBuffer = null;
+            mLength = 0;
         }
-        if (bytesRead >= 0) {
-            mBuffer.position(Math.min(bytesRead, mLength));
-        }
-        mBuffer = null;
-        mLength = 0;
     }
 
     /**
@@ -202,6 +332,7 @@
     private native boolean native_init(UsbDeviceConnection connection, int ep_address,
             int ep_attributes, int ep_max_packet_size, int ep_interval);
     private native void native_close();
+    private native boolean native_enqueue(ByteBuffer buffer, int offset, int length);
     private native boolean native_queue_array(byte[] buffer, int length, boolean out);
     private native int native_dequeue_array(byte[] buffer, int length, boolean out);
     private native boolean native_queue_direct(ByteBuffer buffer, int length, boolean out);
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 9e5aaf5..0073dde 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2679,6 +2679,7 @@
     public static final int CALLBACK_IP_CHANGED          = BASE + 7;
     /** @hide */
     public static final int CALLBACK_RELEASED            = BASE + 8;
+    // TODO: consider deleting CALLBACK_EXIT and shifting following enum codes down by 1.
     /** @hide */
     public static final int CALLBACK_EXIT                = BASE + 9;
     /** @hide obj = NetworkCapabilities, arg1 = seq number */
@@ -2709,24 +2710,17 @@
     }
 
     private class CallbackHandler extends Handler {
-        private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap;
-        private final AtomicInteger mRefCount;
         private static final String TAG = "ConnectivityManager.CallbackHandler";
-        private final ConnectivityManager mCm;
         private static final boolean DBG = false;
 
-        CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap,
-                AtomicInteger refCount, ConnectivityManager cm) {
+        CallbackHandler(Looper looper) {
             super(looper);
-            mCallbackMap = callbackMap;
-            mRefCount = refCount;
-            mCm = cm;
         }
 
         @Override
         public void handleMessage(Message message) {
-            NetworkRequest request = (NetworkRequest) getObject(message, NetworkRequest.class);
-            Network network = (Network) getObject(message, Network.class);
+            NetworkRequest request = getObject(message, NetworkRequest.class);
+            Network network = getObject(message, Network.class);
             if (DBG) {
                 Log.d(TAG, whatToString(message.what) + " for network " + network);
             }
@@ -2769,9 +2763,7 @@
                 case CALLBACK_CAP_CHANGED: {
                     NetworkCallback callback = getCallback(request, "CAP_CHANGED");
                     if (callback != null) {
-                        NetworkCapabilities cap = (NetworkCapabilities)getObject(message,
-                                NetworkCapabilities.class);
-
+                        NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
                         callback.onCapabilitiesChanged(network, cap);
                     }
                     break;
@@ -2779,9 +2771,7 @@
                 case CALLBACK_IP_CHANGED: {
                     NetworkCallback callback = getCallback(request, "IP_CHANGED");
                     if (callback != null) {
-                        LinkProperties lp = (LinkProperties)getObject(message,
-                                LinkProperties.class);
-
+                        LinkProperties lp = getObject(message, LinkProperties.class);
                         callback.onLinkPropertiesChanged(network, lp);
                     }
                     break;
@@ -2801,24 +2791,16 @@
                     break;
                 }
                 case CALLBACK_RELEASED: {
-                    NetworkCallback callback = null;
-                    synchronized(mCallbackMap) {
-                        callback = mCallbackMap.remove(request);
+                    final NetworkCallback callback;
+                    synchronized(sCallbacks) {
+                        callback = sCallbacks.remove(request);
                     }
-                    if (callback != null) {
-                        synchronized(mRefCount) {
-                            if (mRefCount.decrementAndGet() == 0) {
-                                getLooper().quit();
-                            }
-                        }
-                    } else {
+                    if (callback == null) {
                         Log.e(TAG, "callback not found for RELEASED message");
                     }
                     break;
                 }
                 case CALLBACK_EXIT: {
-                    Log.d(TAG, "Listener quitting");
-                    getLooper().quit();
                     break;
                 }
                 case EXPIRE_LEGACY_REQUEST: {
@@ -2828,14 +2810,14 @@
             }
         }
 
-        private Object getObject(Message msg, Class c) {
-            return msg.getData().getParcelable(c.getSimpleName());
+        private <T> T getObject(Message msg, Class<T> c) {
+            return (T) msg.getData().getParcelable(c.getSimpleName());
         }
 
         private NetworkCallback getCallback(NetworkRequest req, String name) {
             NetworkCallback callback;
-            synchronized(mCallbackMap) {
-                callback = mCallbackMap.get(req);
+            synchronized(sCallbacks) {
+                callback = sCallbacks.get(req);
             }
             if (callback == null) {
                 Log.e(TAG, "callback not found for " + name + " message");
@@ -2844,63 +2826,56 @@
         }
     }
 
-    private void incCallbackHandlerRefCount() {
-        synchronized(sCallbackRefCount) {
-            if (sCallbackRefCount.incrementAndGet() == 1) {
-                // TODO: switch this to ConnectivityThread
-                HandlerThread callbackThread = new HandlerThread("ConnectivityManager");
-                callbackThread.start();
-                sCallbackHandler = new CallbackHandler(callbackThread.getLooper(),
-                        sNetworkCallback, sCallbackRefCount, this);
+    private CallbackHandler getHandler() {
+        synchronized (sCallbacks) {
+            if (sCallbackHandler == null) {
+                sCallbackHandler = new CallbackHandler(ConnectivityThread.getInstanceLooper());
             }
+            return sCallbackHandler;
         }
     }
 
-    private void decCallbackHandlerRefCount() {
-        synchronized(sCallbackRefCount) {
-            if (sCallbackRefCount.decrementAndGet() == 0) {
-                sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget();
-                sCallbackHandler = null;
-            }
-        }
-    }
-
-    static final HashMap<NetworkRequest, NetworkCallback> sNetworkCallback =
-            new HashMap<NetworkRequest, NetworkCallback>();
-    static final AtomicInteger sCallbackRefCount = new AtomicInteger(0);
-    static CallbackHandler sCallbackHandler = null;
+    static final HashMap<NetworkRequest, NetworkCallback> sCallbacks = new HashMap<>();
+    static CallbackHandler sCallbackHandler;
 
     private final static int LISTEN  = 1;
     private final static int REQUEST = 2;
 
     private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
-            NetworkCallback networkCallback, int timeoutMs, int action,
-            int legacyType) {
-        if (networkCallback == null) {
+            NetworkCallback callback, int timeoutMs, int action, int legacyType) {
+        return sendRequestForNetwork(need, callback, getHandler(), timeoutMs, action, legacyType);
+    }
+
+    private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
+            NetworkCallback callback, Handler handler, int timeoutMs, int action, int legacyType) {
+        if (callback == null) {
             throw new IllegalArgumentException("null NetworkCallback");
         }
         if (need == null && action != REQUEST) {
             throw new IllegalArgumentException("null NetworkCapabilities");
         }
+        // TODO: throw an exception if callback.networkRequest is not null.
+        // http://b/20701525
+        final NetworkRequest request;
         try {
-            incCallbackHandlerRefCount();
-            synchronized(sNetworkCallback) {
+            synchronized(sCallbacks) {
+                Messenger messenger = new Messenger(handler);
+                Binder binder = new Binder();
                 if (action == LISTEN) {
-                    networkCallback.networkRequest = mService.listenForNetwork(need,
-                            new Messenger(sCallbackHandler), new Binder());
+                    request = mService.listenForNetwork(need, messenger, binder);
                 } else {
-                    networkCallback.networkRequest = mService.requestNetwork(need,
-                            new Messenger(sCallbackHandler), timeoutMs, new Binder(), legacyType);
+                    request = mService.requestNetwork(
+                            need, messenger, timeoutMs, binder, legacyType);
                 }
-                if (networkCallback.networkRequest != null) {
-                    sNetworkCallback.put(networkCallback.networkRequest, networkCallback);
+                if (request != null) {
+                    sCallbacks.put(request, callback);
                 }
+                callback.networkRequest = request;
             }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
-        if (networkCallback.networkRequest == null) decCallbackHandlerRefCount();
-        return networkCallback.networkRequest;
+        return request;
     }
 
     /**
diff --git a/core/java/android/net/ConnectivityThread.java b/core/java/android/net/ConnectivityThread.java
index 55c3402..0b218e7 100644
--- a/core/java/android/net/ConnectivityThread.java
+++ b/core/java/android/net/ConnectivityThread.java
@@ -27,25 +27,30 @@
  * @hide
  */
 public final class ConnectivityThread extends HandlerThread {
-    private static ConnectivityThread sInstance;
+
+    // A class implementing the lazy holder idiom: the unique static instance
+    // of ConnectivityThread is instantiated in a thread-safe way (guaranteed by
+    // the language specs) the first time that Singleton is referenced in get()
+    // or getInstanceLooper().
+    private static class Singleton {
+        private static final ConnectivityThread INSTANCE = createInstance();
+    }
 
     private ConnectivityThread() {
         super("ConnectivityThread");
     }
 
-    private static synchronized ConnectivityThread getInstance() {
-        if (sInstance == null) {
-            sInstance = new ConnectivityThread();
-            sInstance.start();
-        }
-        return sInstance;
+    private static ConnectivityThread createInstance() {
+        ConnectivityThread t = new ConnectivityThread();
+        t.start();
+        return t;
     }
 
     public static ConnectivityThread get() {
-        return getInstance();
+        return Singleton.INSTANCE;
     }
 
     public static Looper getInstanceLooper() {
-        return getInstance().getLooper();
+        return Singleton.INSTANCE.getLooper();
     }
 }
diff --git a/core/java/android/net/IIpConnectivityMetrics.aidl b/core/java/android/net/IIpConnectivityMetrics.aidl
index 8f634bb..d36b766 100644
--- a/core/java/android/net/IIpConnectivityMetrics.aidl
+++ b/core/java/android/net/IIpConnectivityMetrics.aidl
@@ -23,7 +23,8 @@
 interface IIpConnectivityMetrics {
 
     /**
-     * @return number of remaining available slots in buffer.
+     * @return the number of remaining available slots in buffer,
+     * or -1 if the event was dropped due to rate limiting.
      */
     int logEvent(in ConnectivityMetricsEvent event);
 }
diff --git a/core/java/android/os/HardwarePropertiesManager.java b/core/java/android/os/HardwarePropertiesManager.java
index 9d362d6..6dec0dc 100644
--- a/core/java/android/os/HardwarePropertiesManager.java
+++ b/core/java/android/os/HardwarePropertiesManager.java
@@ -18,6 +18,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.content.Context;
+import android.hardware.thermal.V1_0.Constants;
 import android.util.Log;
 
 import java.lang.annotation.Retention;
@@ -56,18 +57,19 @@
     /**
      * Device temperature types. These must match the values in
      * frameworks/native/include/hardwareproperties/HardwarePropertiesManager.h
+     * TODO(b/32022261) Remove this comment.
      */
     /** Temperature of CPUs in Celsius. */
-    public static final int DEVICE_TEMPERATURE_CPU = 0;
+    public static final int DEVICE_TEMPERATURE_CPU = Constants.TemperatureType.CPU;
 
     /** Temperature of GPUs in Celsius. */
-    public static final int DEVICE_TEMPERATURE_GPU = 1;
+    public static final int DEVICE_TEMPERATURE_GPU = Constants.TemperatureType.GPU;
 
     /** Temperature of battery in Celsius. */
-    public static final int DEVICE_TEMPERATURE_BATTERY = 2;
+    public static final int DEVICE_TEMPERATURE_BATTERY = Constants.TemperatureType.BATTERY;
 
     /** Temperature of device skin in Celsius. */
-    public static final int DEVICE_TEMPERATURE_SKIN = 3;
+    public static final int DEVICE_TEMPERATURE_SKIN = Constants.TemperatureType.SKIN;
 
     /** Get current temperature. */
     public static final int TEMPERATURE_CURRENT = 0;
diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java
index 5ff79f7..0e7da63 100644
--- a/core/java/android/os/HwBinder.java
+++ b/core/java/android/os/HwBinder.java
@@ -38,8 +38,11 @@
     public abstract void onTransact(
             int code, HwParcel request, HwParcel reply, int flags);
 
-    public native final void registerService(String serviceName);
-    public static native final IHwBinder getService(String serviceName);
+    public native final void registerService(
+            String serviceName, int versionMajor, int versionMinor);
+
+    public static native final IHwBinder getService(
+            String serviceName, int versionMajor, int versionMinor);
 
     // Returns address of the "freeFunction".
     private static native final long native_init();
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index c153184..d0db255 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -147,10 +147,18 @@
 
     public abstract void setDeviceIdleTempWhitelist(int[] appids);
 
+    public abstract void startUidChanges();
+
+    public abstract void finishUidChanges();
+
     public abstract void updateUidProcState(int uid, int procState);
 
     public abstract void uidGone(int uid);
 
+    public abstract void uidActive(int uid);
+
+    public abstract void uidIdle(int uid);
+
     /**
      * The hintId sent through this method should be in-line with the
      * PowerHint defined in android/hardware/power/<version 1.0 & up>/IPower.h
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index f9dee92..4eee854 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -20,6 +20,7 @@
 import android.system.Os;
 import android.system.OsConstants;
 import android.util.Log;
+import android.webkit.WebViewZygote;
 import dalvik.system.VMRuntime;
 
 /**
@@ -133,6 +134,12 @@
     public static final int CAMERASERVER_UID = 1047;
 
     /**
+     * Defines the UID/GID for the WebView zygote process.
+     * @hide
+     */
+    public static final int WEBVIEW_ZYGOTE_UID = 1051;
+
+    /**
      * Defines the start of a range of UIDs (and GIDs), going from this
      * number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
      * to applications.
@@ -425,6 +432,22 @@
                     abi, instructionSet, appDataDir, zygoteArgs);
     }
 
+    /** @hide */
+    public static final ProcessStartResult startWebView(final String processClass,
+                                  final String niceName,
+                                  int uid, int gid, int[] gids,
+                                  int debugFlags, int mountExternal,
+                                  int targetSdkVersion,
+                                  String seInfo,
+                                  String abi,
+                                  String instructionSet,
+                                  String appDataDir,
+                                  String[] zygoteArgs) {
+        return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids,
+                    debugFlags, mountExternal, targetSdkVersion, seInfo,
+                    abi, instructionSet, appDataDir, zygoteArgs);
+    }
+
     /**
      * Returns elapsed milliseconds of the time this process has run.
      * @return  Returns the number of milliseconds this process has return.
diff --git a/core/java/android/os/ShellCommand.java b/core/java/android/os/ShellCommand.java
index dbb9650..e4a12e8 100644
--- a/core/java/android/os/ShellCommand.java
+++ b/core/java/android/os/ShellCommand.java
@@ -302,7 +302,7 @@
     /**
      * Implement parsing and execution of a command.  If it isn't a command you understand,
      * call {@link #handleDefaultCommands(String)} and return its result as a last resort.
-     * User {@link #getNextOption()}, {@link #getNextArg()}, and {@link #getNextArgRequired()}
+     * Use {@link #getNextOption()}, {@link #getNextArg()}, and {@link #getNextArgRequired()}
      * to process additional command line arguments.  Command output can be written to
      * {@link #getOutPrintWriter()} and errors to {@link #getErrPrintWriter()}.
      *
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index bc5af81..15dd282 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -726,7 +726,7 @@
     /** @hide */
     public UserManager(Context context, IUserManager service) {
         mService = service;
-        mContext = context;
+        mContext = context.getApplicationContext();
     }
 
     /**
diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java
index 93afb43..4bdb92b 100644
--- a/core/java/android/os/UserManagerInternal.java
+++ b/core/java/android/os/UserManagerInternal.java
@@ -128,6 +128,13 @@
     public abstract UserInfo createUserEvenWhenDisallowed(String name, int flags);
 
     /**
+     * Same as {@link UserManager#removeUser(int userHandle)}, but bypasses the check for
+     * {@link UserManager#DISALLOW_REMOVE_USER} and does not require the
+     * {@link android.Manifest.permission#MANAGE_USERS} permission.
+     */
+    public abstract boolean removeUserEvenWhenDisallowed(int userId);
+
+    /**
      * Return whether the given user is running in an
      * {@code UserState.STATE_RUNNING_UNLOCKING} or
      * {@code UserState.STATE_RUNNING_UNLOCKED} state.
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index f050d76..c45fe5a 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -19,7 +19,9 @@
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
 import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.Zygote;
+import com.android.internal.util.Preconditions;
 import java.io.BufferedWriter;
 import java.io.DataInputStream;
 import java.io.IOException;
@@ -110,7 +112,8 @@
             }
 
             String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
-            Log.i("Zygote", "Process: zygote socket opened, supported ABIS: " + abiListString);
+            Log.i("Zygote", "Process: zygote socket " + socketAddress + " opened, supported ABIS: "
+                    + abiListString);
 
             return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
                     Arrays.asList(abiListString.split(",")));
@@ -136,6 +139,13 @@
     }
 
     /**
+     * Lock object to protect access to the two ZygoteStates below. This lock must be
+     * acquired while communicating over the ZygoteState's socket, to prevent
+     * interleaved access.
+     */
+    private final Object mLock = new Object();
+
+    /**
      * The state of the connection to the primary zygote.
      */
     private ZygoteState primaryZygoteState;
@@ -207,6 +217,7 @@
      *
      * @throws ZygoteStartFailedEx if the query failed.
      */
+    @GuardedBy("mLock")
     private static String getAbiList(BufferedWriter writer, DataInputStream inputStream)
             throws IOException {
         // Each query starts with the argument count (1 in this case)
@@ -233,6 +244,7 @@
      *
      * @throws ZygoteStartFailedEx if process start failed for any reason
      */
+    @GuardedBy("mLock")
     private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
             ZygoteState zygoteState, ArrayList<String> args)
             throws ZygoteStartFailedEx {
@@ -320,90 +332,90 @@
                                                       String appDataDir,
                                                       String[] extraArgs)
                                                       throws ZygoteStartFailedEx {
-        synchronized(Process.class) {
-            ArrayList<String> argsForZygote = new ArrayList<String>();
+        ArrayList<String> argsForZygote = new ArrayList<String>();
 
-            // --runtime-args, --setuid=, --setgid=,
-            // and --setgroups= must go first
-            argsForZygote.add("--runtime-args");
-            argsForZygote.add("--setuid=" + uid);
-            argsForZygote.add("--setgid=" + gid);
-            if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
-                argsForZygote.add("--enable-jni-logging");
-            }
-            if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
-                argsForZygote.add("--enable-safemode");
-            }
-            if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
-                argsForZygote.add("--enable-debugger");
-            }
-            if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
-                argsForZygote.add("--enable-checkjni");
-            }
-            if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
-                argsForZygote.add("--generate-debug-info");
-            }
-            if ((debugFlags & Zygote.DEBUG_ALWAYS_JIT) != 0) {
-                argsForZygote.add("--always-jit");
-            }
-            if ((debugFlags & Zygote.DEBUG_NATIVE_DEBUGGABLE) != 0) {
-                argsForZygote.add("--native-debuggable");
-            }
-            if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
-                argsForZygote.add("--enable-assert");
-            }
-            if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
-                argsForZygote.add("--mount-external-default");
-            } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
-                argsForZygote.add("--mount-external-read");
-            } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
-                argsForZygote.add("--mount-external-write");
-            }
-            argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
+        // --runtime-args, --setuid=, --setgid=,
+        // and --setgroups= must go first
+        argsForZygote.add("--runtime-args");
+        argsForZygote.add("--setuid=" + uid);
+        argsForZygote.add("--setgid=" + gid);
+        if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
+            argsForZygote.add("--enable-jni-logging");
+        }
+        if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
+            argsForZygote.add("--enable-safemode");
+        }
+        if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
+            argsForZygote.add("--enable-debugger");
+        }
+        if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
+            argsForZygote.add("--enable-checkjni");
+        }
+        if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
+            argsForZygote.add("--generate-debug-info");
+        }
+        if ((debugFlags & Zygote.DEBUG_ALWAYS_JIT) != 0) {
+            argsForZygote.add("--always-jit");
+        }
+        if ((debugFlags & Zygote.DEBUG_NATIVE_DEBUGGABLE) != 0) {
+            argsForZygote.add("--native-debuggable");
+        }
+        if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
+            argsForZygote.add("--enable-assert");
+        }
+        if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
+            argsForZygote.add("--mount-external-default");
+        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
+            argsForZygote.add("--mount-external-read");
+        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
+            argsForZygote.add("--mount-external-write");
+        }
+        argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
 
-            //TODO optionally enable debuger
-            //argsForZygote.add("--enable-debugger");
+        //TODO optionally enable debuger
+        //argsForZygote.add("--enable-debugger");
 
-            // --setgroups is a comma-separated list
-            if (gids != null && gids.length > 0) {
-                StringBuilder sb = new StringBuilder();
-                sb.append("--setgroups=");
+        // --setgroups is a comma-separated list
+        if (gids != null && gids.length > 0) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("--setgroups=");
 
-                int sz = gids.length;
-                for (int i = 0; i < sz; i++) {
-                    if (i != 0) {
-                        sb.append(',');
-                    }
-                    sb.append(gids[i]);
+            int sz = gids.length;
+            for (int i = 0; i < sz; i++) {
+                if (i != 0) {
+                    sb.append(',');
                 }
-
-                argsForZygote.add(sb.toString());
+                sb.append(gids[i]);
             }
 
-            if (niceName != null) {
-                argsForZygote.add("--nice-name=" + niceName);
+            argsForZygote.add(sb.toString());
+        }
+
+        if (niceName != null) {
+            argsForZygote.add("--nice-name=" + niceName);
+        }
+
+        if (seInfo != null) {
+            argsForZygote.add("--seinfo=" + seInfo);
+        }
+
+        if (instructionSet != null) {
+            argsForZygote.add("--instruction-set=" + instructionSet);
+        }
+
+        if (appDataDir != null) {
+            argsForZygote.add("--app-data-dir=" + appDataDir);
+        }
+
+        argsForZygote.add(processClass);
+
+        if (extraArgs != null) {
+            for (String arg : extraArgs) {
+                argsForZygote.add(arg);
             }
+        }
 
-            if (seInfo != null) {
-                argsForZygote.add("--seinfo=" + seInfo);
-            }
-
-            if (instructionSet != null) {
-                argsForZygote.add("--instruction-set=" + instructionSet);
-            }
-
-            if (appDataDir != null) {
-                argsForZygote.add("--app-data-dir=" + appDataDir);
-            }
-
-            argsForZygote.add(processClass);
-
-            if (extraArgs != null) {
-                for (String arg : extraArgs) {
-                    argsForZygote.add(arg);
-                }
-            }
-
+        synchronized(mLock) {
             return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
         }
     }
@@ -415,7 +427,9 @@
      */
     public void establishZygoteConnectionForAbi(String abi) {
         try {
-            openZygoteSocketIfNeeded(abi);
+            synchronized(mLock) {
+                openZygoteSocketIfNeeded(abi);
+            }
         } catch (ZygoteStartFailedEx ex) {
             throw new RuntimeException("Unable to connect to zygote for abi: " + abi, ex);
         }
@@ -423,9 +437,12 @@
 
     /**
      * Tries to open socket to Zygote process if not already open. If
-     * already open, does nothing.  May block and retry.
+     * already open, does nothing.  May block and retry.  Requires that mLock be held.
      */
+    @GuardedBy("mLock")
     private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
+        Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
+
         if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
             try {
                 primaryZygoteState = ZygoteState.connect(mSocket);
@@ -453,4 +470,28 @@
 
         throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
     }
+
+    /**
+     * Instructs the zygote to pre-load the classes and native libraries at the given paths
+     * for the specified abi. Not all zygotes support this function.
+     */
+    public void preloadPackageForAbi(String packagePath, String libsPath, String abi)
+            throws ZygoteStartFailedEx, IOException {
+        synchronized(mLock) {
+            ZygoteState state = openZygoteSocketIfNeeded(abi);
+            state.writer.write("3");
+            state.writer.newLine();
+
+            state.writer.write("--preload-package");
+            state.writer.newLine();
+
+            state.writer.write(packagePath);
+            state.writer.newLine();
+
+            state.writer.write(libsPath);
+            state.writer.newLine();
+
+            state.writer.flush();
+        }
+    }
 }
diff --git a/core/java/android/os/storage/IMountService.aidl b/core/java/android/os/storage/IMountService.aidl
new file mode 100644
index 0000000..af0d7b7
--- /dev/null
+++ b/core/java/android/os/storage/IMountService.aidl
@@ -0,0 +1,291 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+import android.content.pm.IPackageMoveObserver;
+import android.os.ParcelFileDescriptor;
+import android.os.storage.DiskInfo;
+import android.os.storage.IMountServiceListener;
+import android.os.storage.IMountShutdownObserver;
+import android.os.storage.IObbActionListener;
+import android.os.storage.StorageVolume;
+import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+
+/**
+ * WARNING! Update IMountService.h and IMountService.cpp if you change this
+ * file. In particular, the transaction ids below must match the
+ * _TRANSACTION enum in IMountService.cpp
+ *
+ * @hide - Applications should use android.os.storage.StorageManager to access
+ *       storage functions.
+ */
+interface IMountService {
+    /**
+     * Registers an IMountServiceListener for receiving async notifications.
+     */
+    void registerListener(IMountServiceListener listener) = 1;
+    /**
+     * Unregisters an IMountServiceListener
+     */
+    void unregisterListener(IMountServiceListener listener) = 2;
+    /**
+     * Returns true if a USB mass storage host is connected
+     */
+    boolean isUsbMassStorageConnected() = 3;
+    /**
+     * Enables / disables USB mass storage. The caller should check actual
+     * status of enabling/disabling USB mass storage via StorageEventListener.
+     */
+    void setUsbMassStorageEnabled(boolean enable) = 4;
+    /**
+     * Returns true if a USB mass storage host is enabled (media is shared)
+     */
+    boolean isUsbMassStorageEnabled() = 5;
+    /**
+     * Mount external storage at given mount point. Returns an int consistent
+     * with MountServiceResultCode
+     */
+    int mountVolume(in String mountPoint) = 6;
+    /**
+     * Safely unmount external storage at given mount point. The unmount is an
+     * asynchronous operation. Applications should register StorageEventListener
+     * for storage related status changes.
+     * @param mountPoint the mount point
+     * @param force whether or not to forcefully unmount it (e.g. even if programs are using this
+     *     data currently)
+     * @param removeEncryption whether or not encryption mapping should be removed from the volume.
+     *     This value implies {@code force}.
+     */
+    void unmountVolume(in String mountPoint, boolean force, boolean removeEncryption) = 7;
+    /**
+     * Format external storage given a mount point. Returns an int consistent
+     * with MountServiceResultCode
+     */
+    int formatVolume(in String mountPoint) = 8;
+    /**
+     * Returns an array of pids with open files on the specified path.
+     */
+    int[] getStorageUsers(in String path) = 9;
+    /**
+     * Gets the state of a volume via its mountpoint.
+     */
+    String getVolumeState(in String mountPoint) = 10;
+    /*
+     * Creates a secure container with the specified parameters. Returns an int
+     * consistent with MountServiceResultCode
+     */
+    int createSecureContainer(in String id, int sizeMb, in String fstype, in String key,
+            int ownerUid, boolean external) = 11;
+    /*
+     * Finalize a container which has just been created and populated. After
+     * finalization, the container is immutable. Returns an int consistent with
+     * MountServiceResultCode
+     */
+    int finalizeSecureContainer(in String id) = 12;
+    /*
+     * Destroy a secure container, and free up all resources associated with it.
+     * NOTE: Ensure all references are released prior to deleting. Returns an
+     * int consistent with MountServiceResultCode
+     */
+    int destroySecureContainer(in String id, boolean force) = 13;
+    /*
+     * Mount a secure container with the specified key and owner UID. Returns an
+     * int consistent with MountServiceResultCode
+     */
+    int mountSecureContainer(in String id, in String key, int ownerUid, boolean readOnly) = 14;
+    /*
+     * Unount a secure container. Returns an int consistent with
+     * MountServiceResultCode
+     */
+    int unmountSecureContainer(in String id, boolean force) = 15;
+    /*
+     * Returns true if the specified container is mounted
+     */
+    boolean isSecureContainerMounted(in String id) = 16;
+    /*
+     * Rename an unmounted secure container. Returns an int consistent with
+     * MountServiceResultCode
+     */
+    int renameSecureContainer(in String oldId, in String newId) = 17;
+    /*
+     * Returns the filesystem path of a mounted secure container.
+     */
+    String getSecureContainerPath(in String id) = 18;
+    /**
+     * Gets an Array of currently known secure container IDs
+     */
+    String[] getSecureContainerList() = 19;
+    /**
+     * Shuts down the MountService and gracefully unmounts all external media.
+     * Invokes call back once the shutdown is complete.
+     */
+    void shutdown(IMountShutdownObserver observer) = 20;
+    /**
+     * Call into MountService by PackageManager to notify that its done
+     * processing the media status update request.
+     */
+    void finishMediaUpdate() = 21;
+    /**
+     * Mounts an Opaque Binary Blob (OBB) with the specified decryption key and
+     * only allows the calling process's UID access to the contents.
+     * MountService will call back to the supplied IObbActionListener to inform
+     * it of the terminal state of the call.
+     */
+    void mountObb(in String rawPath, in String canonicalPath, in String key,
+            IObbActionListener token, int nonce) = 22;
+    /**
+     * Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
+     * any program using it will be forcibly killed to unmount the image.
+     * MountService will call back to the supplied IObbActionListener to inform
+     * it of the terminal state of the call.
+     */
+    void unmountObb(in String rawPath, boolean force, IObbActionListener token, int nonce) = 23;
+    /**
+     * Checks whether the specified Opaque Binary Blob (OBB) is mounted
+     * somewhere.
+     */
+    boolean isObbMounted(in String rawPath) = 24;
+    /**
+     * Gets the path to the mounted Opaque Binary Blob (OBB).
+     */
+    String getMountedObbPath(in String rawPath) = 25;
+    /**
+     * Returns whether or not the external storage is emulated.
+     */
+    boolean isExternalStorageEmulated() = 26;
+    /**
+     * Decrypts any encrypted volumes.
+     */
+    int decryptStorage(in String password) = 27;
+    /**
+     * Encrypts storage.
+     */
+    int encryptStorage(int type, in String password) = 28;
+    /**
+     * Changes the encryption password.
+     */
+    int changeEncryptionPassword(int type, in String password) = 29;
+    /**
+     * Returns list of all mountable volumes.
+     */
+    StorageVolume[] getVolumeList(int uid, in String packageName, int flags) = 30;
+    /**
+     * Gets the path on the filesystem for the ASEC container itself.
+     *
+     * @param cid ASEC container ID
+     * @return path to filesystem or {@code null} if it's not found
+     * @throws RemoteException
+     */
+    String getSecureContainerFilesystemPath(in String cid) = 31;
+    /**
+     * Determines the encryption state of the volume.
+     * @return a numerical value. See {@code ENCRYPTION_STATE_*} for possible
+     * values.
+     * Note that this has been replaced in most cases by the APIs in
+     * StorageManager (see isEncryptable and below)
+     * This is still useful to get the error state when encryption has failed
+     * and CryptKeeper needs to throw up a screen advising the user what to do
+     */
+    int getEncryptionState() = 32;
+    /**
+     * Verify the encryption password against the stored volume.  This method
+     * may only be called by the system process.
+     */
+    int verifyEncryptionPassword(in String password) = 33;
+    /*
+     * Fix permissions in a container which has just been created and populated.
+     * Returns an int consistent with MountServiceResultCode
+     */
+    int fixPermissionsSecureContainer(in String id, int gid, in String filename) = 34;
+    /**
+     * Ensure that all directories along given path exist, creating parent
+     * directories as needed. Validates that given path is absolute and that it
+     * contains no relative "." or ".." paths or symlinks. Also ensures that
+     * path belongs to a volume managed by vold, and that path is either
+     * external storage data or OBB directory belonging to calling app.
+     */
+    int mkdirs(in String callingPkg, in String path) = 35;
+    /**
+     * Determines the type of the encryption password
+     * @return PasswordType
+     */
+    int getPasswordType() = 36;
+    /**
+     * Get password from vold
+     * @return password or empty string
+     */
+    String getPassword() = 37;
+    /**
+     * Securely clear password from vold
+     */
+    oneway void clearPassword() = 38;
+    /**
+     * Set a field in the crypto header.
+     * @param field field to set
+     * @param contents contents to set in field
+     */
+    oneway void setField(in String field, in String contents) = 39;
+    /**
+     * Gets a field from the crypto header.
+     * @param field field to get
+     * @return contents of field
+     */
+    String getField(in String field) = 40;
+    int resizeSecureContainer(in String id, int sizeMb, in String key) = 41;
+    /**
+     * Report the time of the last maintenance operation such as fstrim.
+     * @return Timestamp of the last maintenance operation, in the
+     *     System.currentTimeMillis() time base
+     * @throws RemoteException
+     */
+    long lastMaintenance() = 42;
+    /**
+     * Kick off an immediate maintenance operation
+     * @throws RemoteException
+     */
+    void runMaintenance() = 43;
+    void waitForAsecScan() = 44;
+    DiskInfo[] getDisks() = 45;
+    VolumeInfo[] getVolumes(int flags) = 46;
+    VolumeRecord[] getVolumeRecords(int flags) = 47;
+    void mount(in String volId) = 48;
+    void unmount(in String volId) = 49;
+    void format(in String volId) = 50;
+    void partitionPublic(in String diskId) = 51;
+    void partitionPrivate(in String diskId) = 52;
+    void partitionMixed(in String diskId, int ratio) = 53;
+    void setVolumeNickname(in String fsUuid, in String nickname) = 54;
+    void setVolumeUserFlags(in String fsUuid, int flags, int mask) = 55;
+    void forgetVolume(in String fsUuid) = 56;
+    void forgetAllVolumes() = 57;
+    String getPrimaryStorageUuid() = 58;
+    void setPrimaryStorageUuid(in String volumeUuid, IPackageMoveObserver callback) = 59;
+    long benchmark(in String volId) = 60;
+    void setDebugFlags(int flags, int mask) = 61;
+    void createUserKey(int userId, int serialNumber, boolean ephemeral) = 62;
+    void destroyUserKey(int userId) = 63;
+    void unlockUserKey(int userId, int serialNumber, in byte[] token, in byte[] secret) = 64;
+    void lockUserKey(int userId) = 65;
+    boolean isUserKeyUnlocked(int userId) = 66;
+    void prepareUserStorage(in String volumeUuid, int userId, int serialNumber, int flags) = 67;
+    void destroyUserStorage(in String volumeUuid, int userId, int flags) = 68;
+    boolean isConvertibleToFBE() = 69;
+    ParcelFileDescriptor mountAppFuse(in String name) = 70;
+    void addUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 71;
+    void fixateNewestUserKeyAuth(int userId) = 72;
+}
\ No newline at end of file
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
deleted file mode 100644
index b9bcd1c..0000000
--- a/core/java/android/os/storage/IMountService.java
+++ /dev/null
@@ -1,2491 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os.storage;
-
-import android.content.pm.IPackageMoveObserver;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-import android.os.RemoteException;
-
-/**
- * WARNING! Update IMountService.h and IMountService.cpp if you change this
- * file. In particular, the ordering of the methods below must match the
- * _TRANSACTION enum in IMountService.cpp
- *
- * @hide - Applications should use android.os.storage.StorageManager to access
- *       storage functions.
- */
-public interface IMountService extends IInterface {
-    /** Local-side IPC implementation stub class. */
-    public static abstract class Stub extends Binder implements IMountService {
-        private static class Proxy implements IMountService {
-            private final IBinder mRemote;
-
-            Proxy(IBinder remote) {
-                mRemote = remote;
-            }
-
-            public IBinder asBinder() {
-                return mRemote;
-            }
-
-            public String getInterfaceDescriptor() {
-                return DESCRIPTOR;
-            }
-
-            /**
-             * Registers an IMountServiceListener for receiving async
-             * notifications.
-             */
-            public void registerListener(IMountServiceListener listener) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeStrongBinder((listener != null ? listener.asBinder() : null));
-                    mRemote.transact(Stub.TRANSACTION_registerListener, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            /**
-             * Unregisters an IMountServiceListener
-             */
-            public void unregisterListener(IMountServiceListener listener) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeStrongBinder((listener != null ? listener.asBinder() : null));
-                    mRemote.transact(Stub.TRANSACTION_unregisterListener, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            /**
-             * Returns true if a USB mass storage host is connected
-             */
-            public boolean isUsbMassStorageConnected() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                boolean _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_isUsbMassStorageConnected, _data, _reply, 0);
-                    _reply.readException();
-                    _result = 0 != _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /**
-             * Enables / disables USB mass storage. The caller should check
-             * actual status of enabling/disabling USB mass storage via
-             * StorageEventListener.
-             */
-            public void setUsbMassStorageEnabled(boolean enable) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt((enable ? 1 : 0));
-                    mRemote.transact(Stub.TRANSACTION_setUsbMassStorageEnabled, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            /**
-             * Returns true if a USB mass storage host is enabled (media is
-             * shared)
-             */
-            public boolean isUsbMassStorageEnabled() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                boolean _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_isUsbMassStorageEnabled, _data, _reply, 0);
-                    _reply.readException();
-                    _result = 0 != _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /**
-             * Mount external storage at given mount point. Returns an int
-             * consistent with MountServiceResultCode
-             */
-            public int mountVolume(String mountPoint) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(mountPoint);
-                    mRemote.transact(Stub.TRANSACTION_mountVolume, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /**
-             * Safely unmount external storage at given mount point. The unmount
-             * is an asynchronous operation. Applications should register
-             * StorageEventListener for storage related status changes.
-             */
-            public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(mountPoint);
-                    _data.writeInt((force ? 1 : 0));
-                    _data.writeInt((removeEncryption ? 1 : 0));
-                    mRemote.transact(Stub.TRANSACTION_unmountVolume, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            /**
-             * Format external storage given a mount point. Returns an int
-             * consistent with MountServiceResultCode
-             */
-            public int formatVolume(String mountPoint) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(mountPoint);
-                    mRemote.transact(Stub.TRANSACTION_formatVolume, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /**
-             * Returns an array of pids with open files on the specified path.
-             */
-            public int[] getStorageUsers(String path) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int[] _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(path);
-                    mRemote.transact(Stub.TRANSACTION_getStorageUsers, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.createIntArray();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /**
-             * Gets the state of a volume via its mountpoint.
-             */
-            public String getVolumeState(String mountPoint) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                String _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(mountPoint);
-                    mRemote.transact(Stub.TRANSACTION_getVolumeState, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readString();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /*
-             * Creates a secure container with the specified parameters. Returns
-             * an int consistent with MountServiceResultCode
-             */
-            public int createSecureContainer(String id, int sizeMb, String fstype, String key,
-                    int ownerUid, boolean external) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(id);
-                    _data.writeInt(sizeMb);
-                    _data.writeString(fstype);
-                    _data.writeString(key);
-                    _data.writeInt(ownerUid);
-                    _data.writeInt(external ? 1 : 0);
-                    mRemote.transact(Stub.TRANSACTION_createSecureContainer, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /*
-             * Destroy a secure container, and free up all resources associated
-             * with it. NOTE: Ensure all references are released prior to
-             * deleting. Returns an int consistent with MountServiceResultCode
-             */
-            public int destroySecureContainer(String id, boolean force) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(id);
-                    _data.writeInt((force ? 1 : 0));
-                    mRemote.transact(Stub.TRANSACTION_destroySecureContainer, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /*
-             * Finalize a container which has just been created and populated.
-             * After finalization, the container is immutable. Returns an int
-             * consistent with MountServiceResultCode
-             */
-            public int finalizeSecureContainer(String id) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(id);
-                    mRemote.transact(Stub.TRANSACTION_finalizeSecureContainer, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /*
-             * Mount a secure container with the specified key and owner UID.
-             * Returns an int consistent with MountServiceResultCode
-             */
-            public int mountSecureContainer(String id, String key, int ownerUid, boolean readOnly)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(id);
-                    _data.writeString(key);
-                    _data.writeInt(ownerUid);
-                    _data.writeInt(readOnly ? 1 : 0);
-                    mRemote.transact(Stub.TRANSACTION_mountSecureContainer, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /*
-             * Unount a secure container. Returns an int consistent with
-             * MountServiceResultCode
-             */
-            public int unmountSecureContainer(String id, boolean force) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(id);
-                    _data.writeInt((force ? 1 : 0));
-                    mRemote.transact(Stub.TRANSACTION_unmountSecureContainer, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /*
-             * Returns true if the specified container is mounted
-             */
-            public boolean isSecureContainerMounted(String id) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                boolean _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(id);
-                    mRemote.transact(Stub.TRANSACTION_isSecureContainerMounted, _data, _reply, 0);
-                    _reply.readException();
-                    _result = 0 != _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /*
-             * Rename an unmounted secure container. Returns an int consistent
-             * with MountServiceResultCode
-             */
-            public int renameSecureContainer(String oldId, String newId) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(oldId);
-                    _data.writeString(newId);
-                    mRemote.transact(Stub.TRANSACTION_renameSecureContainer, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /*
-             * Returns the filesystem path of a mounted secure container.
-             */
-            public String getSecureContainerPath(String id) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                String _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(id);
-                    mRemote.transact(Stub.TRANSACTION_getSecureContainerPath, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readString();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /**
-             * Gets an Array of currently known secure container IDs
-             */
-            public String[] getSecureContainerList() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                String[] _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_getSecureContainerList, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.createStringArray();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /**
-             * Shuts down the MountService and gracefully unmounts all external
-             * media. Invokes call back once the shutdown is complete.
-             */
-            public void shutdown(IMountShutdownObserver observer)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeStrongBinder((observer != null ? observer.asBinder() : null));
-                    mRemote.transact(Stub.TRANSACTION_shutdown, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            /**
-             * Call into MountService by PackageManager to notify that its done
-             * processing the media status update request.
-             */
-            public void finishMediaUpdate() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_finishMediaUpdate, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            /**
-             * Mounts an Opaque Binary Blob (OBB) with the specified decryption
-             * key and only allows the calling process's UID access to the
-             * contents. MountService will call back to the supplied
-             * IObbActionListener to inform it of the terminal state of the
-             * call.
-             */
-            public void mountObb(String rawPath, String canonicalPath, String key,
-                    IObbActionListener token, int nonce) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(rawPath);
-                    _data.writeString(canonicalPath);
-                    _data.writeString(key);
-                    _data.writeStrongBinder((token != null ? token.asBinder() : null));
-                    _data.writeInt(nonce);
-                    mRemote.transact(Stub.TRANSACTION_mountObb, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            /**
-             * Unmounts an Opaque Binary Blob (OBB). When the force flag is
-             * specified, any program using it will be forcibly killed to
-             * unmount the image. MountService will call back to the supplied
-             * IObbActionListener to inform it of the terminal state of the
-             * call.
-             */
-            public void unmountObb(
-                    String rawPath, boolean force, IObbActionListener token, int nonce)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(rawPath);
-                    _data.writeInt((force ? 1 : 0));
-                    _data.writeStrongBinder((token != null ? token.asBinder() : null));
-                    _data.writeInt(nonce);
-                    mRemote.transact(Stub.TRANSACTION_unmountObb, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            /**
-             * Checks whether the specified Opaque Binary Blob (OBB) is mounted
-             * somewhere.
-             */
-            public boolean isObbMounted(String rawPath) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                boolean _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(rawPath);
-                    mRemote.transact(Stub.TRANSACTION_isObbMounted, _data, _reply, 0);
-                    _reply.readException();
-                    _result = 0 != _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /**
-             * Gets the path to the mounted Opaque Binary Blob (OBB).
-             */
-            public String getMountedObbPath(String rawPath) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                String _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(rawPath);
-                    mRemote.transact(Stub.TRANSACTION_getMountedObbPath, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readString();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /**
-             * Returns whether the external storage is emulated.
-             */
-            public boolean isExternalStorageEmulated() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                boolean _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_isExternalStorageEmulated, _data, _reply, 0);
-                    _reply.readException();
-                    _result = 0 != _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int getEncryptionState() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_getEncryptionState, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int decryptStorage(String password) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(password);
-                    mRemote.transact(Stub.TRANSACTION_decryptStorage, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int encryptStorage(int type, String password) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(type);
-                    _data.writeString(password);
-                    mRemote.transact(Stub.TRANSACTION_encryptStorage, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int changeEncryptionPassword(int type, String password) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(type);
-                    _data.writeString(password);
-                    mRemote.transact(Stub.TRANSACTION_changeEncryptionPassword, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public int verifyEncryptionPassword(String password) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(password);
-                    mRemote.transact(Stub.TRANSACTION_verifyEncryptionPassword, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public int getPasswordType() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_getPasswordType, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public String getPassword() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                String _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_getPassword, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readString();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public void clearPassword() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_clearPassword, _data, _reply, IBinder.FLAG_ONEWAY);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            public void setField(String field, String data) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(field);
-                    _data.writeString(data);
-                    mRemote.transact(Stub.TRANSACTION_setField, _data, _reply, IBinder.FLAG_ONEWAY);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            public String getField(String field) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                String _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(field);
-                    mRemote.transact(Stub.TRANSACTION_getField, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readString();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public boolean isConvertibleToFBE() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                boolean _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_isConvertibleToFBE, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt() != 0;
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            public StorageVolume[] getVolumeList(int uid, String packageName, int flags)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                StorageVolume[] _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(uid);
-                    _data.writeString(packageName);
-                    _data.writeInt(flags);
-                    mRemote.transact(Stub.TRANSACTION_getVolumeList, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.createTypedArray(StorageVolume.CREATOR);
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /*
-             * Returns the filesystem path of a mounted secure container.
-             */
-            public String getSecureContainerFilesystemPath(String id) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                String _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(id);
-                    mRemote.transact(Stub.TRANSACTION_getSecureContainerFilesystemPath, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readString();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            /**
-             * Fix permissions in a container which has just been created and
-             * populated. Returns an int consistent with MountServiceResultCode
-             */
-            public int fixPermissionsSecureContainer(String id, int gid, String filename)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(id);
-                    _data.writeInt(gid);
-                    _data.writeString(filename);
-                    mRemote.transact(Stub.TRANSACTION_fixPermissionsSecureContainer, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public int mkdirs(String callingPkg, String path) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(callingPkg);
-                    _data.writeString(path);
-                    mRemote.transact(Stub.TRANSACTION_mkdirs, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public int resizeSecureContainer(String id, int sizeMb, String key)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                int _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(id);
-                    _data.writeInt(sizeMb);
-                    _data.writeString(key);
-                    mRemote.transact(Stub.TRANSACTION_resizeSecureContainer, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public long lastMaintenance() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                long _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_lastMaintenance, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readLong();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public void runMaintenance() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_runMaintenance, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return;
-            }
-
-            @Override
-            public void waitForAsecScan() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_waitForAsecScan, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return;
-            }
-
-            @Override
-            public DiskInfo[] getDisks() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                DiskInfo[] _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_getDisks, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.createTypedArray(DiskInfo.CREATOR);
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public VolumeInfo[] getVolumes(int _flags) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                VolumeInfo[] _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(_flags);
-                    mRemote.transact(Stub.TRANSACTION_getVolumes, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.createTypedArray(VolumeInfo.CREATOR);
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public VolumeRecord[] getVolumeRecords(int _flags) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                VolumeRecord[] _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(_flags);
-                    mRemote.transact(Stub.TRANSACTION_getVolumeRecords, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.createTypedArray(VolumeRecord.CREATOR);
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public void mount(String volId) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(volId);
-                    mRemote.transact(Stub.TRANSACTION_mount, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void unmount(String volId) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(volId);
-                    mRemote.transact(Stub.TRANSACTION_unmount, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void format(String volId) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(volId);
-                    mRemote.transact(Stub.TRANSACTION_format, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public long benchmark(String volId) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(volId);
-                    mRemote.transact(Stub.TRANSACTION_benchmark, _data, _reply, 0);
-                    _reply.readException();
-                    return _reply.readLong();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void partitionPublic(String diskId) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(diskId);
-                    mRemote.transact(Stub.TRANSACTION_partitionPublic, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void partitionPrivate(String diskId) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(diskId);
-                    mRemote.transact(Stub.TRANSACTION_partitionPrivate, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void partitionMixed(String diskId, int ratio) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(diskId);
-                    _data.writeInt(ratio);
-                    mRemote.transact(Stub.TRANSACTION_partitionMixed, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(fsUuid);
-                    _data.writeString(nickname);
-                    mRemote.transact(Stub.TRANSACTION_setVolumeNickname, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(fsUuid);
-                    _data.writeInt(flags);
-                    _data.writeInt(mask);
-                    mRemote.transact(Stub.TRANSACTION_setVolumeUserFlags, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void forgetVolume(String fsUuid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(fsUuid);
-                    mRemote.transact(Stub.TRANSACTION_forgetVolume, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void forgetAllVolumes() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_forgetAllVolumes, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void setDebugFlags(int _flags, int _mask) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(_flags);
-                    _data.writeInt(_mask);
-                    mRemote.transact(Stub.TRANSACTION_setDebugFlags, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public String getPrimaryStorageUuid() throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                String _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    mRemote.transact(Stub.TRANSACTION_getPrimaryStorageUuid, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.readString();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(volumeUuid);
-                    _data.writeStrongBinder((callback != null ? callback.asBinder() : null));
-                    mRemote.transact(Stub.TRANSACTION_setPrimaryStorageUuid, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void createUserKey(int userId, int serialNumber, boolean ephemeral)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(userId);
-                    _data.writeInt(serialNumber);
-                    _data.writeInt(ephemeral ? 1 : 0);
-                    mRemote.transact(Stub.TRANSACTION_createUserKey, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void destroyUserKey(int userId) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(userId);
-                    mRemote.transact(Stub.TRANSACTION_destroyUserKey, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void addUserKeyAuth(int userId, int serialNumber,
-                    byte[] token, byte[] secret) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(userId);
-                    _data.writeInt(serialNumber);
-                    _data.writeByteArray(token);
-                    _data.writeByteArray(secret);
-                    mRemote.transact(Stub.TRANSACTION_addUserKeyAuth, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void fixateNewestUserKeyAuth(int userId) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(userId);
-                    mRemote.transact(Stub.TRANSACTION_fixateNewestUserKeyAuth, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void unlockUserKey(int userId, int serialNumber,
-                    byte[] token, byte[] secret) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(userId);
-                    _data.writeInt(serialNumber);
-                    _data.writeByteArray(token);
-                    _data.writeByteArray(secret);
-                    mRemote.transact(Stub.TRANSACTION_unlockUserKey, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void lockUserKey(int userId) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(userId);
-                    mRemote.transact(Stub.TRANSACTION_lockUserKey, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public boolean isUserKeyUnlocked(int userId) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                boolean _result;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(userId);
-                    mRemote.transact(Stub.TRANSACTION_isUserKeyUnlocked, _data, _reply, 0);
-                    _reply.readException();
-                    _result = 0 != _reply.readInt();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-
-            @Override
-            public void prepareUserStorage(
-                    String volumeUuid, int userId, int serialNumber, int flags)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(volumeUuid);
-                    _data.writeInt(userId);
-                    _data.writeInt(serialNumber);
-                    _data.writeInt(flags);
-                    mRemote.transact(Stub.TRANSACTION_prepareUserStorage, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void destroyUserStorage(String volumeUuid, int userId, int flags)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(volumeUuid);
-                    _data.writeInt(userId);
-                    _data.writeInt(flags);
-                    mRemote.transact(Stub.TRANSACTION_destroyUserStorage, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public ParcelFileDescriptor mountAppFuse(String name) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                ParcelFileDescriptor _result = null;
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(name);
-                    mRemote.transact(Stub.TRANSACTION_mountAppFuse, _data, _reply, 0);
-                    _reply.readException();
-                    _result = _reply.<ParcelFileDescriptor>readParcelable(
-                            ClassLoader.getSystemClassLoader());
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-                return _result;
-            }
-        }
-
-        private static final String DESCRIPTOR = "IMountService";
-
-        static final int TRANSACTION_registerListener = IBinder.FIRST_CALL_TRANSACTION + 0;
-
-        static final int TRANSACTION_unregisterListener = IBinder.FIRST_CALL_TRANSACTION + 1;
-
-        static final int TRANSACTION_isUsbMassStorageConnected = IBinder.FIRST_CALL_TRANSACTION + 2;
-
-        static final int TRANSACTION_setUsbMassStorageEnabled = IBinder.FIRST_CALL_TRANSACTION + 3;
-
-        static final int TRANSACTION_isUsbMassStorageEnabled = IBinder.FIRST_CALL_TRANSACTION + 4;
-
-        static final int TRANSACTION_mountVolume = IBinder.FIRST_CALL_TRANSACTION + 5;
-
-        static final int TRANSACTION_unmountVolume = IBinder.FIRST_CALL_TRANSACTION + 6;
-
-        static final int TRANSACTION_formatVolume = IBinder.FIRST_CALL_TRANSACTION + 7;
-
-        static final int TRANSACTION_getStorageUsers = IBinder.FIRST_CALL_TRANSACTION + 8;
-
-        static final int TRANSACTION_getVolumeState = IBinder.FIRST_CALL_TRANSACTION + 9;
-
-        static final int TRANSACTION_createSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 10;
-
-        static final int TRANSACTION_finalizeSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 11;
-
-        static final int TRANSACTION_destroySecureContainer = IBinder.FIRST_CALL_TRANSACTION + 12;
-
-        static final int TRANSACTION_mountSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 13;
-
-        static final int TRANSACTION_unmountSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 14;
-
-        static final int TRANSACTION_isSecureContainerMounted = IBinder.FIRST_CALL_TRANSACTION + 15;
-
-        static final int TRANSACTION_renameSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 16;
-
-        static final int TRANSACTION_getSecureContainerPath = IBinder.FIRST_CALL_TRANSACTION + 17;
-
-        static final int TRANSACTION_getSecureContainerList = IBinder.FIRST_CALL_TRANSACTION + 18;
-
-        static final int TRANSACTION_shutdown = IBinder.FIRST_CALL_TRANSACTION + 19;
-
-        static final int TRANSACTION_finishMediaUpdate = IBinder.FIRST_CALL_TRANSACTION + 20;
-
-        static final int TRANSACTION_mountObb = IBinder.FIRST_CALL_TRANSACTION + 21;
-
-        static final int TRANSACTION_unmountObb = IBinder.FIRST_CALL_TRANSACTION + 22;
-
-        static final int TRANSACTION_isObbMounted = IBinder.FIRST_CALL_TRANSACTION + 23;
-
-        static final int TRANSACTION_getMountedObbPath = IBinder.FIRST_CALL_TRANSACTION + 24;
-
-        static final int TRANSACTION_isExternalStorageEmulated = IBinder.FIRST_CALL_TRANSACTION + 25;
-
-        static final int TRANSACTION_decryptStorage = IBinder.FIRST_CALL_TRANSACTION + 26;
-
-        static final int TRANSACTION_encryptStorage = IBinder.FIRST_CALL_TRANSACTION + 27;
-
-        static final int TRANSACTION_changeEncryptionPassword = IBinder.FIRST_CALL_TRANSACTION + 28;
-
-        static final int TRANSACTION_getVolumeList = IBinder.FIRST_CALL_TRANSACTION + 29;
-
-        static final int TRANSACTION_getSecureContainerFilesystemPath = IBinder.FIRST_CALL_TRANSACTION + 30;
-
-        static final int TRANSACTION_getEncryptionState = IBinder.FIRST_CALL_TRANSACTION + 31;
-
-        static final int TRANSACTION_verifyEncryptionPassword = IBinder.FIRST_CALL_TRANSACTION + 32;
-
-        static final int TRANSACTION_fixPermissionsSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 33;
-
-        static final int TRANSACTION_mkdirs = IBinder.FIRST_CALL_TRANSACTION + 34;
-
-        static final int TRANSACTION_getPasswordType = IBinder.FIRST_CALL_TRANSACTION + 35;
-
-        static final int TRANSACTION_getPassword = IBinder.FIRST_CALL_TRANSACTION + 36;
-
-        static final int TRANSACTION_clearPassword = IBinder.FIRST_CALL_TRANSACTION + 37;
-
-        static final int TRANSACTION_setField = IBinder.FIRST_CALL_TRANSACTION + 38;
-
-        static final int TRANSACTION_getField = IBinder.FIRST_CALL_TRANSACTION + 39;
-
-        static final int TRANSACTION_resizeSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 40;
-
-        static final int TRANSACTION_lastMaintenance = IBinder.FIRST_CALL_TRANSACTION + 41;
-
-        static final int TRANSACTION_runMaintenance = IBinder.FIRST_CALL_TRANSACTION + 42;
-
-        static final int TRANSACTION_waitForAsecScan = IBinder.FIRST_CALL_TRANSACTION + 43;
-
-        static final int TRANSACTION_getDisks = IBinder.FIRST_CALL_TRANSACTION + 44;
-        static final int TRANSACTION_getVolumes = IBinder.FIRST_CALL_TRANSACTION + 45;
-        static final int TRANSACTION_getVolumeRecords = IBinder.FIRST_CALL_TRANSACTION + 46;
-
-        static final int TRANSACTION_mount = IBinder.FIRST_CALL_TRANSACTION + 47;
-        static final int TRANSACTION_unmount = IBinder.FIRST_CALL_TRANSACTION + 48;
-        static final int TRANSACTION_format = IBinder.FIRST_CALL_TRANSACTION + 49;
-
-        static final int TRANSACTION_partitionPublic = IBinder.FIRST_CALL_TRANSACTION + 50;
-        static final int TRANSACTION_partitionPrivate = IBinder.FIRST_CALL_TRANSACTION + 51;
-        static final int TRANSACTION_partitionMixed = IBinder.FIRST_CALL_TRANSACTION + 52;
-
-        static final int TRANSACTION_setVolumeNickname = IBinder.FIRST_CALL_TRANSACTION + 53;
-        static final int TRANSACTION_setVolumeUserFlags = IBinder.FIRST_CALL_TRANSACTION + 54;
-        static final int TRANSACTION_forgetVolume = IBinder.FIRST_CALL_TRANSACTION + 55;
-        static final int TRANSACTION_forgetAllVolumes = IBinder.FIRST_CALL_TRANSACTION + 56;
-
-        static final int TRANSACTION_getPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 57;
-        static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 58;
-
-        static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
-        static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
-
-        static final int TRANSACTION_createUserKey = IBinder.FIRST_CALL_TRANSACTION + 61;
-        static final int TRANSACTION_destroyUserKey = IBinder.FIRST_CALL_TRANSACTION + 62;
-
-        static final int TRANSACTION_unlockUserKey = IBinder.FIRST_CALL_TRANSACTION + 63;
-        static final int TRANSACTION_lockUserKey = IBinder.FIRST_CALL_TRANSACTION + 64;
-        static final int TRANSACTION_isUserKeyUnlocked = IBinder.FIRST_CALL_TRANSACTION + 65;
-
-        static final int TRANSACTION_prepareUserStorage = IBinder.FIRST_CALL_TRANSACTION + 66;
-        static final int TRANSACTION_destroyUserStorage = IBinder.FIRST_CALL_TRANSACTION + 67;
-
-        static final int TRANSACTION_isConvertibleToFBE = IBinder.FIRST_CALL_TRANSACTION + 68;
-
-        static final int TRANSACTION_mountAppFuse = IBinder.FIRST_CALL_TRANSACTION + 69;
-
-        static final int TRANSACTION_addUserKeyAuth = IBinder.FIRST_CALL_TRANSACTION + 70;
-
-        static final int TRANSACTION_fixateNewestUserKeyAuth = IBinder.FIRST_CALL_TRANSACTION + 71;
-
-        /**
-         * Cast an IBinder object into an IMountService interface, generating a
-         * proxy if needed.
-         */
-        public static IMountService asInterface(IBinder obj) {
-            if (obj == null) {
-                return null;
-            }
-            IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
-            if (iin != null && iin instanceof IMountService) {
-                return (IMountService) iin;
-            }
-            return new IMountService.Stub.Proxy(obj);
-        }
-
-        /** Construct the stub at attach it to the interface. */
-        public Stub() {
-            attachInterface(this, DESCRIPTOR);
-        }
-
-        public IBinder asBinder() {
-            return this;
-        }
-
-        @Override
-        public boolean onTransact(int code, Parcel data, Parcel reply,
-                int flags) throws RemoteException {
-            switch (code) {
-                case INTERFACE_TRANSACTION: {
-                    reply.writeString(DESCRIPTOR);
-                    return true;
-                }
-                case TRANSACTION_registerListener: {
-                    data.enforceInterface(DESCRIPTOR);
-                    IMountServiceListener listener;
-                    listener = IMountServiceListener.Stub.asInterface(data.readStrongBinder());
-                    registerListener(listener);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_unregisterListener: {
-                    data.enforceInterface(DESCRIPTOR);
-                    IMountServiceListener listener;
-                    listener = IMountServiceListener.Stub.asInterface(data.readStrongBinder());
-                    unregisterListener(listener);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_isUsbMassStorageConnected: {
-                    data.enforceInterface(DESCRIPTOR);
-                    boolean result = isUsbMassStorageConnected();
-                    reply.writeNoException();
-                    reply.writeInt((result ? 1 : 0));
-                    return true;
-                }
-                case TRANSACTION_setUsbMassStorageEnabled: {
-                    data.enforceInterface(DESCRIPTOR);
-                    boolean enable;
-                    enable = 0 != data.readInt();
-                    setUsbMassStorageEnabled(enable);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_isUsbMassStorageEnabled: {
-                    data.enforceInterface(DESCRIPTOR);
-                    boolean result = isUsbMassStorageEnabled();
-                    reply.writeNoException();
-                    reply.writeInt((result ? 1 : 0));
-                    return true;
-                }
-                case TRANSACTION_mountVolume: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String mountPoint;
-                    mountPoint = data.readString();
-                    int resultCode = mountVolume(mountPoint);
-                    reply.writeNoException();
-                    reply.writeInt(resultCode);
-                    return true;
-                }
-                case TRANSACTION_unmountVolume: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String mountPoint;
-                    mountPoint = data.readString();
-                    boolean force = 0 != data.readInt();
-                    boolean removeEncrypt = 0 != data.readInt();
-                    unmountVolume(mountPoint, force, removeEncrypt);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_formatVolume: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String mountPoint;
-                    mountPoint = data.readString();
-                    int result = formatVolume(mountPoint);
-                    reply.writeNoException();
-                    reply.writeInt(result);
-                    return true;
-                }
-                case TRANSACTION_getStorageUsers: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String path;
-                    path = data.readString();
-                    int[] pids = getStorageUsers(path);
-                    reply.writeNoException();
-                    reply.writeIntArray(pids);
-                    return true;
-                }
-                case TRANSACTION_getVolumeState: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String mountPoint;
-                    mountPoint = data.readString();
-                    String state = getVolumeState(mountPoint);
-                    reply.writeNoException();
-                    reply.writeString(state);
-                    return true;
-                }
-                case TRANSACTION_createSecureContainer: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String id;
-                    id = data.readString();
-                    int sizeMb;
-                    sizeMb = data.readInt();
-                    String fstype;
-                    fstype = data.readString();
-                    String key;
-                    key = data.readString();
-                    int ownerUid;
-                    ownerUid = data.readInt();
-                    boolean external;
-                    external = 0 != data.readInt();
-                    int resultCode = createSecureContainer(id, sizeMb, fstype, key, ownerUid,
-                            external);
-                    reply.writeNoException();
-                    reply.writeInt(resultCode);
-                    return true;
-                }
-                case TRANSACTION_finalizeSecureContainer: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String id;
-                    id = data.readString();
-                    int resultCode = finalizeSecureContainer(id);
-                    reply.writeNoException();
-                    reply.writeInt(resultCode);
-                    return true;
-                }
-                case TRANSACTION_destroySecureContainer: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String id;
-                    id = data.readString();
-                    boolean force;
-                    force = 0 != data.readInt();
-                    int resultCode = destroySecureContainer(id, force);
-                    reply.writeNoException();
-                    reply.writeInt(resultCode);
-                    return true;
-                }
-                case TRANSACTION_mountSecureContainer: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String id;
-                    id = data.readString();
-                    String key;
-                    key = data.readString();
-                    int ownerUid;
-                    ownerUid = data.readInt();
-                    boolean readOnly;
-                    readOnly = data.readInt() != 0;
-                    int resultCode = mountSecureContainer(id, key, ownerUid, readOnly);
-                    reply.writeNoException();
-                    reply.writeInt(resultCode);
-                    return true;
-                }
-                case TRANSACTION_unmountSecureContainer: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String id;
-                    id = data.readString();
-                    boolean force;
-                    force = 0 != data.readInt();
-                    int resultCode = unmountSecureContainer(id, force);
-                    reply.writeNoException();
-                    reply.writeInt(resultCode);
-                    return true;
-                }
-                case TRANSACTION_isSecureContainerMounted: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String id;
-                    id = data.readString();
-                    boolean status = isSecureContainerMounted(id);
-                    reply.writeNoException();
-                    reply.writeInt((status ? 1 : 0));
-                    return true;
-                }
-                case TRANSACTION_renameSecureContainer: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String oldId;
-                    oldId = data.readString();
-                    String newId;
-                    newId = data.readString();
-                    int resultCode = renameSecureContainer(oldId, newId);
-                    reply.writeNoException();
-                    reply.writeInt(resultCode);
-                    return true;
-                }
-                case TRANSACTION_getSecureContainerPath: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String id;
-                    id = data.readString();
-                    String path = getSecureContainerPath(id);
-                    reply.writeNoException();
-                    reply.writeString(path);
-                    return true;
-                }
-                case TRANSACTION_getSecureContainerList: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String[] ids = getSecureContainerList();
-                    reply.writeNoException();
-                    reply.writeStringArray(ids);
-                    return true;
-                }
-                case TRANSACTION_shutdown: {
-                    data.enforceInterface(DESCRIPTOR);
-                    IMountShutdownObserver observer;
-                    observer = IMountShutdownObserver.Stub.asInterface(data
-                            .readStrongBinder());
-                    shutdown(observer);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_finishMediaUpdate: {
-                    data.enforceInterface(DESCRIPTOR);
-                    finishMediaUpdate();
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_mountObb: {
-                    data.enforceInterface(DESCRIPTOR);
-                    final String rawPath = data.readString();
-                    final String canonicalPath = data.readString();
-                    final String key = data.readString();
-                    IObbActionListener observer;
-                    observer = IObbActionListener.Stub.asInterface(data.readStrongBinder());
-                    int nonce;
-                    nonce = data.readInt();
-                    mountObb(rawPath, canonicalPath, key, observer, nonce);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_unmountObb: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String filename;
-                    filename = data.readString();
-                    boolean force;
-                    force = 0 != data.readInt();
-                    IObbActionListener observer;
-                    observer = IObbActionListener.Stub.asInterface(data.readStrongBinder());
-                    int nonce;
-                    nonce = data.readInt();
-                    unmountObb(filename, force, observer, nonce);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_isObbMounted: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String filename;
-                    filename = data.readString();
-                    boolean status = isObbMounted(filename);
-                    reply.writeNoException();
-                    reply.writeInt((status ? 1 : 0));
-                    return true;
-                }
-                case TRANSACTION_getMountedObbPath: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String filename;
-                    filename = data.readString();
-                    String mountedPath = getMountedObbPath(filename);
-                    reply.writeNoException();
-                    reply.writeString(mountedPath);
-                    return true;
-                }
-                case TRANSACTION_isExternalStorageEmulated: {
-                    data.enforceInterface(DESCRIPTOR);
-                    boolean emulated = isExternalStorageEmulated();
-                    reply.writeNoException();
-                    reply.writeInt(emulated ? 1 : 0);
-                    return true;
-                }
-                case TRANSACTION_decryptStorage: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String password = data.readString();
-                    int result = decryptStorage(password);
-                    reply.writeNoException();
-                    reply.writeInt(result);
-                    return true;
-                }
-                case TRANSACTION_encryptStorage: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int type = data.readInt();
-                    String password = data.readString();
-                    int result = encryptStorage(type, password);
-                    reply.writeNoException();
-                    reply.writeInt(result);
-                    return true;
-                }
-                case TRANSACTION_changeEncryptionPassword: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int type = data.readInt();
-                    String password = data.readString();
-                    int result = changeEncryptionPassword(type, password);
-                    reply.writeNoException();
-                    reply.writeInt(result);
-                    return true;
-                }
-                case TRANSACTION_getVolumeList: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int uid = data.readInt();
-                    String packageName = data.readString();
-                    int _flags = data.readInt();
-                    StorageVolume[] result = getVolumeList(uid, packageName, _flags);
-                    reply.writeNoException();
-                    reply.writeTypedArray(result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-                    return true;
-                }
-                case TRANSACTION_getSecureContainerFilesystemPath: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String id;
-                    id = data.readString();
-                    String path = getSecureContainerFilesystemPath(id);
-                    reply.writeNoException();
-                    reply.writeString(path);
-                    return true;
-                }
-                case TRANSACTION_getEncryptionState: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int result = getEncryptionState();
-                    reply.writeNoException();
-                    reply.writeInt(result);
-                    return true;
-                }
-                case TRANSACTION_fixPermissionsSecureContainer: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String id;
-                    id = data.readString();
-                    int gid;
-                    gid = data.readInt();
-                    String filename;
-                    filename = data.readString();
-                    int resultCode = fixPermissionsSecureContainer(id, gid, filename);
-                    reply.writeNoException();
-                    reply.writeInt(resultCode);
-                    return true;
-                }
-                case TRANSACTION_mkdirs: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String callingPkg = data.readString();
-                    String path = data.readString();
-                    int result = mkdirs(callingPkg, path);
-                    reply.writeNoException();
-                    reply.writeInt(result);
-                    return true;
-                }
-                case TRANSACTION_getPasswordType: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int result = getPasswordType();
-                    reply.writeNoException();
-                    reply.writeInt(result);
-                    return true;
-                }
-                case TRANSACTION_getPassword: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String result = getPassword();
-                    reply.writeNoException();
-                    reply.writeString(result);
-                    return true;
-                }
-                case TRANSACTION_clearPassword: {
-                    data.enforceInterface(DESCRIPTOR);
-                    clearPassword();
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_setField: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String field = data.readString();
-                    String contents = data.readString();
-                    setField(field, contents);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_getField: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String field = data.readString();
-                    String contents = getField(field);
-                    reply.writeNoException();
-                    reply.writeString(contents);
-                    return true;
-                }
-                case TRANSACTION_isConvertibleToFBE: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int resultCode = isConvertibleToFBE() ? 1 : 0;
-                    reply.writeNoException();
-                    reply.writeInt(resultCode);
-                    return true;
-                }
-                case TRANSACTION_resizeSecureContainer: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String id;
-                    id = data.readString();
-                    int sizeMb;
-                    sizeMb = data.readInt();
-                    String key;
-                    key = data.readString();
-                    int resultCode = resizeSecureContainer(id, sizeMb, key);
-                    reply.writeNoException();
-                    reply.writeInt(resultCode);
-                    return true;
-                }
-                case TRANSACTION_lastMaintenance: {
-                    data.enforceInterface(DESCRIPTOR);
-                    long lastMaintenance = lastMaintenance();
-                    reply.writeNoException();
-                    reply.writeLong(lastMaintenance);
-                    return true;
-                }
-                case TRANSACTION_runMaintenance: {
-                    data.enforceInterface(DESCRIPTOR);
-                    runMaintenance();
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_waitForAsecScan: {
-                    data.enforceInterface(DESCRIPTOR);
-                    waitForAsecScan();
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_getDisks: {
-                    data.enforceInterface(DESCRIPTOR);
-                    DiskInfo[] disks = getDisks();
-                    reply.writeNoException();
-                    reply.writeTypedArray(disks, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-                    return true;
-                }
-                case TRANSACTION_getVolumes: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int _flags = data.readInt();
-                    VolumeInfo[] volumes = getVolumes(_flags);
-                    reply.writeNoException();
-                    reply.writeTypedArray(volumes, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-                    return true;
-                }
-                case TRANSACTION_getVolumeRecords: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int _flags = data.readInt();
-                    VolumeRecord[] volumes = getVolumeRecords(_flags);
-                    reply.writeNoException();
-                    reply.writeTypedArray(volumes, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-                    return true;
-                }
-                case TRANSACTION_mount: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String volId = data.readString();
-                    mount(volId);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_unmount: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String volId = data.readString();
-                    unmount(volId);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_format: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String volId = data.readString();
-                    format(volId);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_benchmark: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String volId = data.readString();
-                    long res = benchmark(volId);
-                    reply.writeNoException();
-                    reply.writeLong(res);
-                    return true;
-                }
-                case TRANSACTION_partitionPublic: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String diskId = data.readString();
-                    partitionPublic(diskId);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_partitionPrivate: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String diskId = data.readString();
-                    partitionPrivate(diskId);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_partitionMixed: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String diskId = data.readString();
-                    int ratio = data.readInt();
-                    partitionMixed(diskId, ratio);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_setVolumeNickname: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String volId = data.readString();
-                    String nickname = data.readString();
-                    setVolumeNickname(volId, nickname);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_setVolumeUserFlags: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String volId = data.readString();
-                    int _flags = data.readInt();
-                    int _mask = data.readInt();
-                    setVolumeUserFlags(volId, _flags, _mask);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_forgetVolume: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String fsUuid = data.readString();
-                    forgetVolume(fsUuid);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_forgetAllVolumes: {
-                    data.enforceInterface(DESCRIPTOR);
-                    forgetAllVolumes();
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_setDebugFlags: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int _flags = data.readInt();
-                    int _mask = data.readInt();
-                    setDebugFlags(_flags, _mask);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_getPrimaryStorageUuid: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String volumeUuid = getPrimaryStorageUuid();
-                    reply.writeNoException();
-                    reply.writeString(volumeUuid);
-                    return true;
-                }
-                case TRANSACTION_setPrimaryStorageUuid: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String volumeUuid = data.readString();
-                    IPackageMoveObserver listener = IPackageMoveObserver.Stub.asInterface(
-                            data.readStrongBinder());
-                    setPrimaryStorageUuid(volumeUuid, listener);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_createUserKey: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int userId = data.readInt();
-                    int serialNumber = data.readInt();
-                    boolean ephemeral = data.readInt() != 0;
-                    createUserKey(userId, serialNumber, ephemeral);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_destroyUserKey: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int userId = data.readInt();
-                    destroyUserKey(userId);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_addUserKeyAuth: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int userId = data.readInt();
-                    int serialNumber = data.readInt();
-                    byte[] token = data.createByteArray();
-                    byte[] secret = data.createByteArray();
-                    addUserKeyAuth(userId, serialNumber, token, secret);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_fixateNewestUserKeyAuth: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int userId = data.readInt();
-                    fixateNewestUserKeyAuth(userId);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_unlockUserKey: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int userId = data.readInt();
-                    int serialNumber = data.readInt();
-                    byte[] token = data.createByteArray();
-                    byte[] secret = data.createByteArray();
-                    unlockUserKey(userId, serialNumber, token, secret);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_lockUserKey: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int userId = data.readInt();
-                    lockUserKey(userId);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_isUserKeyUnlocked: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int userId = data.readInt();
-                    boolean result = isUserKeyUnlocked(userId);
-                    reply.writeNoException();
-                    reply.writeInt(result ? 1 : 0);
-                    return true;
-                }
-                case TRANSACTION_prepareUserStorage: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String volumeUuid = data.readString();
-                    int userId = data.readInt();
-                    int serialNumber = data.readInt();
-                    int _flags = data.readInt();
-                    prepareUserStorage(volumeUuid, userId, serialNumber, _flags);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_destroyUserStorage: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String volumeUuid = data.readString();
-                    int userId = data.readInt();
-                    int _flags = data.readInt();
-                    destroyUserStorage(volumeUuid, userId, _flags);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_mountAppFuse: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String name = data.readString();
-                    ParcelFileDescriptor fd = mountAppFuse(name);
-                    reply.writeNoException();
-                    reply.writeParcelable(fd, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-                    return true;
-                }
-            }
-            return super.onTransact(code, data, reply, flags);
-        }
-    }
-
-    /*
-     * Creates a secure container with the specified parameters. Returns an int
-     * consistent with MountServiceResultCode
-     */
-    public int createSecureContainer(String id, int sizeMb, String fstype, String key,
-            int ownerUid, boolean external) throws RemoteException;
-
-    /*
-     * Destroy a secure container, and free up all resources associated with it.
-     * NOTE: Ensure all references are released prior to deleting. Returns an
-     * int consistent with MountServiceResultCode
-     */
-    public int destroySecureContainer(String id, boolean force) throws RemoteException;
-
-    /*
-     * Finalize a container which has just been created and populated. After
-     * finalization, the container is immutable. Returns an int consistent with
-     * MountServiceResultCode
-     */
-    public int finalizeSecureContainer(String id) throws RemoteException;
-
-    /**
-     * Call into MountService by PackageManager to notify that its done
-     * processing the media status update request.
-     */
-    public void finishMediaUpdate() throws RemoteException;
-
-    /**
-     * Format external storage given a mount point. Returns an int consistent
-     * with MountServiceResultCode
-     */
-    public int formatVolume(String mountPoint) throws RemoteException;
-
-    /**
-     * Gets the path to the mounted Opaque Binary Blob (OBB).
-     */
-    public String getMountedObbPath(String rawPath) throws RemoteException;
-
-    /**
-     * Gets an Array of currently known secure container IDs
-     */
-    public String[] getSecureContainerList() throws RemoteException;
-
-    /*
-     * Returns the filesystem path of a mounted secure container.
-     */
-    public String getSecureContainerPath(String id) throws RemoteException;
-
-    /**
-     * Returns an array of pids with open files on the specified path.
-     */
-    public int[] getStorageUsers(String path) throws RemoteException;
-
-    /**
-     * Gets the state of a volume via its mountpoint.
-     */
-    public String getVolumeState(String mountPoint) throws RemoteException;
-
-    /**
-     * Checks whether the specified Opaque Binary Blob (OBB) is mounted
-     * somewhere.
-     */
-    public boolean isObbMounted(String rawPath) throws RemoteException;
-
-    /*
-     * Returns true if the specified container is mounted
-     */
-    public boolean isSecureContainerMounted(String id) throws RemoteException;
-
-    /**
-     * Returns true if a USB mass storage host is connected
-     */
-    public boolean isUsbMassStorageConnected() throws RemoteException;
-
-    /**
-     * Returns true if a USB mass storage host is enabled (media is shared)
-     */
-    public boolean isUsbMassStorageEnabled() throws RemoteException;
-
-    /**
-     * Mounts an Opaque Binary Blob (OBB) with the specified decryption key and
-     * only allows the calling process's UID access to the contents.
-     * MountService will call back to the supplied IObbActionListener to inform
-     * it of the terminal state of the call.
-     */
-    public void mountObb(String rawPath, String canonicalPath, String key,
-            IObbActionListener token, int nonce) throws RemoteException;
-
-    /*
-     * Mount a secure container with the specified key and owner UID. Returns an
-     * int consistent with MountServiceResultCode
-     */
-    public int mountSecureContainer(String id, String key, int ownerUid, boolean readOnly)
-            throws RemoteException;
-
-    /**
-     * Mount external storage at given mount point. Returns an int consistent
-     * with MountServiceResultCode
-     */
-    public int mountVolume(String mountPoint) throws RemoteException;
-
-    /**
-     * Registers an IMountServiceListener for receiving async notifications.
-     */
-    public void registerListener(IMountServiceListener listener) throws RemoteException;
-
-    /*
-     * Rename an unmounted secure container. Returns an int consistent with
-     * MountServiceResultCode
-     */
-    public int renameSecureContainer(String oldId, String newId) throws RemoteException;
-
-    /**
-     * Enables / disables USB mass storage. The caller should check actual
-     * status of enabling/disabling USB mass storage via StorageEventListener.
-     */
-    public void setUsbMassStorageEnabled(boolean enable) throws RemoteException;
-
-    /**
-     * Shuts down the MountService and gracefully unmounts all external media.
-     * Invokes call back once the shutdown is complete.
-     */
-    public void shutdown(IMountShutdownObserver observer) throws RemoteException;
-
-    /**
-     * Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
-     * any program using it will be forcibly killed to unmount the image.
-     * MountService will call back to the supplied IObbActionListener to inform
-     * it of the terminal state of the call.
-     */
-    public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce)
-            throws RemoteException;
-
-    /*
-     * Unount a secure container. Returns an int consistent with
-     * MountServiceResultCode
-     */
-    public int unmountSecureContainer(String id, boolean force) throws RemoteException;
-
-    /**
-     * Safely unmount external storage at given mount point. The unmount is an
-     * asynchronous operation. Applications should register StorageEventListener
-     * for storage related status changes.
-     * @param mountPoint the mount point
-     * @param force whether or not to forcefully unmount it (e.g. even if programs are using this
-     *     data currently)
-     * @param removeEncryption whether or not encryption mapping should be removed from the volume.
-     *     This value implies {@code force}.
-     */
-    public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
-            throws RemoteException;
-
-    /**
-     * Unregisters an IMountServiceListener
-     */
-    public void unregisterListener(IMountServiceListener listener) throws RemoteException;
-
-    /**
-     * Returns whether or not the external storage is emulated.
-     */
-    public boolean isExternalStorageEmulated() throws RemoteException;
-
-    /** The volume is not encrypted. */
-    static final int ENCRYPTION_STATE_NONE = 1;
-    /** The volume has been encrypted succesfully. */
-    static final int ENCRYPTION_STATE_OK = 0;
-    /** The volume is in a bad state.*/
-    static final int ENCRYPTION_STATE_ERROR_UNKNOWN = -1;
-    /** Encryption is incomplete */
-    static final int ENCRYPTION_STATE_ERROR_INCOMPLETE = -2;
-    /** Encryption is incomplete and irrecoverable */
-    static final int ENCRYPTION_STATE_ERROR_INCONSISTENT = -3;
-    /** Underlying data is corrupt */
-    static final int ENCRYPTION_STATE_ERROR_CORRUPT = -4;
-
-    /**
-     * Determines the encryption state of the volume.
-     * @return a numerical value. See {@code ENCRYPTION_STATE_*} for possible
-     * values.
-     * Note that this has been replaced in most cases by the APIs in
-     * StorageManager (see isEncryptable and below)
-     * This is still useful to get the error state when encryption has failed
-     * and CryptKeeper needs to throw up a screen advising the user what to do
-     */
-    public int getEncryptionState() throws RemoteException;
-
-    /**
-     * Decrypts any encrypted volumes.
-     */
-    public int decryptStorage(String password) throws RemoteException;
-
-    /**
-     * Encrypts storage.
-     */
-    public int encryptStorage(int type, String password) throws RemoteException;
-
-    /**
-     * Changes the encryption password.
-     */
-    public int changeEncryptionPassword(int type, String password)
-        throws RemoteException;
-
-    /**
-     * Verify the encryption password against the stored volume.  This method
-     * may only be called by the system process.
-     */
-    public int verifyEncryptionPassword(String password) throws RemoteException;
-
-    /**
-     * Returns list of all mountable volumes.
-     */
-    public StorageVolume[] getVolumeList(int uid, String packageName, int flags) throws RemoteException;
-
-    /**
-     * Gets the path on the filesystem for the ASEC container itself.
-     *
-     * @param cid ASEC container ID
-     * @return path to filesystem or {@code null} if it's not found
-     * @throws RemoteException
-     */
-    public String getSecureContainerFilesystemPath(String cid) throws RemoteException;
-
-    /*
-     * Fix permissions in a container which has just been created and populated.
-     * Returns an int consistent with MountServiceResultCode
-     */
-    public int fixPermissionsSecureContainer(String id, int gid, String filename)
-            throws RemoteException;
-
-    /**
-     * Ensure that all directories along given path exist, creating parent
-     * directories as needed. Validates that given path is absolute and that it
-     * contains no relative "." or ".." paths or symlinks. Also ensures that
-     * path belongs to a volume managed by vold, and that path is either
-     * external storage data or OBB directory belonging to calling app.
-     */
-    public int mkdirs(String callingPkg, String path) throws RemoteException;
-
-    /**
-     * Determines the type of the encryption password
-     * @return PasswordType
-     */
-    public int getPasswordType() throws RemoteException;
-
-    /**
-     * Get password from vold
-     * @return password or empty string
-     */
-    public String getPassword() throws RemoteException;
-
-    /**
-     * Securely clear password from vold
-     */
-    public void clearPassword() throws RemoteException;
-
-    /**
-     * Set a field in the crypto header.
-     * @param field field to set
-     * @param contents contents to set in field
-     */
-    public void setField(String field, String contents) throws RemoteException;
-
-    /**
-     * Gets a field from the crypto header.
-     * @param field field to get
-     * @return contents of field
-     */
-    public String getField(String field) throws RemoteException;
-
-    public boolean isConvertibleToFBE() throws RemoteException;
-
-    public int resizeSecureContainer(String id, int sizeMb, String key) throws RemoteException;
-
-    /**
-     * Report the time of the last maintenance operation such as fstrim.
-     * @return Timestamp of the last maintenance operation, in the
-     *     System.currentTimeMillis() time base
-     * @throws RemoteException
-     */
-    public long lastMaintenance() throws RemoteException;
-
-    /**
-     * Kick off an immediate maintenance operation
-     * @throws RemoteException
-     */
-    public void runMaintenance() throws RemoteException;
-
-    public void waitForAsecScan() throws RemoteException;
-
-    public DiskInfo[] getDisks() throws RemoteException;
-    public VolumeInfo[] getVolumes(int flags) throws RemoteException;
-    public VolumeRecord[] getVolumeRecords(int flags) throws RemoteException;
-
-    public void mount(String volId) throws RemoteException;
-    public void unmount(String volId) throws RemoteException;
-    public void format(String volId) throws RemoteException;
-    public long benchmark(String volId) throws RemoteException;
-
-    public void partitionPublic(String diskId) throws RemoteException;
-    public void partitionPrivate(String diskId) throws RemoteException;
-    public void partitionMixed(String diskId, int ratio) throws RemoteException;
-
-    public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException;
-    public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException;
-    public void forgetVolume(String fsUuid) throws RemoteException;
-    public void forgetAllVolumes() throws RemoteException;
-    public void setDebugFlags(int flags, int mask) throws RemoteException;
-
-    public String getPrimaryStorageUuid() throws RemoteException;
-    public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
-            throws RemoteException;
-
-    public void createUserKey(int userId, int serialNumber, boolean ephemeral)
-            throws RemoteException;
-    public void destroyUserKey(int userId) throws RemoteException;
-    public void addUserKeyAuth(int userId, int serialNumber,
-            byte[] token, byte[] secret) throws RemoteException;
-    public void fixateNewestUserKeyAuth(int userId) throws RemoteException;
-
-    public void unlockUserKey(int userId, int serialNumber,
-            byte[] token, byte[] secret) throws RemoteException;
-    public void lockUserKey(int userId) throws RemoteException;
-    public boolean isUserKeyUnlocked(int userId) throws RemoteException;
-
-    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber,
-            int flags) throws RemoteException;
-    public void destroyUserStorage(String volumeUuid, int userId, int flags) throws RemoteException;
-
-    public ParcelFileDescriptor mountAppFuse(String name) throws RemoteException;
-}
diff --git a/core/java/android/os/storage/IMountServiceListener.aidl b/core/java/android/os/storage/IMountServiceListener.aidl
new file mode 100644
index 0000000..e149978
--- /dev/null
+++ b/core/java/android/os/storage/IMountServiceListener.aidl
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+import android.os.storage.DiskInfo;
+import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+
+/**
+ * Callback class for receiving events from MountService.
+ *
+ * Don't change the existing transaction Ids as they could be used in the native code.
+ * When adding a new method, assign the next available transaction id.
+ *
+ * @hide - Applications should use IStorageEventListener for storage event
+ *       callbacks.
+ */
+oneway interface IMountServiceListener {
+    /**
+     * Detection state of USB Mass Storage has changed
+     *
+     * @param available true if a UMS host is connected.
+     */
+    void onUsbMassStorageConnectionChanged(boolean connected) = 1;
+
+    /**
+     * Storage state has changed.
+     *
+     * @param path The volume mount path.
+     * @param oldState The old state of the volume.
+     * @param newState The new state of the volume. Note: State is one of the
+     *            values returned by Environment.getExternalStorageState()
+     */
+    void onStorageStateChanged(in String path, in String oldState, in String newState) = 2;
+
+    void onVolumeStateChanged(in VolumeInfo vol, int oldState, int newState) = 3;
+
+    void onVolumeRecordChanged(in VolumeRecord rec) = 4;
+
+    void onVolumeForgotten(in String fsUuid) = 5;
+
+    void onDiskScanned(in DiskInfo disk, int volumeCount) = 6;
+
+    void onDiskDestroyed(in DiskInfo disk) = 7;
+
+    /**
+     * Don't change the existing transaction Ids as they could be used in the native code.
+     * When adding a new method, assign the next available transaction id.
+     */
+}
\ No newline at end of file
diff --git a/core/java/android/os/storage/IMountServiceListener.java b/core/java/android/os/storage/IMountServiceListener.java
deleted file mode 100644
index cade9d7..0000000
--- a/core/java/android/os/storage/IMountServiceListener.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os.storage;
-
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.RemoteException;
-
-/**
- * Callback class for receiving events from MountService.
- * 
- * @hide - Applications should use IStorageEventListener for storage event
- *       callbacks.
- */
-public interface IMountServiceListener extends IInterface {
-    /** Local-side IPC implementation stub class. */
-    public static abstract class Stub extends Binder implements IMountServiceListener {
-        private static final String DESCRIPTOR = "IMountServiceListener";
-
-        /** Construct the stub at attach it to the interface. */
-        public Stub() {
-            this.attachInterface(this, DESCRIPTOR);
-        }
-
-        /**
-         * Cast an IBinder object into an IMountServiceListener interface,
-         * generating a proxy if needed.
-         */
-        public static IMountServiceListener asInterface(IBinder obj) {
-            if ((obj == null)) {
-                return null;
-            }
-            IInterface iin = (IInterface) obj.queryLocalInterface(DESCRIPTOR);
-            if (((iin != null) && (iin instanceof IMountServiceListener))) {
-                return ((IMountServiceListener) iin);
-            }
-            return new IMountServiceListener.Stub.Proxy(obj);
-        }
-
-        public IBinder asBinder() {
-            return this;
-        }
-
-        @Override
-        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-                throws RemoteException {
-            switch (code) {
-                case INTERFACE_TRANSACTION: {
-                    reply.writeString(DESCRIPTOR);
-                    return true;
-                }
-                case TRANSACTION_onUsbMassStorageConnectionChanged: {
-                    data.enforceInterface(DESCRIPTOR);
-                    boolean connected;
-                    connected = (0 != data.readInt());
-                    this.onUsbMassStorageConnectionChanged(connected);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_onStorageStateChanged: {
-                    data.enforceInterface(DESCRIPTOR);
-                    final String path = data.readString();
-                    final String oldState = data.readString();
-                    final String newState = data.readString();
-                    this.onStorageStateChanged(path, oldState, newState);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_onVolumeStateChanged: {
-                    data.enforceInterface(DESCRIPTOR);
-                    final VolumeInfo vol = (VolumeInfo) data.readParcelable(null);
-                    final int oldState = data.readInt();
-                    final int newState = data.readInt();
-                    onVolumeStateChanged(vol, oldState, newState);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_onVolumeRecordChanged: {
-                    data.enforceInterface(DESCRIPTOR);
-                    final VolumeRecord rec = (VolumeRecord) data.readParcelable(null);
-                    onVolumeRecordChanged(rec);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_onVolumeForgotten: {
-                    data.enforceInterface(DESCRIPTOR);
-                    final String fsUuid = data.readString();
-                    onVolumeForgotten(fsUuid);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_onDiskScanned: {
-                    data.enforceInterface(DESCRIPTOR);
-                    final DiskInfo disk = (DiskInfo) data.readParcelable(null);
-                    final int volumeCount = data.readInt();
-                    onDiskScanned(disk, volumeCount);
-                    reply.writeNoException();
-                    return true;
-                }
-                case TRANSACTION_onDiskDestroyed: {
-                    data.enforceInterface(DESCRIPTOR);
-                    final DiskInfo disk = (DiskInfo) data.readParcelable(null);
-                    onDiskDestroyed(disk);
-                    reply.writeNoException();
-                    return true;
-                }
-            }
-            return super.onTransact(code, data, reply, flags);
-        }
-
-        private static class Proxy implements IMountServiceListener {
-            private IBinder mRemote;
-
-            Proxy(IBinder remote) {
-                mRemote = remote;
-            }
-
-            public IBinder asBinder() {
-                return mRemote;
-            }
-
-            public String getInterfaceDescriptor() {
-                return DESCRIPTOR;
-            }
-
-            /**
-             * Detection state of USB Mass Storage has changed
-             * 
-             * @param available true if a UMS host is connected.
-             */
-            public void onUsbMassStorageConnectionChanged(boolean connected) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(((connected) ? (1) : (0)));
-                    mRemote.transact(Stub.TRANSACTION_onUsbMassStorageConnectionChanged, _data,
-                            _reply, android.os.IBinder.FLAG_ONEWAY);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            /**
-             * Storage state has changed.
-             * 
-             * @param path The volume mount path.
-             * @param oldState The old state of the volume.
-             * @param newState The new state of the volume. Note: State is one
-             *            of the values returned by
-             *            Environment.getExternalStorageState()
-             */
-            public void onStorageStateChanged(String path, String oldState, String newState)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(path);
-                    _data.writeString(oldState);
-                    _data.writeString(newState);
-                    mRemote.transact(Stub.TRANSACTION_onStorageStateChanged, _data, _reply,
-                            android.os.IBinder.FLAG_ONEWAY);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeParcelable(vol, 0);
-                    _data.writeInt(oldState);
-                    _data.writeInt(newState);
-                    mRemote.transact(Stub.TRANSACTION_onVolumeStateChanged, _data, _reply,
-                            android.os.IBinder.FLAG_ONEWAY);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void onVolumeRecordChanged(VolumeRecord rec) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeParcelable(rec, 0);
-                    mRemote.transact(Stub.TRANSACTION_onVolumeRecordChanged, _data, _reply,
-                            android.os.IBinder.FLAG_ONEWAY);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void onVolumeForgotten(String fsUuid) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(fsUuid);
-                    mRemote.transact(Stub.TRANSACTION_onVolumeForgotten, _data, _reply,
-                            android.os.IBinder.FLAG_ONEWAY);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void onDiskScanned(DiskInfo disk, int volumeCount) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeParcelable(disk, 0);
-                    _data.writeInt(volumeCount);
-                    mRemote.transact(Stub.TRANSACTION_onDiskScanned, _data, _reply,
-                            android.os.IBinder.FLAG_ONEWAY);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-
-            @Override
-            public void onDiskDestroyed(DiskInfo disk) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeParcelable(disk, 0);
-                    mRemote.transact(Stub.TRANSACTION_onDiskDestroyed, _data, _reply,
-                            android.os.IBinder.FLAG_ONEWAY);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-        }
-
-        static final int TRANSACTION_onUsbMassStorageConnectionChanged = (IBinder.FIRST_CALL_TRANSACTION + 0);
-        static final int TRANSACTION_onStorageStateChanged = (IBinder.FIRST_CALL_TRANSACTION + 1);
-        static final int TRANSACTION_onVolumeStateChanged = (IBinder.FIRST_CALL_TRANSACTION + 2);
-        static final int TRANSACTION_onVolumeRecordChanged = (IBinder.FIRST_CALL_TRANSACTION + 3);
-        static final int TRANSACTION_onVolumeForgotten = (IBinder.FIRST_CALL_TRANSACTION + 4);
-        static final int TRANSACTION_onDiskScanned = (IBinder.FIRST_CALL_TRANSACTION + 5);
-        static final int TRANSACTION_onDiskDestroyed = (IBinder.FIRST_CALL_TRANSACTION + 6);
-    }
-
-    /**
-     * Detection state of USB Mass Storage has changed
-     * 
-     * @param available true if a UMS host is connected.
-     */
-    public void onUsbMassStorageConnectionChanged(boolean connected) throws RemoteException;
-
-    /**
-     * Storage state has changed.
-     * 
-     * @param path The volume mount path.
-     * @param oldState The old state of the volume.
-     * @param newState The new state of the volume. Note: State is one of the
-     *            values returned by Environment.getExternalStorageState()
-     */
-    public void onStorageStateChanged(String path, String oldState, String newState)
-            throws RemoteException;
-
-    public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState)
-            throws RemoteException;
-    public void onVolumeRecordChanged(VolumeRecord rec) throws RemoteException;
-    public void onVolumeForgotten(String fsUuid) throws RemoteException;
-
-    public void onDiskScanned(DiskInfo disk, int volumeCount) throws RemoteException;
-
-    public void onDiskDestroyed(DiskInfo disk) throws RemoteException;
-}
diff --git a/core/java/android/os/storage/IMountShutdownObserver.aidl b/core/java/android/os/storage/IMountShutdownObserver.aidl
new file mode 100644
index 0000000..3353bc5
--- /dev/null
+++ b/core/java/android/os/storage/IMountShutdownObserver.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+/**
+ * Callback class for receiving events related to shutdown.
+ *
+ * Don't change the existing transaction Ids as they could be used in the native code.
+ * When adding a new method, assign the next available transaction id.
+ *
+ * @hide - For internal consumption only.
+ */
+interface IMountShutdownObserver {
+    /**
+     * This method is called when the shutdown of MountService completed.
+     *
+     * @param statusCode indicates success or failure of the shutdown.
+     */
+    void onShutDownComplete(int statusCode) = 1;
+
+    /**
+     * Don't change the existing transaction Ids as they could be used in the native code.
+     * When adding a new method, assign the next available transaction id.
+     */
+}
\ No newline at end of file
diff --git a/core/java/android/os/storage/IMountShutdownObserver.java b/core/java/android/os/storage/IMountShutdownObserver.java
deleted file mode 100644
index d946e1a..0000000
--- a/core/java/android/os/storage/IMountShutdownObserver.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os.storage;
-
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.RemoteException;
-
-/**
- * Callback class for receiving events related to shutdown.
- * 
- * @hide - For internal consumption only.
- */
-public interface IMountShutdownObserver extends IInterface {
-    /** Local-side IPC implementation stub class. */
-    public static abstract class Stub extends Binder implements IMountShutdownObserver {
-        private static final java.lang.String DESCRIPTOR = "IMountShutdownObserver";
-
-        /** Construct the stub at attach it to the interface. */
-        public Stub() {
-            this.attachInterface(this, DESCRIPTOR);
-        }
-
-        /**
-         * Cast an IBinder object into an IMountShutdownObserver interface,
-         * generating a proxy if needed.
-         */
-        public static IMountShutdownObserver asInterface(IBinder obj) {
-            if ((obj == null)) {
-                return null;
-            }
-            IInterface iin = (IInterface) obj.queryLocalInterface(DESCRIPTOR);
-            if (((iin != null) && (iin instanceof IMountShutdownObserver))) {
-                return ((IMountShutdownObserver) iin);
-            }
-            return new IMountShutdownObserver.Stub.Proxy(obj);
-        }
-
-        public IBinder asBinder() {
-            return this;
-        }
-
-        @Override
-        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-                throws RemoteException {
-            switch (code) {
-                case INTERFACE_TRANSACTION: {
-                    reply.writeString(DESCRIPTOR);
-                    return true;
-                }
-                case TRANSACTION_onShutDownComplete: {
-                    data.enforceInterface(DESCRIPTOR);
-                    int statusCode;
-                    statusCode = data.readInt();
-                    this.onShutDownComplete(statusCode);
-                    reply.writeNoException();
-                    return true;
-                }
-            }
-            return super.onTransact(code, data, reply, flags);
-        }
-
-        private static class Proxy implements IMountShutdownObserver {
-            private IBinder mRemote;
-
-            Proxy(IBinder remote) {
-                mRemote = remote;
-            }
-
-            public IBinder asBinder() {
-                return mRemote;
-            }
-
-            public java.lang.String getInterfaceDescriptor() {
-                return DESCRIPTOR;
-            }
-
-            /**
-             * This method is called when the shutdown of MountService
-             * completed.
-             * 
-             * @param statusCode indicates success or failure of the shutdown.
-             */
-            public void onShutDownComplete(int statusCode) throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(statusCode);
-                    mRemote.transact(Stub.TRANSACTION_onShutDownComplete, _data, _reply, 0);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-        }
-
-        static final int TRANSACTION_onShutDownComplete = (IBinder.FIRST_CALL_TRANSACTION + 0);
-    }
-
-    /**
-     * This method is called when the shutdown of MountService completed.
-     * 
-     * @param statusCode indicates success or failure of the shutdown.
-     */
-    public void onShutDownComplete(int statusCode) throws RemoteException;
-}
diff --git a/core/java/android/os/storage/IObbActionListener.aidl b/core/java/android/os/storage/IObbActionListener.aidl
new file mode 100644
index 0000000..71e6aaf
--- /dev/null
+++ b/core/java/android/os/storage/IObbActionListener.aidl
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+/**
+ * Callback class for receiving events from MountService about Opaque Binary
+ * Blobs (OBBs).
+ *
+ * Don't change the existing transaction Ids as they could be used in the native code.
+ * When adding a new method, assign the next available transaction id.
+ *
+ * @hide - Applications should use StorageManager to interact with OBBs.
+ */
+oneway interface IObbActionListener {
+    /**
+     * Return from an OBB action result.
+     *
+     * @param filename the path to the OBB the operation was performed on
+     * @param nonce identifier that is meaningful to the receiver
+     * @param status status code as defined in {@link OnObbStateChangeListener}
+     */
+    void onObbResult(in String filename, int nonce, int status) = 1;
+
+    /**
+     * Don't change the existing transaction Ids as they could be used in the native code.
+     * When adding a new method, assign the next available transaction id.
+     */
+}
\ No newline at end of file
diff --git a/core/java/android/os/storage/IObbActionListener.java b/core/java/android/os/storage/IObbActionListener.java
deleted file mode 100644
index 35da4b0..0000000
--- a/core/java/android/os/storage/IObbActionListener.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os.storage;
-
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.RemoteException;
-
-/**
- * Callback class for receiving events from MountService about Opaque Binary
- * Blobs (OBBs).
- * 
- * @hide - Applications should use StorageManager to interact with OBBs.
- */
-public interface IObbActionListener extends IInterface {
-    /** Local-side IPC implementation stub class. */
-    public static abstract class Stub extends Binder implements IObbActionListener {
-        private static final String DESCRIPTOR = "IObbActionListener";
-
-        /** Construct the stub at attach it to the interface. */
-        public Stub() {
-            this.attachInterface(this, DESCRIPTOR);
-        }
-
-        /**
-         * Cast an IBinder object into an IObbActionListener interface,
-         * generating a proxy if needed.
-         */
-        public static IObbActionListener asInterface(IBinder obj) {
-            if ((obj == null)) {
-                return null;
-            }
-            IInterface iin = (IInterface) obj.queryLocalInterface(DESCRIPTOR);
-            if (((iin != null) && (iin instanceof IObbActionListener))) {
-                return ((IObbActionListener) iin);
-            }
-            return new IObbActionListener.Stub.Proxy(obj);
-        }
-
-        public IBinder asBinder() {
-            return this;
-        }
-
-        @Override
-        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-                throws RemoteException {
-            switch (code) {
-                case INTERFACE_TRANSACTION: {
-                    reply.writeString(DESCRIPTOR);
-                    return true;
-                }
-                case TRANSACTION_onObbResult: {
-                    data.enforceInterface(DESCRIPTOR);
-                    String filename;
-                    filename = data.readString();
-                    int nonce;
-                    nonce = data.readInt();
-                    int status;
-                    status = data.readInt();
-                    this.onObbResult(filename, nonce, status);
-                    reply.writeNoException();
-                    return true;
-                }
-            }
-            return super.onTransact(code, data, reply, flags);
-        }
-
-        private static class Proxy implements IObbActionListener {
-            private IBinder mRemote;
-
-            Proxy(IBinder remote) {
-                mRemote = remote;
-            }
-
-            public IBinder asBinder() {
-                return mRemote;
-            }
-
-            public String getInterfaceDescriptor() {
-                return DESCRIPTOR;
-            }
-
-            /**
-             * Return from an OBB action result.
-             * 
-             * @param filename the path to the OBB the operation was performed
-             *            on
-             * @param returnCode status of the operation
-             */
-            public void onObbResult(String filename, int nonce, int status)
-                    throws RemoteException {
-                Parcel _data = Parcel.obtain();
-                Parcel _reply = Parcel.obtain();
-                try {
-                    _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(filename);
-                    _data.writeInt(nonce);
-                    _data.writeInt(status);
-                    mRemote.transact(Stub.TRANSACTION_onObbResult, _data, _reply,
-                            android.os.IBinder.FLAG_ONEWAY);
-                    _reply.readException();
-                } finally {
-                    _reply.recycle();
-                    _data.recycle();
-                }
-            }
-        }
-
-        static final int TRANSACTION_onObbResult = (IBinder.FIRST_CALL_TRANSACTION + 0);
-    }
-
-    /**
-     * Return from an OBB action result.
-     * 
-     * @param filename the path to the OBB the operation was performed on
-     * @param nonce identifier that is meaningful to the receiver
-     * @param status status code as defined in {@link OnObbStateChangeListener}
-     */
-    public void onObbResult(String filename, int nonce, int status) throws RemoteException;
-}
diff --git a/core/java/android/os/storage/MountServiceListener.java b/core/java/android/os/storage/MountServiceListener.java
deleted file mode 100644
index bebb3f6..0000000
--- a/core/java/android/os/storage/MountServiceListener.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os.storage;
-
-/**
- * Callback class for receiving progress reports during a restore operation.  These
- * methods will all be called on your application's main thread.
- * @hide
- */
-public abstract class MountServiceListener {
-    /**
-     * USB Mass storage connection state has changed.
-     *
-     * @param connected True if UMS is connected.
-     */
-    void onUsbMassStorageConnectionChanged(boolean connected) {
-    }
-
-    /**
-     *  Storage state has changed.
-     *
-     * @param path The volume mount path.
-     * @param oldState The old state of the volume.
-     * @param newState The new state of the volume.
-     *
-     * @Note: State is one of the values returned by Environment.getExternalStorageState()
-     */
-    void onStorageStateChange(String path, String oldState, String newState) {
-    }
-}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 1a78fe7..1942fde 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -41,6 +41,7 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -133,6 +134,24 @@
     /** {@hide} */
     public static final int FLAG_INCLUDE_INVISIBLE = 1 << 10;
 
+    /** @hide The volume is not encrypted. */
+    public static final int ENCRYPTION_STATE_NONE = 1;
+
+    /** @hide The volume has been encrypted succesfully. */
+    public static final int ENCRYPTION_STATE_OK = 0;
+
+    /** @hide The volume is in a bad state.*/
+    public static final int ENCRYPTION_STATE_ERROR_UNKNOWN = -1;
+
+    /** @hide Encryption is incomplete */
+    public static final int ENCRYPTION_STATE_ERROR_INCOMPLETE = -2;
+
+    /** @hide Encryption is incomplete and irrecoverable */
+    public static final int ENCRYPTION_STATE_ERROR_INCONSISTENT = -3;
+
+    /** @hide Underlying data is corrupt */
+    public static final int ENCRYPTION_STATE_ERROR_CORRUPT = -4;
+
     private static volatile IMountService sMountService = null;
 
     // TODO: the location of the primary storage block varies from device to device, so we need to
@@ -929,22 +948,29 @@
     }
 
     /** {@hide} */
-    public long getPrimaryStorageSize() {
+    public static Pair<String, Long> getPrimaryStoragePathAndSize() {
         for (String path : INTERNAL_STORAGE_SIZE_PATHS) {
             final long numberBlocks = readLong(path);
             if (numberBlocks > 0) {
-                return numberBlocks * INTERNAL_STORAGE_SECTOR_SIZE;
+                return new Pair<>(path, Long.valueOf(numberBlocks * INTERNAL_STORAGE_SECTOR_SIZE));
             }
         }
-        return 0;
+        return null;
     }
 
-    private long readLong(String path) {
+
+    /** {@hide} */
+    public long getPrimaryStorageSize() {
+        final Pair<String, Long> pair = getPrimaryStoragePathAndSize();
+        return pair == null ? 0 : pair.second.longValue();
+    }
+
+    private static long readLong(String path) {
         try (final FileInputStream fis = new FileInputStream(path);
                 final BufferedReader reader = new BufferedReader(new InputStreamReader(fis));) {
             return Long.parseLong(reader.readLine());
         } catch (Exception e) {
-            Slog.w(TAG, "Could not read " + path, e);
+            Slog.w(TAG, "readLong(): could not read " + path + ": " + e);
             return 0;
         }
     }
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index e399be0..7b63b62 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -442,7 +442,6 @@
         // note that docsui treats this as *force* show advanced. So sending
         // false permits advanced to be shown based on user preferences.
         intent.putExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, isPrimary());
-        intent.putExtra(DocumentsContract.EXTRA_FANCY_FEATURES, true);
         return intent;
     }
 
diff --git a/core/java/android/os/storage/VolumeRecord.aidl b/core/java/android/os/storage/VolumeRecord.aidl
new file mode 100644
index 0000000..27c4010
--- /dev/null
+++ b/core/java/android/os/storage/VolumeRecord.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+/** @hide */
+parcelable VolumeRecord;
\ No newline at end of file
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index a858324..20c7073 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -103,9 +103,6 @@
     public static final String EXTRA_SHOW_ADVANCED = "android.content.extra.SHOW_ADVANCED";
 
     /** {@hide} */
-    public static final String EXTRA_FANCY_FEATURES = "android.content.extra.FANCY";
-
-    /** {@hide} */
     public static final String EXTRA_TARGET_URI = "android.content.extra.TARGET_URI";
 
     /**
@@ -377,19 +374,6 @@
         public static final int FLAG_SUPPORTS_REMOVE = 1 << 10;
 
         /**
-         * Flag indicating that a document is an archive, and it's contents can be
-         * obtained via {@link DocumentsProvider#queryChildDocuments}.
-         * <p>
-         * The <em>provider</em> support library offers utility classes to add common
-         * archive support.
-         *
-         * @see #COLUMN_FLAGS
-         * @see DocumentsProvider#queryChildDocuments(String, String[], String)
-         * @hide
-         */
-        public static final int FLAG_ARCHIVE = 1 << 15;
-
-        /**
          * Flag indicating that a document is not complete, likely its
          * contents are being downloaded. Partial files cannot be opened,
          * copied, moved in the UI. But they can be deleted and retried
@@ -1425,7 +1409,7 @@
          * @param path the list of document ids from the parent document at
          *          position 0 to the child document.
          */
-        public Path(String rootId, List<String> path) {
+        public Path(@Nullable String rootId, List<String> path) {
             checkCollectionNotEmpty(path, "path");
             checkCollectionElementsNotNull(path, "path");
 
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index d75781b..4256484 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -927,14 +927,20 @@
                     ? DocumentsContract.getTreeDocumentId(documentUri)
                     : null;
 
-            final Path path = findPath(documentId, parentDocumentId);
+            Path path = findPath(documentId, parentDocumentId);
 
             // Ensure provider doesn't leak information to unprivileged callers.
-            if (isTreeUri
-                    && (path.getRootId() != null
-                        || !Objects.equals(path.getPath().get(0), parentDocumentId))) {
-                throw new IllegalStateException(
-                        "Provider returns an invalid result for findPath.");
+            if (isTreeUri) {
+                if (!Objects.equals(path.getPath().get(0), parentDocumentId)) {
+                    Log.wtf(TAG, "Provider doesn't return path from the tree root. Expected: "
+                            + parentDocumentId + " found: " + path.getPath().get(0));
+                }
+
+                if (path.getRootId() != null) {
+                    Log.wtf(TAG, "Provider returns root id :"
+                            + path.getRootId() + " unexpectedly. Erase root id.");
+                    path = new Path(null, path.getPath());
+                }
             }
 
             out.putParcelable(DocumentsContract.EXTRA_RESULT, path);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 875b9af..68b7b3a 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6001,6 +6001,12 @@
         public static final String DOZE_ENABLED = "doze_enabled";
 
         /**
+         * Whether doze should be always on.
+         * @hide
+         */
+        public static final String DOZE_ALWAYS_ON = "doze_always_on";
+
+        /**
          * Whether the device should pulse on pick up gesture.
          * @hide
          */
@@ -6933,6 +6939,12 @@
         public static final String DOCK_SOUNDS_ENABLED = "dock_sounds_enabled";
 
         /**
+         * Whether to play a sound for dock events, only when an accessibility service is on.
+         * @hide
+         */
+        public static final String DOCK_SOUNDS_ENABLED_WHEN_ACCESSIBILITY = "dock_sounds_enabled_when_accessbility";
+
+        /**
          * URI for the "device locked" (keyguard shown) sound.
          * @hide
          */
@@ -7226,6 +7238,13 @@
         */
        public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
 
+        /**
+         * Size of the event buffer for IP connectivity metrics.
+         * @hide
+         */
+        public static final String CONNECTIVITY_METRICS_BUFFER_SIZE =
+              "connectivity_metrics_buffer_size";
+
        /** {@hide} */
        public static final String NETSTATS_ENABLED = "netstats_enabled";
        /** {@hide} */
@@ -8274,6 +8293,9 @@
         /** {@hide} */
         public static final String
                 BLUETOOTH_SAP_PRIORITY_PREFIX = "bluetooth_sap_priority_";
+        /** {@hide} */
+        public static final String
+                BLUETOOTH_PAN_PRIORITY_PREFIX = "bluetooth_pan_priority_";
 
         /**
          * Device Idle (Doze) specific settings.
@@ -8451,6 +8473,14 @@
         }
 
         /**
+         * Get the key that retrieves a bluetooth pan client priority.
+         * @hide
+         */
+        public static final String getBluetoothPanPriorityKey(String address) {
+            return BLUETOOTH_PAN_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT);
+        }
+
+        /**
          * Get the key that retrieves a bluetooth map priority.
          * @hide
          */
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 06d87f8..64f0222 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -232,8 +232,7 @@
                         "Wallpapers do not support keep screen on");
             }
 
-            @Override
-            public Canvas lockCanvas() {
+            private void prepareToDraw() {
                 if (mDisplayState == Display.STATE_DOZE
                         || mDisplayState == Display.STATE_DOZE_SUSPEND) {
                     try {
@@ -242,8 +241,25 @@
                         // System server died, can be ignored.
                     }
                 }
+            }
+
+            @Override
+            public Canvas lockCanvas() {
+                prepareToDraw();
                 return super.lockCanvas();
             }
+
+            @Override
+            public Canvas lockCanvas(Rect dirty) {
+                prepareToDraw();
+                return super.lockCanvas(dirty);
+            }
+
+            @Override
+            public Canvas lockHardwareCanvas() {
+                prepareToDraw();
+                return super.lockHardwareCanvas();
+            }
         };
 
         final class WallpaperInputEventReceiver extends InputEventReceiver {
diff --git a/core/java/android/util/Half.java b/core/java/android/util/Half.java
new file mode 100644
index 0000000..f4eb132
--- /dev/null
+++ b/core/java/android/util/Half.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ * <p>Half is a utility class to manipulate half-precision 16-bit
+ * <a href="https://en.wikipedia.org/wiki/Half-precision_floating-point_format">IEEE 754</a>
+ * floating point data types (also called fp16 or binary16). A half-precision
+ * float is stored in a short data type. A half-precision float can be
+ * created from or converted to single-precision floats.</p>
+ *
+ * <p>The IEEE 754 standard specifies an fp16 as having the following format:</p>
+ * <ul>
+ * <li>Sign bit: 1 bit</li>
+ * <li>Exponent width: 5 bits</li>
+ * <li>Mantissa: 10 bits</li>
+ * </ul>
+ *
+ * <p>The format is laid out thusly:</p>
+ * <pre>
+ * 1   11111   1111111111
+ * ^   --^--   -----^----
+ * sign  |          |_______ mantissa
+ *       |
+ *       -- exponent
+ * </pre>
+ *
+ * @hide
+ */
+public final class Half {
+    /**
+     * The number of bits used to represent a half-precision float value.
+     */
+    public static final int SIZE = 16;
+
+    /**
+     * Epsilon is the difference between 1.0 and the next value representable
+     * by a half-precision floating-point.
+     */
+    public static final short EPSILON            = (short) 0x1400;
+    /**
+     * Smallest negative value a half-precision float may have.
+     */
+    public static final short LOWEST_VALUE       = (short) 0xfbff;
+    /**
+     * Maximum exponent a finite half-precision float may have.
+     */
+    public static final short MAX_EXPONENT       = 15;
+    /**
+     * Maximum positive finite value a half-precision float may have.
+     */
+    public static final short MAX_VALUE          = (short) 0x7bff;
+    /**
+     * Minimum exponent a normalized half-precision float may have.
+     */
+    public static final short MIN_EXPONENT       = -14;
+    /**
+     * Smallest positive normal value a half-precision float may have.
+     */
+    public static final short MIN_NORMAL         = (short) 0x0400;
+    /**
+     * Smallest positive non-zero value a half-precision float may have.
+     */
+    public static final short MIN_VALUE          = (short) 0x0001;
+    /**
+     * A Not-a-Number representation of a half-precision float.
+     */
+    public static final short NaN                = (short) 0x7e00;
+    /**
+     * Negative infinity of type half-precision float.
+     */
+    public static final short NEGATIVE_INFINITY  = (short) 0xfc00;
+    /**
+     * Negative 0 of type half-precision float.
+     */
+    public static final short NEGATIVE_ZERO      = (short) 0x8000;
+    /**
+     * Positive infinity of type half-precision float.
+     */
+    public static final short POSITIVE_INFINITY  = (short) 0x7c00;
+    /**
+     * Positive 0 of type half-precision float.
+     */
+    public static final short POSITIVE_ZERO      = (short) 0x0000;
+
+    private static final int FP16_SIGN_SHIFT     = 15;
+    private static final int FP16_EXPONENT_SHIFT = 10;
+    private static final int FP16_EXPONENT_MASK  = 0x1f;
+    private static final int FP16_MANTISSA_MASK  = 0x3ff;
+    private static final int FP16_EXPONENT_BIAS  = 15;
+
+    private static final int FP32_SIGN_SHIFT     = 31;
+    private static final int FP32_EXPONENT_SHIFT = 23;
+    private static final int FP32_EXPONENT_MASK  = 0xff;
+    private static final int FP32_MANTISSA_MASK  = 0x7fffff;
+    private static final int FP32_EXPONENT_BIAS  = 127;
+
+    private static final int   FP32_DENORMAL_MAGIC = 126 << 23;
+    private static final float FP32_DENORMAL_FLOAT =
+            Float.intBitsToFloat(FP32_DENORMAL_MAGIC);
+
+    private Half() {
+    }
+
+    /**
+     * Returns the sign of the specified half-precision float.
+     *
+     * @param h A half-precision float value
+     * @return 1 if the value is positive, -1 if the value is negative
+     */
+    public static int getSign(short h) {
+        return (h >>> FP16_SIGN_SHIFT) == 0 ? 1 : -1;
+    }
+
+    /**
+     * Returns the unbiased exponent used in the representation of
+     * the specified  half-precision float value. if the value is NaN
+     * or infinite, this* method returns {@link #MAX_EXPONENT} + 1.
+     * If the argument is* 0 or denormal, this method returns
+     * {@link #MIN_EXPONENT} - 1.
+     *
+     * @param h A half-precision float value
+     * @return The unbiased exponent of the specified value
+     */
+    public static int getExponent(short h) {
+        return ((h >>> FP16_EXPONENT_SHIFT) & FP16_EXPONENT_MASK) - FP16_EXPONENT_BIAS;
+    }
+
+    /**
+     * Returns the mantissa, or significand, used in the representation
+     * of the specified half-precision float value.
+     *
+     * @param h A half-precision float value
+     * @return The mantissa, or significand, of the specified vlaue
+     */
+    public static int getMantissa(short h) {
+        return h & FP16_MANTISSA_MASK;
+    }
+
+    /**
+     * Returns true if the specified half-precision float value represents
+     * infinity, false otherwise.
+     *
+     * @param h A half-precision float value
+     * @return true if the value is positive infinity or negative infinity,
+     *         false otherwise
+     */
+    public static boolean isInfinite(short h) {
+        int e = (h >>> FP16_EXPONENT_SHIFT) & FP16_EXPONENT_MASK;
+        int m = (h                        ) & FP16_MANTISSA_MASK;
+        return e == 0x1f && m == 0;
+    }
+
+    /**
+     * Returns true if the specified half-precision float value represents
+     * a Not-a-Number, false otherwise.
+     *
+     * @param h A half-precision float value
+     * @return true if the value is a NaN, false otherwise
+     */
+    public static boolean isNaN(short h) {
+        int e = (h >>> FP16_EXPONENT_SHIFT) & FP16_EXPONENT_MASK;
+        int m = (h                        ) & FP16_MANTISSA_MASK;
+        return e == 0x1f && m != 0;
+    }
+
+    /**
+     * <p>Converts the specified half-precision float value into a
+     * single-precision float value with the following special cases:</p>
+     * <ul>
+     * <li>If the input is {@link #NaN}, the returned* value is {@link Float#NaN}</li>
+     * <li>If the input is {@link #POSITIVE_INFINITY} or
+     * {@link #NEGATIVE_INFINITY}, the returned value is respectively
+     * {@link Float#POSITIVE_INFINITY} or {@link Float#NEGATIVE_INFINITY}</li>
+     * <li>If the input is 0 (positive or negative), the returned value is +/-0.0f</li>
+     * <li>Otherwise, the returned value is a normalized single-precision float value</li>
+     * </ul>
+     *
+     * @param h The half-precision float value to convert to single-precision
+     * @return A normalized single-precision float value
+     */
+    public static float toFloat(short h) {
+        int bits = h & 0xffff;
+        int s = (bits >>> FP16_SIGN_SHIFT    );
+        int e = (bits >>> FP16_EXPONENT_SHIFT) & FP16_EXPONENT_MASK;
+        int m = (bits                        ) & FP16_MANTISSA_MASK;
+
+        int outE = 0;
+        int outM = 0;
+
+        if (e == 0) { // Denormal or 0
+            if (m != 0) {
+                // Convert denorm fp16 into normalized fp32
+                float o = Float.intBitsToFloat(FP32_DENORMAL_MAGIC + m);
+                o -= FP32_DENORMAL_FLOAT;
+                return s == 0 ? o : -o;
+            }
+        } else {
+            outM = m << 13;
+            if (e == 0x1f) { // Infinite or NaN
+                outE = 0xff;
+            } else {
+                outE = e - FP16_EXPONENT_BIAS + FP32_EXPONENT_BIAS;
+            }
+        }
+
+        int out = (s << FP32_SIGN_SHIFT) | (outE << FP32_EXPONENT_SHIFT) | outM;
+        return Float.intBitsToFloat(out);
+    }
+
+    /**
+     * <p>Converts the specified single-precision float value into a
+     * half-precision float value with the following special cases:</p>
+     * <ul>
+     * <li>If the input is NaN (see {@link Float#isNaN(float)}), the returned
+     * value is {@link #NaN}</li>
+     * <li>If the input is {@link Float#POSITIVE_INFINITY} or
+     * {@link Float#NEGATIVE_INFINITY}, the returned value is respectively
+     * {@link #POSITIVE_INFINITY} or {@link #NEGATIVE_INFINITY}</li>
+     * <li>If the input is 0 (positive or negative), the returned value is
+     * {@link #POSITIVE_ZERO} or {@link #NEGATIVE_ZERO}</li>
+     * <li>If the input is a less than {@link #MIN_VALUE}, the returned value
+     * is flushed to {@link #POSITIVE_ZERO} or {@link #NEGATIVE_ZERO}</li>
+     * <li>If the input is a less than {@link #MIN_NORMAL}, the returned value
+     * is a denorm half-precision float</li>
+     * <li>Otherwise, the returned value is rounded to the nearest
+     * representable half-precision float value</li>
+     * </ul>
+     *
+     * @param f The single-precision float value to convert to half-precision
+     * @return A half-precision float value
+     */
+    @SuppressWarnings("StatementWithEmptyBody")
+    public static short valueOf(float f) {
+        int bits = Float.floatToRawIntBits(f);
+        int s = (bits >>> FP32_SIGN_SHIFT    );
+        int e = (bits >>> FP32_EXPONENT_SHIFT) & FP32_EXPONENT_MASK;
+        int m = (bits                        ) & FP32_MANTISSA_MASK;
+
+        int outE = 0;
+        int outM = 0;
+
+        if (e == 0xff) { // Infinite or NaN
+            outE = 0x1f;
+            outM = m != 0 ? 0x200 : 0;
+        } else {
+            e = e - FP32_EXPONENT_BIAS + FP16_EXPONENT_BIAS;
+            if (e >= 0x1f) { // Overflow
+                outE = 0x31;
+            } else if (e <= 0) { // Underflow
+                if (e < -10) {
+                    // The absolute fp32 value is less than MIN_VALUE, flush to +/-0
+                } else {
+                    // The fp32 value is a normalized float less than MIN_NORMAL,
+                    // we convert to a denorm fp16
+                    m = (m | 0x800000) >> (1 - e);
+                    if ((m & 0x1000) != 0) m += 0x2000;
+                    outM = m >> 13;
+                }
+            } else {
+                outE = e;
+                outM = m >> 13;
+                if ((m & 0x1000) != 0) {
+                    // Round to nearest "0.5" up
+                    int out = (outE << FP16_EXPONENT_SHIFT) | outM;
+                    out++;
+                    out |= (s << FP16_SIGN_SHIFT);
+                    return (short) out;
+                }
+            }
+        }
+
+        int out = (s << FP16_SIGN_SHIFT) | (outE << FP16_EXPONENT_SHIFT) | outM;
+        return (short) out;
+    }
+
+    /**
+     * Returns a string representation of the specified half-precision
+     * float value. Calling this method is equivalent to calling
+     * <code>Float.toString(toFloat(h))</code>. See {@link Float#toString(float)}
+     * for more information on the format of the string representation.
+     *
+     * @param h A half-precision float value
+     * @return A string representation of the specified value
+     */
+    public static String toString(short h) {
+        return Float.toString(toFloat(h));
+    }
+
+    /**
+     * <p>Returns a hexadecimal string representation of the specified half-precision
+     * float value. If the value is a NaN, the result is <code>"NaN"</code>,
+     * otherwise the result follows this format:</p>
+     * <ul>
+     * <li>If the sign is positive, no sign character appears in the result</li>
+     * <li>If the sign is negative, the first character is <code>'-'</code></li>
+     * <li>If the value is inifinity, the string is <code>"Infinity"</code></li>
+     * <li>If the value is 0, the string is <code>"0x0.0p0"</code></li>
+     * <li>If the value has a normalized representation, the exponent and
+     * mantissa are represented in the string in two fields. The mantissa starts
+     * with <code>"0x1."</code> followed by its lowercase hexadecimal
+     * representation. Trailing zeroes are removed unless all digits are 0, then
+     * a single zero is used. The mantissa representation is followed by the
+     * exponent, represented by <code>"p"</code>, itself followed by a decimal
+     * string of the unbiased exponent</li>
+     * <li>If the value has a denormal representation, the mantissa starts
+     * with <code>"0x0."</code> followed by its lowercase hexadecimal
+     * representation. Trailing zeroes are removed unless all digits are 0, then
+     * a single zero is used. The mantissa representation is followed by the
+     * exponent, represented by <code>"p-14"</code></li>
+     * </ul>
+     *
+     * @param h A half-precision float value
+     * @return A hexadecimal string representation of the specified value
+     */
+    public static String toHexString(short h) {
+        StringBuilder o = new StringBuilder();
+
+        int bits = h & 0xffff;
+        int s = (bits >>> FP16_SIGN_SHIFT    );
+        int e = (bits >>> FP16_EXPONENT_SHIFT) & FP16_EXPONENT_MASK;
+        int m = (bits                        ) & FP16_MANTISSA_MASK;
+
+        if (e == 0x1f) { // Infinite or NaN
+            if (m == 0) {
+                if (s == 1) o.append('-');
+                o.append("Infinity");
+            } else {
+                o.append("NaN");
+            }
+        } else {
+            if (s == 1) o.append('-');
+            if (e == 0) {
+                if (m == 0) {
+                    o.append("0x0.0p0");
+                } else {
+                    o.append("0x0.");
+                    String mantissa = Integer.toHexString(m);
+                    o.append(mantissa.replaceFirst("0{2,}$", ""));
+                    o.append("p-14");
+                }
+            } else {
+                o.append("0x1.");
+                String mantissa = Integer.toHexString(m);
+                o.append(mantissa.replaceFirst("0{2,}$", ""));
+                o.append('p');
+                o.append(Integer.toString(e - FP16_EXPONENT_BIAS));
+            }
+        }
+
+        return o.toString();
+    }
+}
diff --git a/core/java/android/util/jar/StrictJarFile.java b/core/java/android/util/jar/StrictJarFile.java
index 60e4adf..d9556aa 100644
--- a/core/java/android/util/jar/StrictJarFile.java
+++ b/core/java/android/util/jar/StrictJarFile.java
@@ -17,19 +17,24 @@
 
 package android.util.jar;
 
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+
 import dalvik.system.CloseGuard;
+import java.io.FileDescriptor;
 import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.RandomAccessFile;
 import java.security.cert.Certificate;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Set;
+import java.util.jar.JarFile;
 import java.util.zip.Inflater;
 import java.util.zip.InflaterInputStream;
 import java.util.zip.ZipEntry;
-import java.util.jar.JarFile;
+import libcore.io.IoBridge;
 import libcore.io.IoUtils;
 import libcore.io.Streams;
 
@@ -46,7 +51,7 @@
 
     // NOTE: It's possible to share a file descriptor with the native
     // code, at the cost of some additional complexity.
-    private final RandomAccessFile raf;
+    private final FileDescriptor fd;
 
     private final StrictJarManifest manifest;
     private final StrictJarVerifier verifier;
@@ -61,8 +66,30 @@
         this(fileName, true, true);
     }
 
+    public StrictJarFile(FileDescriptor fd)
+            throws IOException, SecurityException {
+        this(fd, true, true);
+    }
+
+    public StrictJarFile(FileDescriptor fd,
+            boolean verify,
+            boolean signatureSchemeRollbackProtectionsEnforced)
+                    throws IOException, SecurityException {
+        this("[fd:" + fd.getInt$() + "]", fd, verify,
+                signatureSchemeRollbackProtectionsEnforced);
+    }
+
+    public StrictJarFile(String fileName,
+            boolean verify,
+            boolean signatureSchemeRollbackProtectionsEnforced)
+                    throws IOException, SecurityException {
+        this(fileName, IoBridge.open(fileName, OsConstants.O_RDONLY),
+                verify, signatureSchemeRollbackProtectionsEnforced);
+    }
+
     /**
-     *
+     * @param name of the archive (not necessarily a path).
+     * @param fd seekable file descriptor for the JAR file.
      * @param verify whether to verify the file's JAR signatures and collect the corresponding
      *        signer certificates.
      * @param signatureSchemeRollbackProtectionsEnforced {@code true} to enforce protections against
@@ -70,12 +97,13 @@
      *        {@code false} to ignore any such protections. This parameter is ignored when
      *        {@code verify} is {@code false}.
      */
-    public StrictJarFile(String fileName,
+    private StrictJarFile(String name,
+            FileDescriptor fd,
             boolean verify,
             boolean signatureSchemeRollbackProtectionsEnforced)
                     throws IOException, SecurityException {
-        this.nativeHandle = nativeOpenJarFile(fileName);
-        this.raf = new RandomAccessFile(fileName, "r");
+        this.nativeHandle = nativeOpenJarFile(name, fd.getInt$());
+        this.fd = fd;
 
         try {
             // Read the MANIFEST and signature files up front and try to
@@ -86,14 +114,14 @@
                 this.manifest = new StrictJarManifest(metaEntries.get(JarFile.MANIFEST_NAME), true);
                 this.verifier =
                         new StrictJarVerifier(
-                                fileName,
+                                name,
                                 manifest,
                                 metaEntries,
                                 signatureSchemeRollbackProtectionsEnforced);
                 Set<String> files = manifest.getEntries().keySet();
                 for (String file : files) {
                     if (findEntry(file) == null) {
-                        throw new SecurityException(fileName + ": File " + file + " in manifest does not exist");
+                        throw new SecurityException("File " + file + " in manifest does not exist");
                     }
                 }
 
@@ -105,7 +133,7 @@
             }
         } catch (IOException | SecurityException e) {
             nativeClose(this.nativeHandle);
-            IoUtils.closeQuietly(this.raf);
+            IoUtils.closeQuietly(fd);
             throw e;
         }
 
@@ -192,10 +220,12 @@
 
     public void close() throws IOException {
         if (!closed) {
-            guard.close();
+            if (guard != null) {
+                guard.close();
+            }
 
             nativeClose(nativeHandle);
-            IoUtils.closeQuietly(raf);
+            IoUtils.closeQuietly(fd);
             closed = true;
         }
     }
@@ -214,11 +244,11 @@
 
     private InputStream getZipInputStream(ZipEntry ze) {
         if (ze.getMethod() == ZipEntry.STORED) {
-            return new RAFStream(raf, ze.getDataOffset(),
+            return new FDStream(fd, ze.getDataOffset(),
                     ze.getDataOffset() + ze.getSize());
         } else {
-            final RAFStream wrapped = new RAFStream(
-                    raf, ze.getDataOffset(), ze.getDataOffset() + ze.getCompressedSize());
+            final FDStream wrapped = new FDStream(
+                    fd, ze.getDataOffset(), ze.getDataOffset() + ze.getCompressedSize());
 
             int bufSize = Math.max(1024, (int) Math.min(ze.getSize(), 65535L));
             return new ZipInflaterInputStream(wrapped, new Inflater(true), bufSize, ze);
@@ -396,7 +426,7 @@
     }
 
     /**
-     * Wrap a stream around a RandomAccessFile.  The RandomAccessFile is shared
+     * Wrap a stream around a FileDescriptor.  The file descriptor is shared
      * among all streams returned by getInputStream(), so we have to synchronize
      * access to it.  (We can optimize this by adding buffering here to reduce
      * collisions.)
@@ -405,22 +435,17 @@
      *
      * @hide
      */
-    public static class RAFStream extends InputStream {
-        private final RandomAccessFile sharedRaf;
+    public static class FDStream extends InputStream {
+        private final FileDescriptor fd;
         private long endOffset;
         private long offset;
 
-
-        public RAFStream(RandomAccessFile raf, long initialOffset, long endOffset) {
-            sharedRaf = raf;
+        public FDStream(FileDescriptor fd, long initialOffset, long endOffset) {
+            this.fd = fd;
             offset = initialOffset;
             this.endOffset = endOffset;
         }
 
-        public RAFStream(RandomAccessFile raf, long initialOffset) throws IOException {
-            this(raf, initialOffset, raf.length());
-        }
-
         @Override public int available() throws IOException {
             return (offset < endOffset ? 1 : 0);
         }
@@ -430,13 +455,17 @@
         }
 
         @Override public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
-            synchronized (sharedRaf) {
+            synchronized (this.fd) {
                 final long length = endOffset - offset;
                 if (byteCount > length) {
                     byteCount = (int) length;
                 }
-                sharedRaf.seek(offset);
-                int count = sharedRaf.read(buffer, byteOffset, byteCount);
+                try {
+                    Os.lseek(fd, offset, OsConstants.SEEK_SET);
+                } catch (ErrnoException e) {
+                    throw new IOException(e);
+                }
+                int count = IoBridge.read(fd, buffer, byteOffset, byteCount);
                 if (count > 0) {
                     offset += count;
                     return count;
@@ -455,8 +484,8 @@
         }
     }
 
-
-    private static native long nativeOpenJarFile(String fileName) throws IOException;
+    private static native long nativeOpenJarFile(String name, int fd)
+            throws IOException;
     private static native long nativeStartIteration(long nativeHandle, String prefix);
     private static native ZipEntry nativeNextEntry(long iterationHandle);
     private static native ZipEntry nativeFindEntry(long nativeHandle, String entryName);
diff --git a/core/java/android/view/IPinnedStackController.aidl b/core/java/android/view/IPinnedStackController.aidl
new file mode 100644
index 0000000..830591d
--- /dev/null
+++ b/core/java/android/view/IPinnedStackController.aidl
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.graphics.Rect;
+
+/**
+ * An interface to the PinnedStackController to update it of state changes, and to query
+ * information based on the current state.
+ *
+ * @hide
+ */
+interface IPinnedStackController {
+
+    /**
+     * Notifies the controller that the user is currently interacting with the PIP.
+     */
+    oneway void setInInteractiveMode(boolean inInteractiveMode);
+}
diff --git a/core/java/android/view/IPinnedStackListener.aidl b/core/java/android/view/IPinnedStackListener.aidl
new file mode 100644
index 0000000..3050dbb
--- /dev/null
+++ b/core/java/android/view/IPinnedStackListener.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.view.IPinnedStackController;
+
+/**
+  * Listener for changes to the pinned stack made by the WindowManager.
+  *
+  * @hide
+  */
+oneway interface IPinnedStackListener {
+
+    /**
+     * Called when the listener is registered and provides an interface to call back to the pinned
+     * stack controller to update the controller of the pinned stack state.
+     */
+    void onListenerRegistered(IPinnedStackController controller);
+
+    /**
+     * Called when window manager decides to adjust the pinned stack bounds, or when the listener
+     * is first registered to allow the listener to synchronized its state with the controller.
+     */
+    void onBoundsChanged(boolean adjustedForIme);
+}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 717b675..986ff46 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -34,6 +34,7 @@
 import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.IDockedStackListener;
 import android.view.IOnKeyguardExitResult;
+import android.view.IPinnedStackListener;
 import android.view.IRotationWatcher;
 import android.view.IWindowSession;
 import android.view.IWindowSessionCallback;
@@ -191,10 +192,10 @@
     // If there is a change, the new Configuration is returned and the
     // caller must call setNewConfiguration() sometime later.
     Configuration updateOrientationFromAppTokens(in Configuration currentConfig,
-            IBinder freezeThisOneIfNeeded);
-    // Notify window manager of the new configuration. Returns an array of stack ids that's
-    // affected by the update, ActivityManager should resize these stacks.
-    int[] setNewConfiguration(in Configuration config);
+            IBinder freezeThisOneIfNeeded, int displayId);
+    // Notify window manager of the new display override configuration. Returns an array of stack
+    // ids that were affected by the update, ActivityManager should resize these stacks.
+    int[] setNewDisplayOverrideConfiguration(in Configuration overrideConfig, int displayId);
 
     // Retrieves the new bounds after the configuration update evaluated by window manager.
     Rect getBoundsForNewConfiguration(int stackId);
@@ -426,6 +427,21 @@
     void registerDockedStackListener(IDockedStackListener listener);
 
     /**
+     * Registers a listener that will be called when the pinned stack state changes.
+     */
+    void registerPinnedStackListener(int displayId, IPinnedStackListener listener);
+
+    /**
+     * Returns the initial bounds that PIP will be shown when it is first started.
+     */
+    Rect getPictureInPictureDefaultBounds(int displayId);
+
+    /**
+     * Returns the bounds that the PIP can move on the screen in the current PIP state.
+     */
+    Rect getPictureInPictureMovementBounds(int displayId);
+
+    /**
      * Updates the dim layer used while resizing.
      *
      * @param visible Whether the dim layer should be visible.
@@ -444,7 +460,7 @@
     /**
      * Retrieves the current stable insets from the primary display.
      */
-    void getStableInsets(out Rect outInsets);
+    void getStableInsets(int displayId, out Rect outInsets);
 
     /**
      * Register shortcut key. Shortcut code is packed as:
diff --git a/core/java/android/view/RoundScrollbarRenderer.java b/core/java/android/view/RoundScrollbarRenderer.java
index 4c555ae..1348510 100644
--- a/core/java/android/view/RoundScrollbarRenderer.java
+++ b/core/java/android/view/RoundScrollbarRenderer.java
@@ -31,8 +31,8 @@
     private static final int MAX_SCROLLBAR_ANGLE_SWIPE = 16;
     private static final int MIN_SCROLLBAR_ANGLE_SWIPE = 6;
     private static final float WIDTH_PERCENTAGE = 0.02f;
-    private static final int DEFAULT_THUMB_COLOR = 0xFF757575;
-    private static final int DEFAULT_TRACK_COLOR = 0x21FFFFFF;
+    private static final int DEFAULT_THUMB_COLOR = 0x4CFFFFFF;
+    private static final int DEFAULT_TRACK_COLOR = 0x26FFFFFF;
 
     private final Paint mThumbPaint = new Paint();
     private final Paint mTrackPaint = new Paint();
diff --git a/core/java/android/view/SurfaceHolder.java b/core/java/android/view/SurfaceHolder.java
index 99fa2a4..a3e8312 100644
--- a/core/java/android/view/SurfaceHolder.java
+++ b/core/java/android/view/SurfaceHolder.java
@@ -24,7 +24,7 @@
  * control the surface size and format, edit the pixels in the surface, and
  * monitor changes to the surface.  This interface is typically available
  * through the {@link SurfaceView} class.
- * 
+ *
  * <p>When using this interface from a thread other than the one running
  * its {@link SurfaceView}, you will want to carefully read the
  * methods
@@ -73,7 +73,7 @@
          * they desire.  Note that only one thread can ever draw into
          * a {@link Surface}, so you should not draw into the Surface here
          * if your normal rendering will be in another thread.
-         * 
+         *
          * @param holder The SurfaceHolder whose surface is being created.
          */
         public void surfaceCreated(SurfaceHolder holder);
@@ -83,7 +83,7 @@
          * size) have been made to the surface.  You should at this point update
          * the imagery in the surface.  This method is always called at least
          * once, after {@link #surfaceCreated}.
-         * 
+         *
          * @param holder The SurfaceHolder whose surface has changed.
          * @param format The new PixelFormat of the surface.
          * @param width The new width of the surface.
@@ -96,9 +96,9 @@
          * This is called immediately before a surface is being destroyed. After
          * returning from this call, you should no longer try to access this
          * surface.  If you have a rendering thread that directly accesses
-         * the surface, you must ensure that thread is no longer touching the 
+         * the surface, you must ensure that thread is no longer touching the
          * Surface before returning from this function.
-         * 
+         *
          * @param holder The SurfaceHolder whose surface is being destroyed.
          */
         public void surfaceDestroyed(SurfaceHolder holder);
@@ -124,14 +124,14 @@
     /**
      * Add a Callback interface for this holder.  There can several Callback
      * interfaces associated with a holder.
-     * 
+     *
      * @param callback The new Callback interface.
      */
     public void addCallback(Callback callback);
 
     /**
      * Removes a previously added Callback interface from this holder.
-     * 
+     *
      * @param callback The Callback interface to remove.
      */
     public void removeCallback(Callback callback);
@@ -140,14 +140,14 @@
      * Use this method to find out if the surface is in the process of being
      * created from Callback methods. This is intended to be used with
      * {@link Callback#surfaceChanged}.
-     * 
+     *
      * @return true if the surface is in the process of being created.
      */
     public boolean isCreating();
-    
+
     /**
      * Sets the surface's type.
-     *  
+     *
      * @deprecated this is ignored, this value is set automatically when needed.
      */
     @Deprecated
@@ -157,7 +157,7 @@
      * Make the surface a fixed size.  It will never change from this size.
      * When working with a {@link SurfaceView}, this must be called from the
      * same thread running the SurfaceView's window.
-     * 
+     *
      * @param width The surface's width.
      * @param height The surface's height.
      */
@@ -176,9 +176,9 @@
      * Set the desired PixelFormat of the surface.  The default is OPAQUE.
      * When working with a {@link SurfaceView}, this must be called from the
      * same thread running the SurfaceView's window.
-     * 
+     *
      * @param format A constant from PixelFormat.
-     * 
+     *
      * @see android.graphics.PixelFormat
      */
     public void setFormat(int format);
@@ -187,30 +187,30 @@
      * Enable or disable option to keep the screen turned on while this
      * surface is displayed.  The default is false, allowing it to turn off.
      * This is safe to call from any thread.
-     * 
+     *
      * @param screenOn Set to true to force the screen to stay on, false
      * to allow it to turn off.
      */
     public void setKeepScreenOn(boolean screenOn);
-    
+
     /**
      * Start editing the pixels in the surface.  The returned Canvas can be used
      * to draw into the surface's bitmap.  A null is returned if the surface has
      * not been created or otherwise cannot be edited.  You will usually need
      * to implement {@link Callback#surfaceCreated Callback.surfaceCreated}
      * to find out when the Surface is available for use.
-     * 
+     *
      * <p>The content of the Surface is never preserved between unlockCanvas() and
      * lockCanvas(), for this reason, every pixel within the Surface area
      * must be written. The only exception to this rule is when a dirty
      * rectangle is specified, in which case, non-dirty pixels will be
      * preserved.
-     * 
+     *
      * <p>If you call this repeatedly when the Surface is not ready (before
      * {@link Callback#surfaceCreated Callback.surfaceCreated} or after
      * {@link Callback#surfaceDestroyed Callback.surfaceDestroyed}), your calls
      * will be throttled to a slow rate in order to avoid consuming CPU.
-     * 
+     *
      * <p>If null is not returned, this function internally holds a lock until
      * the corresponding {@link #unlockCanvasAndPost} call, preventing
      * {@link SurfaceView} from creating, destroying, or modifying the surface
@@ -218,31 +218,45 @@
      * the Surface directly, as you do not need to do special synchronization
      * with a drawing thread in {@link Callback#surfaceDestroyed
      * Callback.surfaceDestroyed}.
-     * 
+     *
      * @return Canvas Use to draw into the surface.
      */
     public Canvas lockCanvas();
 
-    
+
     /**
      * Just like {@link #lockCanvas()} but allows specification of a dirty rectangle.
      * Every
      * pixel within that rectangle must be written; however pixels outside
      * the dirty rectangle will be preserved by the next call to lockCanvas().
-     * 
+     *
      * @see android.view.SurfaceHolder#lockCanvas
-     * 
+     *
      * @param dirty Area of the Surface that will be modified.
      * @return Canvas Use to draw into the surface.
      */
     public Canvas lockCanvas(Rect dirty);
 
     /**
+     * <p>Just like {@link #lockCanvas()} but the returned canvas is hardware-accelerated.
+     *
+     * <p>See the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#unsupported">
+     * unsupported drawing operations</a> for a list of what is and isn't
+     * supported in a hardware-accelerated canvas.
+     *
+     * @return Canvas Use to draw into the surface.
+     * @throws IllegalStateException If the canvas cannot be locked.
+     */
+    default Canvas lockHardwareCanvas() {
+        throw new IllegalStateException("This SurfaceHolder doesn't support lockHardwareCanvas");
+    }
+
+    /**
      * Finish editing pixels in the surface.  After this call, the surface's
      * current pixels will be shown on the screen, but its content is lost,
      * in particular there is no guarantee that the content of the Surface
      * will remain unchanged when lockCanvas() is called again.
-     * 
+     *
      * @see #lockCanvas()
      *
      * @param canvas The Canvas previously returned by lockCanvas().
@@ -254,7 +268,7 @@
      * returned Rect.  This is only safe to call from the thread of
      * {@link SurfaceView}'s window, or while inside of
      * {@link #lockCanvas()}.
-     * 
+     *
      * @return Rect The surface's dimensions.  The left and top are always 0.
      */
     public Rect getSurfaceFrame();
@@ -267,17 +281,17 @@
      * and screen position of the Surface.    You will thus usually need
      * to implement {@link Callback#surfaceCreated Callback.surfaceCreated}
      * to find out when the Surface is available for use.
-     * 
+     *
      * <p>Note that if you directly access the Surface from another thread,
      * it is critical that you correctly implement
      * {@link Callback#surfaceCreated Callback.surfaceCreated} and
      * {@link Callback#surfaceDestroyed Callback.surfaceDestroyed} to ensure
      * that thread only accesses the Surface while it is valid, and that the
      * Surface does not get destroyed while the thread is using it.
-     * 
+     *
      * <p>This method is intended to be used by frameworks which often need
      * direct access to the Surface object (usually to pass it to native code).
-     * 
+     *
      * @return Surface The surface.
      */
     public Surface getSurface();
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 80f447e..5c56ebc 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -957,7 +957,7 @@
          */
         @Override
         public Canvas lockCanvas() {
-            return internalLockCanvas(null);
+            return internalLockCanvas(null, false);
         }
 
         /**
@@ -977,10 +977,15 @@
          */
         @Override
         public Canvas lockCanvas(Rect inOutDirty) {
-            return internalLockCanvas(inOutDirty);
+            return internalLockCanvas(inOutDirty, false);
         }
 
-        private final Canvas internalLockCanvas(Rect dirty) {
+        @Override
+        public Canvas lockHardwareCanvas() {
+            return internalLockCanvas(null, true);
+        }
+
+        private Canvas internalLockCanvas(Rect dirty, boolean hardware) {
             mSurfaceLock.lock();
 
             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Locking canvas... stopped="
@@ -989,7 +994,11 @@
             Canvas c = null;
             if (!mDrawingStopped && mWindow != null) {
                 try {
-                    c = mSurface.lockCanvas(dirty);
+                    if (hardware) {
+                        c = mSurface.lockHardwareCanvas();
+                    } else {
+                        c = mSurface.lockCanvas(dirty);
+                    }
                 } catch (Exception e) {
                     Log.e(LOG_TAG, "Exception locking surface", e);
                 }
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 8023201..71c1d62 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -860,32 +860,35 @@
             android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;  // 0x00000001
 
     /**
-     * Called by the input method to commit a content such as PNG image to the editor.
+     * Called by the input method to commit content such as a PNG image to the editor.
      *
-     * <p>In order to avoid variety of compatibility issues, this focuses on a simple use case,
-     * where we expect editors and IMEs work cooperatively as follows:</p>
+     * <p>In order to avoid a variety of compatibility issues, this focuses on a simple use case,
+     * where editors and IMEs are expected to work cooperatively as follows:</p>
      * <ul>
-     *     <li>Editor must keep {@link EditorInfo#contentMimeTypes} to be {@code null} if it does
+     *     <li>Editor must keep {@link EditorInfo#contentMimeTypes} equal to {@code null} if it does
      *     not support this method at all.</li>
      *     <li>Editor can ignore this request when the MIME type specified in
-     *     {@code inputContentInfo} does not match to any of {@link EditorInfo#contentMimeTypes}.
+     *     {@code inputContentInfo} does not match any of {@link EditorInfo#contentMimeTypes}.
      *     </li>
-     *     <li>Editor can ignore the cursor position when inserting the provided context.</li>
+     *     <li>Editor can ignore the cursor position when inserting the provided content.</li>
      *     <li>Editor can return {@code true} asynchronously, even before it starts loading the
      *     content.</li>
-     *     <li>Editor should provide a way to delete the content inserted by this method, or revert
-     *     the effect caused by this method.</li>
+     *     <li>Editor should provide a way to delete the content inserted by this method or to
+     *     revert the effect caused by this method.</li>
      *     <li>IME should not call this method when there is any composing text, in case calling
-     *     this method causes focus change.</li>
+     *     this method causes a focus change.</li>
      *     <li>IME should grant a permission for the editor to read the content. See
      *     {@link EditorInfo#packageName} about how to obtain the package name of the editor.</li>
      * </ul>
      *
      * @param inputContentInfo Content to be inserted.
-     * @param flags {@code 0} or {@link #INPUT_CONTENT_GRANT_READ_URI_PERMISSION}.
+     * @param flags {@link #INPUT_CONTENT_GRANT_READ_URI_PERMISSION} if the content provider
+     * allows {@link android.R.styleable#AndroidManifestProvider_grantUriPermissions
+     * grantUriPermissions} or {@code 0} if the application does not need to call
+     * {@link InputContentInfo#requestPermission()}.
      * @param opts optional bundle data. This can be {@code null}.
-     * @return {@code true} if this request is accepted by the application, no matter if the request
-     * is already handled or still being handled in background.
+     * @return {@code true} if this request is accepted by the application, whether the request
+     * is already handled or still being handled in background, {@code false} otherwise.
      */
     public boolean commitContent(@NonNull InputContentInfo inputContentInfo, int flags,
             @Nullable Bundle opts);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 939f45f..b840f4a 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2566,6 +2566,13 @@
         mProvider.getViewDelegate().onConfigurationChanged(newConfig);
     }
 
+    /**
+     * Creates a new InputConnection for an InputMethod to interact with the WebView.
+     * This is similar to {@link View#onCreateInputConnection} but note that WebView
+     * calls InputConnection methods on a thread other than the UI thread.
+     * If these methods are overridden, then the overriding methods should respect
+     * thread restrictions when calling View methods or accessing data.
+     */
     @Override
     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
         return mProvider.getViewDelegate().onCreateInputConnection(outAttrs);
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 884a86c..f4ea90b 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -490,6 +490,9 @@
             // Log and discard errors at this stage as we must not crash the system server.
             Log.e(LOGTAG, "error preparing webview native library", t);
         }
+
+        WebViewZygote.onWebViewProviderChanged(packageInfo);
+
         return prepareWebViewInSystemServer(nativeLibs);
     }
 
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
new file mode 100644
index 0000000..bc6e7b4
--- /dev/null
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import android.content.pm.PackageInfo;
+import android.os.Build;
+import android.os.SystemService;
+import android.os.ZygoteProcess;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.concurrent.TimeoutException;
+
+/** @hide */
+public class WebViewZygote {
+    private static final String LOGTAG = "WebViewZygote";
+
+    private static final String WEBVIEW_ZYGOTE_SERVICE_32 = "webview_zygote32";
+    private static final String WEBVIEW_ZYGOTE_SERVICE_64 = "webview_zygote64";
+
+    private static ZygoteProcess sZygote;
+
+    private static PackageInfo sPackage;
+
+    private static boolean sMultiprocessEnabled = false;
+
+    public static ZygoteProcess getProcess() {
+        connectToZygoteIfNeeded();
+        return sZygote;
+    }
+
+    public static String getPackageName() {
+        return sPackage.packageName;
+    }
+
+    public static void setMultiprocessEnabled(boolean enabled) {
+        sMultiprocessEnabled = enabled;
+
+        // When toggling between multi-process being on/off, start or stop the
+        // service. If it is enabled and the zygote is not yet started, bring up the service.
+        // Otherwise, bring down the service. The name may be null if the package
+        // information has not yet been resolved.
+        final String serviceName = getServiceName();
+        if (serviceName == null) return;
+
+        if (enabled && sZygote == null) {
+            SystemService.start(serviceName);
+        } else {
+            SystemService.stop(serviceName);
+            sZygote = null;
+        }
+    }
+
+    public static void onWebViewProviderChanged(PackageInfo packageInfo) {
+        sPackage = packageInfo;
+
+        // If multi-process is not enabled, then do not start the zygote service.
+        if (!sMultiprocessEnabled) {
+            return;
+        }
+
+        final String serviceName = getServiceName();
+
+        if (SystemService.isStopped(serviceName)) {
+            SystemService.start(serviceName);
+        } else if (sZygote != null) {
+            SystemService.restart(serviceName);
+        }
+
+        try {
+            SystemService.waitForState(serviceName, SystemService.State.RUNNING, 5000);
+        } catch (TimeoutException e) {
+            Log.e(LOGTAG, "Timed out waiting for " + serviceName);
+            return;
+        }
+
+        connectToZygoteIfNeeded();
+    }
+
+    private static String getServiceName() {
+        if (sPackage == null)
+            return null;
+
+        if (Arrays.asList(Build.SUPPORTED_64_BIT_ABIS).contains(
+                    sPackage.applicationInfo.primaryCpuAbi)) {
+            return WEBVIEW_ZYGOTE_SERVICE_64;
+        }
+
+        return WEBVIEW_ZYGOTE_SERVICE_32;
+    }
+
+    private static void connectToZygoteIfNeeded() {
+        if (sZygote != null)
+            return;
+
+        if (sPackage == null) {
+            Log.e(LOGTAG, "Cannot connect to zygote, no package specified");
+            return;
+        }
+
+        final String serviceName = getServiceName();
+        if (!SystemService.isRunning(serviceName)) {
+            Log.e(LOGTAG, serviceName + " is not running");
+            return;
+        }
+
+        try {
+            sZygote = new ZygoteProcess("webview_zygote", null);
+
+            String packagePath = sPackage.applicationInfo.sourceDir;
+            String libsPath = sPackage.applicationInfo.nativeLibraryDir;
+
+            Log.d(LOGTAG, "Preloading package " + packagePath + " " + libsPath);
+            sZygote.preloadPackageForAbi(packagePath, libsPath, Build.SUPPORTED_ABIS[0]);
+        } catch (Exception e) {
+            Log.e(LOGTAG, "Error connecting to " + serviceName, e);
+            sZygote = null;
+        }
+    }
+}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 184453b..d5a933c 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -6284,6 +6284,17 @@
      * @param intent the intent used to identify the RemoteViewsService for the adapter to connect to.
      */
     public void setRemoteViewsAdapter(Intent intent) {
+        setRemoteViewsAdapter(intent, false);
+    }
+
+    /** @hide **/
+    public Runnable setRemoteViewsAdapterAsync(final Intent intent) {
+        return new RemoteViewsAdapter.AsyncRemoteAdapterAction(this, intent);
+    }
+
+    /** @hide **/
+    @Override
+    public void setRemoteViewsAdapter(Intent intent, boolean isAsync) {
         // Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing
         // service handling the specified intent.
         if (mRemoteAdapter != null) {
@@ -6296,7 +6307,7 @@
         }
         mDeferNotifyDataSetChanged = false;
         // Otherwise, create a new RemoteViewsAdapter for binding
-        mRemoteAdapter = new RemoteViewsAdapter(getContext(), intent, this);
+        mRemoteAdapter = new RemoteViewsAdapter(getContext(), intent, this, isAsync);
         if (mRemoteAdapter.isDataReady()) {
             setAdapter(mRemoteAdapter);
         }
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 0e3a69f..6f29368 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -975,8 +975,19 @@
      * @param intent the intent used to identify the RemoteViewsService for the adapter to
      *        connect to.
      */
-    @android.view.RemotableViewMethod
+    @android.view.RemotableViewMethod(asyncImpl="setRemoteViewsAdapterAsync")
     public void setRemoteViewsAdapter(Intent intent) {
+        setRemoteViewsAdapter(intent, false);
+    }
+
+    /** @hide **/
+    public Runnable setRemoteViewsAdapterAsync(final Intent intent) {
+        return new RemoteViewsAdapter.AsyncRemoteAdapterAction(this, intent);
+    }
+
+    /** @hide **/
+    @Override
+    public void setRemoteViewsAdapter(Intent intent, boolean isAsync) {
         // Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing
         // service handling the specified intent.
         if (mRemoteViewsAdapter != null) {
@@ -989,7 +1000,7 @@
         }
         mDeferNotifyDataSetChanged = false;
         // Otherwise, create a new RemoteViewsAdapter for binding
-        mRemoteViewsAdapter = new RemoteViewsAdapter(getContext(), intent, this);
+        mRemoteViewsAdapter = new RemoteViewsAdapter(getContext(), intent, this, isAsync);
         if (mRemoteViewsAdapter.isDataReady()) {
             setAdapter(mRemoteViewsAdapter);
         }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index bf49048..5eaabe7 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -2345,7 +2345,7 @@
         }
 
         mCorrectionHighlighter.highlight(info);
-        mUndoInputFilter.onCommitCorrection();
+        mUndoInputFilter.freezeLastEdit();
     }
 
     void onScrollChanged() {
@@ -2477,6 +2477,7 @@
         }
 
         mTextView.beginBatchEdit();
+        mUndoInputFilter.freezeLastEdit();
         try {
             final int offset = mTextView.getOffsetForPosition(event.getX(), event.getY());
             Object localState = event.getLocalState();
@@ -2526,6 +2527,7 @@
             }
         } finally {
             mTextView.endBatchEdit();
+            mUndoInputFilter.freezeLastEdit();
         }
     }
 
@@ -5477,10 +5479,12 @@
                 // Expanding with start handle.
                 offset = getWordStart(offset);
                 startOffset = getWordEnd(mStartOffset);
+                if (startOffset == offset) {
+                    offset = getNextCursorOffset(offset, false);
+                }
             }
             mLineSelectionIsOn = currLine;
-            Selection.setSelection((Spannable) mTextView.getText(),
-                    startOffset, offset);
+            Selection.setSelection((Spannable) mTextView.getText(), startOffset, offset);
         }
 
         private void updateParagraphBasedSelection(MotionEvent event) {
@@ -5843,7 +5847,7 @@
             return null;
         }
 
-        void onCommitCorrection() {
+        void freezeLastEdit() {
             mEditor.mUndoManager.beginUpdate("Edit text");
             EditOperation lastEdit = getLastEdit();
             if (lastEdit != null) {
@@ -5904,7 +5908,6 @@
                 // Add this as the first edit.
                 if (DEBUG_UNDO) Log.d(TAG, "filter: adding first op " + edit);
                 um.addOperation(edit, UndoManager.MERGE_MODE_NONE);
-                mPreviousOperationWasInSameBatchEdit = mIsUserEdit;
             } else if (mergeMode == MERGE_EDIT_MODE_FORCE_MERGE) {
                 // Forced merges take priority because they could be the result of a non-user-edit
                 // change and this case should not create a new undo operation.
@@ -5916,7 +5919,6 @@
                 if (DEBUG_UNDO) Log.d(TAG, "non-user edit, new op " + edit);
                 um.commitState(mEditor.mUndoOwner);
                 um.addOperation(edit, UndoManager.MERGE_MODE_NONE);
-                mPreviousOperationWasInSameBatchEdit = mIsUserEdit;
             } else if (mergeMode == MERGE_EDIT_MODE_NORMAL && lastEdit.mergeWith(edit)) {
                 // Merge succeeded, nothing else to do.
                 if (DEBUG_UNDO) Log.d(TAG, "filter: merge succeeded, created " + lastEdit);
@@ -5925,8 +5927,8 @@
                 if (DEBUG_UNDO) Log.d(TAG, "filter: merge failed, adding " + edit);
                 um.commitState(mEditor.mUndoOwner);
                 um.addOperation(edit, UndoManager.MERGE_MODE_NONE);
-                mPreviousOperationWasInSameBatchEdit = mIsUserEdit;
             }
+            mPreviousOperationWasInSameBatchEdit = mIsUserEdit;
             um.endUpdate();
         }
 
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 20543fb..82071d7 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -175,7 +175,7 @@
      * through the specified intent.
      * @param intent the intent used to identify the RemoteViewsService for the adapter to connect to.
      */
-    @android.view.RemotableViewMethod
+    @android.view.RemotableViewMethod(asyncImpl="setRemoteViewsAdapterAsync")
     public void setRemoteViewsAdapter(Intent intent) {
         super.setRemoteViewsAdapter(intent);
     }
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 4d405c5..cd80651 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -455,7 +455,16 @@
 
     /** @hide **/
     public Runnable setImageResourceAsync(@DrawableRes int resId) {
-        return new ImageDrawableCallback(getContext().getDrawable(resId), null, resId);
+        Drawable d = null;
+        if (resId != 0) {
+            try {
+                d = getContext().getDrawable(resId);
+            } catch (Exception e) {
+                Log.w(LOG_TAG, "Unable to find resource: " + resId, e);
+                resId = 0;
+            }
+        }
+        return new ImageDrawableCallback(d, null, resId);
     }
 
     /**
@@ -865,7 +874,7 @@
             } catch (Exception e) {
                 Log.w(LOG_TAG, "Unable to find resource: " + mResource, e);
                 // Don't try again.
-                mUri = null;
+                mResource = 0;
             }
         } else if (mUri != null) {
             d = getDrawableFromUri(mUri);
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index e88c7ef..e52c13b 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -448,7 +448,7 @@
      * through the specified intent.
      * @param intent the intent used to identify the RemoteViewsService for the adapter to connect to.
      */
-    @android.view.RemotableViewMethod
+    @android.view.RemotableViewMethod(asyncImpl="setRemoteViewsAdapterAsync")
     public void setRemoteViewsAdapter(Intent intent) {
         super.setRemoteViewsAdapter(intent);
     }
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 6543d0c..316dab5 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -320,6 +320,10 @@
             return this;
         }
 
+        public boolean prefersAsyncApply() {
+            return false;
+        }
+
         int viewId;
     }
 
@@ -715,20 +719,29 @@
             intent.putExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, host.getAppWidgetId());
             if (target instanceof AbsListView) {
                 AbsListView v = (AbsListView) target;
-                v.setRemoteViewsAdapter(intent);
+                v.setRemoteViewsAdapter(intent, isAsync);
                 v.setRemoteViewsOnClickHandler(handler);
             } else if (target instanceof AdapterViewAnimator) {
                 AdapterViewAnimator v = (AdapterViewAnimator) target;
-                v.setRemoteViewsAdapter(intent);
+                v.setRemoteViewsAdapter(intent, isAsync);
                 v.setRemoteViewsOnClickHandler(handler);
             }
         }
 
+        @Override
+        public Action initActionAsync(ViewTree root, ViewGroup rootParent,
+                OnClickHandler handler) {
+            SetRemoteViewsAdapterIntent copy = new SetRemoteViewsAdapterIntent(viewId, intent);
+            copy.isAsync = true;
+            return copy;
+        }
+
         public String getActionName() {
             return "SetRemoteViewsAdapterIntent";
         }
 
         Intent intent;
+        boolean isAsync = false;
 
         public final static int TAG = 10;
     }
@@ -1461,6 +1474,11 @@
             // unique from the standpoint of merging.
             return "ReflectionAction" + this.methodName + this.type;
         }
+
+        @Override
+        public boolean prefersAsyncApply() {
+            return this.type == URI || this.type == ICON;
+        }
     }
 
     /**
@@ -1598,6 +1616,11 @@
             return MERGE_APPEND;
         }
 
+        @Override
+        public boolean prefersAsyncApply() {
+            return nestedViews != null && nestedViews.prefersAsyncApply();
+        }
+
         RemoteViews nestedViews;
 
         public final static int TAG = 4;
@@ -1749,6 +1772,11 @@
             return copy;
         }
 
+        @Override
+        public boolean prefersAsyncApply() {
+            return useIcons;
+        }
+
         public String getActionName() {
             return "TextViewDrawableAction";
         }
@@ -3443,6 +3471,24 @@
         }
     }
 
+    /**
+     * Returns true if the RemoteViews contains potentially costly operations and should be
+     * applied asynchronously.
+     *
+     * @hide
+     */
+    public boolean prefersAsyncApply() {
+        if (mActions != null) {
+            final int count = mActions.size();
+            for (int i = 0; i < count; i++) {
+                if (mActions.get(i).prefersAsyncApply()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private Context getContextForResources(Context context) {
         if (mApplication != null) {
             if (context.getUserId() == UserHandle.getUserId(mApplication.uid)
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index e0f94fd..11e0a3f 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -45,6 +45,12 @@
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.concurrent.Executor;
+
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
 
 /**
  * An adapter to a RemoteViewsService which fetches and caches RemoteViews
@@ -73,7 +79,8 @@
     private final Context mContext;
     private final Intent mIntent;
     private final int mAppWidgetId;
-    private LayoutInflater mLayoutInflater;
+    private final Executor mAsyncViewLoadExecutor;
+
     private RemoteViewsAdapterServiceConnection mServiceConnection;
     private WeakReference<RemoteAdapterConnectionCallback> mCallback;
     private OnClickHandler mRemoteViewsOnClickHandler;
@@ -120,15 +127,33 @@
         /**
          * @return whether the adapter was set or not.
          */
-        public boolean onRemoteAdapterConnected();
+        boolean onRemoteAdapterConnected();
 
-        public void onRemoteAdapterDisconnected();
+        void onRemoteAdapterDisconnected();
 
         /**
          * This defers a notifyDataSetChanged on the pending RemoteViewsAdapter if it has not
          * connected yet.
          */
-        public void deferNotifyDataSetChanged();
+        void deferNotifyDataSetChanged();
+
+        void setRemoteViewsAdapter(Intent intent, boolean isAsync);
+    }
+
+    public static class AsyncRemoteAdapterAction implements Runnable {
+
+        private final RemoteAdapterConnectionCallback mCallback;
+        private final Intent mIntent;
+
+        public AsyncRemoteAdapterAction(RemoteAdapterConnectionCallback callback, Intent intent) {
+            mCallback = callback;
+            mIntent = intent;
+        }
+
+        @Override
+        public void run() {
+            mCallback.setRemoteViewsAdapter(mIntent, true);
+        }
     }
 
     /**
@@ -162,7 +187,7 @@
                     }
                     mIsConnecting = true;
                 } catch (Exception e) {
-                    Log.e("RemoteViewsAdapterServiceConnection", "bind(): " + e.getMessage());
+                    Log.e("RVAServiceConnection", "bind(): " + e.getMessage());
                     mIsConnecting = false;
                     mIsConnected = false;
                 }
@@ -180,7 +205,7 @@
                 }
                 mIsConnecting = false;
             } catch (Exception e) {
-                Log.e("RemoteViewsAdapterServiceConnection", "unbind(): " + e.getMessage());
+                Log.e("RVAServiceConnection", "unbind(): " + e.getMessage());
                 mIsConnecting = false;
                 mIsConnected = false;
             }
@@ -298,15 +323,29 @@
          * Updates this RemoteViewsFrameLayout depending on the view that was loaded.
          * @param view the RemoteViews that was loaded. If null, the RemoteViews was not loaded
          *             successfully.
+         * @param forceApplyAsync when true, the host will always try to inflate the view
+         *                        asynchronously (for eg, when we are already showing the loading
+         *                        view)
          */
-        public void onRemoteViewsLoaded(RemoteViews view, OnClickHandler handler) {
+        public void onRemoteViewsLoaded(RemoteViews view, OnClickHandler handler,
+                boolean forceApplyAsync) {
             setOnClickHandler(handler);
-            applyRemoteViews(view);
+            applyRemoteViews(view, forceApplyAsync || ((view != null) && view.prefersAsyncApply()));
         }
 
+        /**
+         * Creates a default loading view. Uses the size of the first row as a guide for the
+         * size of the loading view.
+         */
         @Override
         protected View getDefaultView() {
-            return mCache.getMetaData().createDefaultLoadingView(this);
+            int viewHeight = mCache.getMetaData().getLoadingTemplate(getContext()).defaultHeight;
+            // Compose the loading view text
+            TextView loadingTextView = (TextView) LayoutInflater.from(getContext()).inflate(
+                    com.android.internal.R.layout.remote_views_adapter_default_loading_view,
+                    this, false);
+            loadingTextView.setHeight(viewHeight);
+            return loadingTextView;
         }
 
         @Override
@@ -359,7 +398,7 @@
             if (refs != null) {
                 // Notify all the references for that position of the newly loaded RemoteViews
                 for (final RemoteViewsFrameLayout ref : refs) {
-                    ref.onRemoteViewsLoaded(view, mRemoteViewsOnClickHandler);
+                    ref.onRemoteViewsLoaded(view, mRemoteViewsOnClickHandler, true);
                     if (mViewToLinkedList.containsKey(ref)) {
                         mViewToLinkedList.remove(ref);
                     }
@@ -402,9 +441,7 @@
         // Used to determine how to construct loading views.  If a loading view is not specified
         // by the user, then we try and load the first view, and use its height as the height for
         // the default loading view.
-        RemoteViews mUserLoadingView;
-        RemoteViews mFirstView;
-        int mFirstViewHeight;
+        LoadingViewTemplate loadingTemplate;
 
         // A mapping from type id to a set of unique type ids
         private final SparseIntArray mTypeIdIndexMap = new SparseIntArray();
@@ -418,7 +455,7 @@
                 count = d.count;
                 viewTypeCount = d.viewTypeCount;
                 hasStableIds = d.hasStableIds;
-                setLoadingViewTemplates(d.mUserLoadingView, d.mFirstView);
+                loadingTemplate = d.loadingTemplate;
             }
         }
 
@@ -428,20 +465,10 @@
             // by default there is at least one dummy view type
             viewTypeCount = 1;
             hasStableIds = true;
-            mUserLoadingView = null;
-            mFirstView = null;
-            mFirstViewHeight = 0;
+            loadingTemplate = null;
             mTypeIdIndexMap.clear();
         }
 
-        public void setLoadingViewTemplates(RemoteViews loadingView, RemoteViews firstView) {
-            mUserLoadingView = loadingView;
-            if (firstView != null) {
-                mFirstView = firstView;
-                mFirstViewHeight = -1;
-            }
-        }
-
         public int getMappedViewType(int typeId) {
             int mappedTypeId = mTypeIdIndexMap.get(typeId, -1);
             if (mappedTypeId == -1) {
@@ -457,33 +484,11 @@
             return (mappedType < viewTypeCount);
         }
 
-        /**
-         * Creates a default loading view. Uses the size of the first row as a guide for the
-         * size of the loading view.
-         */
-        private synchronized View createDefaultLoadingView(ViewGroup parent) {
-            final Context context = parent.getContext();
-            if (mFirstViewHeight < 0) {
-                try {
-                    View firstView = mFirstView.apply(parent.getContext(), parent);
-                    firstView.measure(
-                            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
-                            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-                    mFirstViewHeight = firstView.getMeasuredHeight();
-                } catch (Exception e) {
-                    float density = context.getResources().getDisplayMetrics().density;
-                    mFirstViewHeight = Math.round(sDefaultLoadingViewHeight * density);
-                    Log.w(TAG, "Error inflating first RemoteViews" + e);
-                }
-                mFirstView = null;
+        public synchronized LoadingViewTemplate getLoadingTemplate(Context context) {
+            if (loadingTemplate == null) {
+                loadingTemplate = new LoadingViewTemplate(null, context);
             }
-
-            // Compose the loading view text
-            TextView loadingTextView = (TextView) LayoutInflater.from(context).inflate(
-                    com.android.internal.R.layout.remote_views_adapter_default_loading_view,
-                    parent, false);
-            loadingTextView.setHeight(mFirstViewHeight);
-            return loadingTextView;
+            return loadingTemplate;
         }
     }
 
@@ -772,7 +777,7 @@
     }
 
     public RemoteViewsAdapter(Context context, Intent intent,
-            RemoteAdapterConnectionCallback callback) {
+            RemoteAdapterConnectionCallback callback, boolean useAsyncLoader) {
         mContext = context;
         mIntent = intent;
 
@@ -781,7 +786,6 @@
         }
 
         mAppWidgetId = intent.getIntExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID, -1);
-        mLayoutInflater = LayoutInflater.from(context);
         mRequestedViews = new RemoteViewsFrameLayoutRefSet();
 
         // Strip the previously injected app widget id from service intent
@@ -794,6 +798,7 @@
         mWorkerThread.start();
         mWorkerQueue = new Handler(mWorkerThread.getLooper());
         mMainQueue = new Handler(Looper.myLooper(), this);
+        mAsyncViewLoadExecutor = useAsyncLoader ? new HandlerThreadExecutor(mWorkerThread) : null;
 
         if (sCacheRemovalThread == null) {
             sCacheRemovalThread = new HandlerThread("RemoteViewsAdapter-cachePruner");
@@ -941,10 +946,14 @@
             boolean hasStableIds = factory.hasStableIds();
             int viewTypeCount = factory.getViewTypeCount();
             int count = factory.getCount();
-            RemoteViews loadingView = factory.getLoadingView();
-            RemoteViews firstView = null;
-            if ((count > 0) && (loadingView == null)) {
-                firstView = factory.getViewAt(0);
+            LoadingViewTemplate loadingTemplate =
+                    new LoadingViewTemplate(factory.getLoadingView(), mContext);
+            if ((count > 0) && (loadingTemplate.remoteViews == null)) {
+                RemoteViews firstView = factory.getViewAt(0);
+                if (firstView != null) {
+                    loadingTemplate.loadFirstViewHeight(firstView, mContext,
+                            new HandlerThreadExecutor(mWorkerThread));
+                }
             }
             final RemoteViewsMetaData tmpMetaData = mCache.getTemporaryMetaData();
             synchronized (tmpMetaData) {
@@ -952,7 +961,7 @@
                 // We +1 because the base view type is the loading view
                 tmpMetaData.viewTypeCount = viewTypeCount + 1;
                 tmpMetaData.count = count;
-                tmpMetaData.setLoadingViewTemplates(loadingView, firstView);
+                tmpMetaData.loadingTemplate = loadingTemplate;
             }
         } catch(RemoteException e) {
             processException("updateMetaData", e);
@@ -1100,18 +1109,25 @@
                 hasNewItems = mCache.queuePositionsToBePreloadedFromRequestedPosition(position);
             }
 
-            final RemoteViewsFrameLayout layout =
-                    (convertView instanceof RemoteViewsFrameLayout)
-                            ? (RemoteViewsFrameLayout) convertView
-                            : new RemoteViewsFrameLayout(parent.getContext(), mCache);
+            final RemoteViewsFrameLayout layout;
+            if (convertView instanceof RemoteViewsFrameLayout) {
+                layout = (RemoteViewsFrameLayout) convertView;
+            } else {
+                layout = new RemoteViewsFrameLayout(parent.getContext(), mCache);
+                layout.setAsyncExecutor(mAsyncViewLoadExecutor);
+            }
+
             if (isInCache) {
-                layout.onRemoteViewsLoaded(rv, mRemoteViewsOnClickHandler);
+                // Apply the view synchronously if possible, to avoid flickering
+                layout.onRemoteViewsLoaded(rv, mRemoteViewsOnClickHandler, false);
                 if (hasNewItems) loadNextIndexInBackground();
             } else {
                 // If the views is not loaded, apply the loading view. If the loading view doesn't
                 // exist, the layout will create a default view based on the firstView height.
-                layout.onRemoteViewsLoaded(mCache.getMetaData().mUserLoadingView,
-                        mRemoteViewsOnClickHandler);
+                layout.onRemoteViewsLoaded(
+                        mCache.getMetaData().getLoadingTemplate(mContext).remoteViews,
+                        mRemoteViewsOnClickHandler,
+                        false);
                 mRequestedViews.add(position, layout);
                 mCache.queueRequestedPositionToLoad(position);
                 loadNextIndexInBackground();
@@ -1285,4 +1301,58 @@
         mMainQueue.removeMessages(sUnbindServiceMessageType);
         return mServiceConnection.isConnected();
     }
+
+    private static class HandlerThreadExecutor implements Executor {
+        private final HandlerThread mThread;
+
+        HandlerThreadExecutor(HandlerThread thread) {
+            mThread = thread;
+        }
+
+        @Override
+        public void execute(Runnable runnable) {
+            if (Thread.currentThread().getId() == mThread.getId()) {
+                runnable.run();
+            } else {
+                new Handler(mThread.getLooper()).post(runnable);
+            }
+        }
+    }
+
+    private static class LoadingViewTemplate {
+        public final RemoteViews remoteViews;
+        public int defaultHeight;
+
+        LoadingViewTemplate(RemoteViews views, Context context) {
+            remoteViews = views;
+
+            float density = context.getResources().getDisplayMetrics().density;
+            defaultHeight = Math.round(sDefaultLoadingViewHeight * density);
+        }
+
+        public void loadFirstViewHeight(
+                RemoteViews firstView, Context context, Executor executor) {
+            // Inflate the first view on the worker thread
+            firstView.applyAsync(context, new RemoteViewsFrameLayout(context, null), executor,
+                    new RemoteViews.OnViewAppliedListener() {
+                        @Override
+                        public void onViewApplied(View v) {
+                            try {
+                                v.measure(
+                                        MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+                                        MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+                                defaultHeight = v.getMeasuredHeight();
+                            } catch (Exception e) {
+                                onError(e);
+                            }
+                        }
+
+                        @Override
+                        public void onError(Exception e) {
+                            // Do nothing. The default height will stay the same.
+                            Log.w(TAG, "Error inflating first RemoteViews", e);
+                        }
+                    });
+        }
+    }
 }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f1c3079..2f9c97b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3685,18 +3685,23 @@
     }
 
     /**
-     * Makes the TextView at least this many lines tall.
+     * Sets the height of the TextView to be at least {@code minLines} tall.
+     * <p>
+     * This value is used for height calculation if LayoutParams does not force TextView to have an
+     * exact height. Setting this value overrides other previous minimum height configurations such
+     * as {@link #setMinHeight(int)} or {@link #setHeight(int)}. {@link #setSingleLine()} will set
+     * this value to 1.
      *
-     * Setting this value overrides any other (minimum) height setting. A single line TextView will
-     * set this value to 1.
+     * @param minLines the minimum height of TextView in terms of number of lines
      *
      * @see #getMinLines()
+     * @see #setLines(int)
      *
      * @attr ref android.R.styleable#TextView_minLines
      */
     @android.view.RemotableViewMethod
-    public void setMinLines(int minlines) {
-        mMinimum = minlines;
+    public void setMinLines(int minLines) {
+        mMinimum = minLines;
         mMinMode = LINES;
 
         requestLayout();
@@ -3704,10 +3709,14 @@
     }
 
     /**
-     * @return the minimum number of lines displayed in this TextView, or -1 if the minimum
-     * height was set in pixels instead using {@link #setMinHeight(int) or #setHeight(int)}.
+     * Returns the minimum height of TextView in terms of number of lines or -1 if the minimum
+     * height was set using {@link #setMinHeight(int)} or {@link #setHeight(int)}.
+     *
+     * @return the minimum height of TextView in terms of number of lines or -1 if the minimum
+     *         height is not defined in lines
      *
      * @see #setMinLines(int)
+     * @see #setLines(int)
      *
      * @attr ref android.R.styleable#TextView_minLines
      */
@@ -3716,15 +3725,26 @@
     }
 
     /**
-     * Makes the TextView at least this many pixels tall.
+     * Sets the height of the TextView to be at least {@code minPixels} tall.
+     * <p>
+     * This value is used for height calculation if LayoutParams does not force TextView to have an
+     * exact height. Setting this value overrides previous minimum height configurations such as
+     * {@link #setMinLines(int)} or {@link #setLines(int)}.
+     * <p>
+     * The value given here is different than {@link #setMinimumHeight(int)}. Between
+     * {@code minHeight} and the value set in {@link #setMinimumHeight(int)}, the greater one is
+     * used to decide the final height.
      *
-     * Setting this value overrides any other (minimum) number of lines setting.
+     * @param minPixels the minimum height of TextView in terms of pixels
+     *
+     * @see #getMinHeight()
+     * @see #setHeight(int)
      *
      * @attr ref android.R.styleable#TextView_minHeight
      */
     @android.view.RemotableViewMethod
-    public void setMinHeight(int minHeight) {
-        mMinimum = minHeight;
+    public void setMinHeight(int minPixels) {
+        mMinimum = minPixels;
         mMinMode = PIXELS;
 
         requestLayout();
@@ -3732,10 +3752,14 @@
     }
 
     /**
-     * @return the minimum height of this TextView expressed in pixels, or -1 if the minimum
-     * height was set in number of lines instead using {@link #setMinLines(int) or #setLines(int)}.
+     * Returns the minimum height of TextView in terms of pixels or -1 if the minimum height was
+     * set using {@link #setMinLines(int)} or {@link #setLines(int)}.
+     *
+     * @return the minimum height of TextView in terms of pixels or -1 if the minimum height is not
+     *         defined in pixels
      *
      * @see #setMinHeight(int)
+     * @see #setHeight(int)
      *
      * @attr ref android.R.styleable#TextView_minHeight
      */
@@ -3744,15 +3768,22 @@
     }
 
     /**
-     * Makes the TextView at most this many lines tall.
+     * Sets the height of the TextView to be at most {@code maxLines} tall.
+     * <p>
+     * This value is used for height calculation if LayoutParams does not force TextView to have an
+     * exact height. Setting this value overrides previous maximum height configurations such as
+     * {@link #setMaxHeight(int)} or {@link #setLines(int)}.
      *
-     * Setting this value overrides any other (maximum) height setting.
+     * @param maxLines the maximum height of TextView in terms of number of lines
+     *
+     * @see #getMaxLines()
+     * @see #setLines(int)
      *
      * @attr ref android.R.styleable#TextView_maxLines
      */
     @android.view.RemotableViewMethod
-    public void setMaxLines(int maxlines) {
-        mMaximum = maxlines;
+    public void setMaxLines(int maxLines) {
+        mMaximum = maxLines;
         mMaxMode = LINES;
 
         requestLayout();
@@ -3760,10 +3791,14 @@
     }
 
     /**
-     * @return the maximum number of lines displayed in this TextView, or -1 if the maximum
-     * height was set in pixels instead using {@link #setMaxHeight(int) or #setHeight(int)}.
+     * Returns the maximum height of TextView in terms of number of lines or -1 if the
+     * maximum height was set using {@link #setMaxHeight(int)} or {@link #setHeight(int)}.
+     *
+     * @return the maximum height of TextView in terms of number of lines. -1 if the maximum height
+     *         is not defined in lines.
      *
      * @see #setMaxLines(int)
+     * @see #setLines(int)
      *
      * @attr ref android.R.styleable#TextView_maxLines
      */
@@ -3772,16 +3807,22 @@
     }
 
     /**
-     * Makes the TextView at most this many pixels tall.  This option is mutually exclusive with the
-     * {@link #setMaxLines(int)} method.
+     * Sets the height of the TextView to be at most {@code maxPixels} tall.
+     * <p>
+     * This value is used for height calculation if LayoutParams does not force TextView to have an
+     * exact height. Setting this value overrides previous maximum height configurations such as
+     * {@link #setMaxLines(int)} or {@link #setLines(int)}.
      *
-     * Setting this value overrides any other (maximum) number of lines setting.
+     * @param maxPixels the maximum height of TextView in terms of pixels
+     *
+     * @see #getMaxHeight()
+     * @see #setHeight(int)
      *
      * @attr ref android.R.styleable#TextView_maxHeight
      */
     @android.view.RemotableViewMethod
-    public void setMaxHeight(int maxHeight) {
-        mMaximum = maxHeight;
+    public void setMaxHeight(int maxPixels) {
+        mMaximum = maxPixels;
         mMaxMode = PIXELS;
 
         requestLayout();
@@ -3789,10 +3830,14 @@
     }
 
     /**
-     * @return the maximum height of this TextView expressed in pixels, or -1 if the maximum
-     * height was set in number of lines instead using {@link #setMaxLines(int) or #setLines(int)}.
+     * Returns the maximum height of TextView in terms of pixels or -1 if the maximum height was
+     * set using {@link #setMaxLines(int)} or {@link #setLines(int)}.
+     *
+     * @return the maximum height of TextView in terms of pixels or -1 if the maximum height
+     *         is not defined in pixels
      *
      * @see #setMaxHeight(int)
+     * @see #setHeight(int)
      *
      * @attr ref android.R.styleable#TextView_maxHeight
      */
@@ -3801,10 +3846,16 @@
     }
 
     /**
-     * Makes the TextView exactly this many lines tall.
+     * Sets the height of the TextView to be exactly {@code lines} tall.
+     * <p>
+     * This value is used for height calculation if LayoutParams does not force TextView to have an
+     * exact height. Setting this value overrides previous minimum/maximum height configurations
+     * such as {@link #setMinLines(int)} or {@link #setMaxLines(int)}. {@link #setSingleLine()} will
+     * set this value to 1.
      *
-     * Note that setting this value overrides any other (minimum / maximum) number of lines or
-     * height setting. A single line TextView will set this value to 1.
+     * @param lines the exact height of the TextView in terms of lines
+     *
+     * @see #setHeight(int)
      *
      * @attr ref android.R.styleable#TextView_lines
      */
@@ -3818,12 +3869,15 @@
     }
 
     /**
-     * Makes the TextView exactly this many pixels tall.
-     * You could do the same thing by specifying this number in the
-     * LayoutParams.
+     * Sets the height of the TextView to be exactly <code>pixels</code> tall.
+     * <p>
+     * This value is used for height calculation if LayoutParams does not force TextView to have an
+     * exact height. Setting this value overrides previous minimum/maximum height configurations
+     * such as {@link #setMinHeight(int)} or {@link #setMaxHeight(int)}.
      *
-     * Note that setting this value overrides any other (minimum / maximum) number of lines or
-     * height setting.
+     * @param pixels the exact height of the TextView in terms of pixels
+     *
+     * @see #setLines(int)
      *
      * @attr ref android.R.styleable#TextView_height
      */
@@ -3837,13 +3891,22 @@
     }
 
     /**
-     * Makes the TextView at least this many ems wide
+     * Sets the width of the TextView to be at least {@code minEms} wide.
+     * <p>
+     * This value is used for width calculation if LayoutParams does not force TextView to have an
+     * exact width. Setting this value overrides previous minimum width configurations such as
+     * {@link #setMinWidth(int)} or {@link #setWidth(int)}.
+     *
+     * @param minEms the minimum width of TextView in terms of ems
+     *
+     * @see #getMinEms()
+     * @see #setEms(int)
      *
      * @attr ref android.R.styleable#TextView_minEms
      */
     @android.view.RemotableViewMethod
-    public void setMinEms(int minems) {
-        mMinWidth = minems;
+    public void setMinEms(int minEms) {
+        mMinWidth = minEms;
         mMinWidthMode = EMS;
 
         requestLayout();
@@ -3851,8 +3914,11 @@
     }
 
     /**
-     * @return the minimum width of the TextView, expressed in ems or -1 if the minimum width
-     * was set in pixels instead (using {@link #setMinWidth(int)} or {@link #setWidth(int)}).
+     * Returns the minimum width of TextView in terms of ems or -1 if the minimum width was set
+     * using {@link #setMinWidth(int)} or {@link #setWidth(int)}.
+     *
+     * @return the minimum width of TextView in terms of ems. -1 if the minimum width is not
+     *         defined in ems
      *
      * @see #setMinEms(int)
      * @see #setEms(int)
@@ -3864,13 +3930,26 @@
     }
 
     /**
-     * Makes the TextView at least this many pixels wide
+     * Sets the width of the TextView to be at least {@code minPixels} wide.
+     * <p>
+     * This value is used for width calculation if LayoutParams does not force TextView to have an
+     * exact width. Setting this value overrides previous minimum width configurations such as
+     * {@link #setMinEms(int)} or {@link #setEms(int)}.
+     * <p>
+     * The value given here is different than {@link #setMinimumWidth(int)}. Between
+     * {@code minWidth} and the value set in {@link #setMinimumWidth(int)}, the greater one is used
+     * to decide the final width.
+     *
+     * @param minPixels the minimum width of TextView in terms of pixels
+     *
+     * @see #getMinWidth()
+     * @see #setWidth(int)
      *
      * @attr ref android.R.styleable#TextView_minWidth
      */
     @android.view.RemotableViewMethod
-    public void setMinWidth(int minpixels) {
-        mMinWidth = minpixels;
+    public void setMinWidth(int minPixels) {
+        mMinWidth = minPixels;
         mMinWidthMode = PIXELS;
 
         requestLayout();
@@ -3878,8 +3957,11 @@
     }
 
     /**
-     * @return the minimum width of the TextView, in pixels or -1 if the minimum width
-     * was set in ems instead (using {@link #setMinEms(int)} or {@link #setEms(int)}).
+     * Returns the minimum width of TextView in terms of pixels or -1 if the minimum width was set
+     * using {@link #setMinEms(int)} or {@link #setEms(int)}.
+     *
+     * @return the minimum width of TextView in terms of pixels or -1 if the minimum width is not
+     *         defined in pixels
      *
      * @see #setMinWidth(int)
      * @see #setWidth(int)
@@ -3891,13 +3973,22 @@
     }
 
     /**
-     * Makes the TextView at most this many ems wide
+     * Sets the width of the TextView to be at most {@code maxEms} wide.
+     * <p>
+     * This value is used for width calculation if LayoutParams does not force TextView to have an
+     * exact width. Setting this value overrides previous maximum width configurations such as
+     * {@link #setMaxWidth(int)} or {@link #setWidth(int)}.
+     *
+     * @param maxEms the maximum width of TextView in terms of ems
+     *
+     * @see #getMaxEms()
+     * @see #setEms(int)
      *
      * @attr ref android.R.styleable#TextView_maxEms
      */
     @android.view.RemotableViewMethod
-    public void setMaxEms(int maxems) {
-        mMaxWidth = maxems;
+    public void setMaxEms(int maxEms) {
+        mMaxWidth = maxEms;
         mMaxWidthMode = EMS;
 
         requestLayout();
@@ -3905,8 +3996,11 @@
     }
 
     /**
-     * @return the maximum width of the TextView, expressed in ems or -1 if the maximum width
-     * was set in pixels instead (using {@link #setMaxWidth(int)} or {@link #setWidth(int)}).
+     * Returns the maximum width of TextView in terms of ems or -1 if the maximum width was set
+     * using {@link #setMaxWidth(int)} or {@link #setWidth(int)}.
+     *
+     * @return the maximum width of TextView in terms of ems or -1 if the maximum width is not
+     *         defined in ems
      *
      * @see #setMaxEms(int)
      * @see #setEms(int)
@@ -3918,13 +4012,22 @@
     }
 
     /**
-     * Makes the TextView at most this many pixels wide
+     * Sets the width of the TextView to be at most {@code maxPixels} wide.
+     * <p>
+     * This value is used for width calculation if LayoutParams does not force TextView to have an
+     * exact width. Setting this value overrides previous maximum width configurations such as
+     * {@link #setMaxEms(int)} or {@link #setEms(int)}.
+     *
+     * @param maxPixels the maximum width of TextView in terms of pixels
+     *
+     * @see #getMaxWidth()
+     * @see #setWidth(int)
      *
      * @attr ref android.R.styleable#TextView_maxWidth
      */
     @android.view.RemotableViewMethod
-    public void setMaxWidth(int maxpixels) {
-        mMaxWidth = maxpixels;
+    public void setMaxWidth(int maxPixels) {
+        mMaxWidth = maxPixels;
         mMaxWidthMode = PIXELS;
 
         requestLayout();
@@ -3932,8 +4035,11 @@
     }
 
     /**
-     * @return the maximum width of the TextView, in pixels or -1 if the maximum width
-     * was set in ems instead (using {@link #setMaxEms(int)} or {@link #setEms(int)}).
+     * Returns the maximum width of TextView in terms of pixels or -1 if the maximum width was set
+     * using {@link #setMaxEms(int)} or {@link #setEms(int)}.
+     *
+     * @return the maximum width of TextView in terms of pixels. -1 if the maximum width is not
+     *         defined in pixels
      *
      * @see #setMaxWidth(int)
      * @see #setWidth(int)
@@ -3945,12 +4051,15 @@
     }
 
     /**
-     * Makes the TextView exactly this many ems wide
+     * Sets the width of the TextView to be exactly {@code ems} wide.
      *
-     * @see #setMaxEms(int)
-     * @see #setMinEms(int)
-     * @see #getMinEms()
-     * @see #getMaxEms()
+     * This value is used for width calculation if LayoutParams does not force TextView to have an
+     * exact width. Setting this value overrides previous minimum/maximum configurations such as
+     * {@link #setMinEms(int)} or {@link #setMaxEms(int)}.
+     *
+     * @param ems the exact width of the TextView in terms of ems
+     *
+     * @see #setWidth(int)
      *
      * @attr ref android.R.styleable#TextView_ems
      */
@@ -3964,14 +4073,15 @@
     }
 
     /**
-     * Makes the TextView exactly this many pixels wide.
-     * You could do the same thing by specifying this number in the
-     * LayoutParams.
+     * Sets the width of the TextView to be exactly {@code pixels} wide.
+     * <p>
+     * This value is used for width calculation if LayoutParams does not force TextView to have an
+     * exact width. Setting this value overrides previous minimum/maximum width configurations
+     * such as {@link #setMinWidth(int)} or {@link #setMaxWidth(int)}.
      *
-     * @see #setMaxWidth(int)
-     * @see #setMinWidth(int)
-     * @see #getMinWidth()
-     * @see #getMaxWidth()
+     * @param pixels the exact width of the TextView in terms of pixels
+     *
+     * @see #setEms(int)
      *
      * @attr ref android.R.styleable#TextView_width
      */
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 4efcb09..789e60b 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -100,13 +100,13 @@
      */
     public Toast(Context context) {
         mContext = context;
-        mTN = new TN();
+        mTN = new TN(context.getPackageName());
         mTN.mY = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.toast_y_offset);
         mTN.mGravity = context.getResources().getInteger(
                 com.android.internal.R.integer.config_toastDefaultGravity);
     }
-    
+
     /**
      * Show the view for the specified duration.
      */
@@ -133,15 +133,9 @@
      * after the appropriate duration.
      */
     public void cancel() {
-        mTN.hide();
-
-        try {
-            getService().cancelToast(mContext.getPackageName(), mTN);
-        } catch (RemoteException e) {
-            // Empty
-        }
+        mTN.cancel();
     }
-    
+
     /**
      * Set the view to show.
      * @see #getView
@@ -328,21 +322,37 @@
     }
 
     private static class TN extends ITransientNotification.Stub {
-        final Runnable mHide = new Runnable() {
-            @Override
-            public void run() {
-                handleHide();
-                // Don't do this in handleHide() because it is also invoked by handleShow()
-                mNextView = null;
-            }
-        };
-
         private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
+
+        private static final int SHOW = 0;
+        private static final int HIDE = 1;
+        private static final int CANCEL = 2;
         final Handler mHandler = new Handler() {
             @Override
             public void handleMessage(Message msg) {
-                IBinder token = (IBinder) msg.obj;
-                handleShow(token);
+                switch (msg.what) {
+                    case SHOW: {
+                        IBinder token = (IBinder) msg.obj;
+                        handleShow(token);
+                        break;
+                    }
+                    case HIDE: {
+                        handleHide();
+                        // Don't do this in handleHide() because it is also invoked by handleShow()
+                        mNextView = null;
+                        break;
+                    }
+                    case CANCEL: {
+                        handleHide();
+                        // Don't do this in handleHide() because it is also invoked by handleShow()
+                        mNextView = null;
+                        try {
+                            getService().cancelToast(mPackageName, TN.this);
+                        } catch (RemoteException e) {
+                        }
+                        break;
+                    }
+                }
             }
         };
 
@@ -358,10 +368,12 @@
 
         WindowManager mWM;
 
+        String mPackageName;
+
         static final long SHORT_DURATION_TIMEOUT = 4000;
         static final long LONG_DURATION_TIMEOUT = 7000;
 
-        TN() {
+        TN(String packageName) {
             // XXX This should be changed to use a Dialog, with a Theme.Toast
             // defined that sets up the layout params appropriately.
             final WindowManager.LayoutParams params = mParams;
@@ -374,6 +386,8 @@
             params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                     | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+
+            mPackageName = packageName;
         }
 
         /**
@@ -382,7 +396,7 @@
         @Override
         public void show(IBinder windowToken) {
             if (localLOGV) Log.v(TAG, "SHOW: " + this);
-            mHandler.obtainMessage(0, windowToken).sendToTarget();
+            mHandler.obtainMessage(SHOW, windowToken).sendToTarget();
         }
 
         /**
@@ -391,7 +405,12 @@
         @Override
         public void hide() {
             if (localLOGV) Log.v(TAG, "HIDE: " + this);
-            mHandler.post(mHide);
+            mHandler.obtainMessage(HIDE).sendToTarget();
+        }
+
+        public void cancel() {
+            if (localLOGV) Log.v(TAG, "CANCEL: " + this);
+            mHandler.obtainMessage(CANCEL).sendToTarget();
         }
 
         public void handleShow(IBinder windowToken) {
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index 2ed7aa2..11dd0e8 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -16,6 +16,15 @@
 
 package com.android.internal.os;
 
+import android.net.LocalSocket;
+import android.os.Build;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.IOException;
+
 /**
  * Startup class for the WebView zygote process.
  *
@@ -26,7 +35,48 @@
 class WebViewZygoteInit {
     public static final String TAG = "WebViewZygoteInit";
 
+    private static ZygoteServer sServer;
+
+    private static class WebViewZygoteServer extends ZygoteServer {
+        @Override
+        protected ZygoteConnection createNewConnection(LocalSocket socket, String abiList)
+                throws IOException {
+            return new WebViewZygoteConnection(socket, abiList);
+        }
+    }
+
+    private static class WebViewZygoteConnection extends ZygoteConnection {
+        WebViewZygoteConnection(LocalSocket socket, String abiList) throws IOException {
+            super(socket, abiList);
+        }
+
+        @Override
+        protected boolean handlePreloadPackage(String packagePath, String libsPath) {
+            // TODO: Use preload information to setup the ClassLoader.
+            return false;
+        }
+    }
+
     public static void main(String argv[]) {
-        throw new RuntimeException("Not implemented yet");
+        sServer = new WebViewZygoteServer();
+
+        // Zygote goes into its own process group.
+        try {
+            Os.setpgid(0, 0);
+        } catch (ErrnoException ex) {
+            throw new RuntimeException("Failed to setpgid(0,0)", ex);
+        }
+
+        try {
+            sServer.registerServerSocket("webview_zygote");
+            sServer.runSelectLoop(TextUtils.join(",", Build.SUPPORTED_ABIS));
+            sServer.closeServerSocket();
+        } catch (Zygote.MethodAndArgsCaller caller) {
+            caller.run();
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Fatal exception:", e);
+        }
+
+        System.exit(0);
     }
 }
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index b8fa034..7edc938 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -44,6 +44,7 @@
 import java.io.PrintStream;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Arrays;
 import libcore.io.IoUtils;
 
 /**
@@ -170,6 +171,11 @@
                 return handleAbiListQuery();
             }
 
+            if (parsedArgs.preloadPackage != null) {
+                return handlePreloadPackage(parsedArgs.preloadPackage,
+                        parsedArgs.preloadPackageLibs);
+            }
+
             if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
                 throw new ZygoteSecurityException("Client may not specify capabilities: " +
                         "permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) +
@@ -271,6 +277,10 @@
         }
     }
 
+    protected boolean handlePreloadPackage(String packagePath, String libsPath) {
+        throw new RuntimeException("Zyogte does not support package preloading");
+    }
+
     /**
      * Closes socket associated with this connection.
      */
@@ -376,6 +386,12 @@
         String appDataDir;
 
         /**
+         * Whether to preload a package, with the package path in the remainingArgs.
+         */
+        String preloadPackage;
+        String preloadPackageLibs;
+
+        /**
          * Constructs instance and parses args
          * @param args zygote command-line args
          * @throws IllegalArgumentException
@@ -533,6 +549,9 @@
                     instructionSet = arg.substring(arg.indexOf('=') + 1);
                 } else if (arg.startsWith("--app-data-dir=")) {
                     appDataDir = arg.substring(arg.indexOf('=') + 1);
+                } else if (arg.equals("--preload-package")) {
+                    preloadPackage = args[++curArg];
+                    preloadPackageLibs = args[++curArg];
                 } else {
                     break;
                 }
@@ -542,6 +561,11 @@
                 if (args.length - curArg > 0) {
                     throw new IllegalArgumentException("Unexpected arguments after --query-abi-list.");
                 }
+            } else if (preloadPackage != null) {
+                if (args.length - curArg > 0) {
+                    throw new IllegalArgumentException(
+                            "Unexpected arguments after --preload-package.");
+                }
             } else {
                 if (!seenRuntimeArgs) {
                     throw new IllegalArgumentException("Unexpected argument : " + args[curArg]);
diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java
index ab876410..126d9e7 100644
--- a/core/java/com/android/internal/os/ZygoteServer.java
+++ b/core/java/com/android/internal/os/ZygoteServer.java
@@ -19,6 +19,7 @@
 import static android.system.OsConstants.POLLIN;
 
 import android.net.LocalServerSocket;
+import android.net.LocalSocket;
 import android.system.Os;
 import android.system.ErrnoException;
 import android.system.StructPollfd;
@@ -80,13 +81,18 @@
      */
     private ZygoteConnection acceptCommandPeer(String abiList) {
         try {
-            return new ZygoteConnection(mServerSocket.accept(), abiList);
+            return createNewConnection(mServerSocket.accept(), abiList);
         } catch (IOException ex) {
             throw new RuntimeException(
                     "IOException during accept()", ex);
         }
     }
 
+    protected ZygoteConnection createNewConnection(LocalSocket socket, String abiList)
+            throws IOException {
+        return new ZygoteConnection(socket, abiList);
+    }
+
     /**
      * Close and clean up zygote sockets. Called on shutdown and on the
      * child's exit path.
diff --git a/core/java/com/android/internal/policy/PipMotionHelper.java b/core/java/com/android/internal/policy/PipMotionHelper.java
new file mode 100644
index 0000000..0543442
--- /dev/null
+++ b/core/java/com/android/internal/policy/PipMotionHelper.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 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.policy;
+
+import android.animation.RectEvaluator;
+import android.animation.ValueAnimator;
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
+
+/**
+ * A helper to animate the PIP.
+ */
+public class PipMotionHelper {
+
+    private static final String TAG = "PipMotionHelper";
+
+    private static final RectEvaluator RECT_EVALUATOR = new RectEvaluator(new Rect());
+    private static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
+    private static final int DEFAULT_DURATION = 225;
+
+    private IActivityManager mActivityManager;
+    private Handler mHandler;
+
+    public PipMotionHelper(Handler handler) {
+        mHandler = handler;
+    }
+
+    /**
+     * Moves the PIP to give given {@param bounds}.
+     */
+    public void resizeToBounds(Rect toBounds) {
+        mHandler.post(() -> {
+            if (mActivityManager == null) {
+                mActivityManager = ActivityManagerNative.getDefault();
+            }
+            try {
+                mActivityManager.resizePinnedStack(toBounds, null /* tempPinnedTaskBounds */);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not move pinned stack to bounds: " + toBounds, e);
+            }
+        });
+    }
+
+    /**
+     * Creates an animation to move the PIP to give given {@param toBounds} with the default
+     * animation properties.
+     */
+    public ValueAnimator createAnimationToBounds(Rect fromBounds, Rect toBounds) {
+        return createAnimationToBounds(fromBounds, toBounds, DEFAULT_DURATION, FAST_OUT_SLOW_IN,
+                null);
+    }
+
+    /**
+     * Creates an animation to move the PIP to give given {@param toBounds}.
+     */
+    public ValueAnimator createAnimationToBounds(Rect fromBounds, Rect toBounds, int duration,
+            Interpolator interpolator, ValueAnimator.AnimatorUpdateListener updateListener) {
+        ValueAnimator anim = ValueAnimator.ofObject(RECT_EVALUATOR, fromBounds, toBounds);
+        anim.setDuration(duration);
+        anim.setInterpolator(interpolator);
+        anim.addUpdateListener((ValueAnimator animation) -> {
+            resizeToBounds((Rect) animation.getAnimatedValue());
+        });
+        if (updateListener != null) {
+            anim.addUpdateListener(updateListener);
+        }
+        return anim;
+    }
+
+
+}
diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
new file mode 100644
index 0000000..51804b0
--- /dev/null
+++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2016 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.policy;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.view.Gravity;
+import android.view.ViewConfiguration;
+import android.widget.Scroller;
+
+import java.util.ArrayList;
+
+/**
+ * Calculates the snap targets and the snap position for the PIP given a position and a velocity.
+ * All bounds are relative to the display top/left.
+ */
+public class PipSnapAlgorithm {
+
+    // Allows snapping to the four corners
+    private static final int SNAP_MODE_CORNERS_ONLY = 0;
+    // Allows snapping to the four corners and the mid-points on the long edge in each orientation
+    private static final int SNAP_MODE_CORNERS_AND_SIDES = 1;
+    // Allows snapping to anywhere along the edge of the screen
+    private static final int SNAP_MODE_EDGE = 2;
+
+    private static final float SCROLL_FRICTION_MULTIPLIER = 8f;
+
+    private final Context mContext;
+
+    private final ArrayList<Integer> mSnapGravities = new ArrayList<>();
+    private final int mSnapMode = SNAP_MODE_CORNERS_ONLY;
+
+    private Scroller mScroller;
+    private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
+
+    public PipSnapAlgorithm(Context context) {
+        mContext = context;
+        mOrientation = context.getResources().getConfiguration().orientation;
+        calculateSnapTargets();
+    }
+
+    /**
+     * @return the closest absolute snap stack bounds for the given {@param stackBounds} moving at
+     * the given {@param velocityX} and {@param velocityY}.  The {@param movementBounds} should be
+     * those for the given {@param stackBounds}.
+     */
+    public Rect findClosestSnapBounds(Rect movementBounds, Rect stackBounds, float velocityX,
+            float velocityY) {
+        final Rect finalStackBounds = new Rect(stackBounds);
+        if (mScroller == null) {
+            final ViewConfiguration viewConfig = ViewConfiguration.get(mContext);
+            mScroller = new Scroller(mContext);
+            mScroller.setFriction(viewConfig.getScrollFriction() * SCROLL_FRICTION_MULTIPLIER);
+        }
+        mScroller.fling(stackBounds.left, stackBounds.top,
+                (int) velocityX, (int) velocityY,
+                movementBounds.left, movementBounds.right,
+                movementBounds.top, movementBounds.bottom);
+        finalStackBounds.offsetTo(mScroller.getFinalX(), mScroller.getFinalY());
+        mScroller.abortAnimation();
+        return findClosestSnapBounds(movementBounds, finalStackBounds);
+    }
+
+    /**
+     * @return the closest absolute snap stack bounds for the given {@param stackBounds}.  The
+     * {@param movementBounds} should be those for the given {@param stackBounds}.
+     */
+    public Rect findClosestSnapBounds(Rect movementBounds, Rect stackBounds) {
+        final Rect pipBounds = new Rect(movementBounds.left, movementBounds.top,
+                movementBounds.right + stackBounds.width(),
+                movementBounds.bottom + stackBounds.height());
+        final Rect newBounds = new Rect(stackBounds);
+        if (mSnapMode == SNAP_MODE_EDGE) {
+            // Find the closest edge to the given stack bounds and snap to it
+            final int fromLeft = stackBounds.left - movementBounds.left;
+            final int fromTop = stackBounds.top - movementBounds.top;
+            final int fromRight = movementBounds.right - stackBounds.left;
+            final int fromBottom = movementBounds.bottom - stackBounds.top;
+            if (fromLeft <= fromTop && fromLeft <= fromRight && fromLeft <= fromBottom) {
+                newBounds.offset(-fromLeft, 0);
+            } else if (fromTop <= fromLeft && fromTop <= fromRight && fromTop <= fromBottom) {
+                newBounds.offset(0, -fromTop);
+            } else if (fromRight < fromLeft && fromRight < fromTop && fromRight < fromBottom) {
+                newBounds.offset(fromRight, 0);
+            } else {
+                newBounds.offset(0, fromBottom);
+            }
+        } else {
+            // Find the closest snap point
+            final Rect tmpBounds = new Rect();
+            final Point[] snapTargets = new Point[mSnapGravities.size()];
+            for (int i = 0; i < mSnapGravities.size(); i++) {
+                Gravity.apply(mSnapGravities.get(i), stackBounds.width(), stackBounds.height(),
+                        pipBounds, 0, 0, tmpBounds);
+                snapTargets[i] = new Point(tmpBounds.left, tmpBounds.top);
+            }
+            Point snapTarget = findClosestPoint(stackBounds.left, stackBounds.top, snapTargets);
+            newBounds.offsetTo(snapTarget.x, snapTarget.y);
+        }
+        return newBounds;
+    }
+
+    /**
+     * @return the closest point in {@param points} to the given {@param x} and {@param y}.
+     */
+    private Point findClosestPoint(int x, int y, Point[] points) {
+        Point closestPoint = null;
+        float minDistance = Float.MAX_VALUE;
+        for (Point p : points) {
+            float distance = distanceToPoint(p, x, y);
+            if (distance < minDistance) {
+                closestPoint = p;
+                minDistance = distance;
+            }
+        }
+        return closestPoint;
+    }
+
+    /**
+     * @return the distance between point {@param p} and the given {@param x} and {@param y}.
+     */
+    private float distanceToPoint(Point p, int x, int y) {
+        return PointF.length(p.x - x, p.y - y);
+    }
+
+    /**
+     * Calculate the snap targets for the discrete snap modes.
+     */
+    private void calculateSnapTargets() {
+        mSnapGravities.clear();
+        switch (mSnapMode) {
+            case SNAP_MODE_CORNERS_AND_SIDES:
+                if (mOrientation == Configuration.ORIENTATION_LANDSCAPE) {
+                    mSnapGravities.add(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
+                    mSnapGravities.add(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
+                } else {
+                    mSnapGravities.add(Gravity.CENTER_VERTICAL | Gravity.LEFT);
+                    mSnapGravities.add(Gravity.CENTER_VERTICAL | Gravity.RIGHT);
+                }
+                // Fall through
+            case SNAP_MODE_CORNERS_ONLY:
+                mSnapGravities.add(Gravity.TOP | Gravity.LEFT);
+                mSnapGravities.add(Gravity.TOP | Gravity.RIGHT);
+                mSnapGravities.add(Gravity.BOTTOM | Gravity.LEFT);
+                mSnapGravities.add(Gravity.BOTTOM | Gravity.RIGHT);
+                break;
+            default:
+                // Skip otherwise
+                break;
+        }
+    }
+}
diff --git a/core/java/com/android/internal/util/TokenBucket.java b/core/java/com/android/internal/util/TokenBucket.java
new file mode 100644
index 0000000..effb82b
--- /dev/null
+++ b/core/java/com/android/internal/util/TokenBucket.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2016 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 android.os.SystemClock;
+
+import static com.android.internal.util.Preconditions.checkArgumentNonnegative;
+import static com.android.internal.util.Preconditions.checkArgumentPositive;
+
+/**
+ * A class useful for rate-limiting or throttling that stores and distributes tokens.
+ *
+ * A TokenBucket starts with a fixed capacity of tokens, an initial amount of tokens, and
+ * a fixed filling period (in milliseconds).
+ *
+ * For every filling period, the bucket gains one token, up to its maximum capacity from
+ * which point tokens simply overflow and are lost. Tokens can be obtained one by one or n by n.
+ *
+ * The available amount of tokens is computed lazily when the bucket state is inspected.
+ * Therefore it is purely synchronous and does not involve any asynchronous activity.
+ * It is not synchronized in any way and not a thread-safe object.
+ */
+public class TokenBucket {
+
+    private final int mFillDelta; // Time in ms it takes to generate one token.
+    private final int mCapacity;  // Maximum number of tokens that can be stored.
+    private long mLastFill;       // Last time in ms the bucket generated tokens.
+    private int mAvailable;       // Current number of available tokens.
+
+    /**
+     * Create a new TokenBucket.
+     * @param deltaMs the time in milliseconds it takes to generate a new token.
+     * Must be strictly positive.
+     * @param capacity the maximum token capacity. Must be strictly positive.
+     * @param tokens the starting amount of token. Must be positive or zero.
+     */
+    public TokenBucket(int deltaMs, int capacity, int tokens) {
+        mFillDelta = checkArgumentPositive(deltaMs, "deltaMs must be strictly positive");
+        mCapacity = checkArgumentPositive(capacity, "capacity must be strictly positive");
+        mAvailable = Math.min(checkArgumentNonnegative(tokens), mCapacity);
+        mLastFill = scaledTime();
+    }
+
+    /**
+     * Create a new TokenBucket that starts completely filled.
+     * @param deltaMs the time in milliseconds it takes to generate a new token.
+     * Must be strictly positive.
+     * @param capacity the maximum token capacity. Must be strictly positive.
+     */
+    public TokenBucket(int deltaMs, int capacity) {
+        this(deltaMs, capacity, capacity);
+    }
+
+    /** Reset this TokenBucket and set its number of available tokens. */
+    public void reset(int tokens) {
+        checkArgumentNonnegative(tokens);
+        mAvailable = Math.min(tokens, mCapacity);
+        mLastFill = scaledTime();
+    }
+
+    /** Returns this TokenBucket maximum token capacity. */
+    public int capacity() {
+        return mCapacity;
+    }
+
+    /** Returns this TokenBucket currently number of available tokens. */
+    public int available() {
+        fill();
+        return mAvailable;
+    }
+
+    /** Returns true if this TokenBucket as one or more tokens available. */
+    public boolean has() {
+        fill();
+        return mAvailable > 0;
+    }
+
+    /** Consumes a token from this TokenBucket and returns true if a token is available. */
+    public boolean get() {
+        return (get(1) == 1);
+    }
+
+    /**
+     * Try to consume many tokens from this TokenBucket.
+     * @param n the number of tokens to consume.
+     * @return the number of tokens that were actually consumed.
+     */
+    public int get(int n) {
+        fill();
+        if (n <= 0) {
+            return 0;
+        }
+        if (n > mAvailable) {
+            int got = mAvailable;
+            mAvailable = 0;
+            return got;
+        }
+        mAvailable -= n;
+        return n;
+    }
+
+    private void fill() {
+        final long now = scaledTime();
+        final int diff = (int) (now - mLastFill);
+        mAvailable = Math.min(mCapacity, mAvailable + diff);
+        mLastFill = now;
+    }
+
+    private long scaledTime() {
+        return SystemClock.elapsedRealtime() / mFillDelta;
+    }
+}
diff --git a/core/java/com/android/internal/view/BaseSurfaceHolder.java b/core/java/com/android/internal/view/BaseSurfaceHolder.java
index f9f94be..b41ef29 100644
--- a/core/java/com/android/internal/view/BaseSurfaceHolder.java
+++ b/core/java/com/android/internal/view/BaseSurfaceHolder.java
@@ -153,15 +153,22 @@
         }
     }
 
+    @Override
     public Canvas lockCanvas() {
-        return internalLockCanvas(null);
+        return internalLockCanvas(null, false);
     }
 
+    @Override
     public Canvas lockCanvas(Rect dirty) {
-        return internalLockCanvas(dirty);
+        return internalLockCanvas(dirty, false);
     }
 
-    private final Canvas internalLockCanvas(Rect dirty) {
+    @Override
+    public Canvas lockHardwareCanvas() {
+        return internalLockCanvas(null, true);
+    }
+
+    private final Canvas internalLockCanvas(Rect dirty, boolean hardware) {
         if (mType == SURFACE_TYPE_PUSH_BUFFERS) {
             throw new BadSurfaceTypeException(
                     "Surface type is SURFACE_TYPE_PUSH_BUFFERS");
@@ -181,7 +188,11 @@
             }
 
             try {
-                c = mSurface.lockCanvas(dirty);
+                if (hardware) {
+                    c = mSurface.lockHardwareCanvas();
+                } else {
+                    c = mSurface.lockCanvas(dirty);
+                }
             } catch (Exception e) {
                 Log.e(TAG, "Exception locking surface", e);
             }
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 0e07bf8..71252fb 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.app.admin.DevicePolicyManager;
+import android.app.admin.PasswordMetrics;
 import android.app.trust.IStrongAuthTracker;
 import android.app.trust.TrustManager;
 import android.content.ComponentName;
@@ -137,10 +138,6 @@
     private static final String ENABLED_TRUST_AGENTS = "lockscreen.enabledtrustagents";
     private static final String IS_TRUST_USUALLY_MANAGED = "lockscreen.istrustusuallymanaged";
 
-    // Maximum allowed number of repeated or ordered characters in a sequence before we'll
-    // consider it a complex PIN/password.
-    public static final int MAX_ALLOWED_SEQUENCE = 3;
-
     public static final String PROFILE_KEY_NAME_ENCRYPT = "profile_key_name_encrypt_";
     public static final String PROFILE_KEY_NAME_DECRYPT = "profile_key_name_decrypt_";
 
@@ -593,8 +590,7 @@
             setCredentialRequiredToDecrypt(false);
         }
 
-        getDevicePolicyManager().setActivePasswordState(
-                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0, userHandle);
+        getDevicePolicyManager().setActivePasswordState(new PasswordMetrics(), userHandle);
 
         onAfterChangingPassword(userHandle);
     }
@@ -665,8 +661,8 @@
             setBoolean(PATTERN_EVER_CHOSEN_KEY, true, userId);
 
             setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
-            dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
-                    pattern.size(), 0, 0, 0, 0, 0, 0, userId);
+            dpm.setActivePasswordState(new PasswordMetrics(
+                    DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern.size()), userId);
             onAfterChangingPassword(userId);
         } catch (RemoteException re) {
             Log.e(TAG, "Couldn't save lock pattern " + re);
@@ -736,96 +732,6 @@
         return getDeviceOwnerInfo() != null;
     }
 
-    /**
-     * Compute the password quality from the given password string.
-     */
-    static public int computePasswordQuality(String password) {
-        boolean hasDigit = false;
-        boolean hasNonDigit = false;
-        final int len = password.length();
-        for (int i = 0; i < len; i++) {
-            if (Character.isDigit(password.charAt(i))) {
-                hasDigit = true;
-            } else {
-                hasNonDigit = true;
-            }
-        }
-
-        if (hasNonDigit && hasDigit) {
-            return DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
-        }
-        if (hasNonDigit) {
-            return DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
-        }
-        if (hasDigit) {
-            return maxLengthSequence(password) > MAX_ALLOWED_SEQUENCE
-                    ? DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
-                    : DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
-        }
-        return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
-    }
-
-    private static int categoryChar(char c) {
-        if ('a' <= c && c <= 'z') return 0;
-        if ('A' <= c && c <= 'Z') return 1;
-        if ('0' <= c && c <= '9') return 2;
-        return 3;
-    }
-
-    private static int maxDiffCategory(int category) {
-        if (category == 0 || category == 1) return 1;
-        else if (category == 2) return 10;
-        return 0;
-    }
-
-    /*
-     * Returns the maximum length of a sequential characters.  A sequence is defined as
-     * monotonically increasing characters with a constant interval or the same character repeated.
-     *
-     * For example:
-     * maxLengthSequence("1234") == 4
-     * maxLengthSequence("1234abc") == 4
-     * maxLengthSequence("aabc") == 3
-     * maxLengthSequence("qwertyuio") == 1
-     * maxLengthSequence("@ABC") == 3
-     * maxLengthSequence(";;;;") == 4 (anything that repeats)
-     * maxLengthSequence(":;<=>") == 1  (ordered, but not composed of alphas or digits)
-     *
-     * @param string the pass
-     * @return the number of sequential letters or digits
-     */
-    public static int maxLengthSequence(String string) {
-        if (string.length() == 0) return 0;
-        char previousChar = string.charAt(0);
-        int category = categoryChar(previousChar); //current category of the sequence
-        int diff = 0; //difference between two consecutive characters
-        boolean hasDiff = false; //if we are currently targeting a sequence
-        int maxLength = 0; //maximum length of a sequence already found
-        int startSequence = 0; //where the current sequence started
-        for (int current = 1; current < string.length(); current++) {
-            char currentChar = string.charAt(current);
-            int categoryCurrent = categoryChar(currentChar);
-            int currentDiff = (int) currentChar - (int) previousChar;
-            if (categoryCurrent != category || Math.abs(currentDiff) > maxDiffCategory(category)) {
-                maxLength = Math.max(maxLength, current - startSequence);
-                startSequence = current;
-                hasDiff = false;
-                category = categoryCurrent;
-            }
-            else {
-                if(hasDiff && currentDiff != diff) {
-                    maxLength = Math.max(maxLength, current - startSequence);
-                    startSequence = current - 1;
-                }
-                diff = currentDiff;
-                hasDiff = true;
-            }
-            previousChar = currentChar;
-        }
-        maxLength = Math.max(maxLength, string.length() - startSequence);
-        return maxLength;
-    }
-
     /** Update the encryption password if it is enabled **/
     private void updateEncryptionPassword(final int type, final String password) {
         if (!isDeviceEncryptionEnabled()) {
@@ -871,7 +777,8 @@
 
             getLockSettings().setLockPassword(password, savedPassword, userHandle);
             getLockSettings().setSeparateProfileChallengeEnabled(userHandle, true, null);
-            int computedQuality = computePasswordQuality(password);
+            final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password);
+            final int computedQuality = metrics.quality;
 
             // Update the device encryption password.
             if (userHandle == UserHandle.USER_SYSTEM
@@ -891,36 +798,11 @@
 
             setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle);
             if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
-                int letters = 0;
-                int uppercase = 0;
-                int lowercase = 0;
-                int numbers = 0;
-                int symbols = 0;
-                int nonletter = 0;
-                for (int i = 0; i < password.length(); i++) {
-                    char c = password.charAt(i);
-                    if (c >= 'A' && c <= 'Z') {
-                        letters++;
-                        uppercase++;
-                    } else if (c >= 'a' && c <= 'z') {
-                        letters++;
-                        lowercase++;
-                    } else if (c >= '0' && c <= '9') {
-                        numbers++;
-                        nonletter++;
-                    } else {
-                        symbols++;
-                        nonletter++;
-                    }
-                }
-                dpm.setActivePasswordState(Math.max(quality, computedQuality),
-                        password.length(), letters, uppercase, lowercase,
-                        numbers, symbols, nonletter, userHandle);
+                metrics.quality = Math.max(quality, metrics.quality);
+                dpm.setActivePasswordState(metrics, userHandle);
             } else {
                 // The password is not anything.
-                dpm.setActivePasswordState(
-                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                        0, 0, 0, 0, 0, 0, 0, userHandle);
+                dpm.setActivePasswordState(new PasswordMetrics(), userHandle);
             }
 
             // Add the password to the password history. We assume all
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 7950685..506a284 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -119,12 +119,15 @@
     android/graphics/DrawFilter.cpp \
     android/graphics/FontFamily.cpp \
     android/graphics/CreateJavaOutputStreamAdaptor.cpp \
+    android/graphics/GIFMovie.cpp \
     android/graphics/Graphics.cpp \
     android/graphics/HarfBuzzNGFaceSkia.cpp \
     android/graphics/Interpolator.cpp \
     android/graphics/MaskFilter.cpp \
     android/graphics/Matrix.cpp \
     android/graphics/Movie.cpp \
+    android/graphics/MovieImpl.cpp \
+    android/graphics/Movie_FactoryDefault.cpp \
     android/graphics/NinePatch.cpp \
     android/graphics/NinePatchPeeker.cpp \
     android/graphics/Paint.cpp \
@@ -200,6 +203,7 @@
     $(TOP)/system/core/include \
     $(TOP)/system/media/camera/include \
     $(TOP)/system/netd/include \
+    external/giflib \
     external/pdfium/core/include/fpdfapi \
     external/pdfium/fpdfsdk/include \
     external/pdfium/public \
@@ -219,6 +223,9 @@
     external/freetype/include
 # TODO: clean up Minikin so it doesn't need the freetype include
 
+LOCAL_STATIC_LIBRARIES := \
+    libgif \
+
 LOCAL_SHARED_LIBRARIES := \
     libmemtrack \
     libandroidfw \
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 6419aa4..467ec37 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -52,7 +52,7 @@
     }
 
     bool valid() {
-        return !!mBitmap;
+        return mBitmap;
     }
 
     Bitmap& bitmap() {
@@ -212,6 +212,12 @@
     return localBitmap->bitmap();
 }
 
+Bitmap& toBitmap(JNIEnv* env, jlong bitmapHandle) {
+    SkASSERT(env);
+    LocalScopedBitmap localBitmap(bitmapHandle);
+    return localBitmap->bitmap();
+}
+
 } // namespace bitmap
 
 } // namespace android
@@ -1199,9 +1205,7 @@
 static void Bitmap_prepareToDraw(JNIEnv* env, jobject, jlong bitmapPtr) {
     LocalScopedBitmap bitmapHandle(bitmapPtr);
     if (!bitmapHandle.valid()) return;
-    SkBitmap bitmap;
-    bitmapHandle->getSkBitmap(&bitmap);
-    android::uirenderer::renderthread::RenderProxy::prepareToDraw(bitmap);
+    android::uirenderer::renderthread::RenderProxy::prepareToDraw(bitmapHandle->bitmap());
 }
 
 static jint Bitmap_getAllocationByteCount(JNIEnv* env, jobject, jlong bitmapPtr) {
diff --git a/core/jni/android/graphics/Bitmap.h b/core/jni/android/graphics/Bitmap.h
index ece7083..387a128 100644
--- a/core/jni/android/graphics/Bitmap.h
+++ b/core/jni/android/graphics/Bitmap.h
@@ -42,6 +42,7 @@
 void toSkBitmap(jlong bitmapHandle, SkBitmap* outBitmap);
 
 Bitmap& toBitmap(JNIEnv* env, jobject bitmap);
+Bitmap& toBitmap(JNIEnv* env, jlong bitmapHandle);
 
 /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in
     sync with isPremultiplied
diff --git a/core/jni/android/graphics/GIFMovie.cpp b/core/jni/android/graphics/GIFMovie.cpp
new file mode 100644
index 0000000..035417e
--- /dev/null
+++ b/core/jni/android/graphics/GIFMovie.cpp
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "Movie.h"
+#include "SkColor.h"
+#include "SkColorPriv.h"
+#include "SkStream.h"
+#include "SkTemplates.h"
+#include "SkUtils.h"
+
+#include "gif_lib.h"
+
+#if GIFLIB_MAJOR < 5 || (GIFLIB_MAJOR == 5 && GIFLIB_MINOR == 0)
+#define DGifCloseFile(a, b) DGifCloseFile(a)
+#endif
+
+class GIFMovie : public Movie {
+public:
+    GIFMovie(SkStream* stream);
+    virtual ~GIFMovie();
+
+protected:
+    virtual bool onGetInfo(Info*);
+    virtual bool onSetTime(SkMSec);
+    virtual bool onGetBitmap(SkBitmap*);
+
+private:
+    GifFileType* fGIF;
+    int fCurrIndex;
+    int fLastDrawIndex;
+    SkBitmap fBackup;
+    SkColor fPaintingColor;
+};
+
+static int Decode(GifFileType* fileType, GifByteType* out, int size) {
+    SkStream* stream = (SkStream*) fileType->UserData;
+    return (int) stream->read(out, size);
+}
+
+GIFMovie::GIFMovie(SkStream* stream)
+{
+#if GIFLIB_MAJOR < 5
+    fGIF = DGifOpen( stream, Decode );
+#else
+    fGIF = DGifOpen( stream, Decode, nullptr );
+#endif
+    if (nullptr == fGIF)
+        return;
+
+    if (DGifSlurp(fGIF) != GIF_OK)
+    {
+        DGifCloseFile(fGIF, nullptr);
+        fGIF = nullptr;
+    }
+    fCurrIndex = -1;
+    fLastDrawIndex = -1;
+    fPaintingColor = SkPackARGB32(0, 0, 0, 0);
+}
+
+GIFMovie::~GIFMovie()
+{
+    if (fGIF)
+        DGifCloseFile(fGIF, nullptr);
+}
+
+static SkMSec savedimage_duration(const SavedImage* image)
+{
+    for (int j = 0; j < image->ExtensionBlockCount; j++)
+    {
+        if (image->ExtensionBlocks[j].Function == GRAPHICS_EXT_FUNC_CODE)
+        {
+            SkASSERT(image->ExtensionBlocks[j].ByteCount >= 4);
+            const uint8_t* b = (const uint8_t*)image->ExtensionBlocks[j].Bytes;
+            return ((b[2] << 8) | b[1]) * 10;
+        }
+    }
+    return 0;
+}
+
+bool GIFMovie::onGetInfo(Info* info)
+{
+    if (nullptr == fGIF)
+        return false;
+
+    SkMSec dur = 0;
+    for (int i = 0; i < fGIF->ImageCount; i++)
+        dur += savedimage_duration(&fGIF->SavedImages[i]);
+
+    info->fDuration = dur;
+    info->fWidth = fGIF->SWidth;
+    info->fHeight = fGIF->SHeight;
+    info->fIsOpaque = false;    // how to compute?
+    return true;
+}
+
+bool GIFMovie::onSetTime(SkMSec time)
+{
+    if (nullptr == fGIF)
+        return false;
+
+    SkMSec dur = 0;
+    for (int i = 0; i < fGIF->ImageCount; i++)
+    {
+        dur += savedimage_duration(&fGIF->SavedImages[i]);
+        if (dur >= time)
+        {
+            fCurrIndex = i;
+            return fLastDrawIndex != fCurrIndex;
+        }
+    }
+    fCurrIndex = fGIF->ImageCount - 1;
+    return true;
+}
+
+static void copyLine(uint32_t* dst, const unsigned char* src, const ColorMapObject* cmap,
+                     int transparent, int width)
+{
+    for (; width > 0; width--, src++, dst++) {
+        if (*src != transparent) {
+            const GifColorType& col = cmap->Colors[*src];
+            *dst = SkPackARGB32(0xFF, col.Red, col.Green, col.Blue);
+        }
+    }
+}
+
+#if GIFLIB_MAJOR < 5
+static void copyInterlaceGroup(SkBitmap* bm, const unsigned char*& src,
+                               const ColorMapObject* cmap, int transparent, int copyWidth,
+                               int copyHeight, const GifImageDesc& imageDesc, int rowStep,
+                               int startRow)
+{
+    int row;
+    // every 'rowStep'th row, starting with row 'startRow'
+    for (row = startRow; row < copyHeight; row += rowStep) {
+        uint32_t* dst = bm->getAddr32(imageDesc.Left, imageDesc.Top + row);
+        copyLine(dst, src, cmap, transparent, copyWidth);
+        src += imageDesc.Width;
+    }
+
+    // pad for rest height
+    src += imageDesc.Width * ((imageDesc.Height - row + rowStep - 1) / rowStep);
+}
+
+static void blitInterlace(SkBitmap* bm, const SavedImage* frame, const ColorMapObject* cmap,
+                          int transparent)
+{
+    int width = bm->width();
+    int height = bm->height();
+    GifWord copyWidth = frame->ImageDesc.Width;
+    if (frame->ImageDesc.Left + copyWidth > width) {
+        copyWidth = width - frame->ImageDesc.Left;
+    }
+
+    GifWord copyHeight = frame->ImageDesc.Height;
+    if (frame->ImageDesc.Top + copyHeight > height) {
+        copyHeight = height - frame->ImageDesc.Top;
+    }
+
+    // deinterlace
+    const unsigned char* src = (unsigned char*)frame->RasterBits;
+
+    // group 1 - every 8th row, starting with row 0
+    copyInterlaceGroup(bm, src, cmap, transparent, copyWidth, copyHeight, frame->ImageDesc, 8, 0);
+
+    // group 2 - every 8th row, starting with row 4
+    copyInterlaceGroup(bm, src, cmap, transparent, copyWidth, copyHeight, frame->ImageDesc, 8, 4);
+
+    // group 3 - every 4th row, starting with row 2
+    copyInterlaceGroup(bm, src, cmap, transparent, copyWidth, copyHeight, frame->ImageDesc, 4, 2);
+
+    copyInterlaceGroup(bm, src, cmap, transparent, copyWidth, copyHeight, frame->ImageDesc, 2, 1);
+}
+#endif
+
+static void blitNormal(SkBitmap* bm, const SavedImage* frame, const ColorMapObject* cmap,
+                       int transparent)
+{
+    int width = bm->width();
+    int height = bm->height();
+    const unsigned char* src = (unsigned char*)frame->RasterBits;
+    uint32_t* dst = bm->getAddr32(frame->ImageDesc.Left, frame->ImageDesc.Top);
+    GifWord copyWidth = frame->ImageDesc.Width;
+    if (frame->ImageDesc.Left + copyWidth > width) {
+        copyWidth = width - frame->ImageDesc.Left;
+    }
+
+    GifWord copyHeight = frame->ImageDesc.Height;
+    if (frame->ImageDesc.Top + copyHeight > height) {
+        copyHeight = height - frame->ImageDesc.Top;
+    }
+
+    for (; copyHeight > 0; copyHeight--) {
+        copyLine(dst, src, cmap, transparent, copyWidth);
+        src += frame->ImageDesc.Width;
+        dst += width;
+    }
+}
+
+static void fillRect(SkBitmap* bm, GifWord left, GifWord top, GifWord width, GifWord height,
+                     uint32_t col)
+{
+    int bmWidth = bm->width();
+    int bmHeight = bm->height();
+    uint32_t* dst = bm->getAddr32(left, top);
+    GifWord copyWidth = width;
+    if (left + copyWidth > bmWidth) {
+        copyWidth = bmWidth - left;
+    }
+
+    GifWord copyHeight = height;
+    if (top + copyHeight > bmHeight) {
+        copyHeight = bmHeight - top;
+    }
+
+    for (; copyHeight > 0; copyHeight--) {
+        sk_memset32(dst, col, copyWidth);
+        dst += bmWidth;
+    }
+}
+
+static void drawFrame(SkBitmap* bm, const SavedImage* frame, const ColorMapObject* cmap)
+{
+    int transparent = -1;
+
+    for (int i = 0; i < frame->ExtensionBlockCount; ++i) {
+        ExtensionBlock* eb = frame->ExtensionBlocks + i;
+        if (eb->Function == GRAPHICS_EXT_FUNC_CODE &&
+            eb->ByteCount == 4) {
+            bool has_transparency = ((eb->Bytes[0] & 1) == 1);
+            if (has_transparency) {
+                transparent = (unsigned char)eb->Bytes[3];
+            }
+        }
+    }
+
+    if (frame->ImageDesc.ColorMap != nullptr) {
+        // use local color table
+        cmap = frame->ImageDesc.ColorMap;
+    }
+
+    if (cmap == nullptr || cmap->ColorCount != (1 << cmap->BitsPerPixel)) {
+        SkDEBUGFAIL("bad colortable setup");
+        return;
+    }
+
+#if GIFLIB_MAJOR < 5
+    // before GIFLIB 5, de-interlacing wasn't done by library at load time
+    if (frame->ImageDesc.Interlace) {
+        blitInterlace(bm, frame, cmap, transparent);
+        return;
+    }
+#endif
+
+    blitNormal(bm, frame, cmap, transparent);
+}
+
+static bool checkIfWillBeCleared(const SavedImage* frame)
+{
+    for (int i = 0; i < frame->ExtensionBlockCount; ++i) {
+        ExtensionBlock* eb = frame->ExtensionBlocks + i;
+        if (eb->Function == GRAPHICS_EXT_FUNC_CODE &&
+            eb->ByteCount == 4) {
+            // check disposal method
+            int disposal = ((eb->Bytes[0] >> 2) & 7);
+            if (disposal == 2 || disposal == 3) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+static void getTransparencyAndDisposalMethod(const SavedImage* frame, bool* trans, int* disposal)
+{
+    *trans = false;
+    *disposal = 0;
+    for (int i = 0; i < frame->ExtensionBlockCount; ++i) {
+        ExtensionBlock* eb = frame->ExtensionBlocks + i;
+        if (eb->Function == GRAPHICS_EXT_FUNC_CODE &&
+            eb->ByteCount == 4) {
+            *trans = ((eb->Bytes[0] & 1) == 1);
+            *disposal = ((eb->Bytes[0] >> 2) & 7);
+        }
+    }
+}
+
+// return true if area of 'target' is completely covers area of 'covered'
+static bool checkIfCover(const SavedImage* target, const SavedImage* covered)
+{
+    if (target->ImageDesc.Left <= covered->ImageDesc.Left
+        && covered->ImageDesc.Left + covered->ImageDesc.Width <=
+               target->ImageDesc.Left + target->ImageDesc.Width
+        && target->ImageDesc.Top <= covered->ImageDesc.Top
+        && covered->ImageDesc.Top + covered->ImageDesc.Height <=
+               target->ImageDesc.Top + target->ImageDesc.Height) {
+        return true;
+    }
+    return false;
+}
+
+static void disposeFrameIfNeeded(SkBitmap* bm, const SavedImage* cur, const SavedImage* next,
+                                 SkBitmap* backup, SkColor color)
+{
+    // We can skip disposal process if next frame is not transparent
+    // and completely covers current area
+    bool curTrans;
+    int curDisposal;
+    getTransparencyAndDisposalMethod(cur, &curTrans, &curDisposal);
+    bool nextTrans;
+    int nextDisposal;
+    getTransparencyAndDisposalMethod(next, &nextTrans, &nextDisposal);
+    if ((curDisposal == 2 || curDisposal == 3)
+        && (nextTrans || !checkIfCover(next, cur))) {
+        switch (curDisposal) {
+        // restore to background color
+        // -> 'background' means background under this image.
+        case 2:
+            fillRect(bm, cur->ImageDesc.Left, cur->ImageDesc.Top,
+                     cur->ImageDesc.Width, cur->ImageDesc.Height,
+                     color);
+            break;
+
+        // restore to previous
+        case 3:
+            bm->swap(*backup);
+            break;
+        }
+    }
+
+    // Save current image if next frame's disposal method == 3
+    if (nextDisposal == 3) {
+        const uint32_t* src = bm->getAddr32(0, 0);
+        uint32_t* dst = backup->getAddr32(0, 0);
+        int cnt = bm->width() * bm->height();
+        memcpy(dst, src, cnt*sizeof(uint32_t));
+    }
+}
+
+bool GIFMovie::onGetBitmap(SkBitmap* bm)
+{
+    const GifFileType* gif = fGIF;
+    if (nullptr == gif)
+        return false;
+
+    if (gif->ImageCount < 1) {
+        return false;
+    }
+
+    const int width = gif->SWidth;
+    const int height = gif->SHeight;
+    if (width <= 0 || height <= 0) {
+        return false;
+    }
+
+    // no need to draw
+    if (fLastDrawIndex >= 0 && fLastDrawIndex == fCurrIndex) {
+        return true;
+    }
+
+    int startIndex = fLastDrawIndex + 1;
+    if (fLastDrawIndex < 0 || !bm->readyToDraw()) {
+        // first time
+
+        startIndex = 0;
+
+        // create bitmap
+        if (!bm->tryAllocN32Pixels(width, height)) {
+            return false;
+        }
+        // create bitmap for backup
+        if (!fBackup.tryAllocN32Pixels(width, height)) {
+            return false;
+        }
+    } else if (startIndex > fCurrIndex) {
+        // rewind to 1st frame for repeat
+        startIndex = 0;
+    }
+
+    int lastIndex = fCurrIndex;
+    if (lastIndex < 0) {
+        // first time
+        lastIndex = 0;
+    } else if (lastIndex > fGIF->ImageCount - 1) {
+        // this block must not be reached.
+        lastIndex = fGIF->ImageCount - 1;
+    }
+
+    SkColor bgColor = SkPackARGB32(0, 0, 0, 0);
+    if (gif->SColorMap != nullptr) {
+        const GifColorType& col = gif->SColorMap->Colors[fGIF->SBackGroundColor];
+        bgColor = SkColorSetARGB(0xFF, col.Red, col.Green, col.Blue);
+    }
+
+    // draw each frames - not intelligent way
+    for (int i = startIndex; i <= lastIndex; i++) {
+        const SavedImage* cur = &fGIF->SavedImages[i];
+        if (i == 0) {
+            bool trans;
+            int disposal;
+            getTransparencyAndDisposalMethod(cur, &trans, &disposal);
+            if (!trans && gif->SColorMap != nullptr) {
+                fPaintingColor = bgColor;
+            } else {
+                fPaintingColor = SkColorSetARGB(0, 0, 0, 0);
+            }
+
+            bm->eraseColor(fPaintingColor);
+            fBackup.eraseColor(fPaintingColor);
+        } else {
+            // Dispose previous frame before move to next frame.
+            const SavedImage* prev = &fGIF->SavedImages[i-1];
+            disposeFrameIfNeeded(bm, prev, cur, &fBackup, fPaintingColor);
+        }
+
+        // Draw frame
+        // We can skip this process if this index is not last and disposal
+        // method == 2 or method == 3
+        if (i == lastIndex || !checkIfWillBeCleared(cur)) {
+            drawFrame(bm, cur, gif->SColorMap);
+        }
+    }
+
+    // save index
+    fLastDrawIndex = lastIndex;
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkTRegistry.h"
+
+Movie* Factory(SkStreamRewindable* stream) {
+    char buf[GIF_STAMP_LEN];
+    if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) {
+        if (memcmp(GIF_STAMP,   buf, GIF_STAMP_LEN) == 0 ||
+                memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 ||
+                memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0) {
+            // must rewind here, since our construct wants to re-read the data
+            stream->rewind();
+            return new GIFMovie(stream);
+        }
+    }
+    return nullptr;
+}
+
+static SkTRegistry<Movie*(*)(SkStreamRewindable*)> gReg(Factory);
diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp
index ad1b0c3..776ed66 100644
--- a/core/jni/android/graphics/Movie.cpp
+++ b/core/jni/android/graphics/Movie.cpp
@@ -2,7 +2,7 @@
 #include "GraphicsJNI.h"
 #include "ScopedLocalRef.h"
 #include "SkFrontBufferedStream.h"
-#include "SkMovie.h"
+#include "Movie.h"
 #include "SkStream.h"
 #include "SkUtils.h"
 #include "Utils.h"
@@ -19,7 +19,7 @@
 static jmethodID    gMovie_constructorMethodID;
 static jfieldID     gMovie_nativeInstanceID;
 
-jobject create_jmovie(JNIEnv* env, SkMovie* moov) {
+jobject create_jmovie(JNIEnv* env, Movie* moov) {
     if (NULL == moov) {
         return NULL;
     }
@@ -27,11 +27,11 @@
             static_cast<jlong>(reinterpret_cast<uintptr_t>(moov)));
 }
 
-static SkMovie* J2Movie(JNIEnv* env, jobject movie) {
+static Movie* J2Movie(JNIEnv* env, jobject movie) {
     SkASSERT(env);
     SkASSERT(movie);
     SkASSERT(env->IsInstanceOf(movie, gMovie_class));
-    SkMovie* m = (SkMovie*)env->GetLongField(movie, gMovie_nativeInstanceID);
+    Movie* m = (Movie*)env->GetLongField(movie, gMovie_nativeInstanceID);
     SkASSERT(m);
     return m;
 }
@@ -74,7 +74,7 @@
     // therefore may be NULL.
     SkASSERT(c != NULL);
 
-    SkMovie* m = J2Movie(env, movie);
+    Movie* m = J2Movie(env, movie);
     const SkBitmap& b = m->bitmap();
     sk_sp<android::Bitmap> wrapper = android::Bitmap::createFrom(b.info(), *b.pixelRef());
     c->drawBitmap(*wrapper, fx, fy, p);
@@ -84,7 +84,7 @@
     android::Asset* asset = reinterpret_cast<android::Asset*>(native_asset);
     if (asset == NULL) return NULL;
     android::AssetStreamAdaptor stream(asset);
-    SkMovie* moov = SkMovie::DecodeStream(&stream);
+    Movie* moov = Movie::DecodeStream(&stream);
     return create_jmovie(env, moov);
 }
 
@@ -107,7 +107,7 @@
     std::unique_ptr<SkStreamRewindable> bufferedStream(SkFrontBufferedStream::Create(strm, 6));
     SkASSERT(bufferedStream.get() != NULL);
 
-    SkMovie* moov = SkMovie::DecodeStream(bufferedStream.get());
+    Movie* moov = Movie::DecodeStream(bufferedStream.get());
     return create_jmovie(env, moov);
 }
 
@@ -124,12 +124,12 @@
     }
 
     AutoJavaByteArray   ar(env, byteArray);
-    SkMovie* moov = SkMovie::DecodeMemory(ar.ptr() + offset, length);
+    Movie* moov = Movie::DecodeMemory(ar.ptr() + offset, length);
     return create_jmovie(env, moov);
 }
 
 static void movie_destructor(JNIEnv* env, jobject, jlong movieHandle) {
-    SkMovie* movie = (SkMovie*) movieHandle;
+    Movie* movie = (Movie*) movieHandle;
     delete movie;
 }
 
diff --git a/core/jni/android/graphics/Movie.h b/core/jni/android/graphics/Movie.h
new file mode 100644
index 0000000..c0fbe4f
--- /dev/null
+++ b/core/jni/android/graphics/Movie.h
@@ -0,0 +1,78 @@
+
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef Movie_DEFINED
+#define Movie_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkCanvas.h"
+
+class SkStreamRewindable;
+
+class Movie : public SkRefCnt {
+public:
+    /** Try to create a movie from the stream. If the stream format is not
+        supported, return NULL.
+    */
+    static Movie* DecodeStream(SkStreamRewindable*);
+    /** Try to create a movie from the specified file path. If the file is not
+        found, or the format is not supported, return NULL. If a movie is
+        returned, the stream may be retained by the movie (via ref()) until
+        the movie is finished with it (by calling unref()).
+    */
+    static Movie* DecodeFile(const char path[]);
+    /** Try to create a movie from the specified memory.
+        If the format is not supported, return NULL. If a movie is returned,
+        the data will have been read or copied, and so the caller may free
+        it.
+    */
+    static Movie* DecodeMemory(const void* data, size_t length);
+
+    SkMSec  duration();
+    int     width();
+    int     height();
+    int     isOpaque();
+
+    /** Specify the time code (between 0...duration) to sample a bitmap
+        from the movie. Returns true if this time code generated a different
+        bitmap/frame from the previous state (i.e. true means you need to
+        redraw).
+    */
+    bool setTime(SkMSec);
+
+    // return the right bitmap for the current time code
+    const SkBitmap& bitmap();
+
+protected:
+    struct Info {
+        SkMSec  fDuration;
+        int     fWidth;
+        int     fHeight;
+        bool    fIsOpaque;
+    };
+
+    virtual bool onGetInfo(Info*) = 0;
+    virtual bool onSetTime(SkMSec) = 0;
+    virtual bool onGetBitmap(SkBitmap*) = 0;
+
+    // visible for subclasses
+    Movie();
+
+private:
+    Info        fInfo;
+    SkMSec      fCurrTime;
+    SkBitmap    fBitmap;
+    bool        fNeedBitmap;
+
+    void ensureInfo();
+
+    typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/core/jni/android/graphics/MovieImpl.cpp b/core/jni/android/graphics/MovieImpl.cpp
new file mode 100644
index 0000000..ae9e04e
--- /dev/null
+++ b/core/jni/android/graphics/MovieImpl.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "Movie.h"
+#include "SkCanvas.h"
+#include "SkPaint.h"
+
+// We should never see this in normal operation since our time values are
+// 0-based. So we use it as a sentinal.
+#define UNINITIALIZED_MSEC ((SkMSec)-1)
+
+Movie::Movie()
+{
+    fInfo.fDuration = UNINITIALIZED_MSEC;  // uninitialized
+    fCurrTime = UNINITIALIZED_MSEC; // uninitialized
+    fNeedBitmap = true;
+}
+
+void Movie::ensureInfo()
+{
+    if (fInfo.fDuration == UNINITIALIZED_MSEC && !this->onGetInfo(&fInfo))
+        memset(&fInfo, 0, sizeof(fInfo));   // failure
+}
+
+SkMSec Movie::duration()
+{
+    this->ensureInfo();
+    return fInfo.fDuration;
+}
+
+int Movie::width()
+{
+    this->ensureInfo();
+    return fInfo.fWidth;
+}
+
+int Movie::height()
+{
+    this->ensureInfo();
+    return fInfo.fHeight;
+}
+
+int Movie::isOpaque()
+{
+    this->ensureInfo();
+    return fInfo.fIsOpaque;
+}
+
+bool Movie::setTime(SkMSec time)
+{
+    SkMSec dur = this->duration();
+    if (time > dur)
+        time = dur;
+
+    bool changed = false;
+    if (time != fCurrTime)
+    {
+        fCurrTime = time;
+        changed = this->onSetTime(time);
+        fNeedBitmap |= changed;
+    }
+    return changed;
+}
+
+const SkBitmap& Movie::bitmap()
+{
+    if (fCurrTime == UNINITIALIZED_MSEC)    // uninitialized
+        this->setTime(0);
+
+    if (fNeedBitmap)
+    {
+        if (!this->onGetBitmap(&fBitmap))   // failure
+            fBitmap.reset();
+        fNeedBitmap = false;
+    }
+    return fBitmap;
+}
+
+////////////////////////////////////////////////////////////////////
+
+#include "SkStream.h"
+
+Movie* Movie::DecodeMemory(const void* data, size_t length) {
+    SkMemoryStream stream(data, length, false);
+    return Movie::DecodeStream(&stream);
+}
+
+Movie* Movie::DecodeFile(const char path[]) {
+    std::unique_ptr<SkStreamRewindable> stream = SkStream::MakeFromFile(path);
+    return stream ? Movie::DecodeStream(stream.get()) : nullptr;
+}
diff --git a/core/jni/android/graphics/Movie_FactoryDefault.cpp b/core/jni/android/graphics/Movie_FactoryDefault.cpp
new file mode 100644
index 0000000..175e0a6
--- /dev/null
+++ b/core/jni/android/graphics/Movie_FactoryDefault.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Movie.h"
+#include "SkStream.h"
+
+typedef SkTRegistry<Movie*(*)(SkStreamRewindable*)> MovieReg;
+
+Movie* Movie::DecodeStream(SkStreamRewindable* stream) {
+    const MovieReg* curr = MovieReg::Head();
+    while (curr) {
+        Movie* movie = curr->factory()(stream);
+        if (movie) {
+            return movie;
+        }
+        // we must rewind only if we got nullptr, since we gave the stream to the
+        // movie, who may have already started reading from it
+        stream->rewind();
+        curr = curr->next();
+    }
+    return nullptr;
+}
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index 4f2f389..91e5caf 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -26,10 +26,10 @@
 #include <ResourceCache.h>
 
 #include "SkCanvas.h"
+#include "SkLatticeIter.h"
 #include "SkRegion.h"
 #include "GraphicsJNI.h"
-
-#include "utils/NinePatch.h"
+#include "NinePatchUtils.h"
 
 #include "JNIHelp.h"
 #include "core_jni_helpers.h"
@@ -88,18 +88,40 @@
     }
 
     static jlong getTransparentRegion(JNIEnv* env, jobject, jobject jbitmap,
-            jlong chunkHandle, jobject boundsRect) {
+            jlong chunkHandle, jobject dstRect) {
         Res_png_9patch* chunk = reinterpret_cast<Res_png_9patch*>(chunkHandle);
         SkASSERT(chunk);
         SkASSERT(boundsRect);
 
         SkBitmap bitmap;
         GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
-        SkRect bounds;
-        GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds);
+        SkRect dst;
+        GraphicsJNI::jrect_to_rect(env, dstRect, &dst);
 
-        SkRegion* region = NULL;
-        NinePatch::Draw(NULL, bounds, bitmap, *chunk, NULL, &region);
+        SkCanvas::Lattice lattice;
+        SkIRect src = SkIRect::MakeWH(bitmap.width(), bitmap.height());
+        lattice.fBounds = &src;
+        NinePatchUtils::SetLatticeDivs(&lattice, *chunk, bitmap.width(), bitmap.height());
+        lattice.fFlags = nullptr;
+
+        SkRegion* region = nullptr;
+        if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), lattice)) {
+            SkLatticeIter iter(lattice, dst);
+            if (iter.numRectsToDraw() == chunk->numColors) {
+                SkRect dummy;
+                SkRect iterDst;
+                int index = 0;
+                while (iter.next(&dummy, &iterDst)) {
+                    if (0 == chunk->getColors()[index++] && !iterDst.isEmpty()) {
+                        if (!region) {
+                            region = new SkRegion();
+                        }
+
+                        region->op(iterDst.round(), SkRegion::kUnion_Op);
+                    }
+                }
+            }
+        }
 
         return reinterpret_cast<jlong>(region);
     }
diff --git a/core/jni/android/graphics/Picture.cpp b/core/jni/android/graphics/Picture.cpp
index d1ddfab..7b381b4 100644
--- a/core/jni/android/graphics/Picture.cpp
+++ b/core/jni/android/graphics/Picture.cpp
@@ -43,7 +43,7 @@
     mRecorder.reset(new SkPictureRecorder);
     mWidth = width;
     mHeight = height;
-    SkCanvas* canvas = mRecorder->beginRecording(width, height, NULL, 0);
+    SkCanvas* canvas = mRecorder->beginRecording(SkIntToScalar(width), SkIntToScalar(height));
     return Canvas::create_canvas(canvas);
 }
 
diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp
index b5960dd..b142925 100644
--- a/core/jni/android/graphics/pdf/PdfEditor.cpp
+++ b/core/jni/android/graphics/pdf/PdfEditor.cpp
@@ -13,6 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define LOG_TAG "PdfEditor"
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <vector>
+
+#include <android/log.h>
+#include <utils/Log.h>
 
 #include "PdfUtils.h"
 
@@ -30,11 +39,6 @@
 #include "SkMatrix.h"
 
 #include <core_jni_helpers.h>
-#include <vector>
-#include <utils/Log.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <unistd.h>
 
 namespace android {
 
@@ -77,8 +81,7 @@
             if (errno == EINTR) {
                 continue;
             }
-            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
-                    "Error writing to buffer: %d", errno);
+            ALOGE("Error writing to buffer: %d", errno);
             return false;
         }
         remainingBytes -= writtenByteCount;
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 6431b94..fd9e714 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -45,6 +45,7 @@
 
 #include "core_jni_helpers.h"
 
+#include "ScopedUtfChars.h"
 
 #define LOG_TRACE(...)
 //#define LOG_TRACE(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
@@ -264,103 +265,108 @@
         ALOGD("loadNativeCode_native");
     }
 
-    const char* pathStr = env->GetStringUTFChars(path, NULL);
+    ScopedUtfChars pathStr(env, path);
     std::unique_ptr<NativeCode> code;
-    bool needNativeBridge = false;
+    bool needs_native_bridge = false;
+    std::string error_msg;
 
-    void* handle = OpenNativeLibrary(env, sdkVersion, pathStr, classLoader, libraryPath);
-    if (handle == NULL) {
-        if (NativeBridgeIsSupported(pathStr)) {
-            handle = NativeBridgeLoadLibrary(pathStr, RTLD_LAZY);
-            needNativeBridge = true;
-        }
+    void* handle = OpenNativeLibrary(env,
+                                     sdkVersion,
+                                     pathStr.c_str(),
+                                     classLoader,
+                                     libraryPath,
+                                     &needs_native_bridge,
+                                     &error_msg);
+
+    if (handle == nullptr) {
+        ALOGW("NativeActivity LoadNativeLibrary(\"%s\") failed: %s",
+              pathStr.c_str(),
+              error_msg.c_str());
+        return 0;
     }
-    env->ReleaseStringUTFChars(path, pathStr);
 
-    if (handle != NULL) {
-        void* funcPtr = NULL;
-        const char* funcStr = env->GetStringUTFChars(funcName, NULL);
-        if (needNativeBridge) {
-            funcPtr = NativeBridgeGetTrampoline(handle, funcStr, NULL, 0);
-        } else {
-            funcPtr = dlsym(handle, funcStr);
-        }
-
-        code.reset(new NativeCode(handle, (ANativeActivity_createFunc*)funcPtr));
-        env->ReleaseStringUTFChars(funcName, funcStr);
-
-        if (code->createActivityFunc == NULL) {
-            ALOGW("ANativeActivity_onCreate not found");
-            return 0;
-        }
-        
-        code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue);
-        if (code->messageQueue == NULL) {
-            ALOGW("Unable to retrieve native MessageQueue");
-            return 0;
-        }
-        
-        int msgpipe[2];
-        if (pipe(msgpipe)) {
-            ALOGW("could not create pipe: %s", strerror(errno));
-            return 0;
-        }
-        code->mainWorkRead = msgpipe[0];
-        code->mainWorkWrite = msgpipe[1];
-        int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK);
-        SLOGW_IF(result != 0, "Could not make main work read pipe "
-                "non-blocking: %s", strerror(errno));
-        result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK);
-        SLOGW_IF(result != 0, "Could not make main work write pipe "
-                "non-blocking: %s", strerror(errno));
-        code->messageQueue->getLooper()->addFd(
-                code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code.get());
-        
-        code->ANativeActivity::callbacks = &code->callbacks;
-        if (env->GetJavaVM(&code->vm) < 0) {
-            ALOGW("NativeActivity GetJavaVM failed");
-            return 0;
-        }
-        code->env = env;
-        code->clazz = env->NewGlobalRef(clazz);
-
-        const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL);
-        code->internalDataPathObj = dirStr;
-        code->internalDataPath = code->internalDataPathObj.string();
-        env->ReleaseStringUTFChars(internalDataDir, dirStr);
-    
-        if (externalDataDir != NULL) {
-            dirStr = env->GetStringUTFChars(externalDataDir, NULL);
-            code->externalDataPathObj = dirStr;
-            env->ReleaseStringUTFChars(externalDataDir, dirStr);
-        }
-        code->externalDataPath = code->externalDataPathObj.string();
-
-        code->sdkVersion = sdkVersion;
-        
-        code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
-
-        if (obbDir != NULL) {
-            dirStr = env->GetStringUTFChars(obbDir, NULL);
-            code->obbPathObj = dirStr;
-            env->ReleaseStringUTFChars(obbDir, dirStr);
-        }
-        code->obbPath = code->obbPathObj.string();
-
-        jbyte* rawSavedState = NULL;
-        jsize rawSavedSize = 0;
-        if (savedState != NULL) {
-            rawSavedState = env->GetByteArrayElements(savedState, NULL);
-            rawSavedSize = env->GetArrayLength(savedState);
-        }
-
-        code->createActivityFunc(code.get(), rawSavedState, rawSavedSize);
-
-        if (rawSavedState != NULL) {
-            env->ReleaseByteArrayElements(savedState, rawSavedState, 0);
-        }
+    void* funcPtr = NULL;
+    const char* funcStr = env->GetStringUTFChars(funcName, NULL);
+    if (needs_native_bridge) {
+        funcPtr = NativeBridgeGetTrampoline(handle, funcStr, NULL, 0);
+    } else {
+        funcPtr = dlsym(handle, funcStr);
     }
-    
+
+    code.reset(new NativeCode(handle, (ANativeActivity_createFunc*)funcPtr));
+    env->ReleaseStringUTFChars(funcName, funcStr);
+
+    if (code->createActivityFunc == NULL) {
+        ALOGW("ANativeActivity_onCreate not found");
+        return 0;
+    }
+
+    code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue);
+    if (code->messageQueue == NULL) {
+        ALOGW("Unable to retrieve native MessageQueue");
+        return 0;
+    }
+
+    int msgpipe[2];
+    if (pipe(msgpipe)) {
+        ALOGW("could not create pipe: %s", strerror(errno));
+        return 0;
+    }
+    code->mainWorkRead = msgpipe[0];
+    code->mainWorkWrite = msgpipe[1];
+    int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK);
+    SLOGW_IF(result != 0, "Could not make main work read pipe "
+            "non-blocking: %s", strerror(errno));
+    result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK);
+    SLOGW_IF(result != 0, "Could not make main work write pipe "
+            "non-blocking: %s", strerror(errno));
+    code->messageQueue->getLooper()->addFd(
+            code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code.get());
+
+    code->ANativeActivity::callbacks = &code->callbacks;
+    if (env->GetJavaVM(&code->vm) < 0) {
+        ALOGW("NativeActivity GetJavaVM failed");
+        return 0;
+    }
+    code->env = env;
+    code->clazz = env->NewGlobalRef(clazz);
+
+    const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL);
+    code->internalDataPathObj = dirStr;
+    code->internalDataPath = code->internalDataPathObj.string();
+    env->ReleaseStringUTFChars(internalDataDir, dirStr);
+
+    if (externalDataDir != NULL) {
+        dirStr = env->GetStringUTFChars(externalDataDir, NULL);
+        code->externalDataPathObj = dirStr;
+        env->ReleaseStringUTFChars(externalDataDir, dirStr);
+    }
+    code->externalDataPath = code->externalDataPathObj.string();
+
+    code->sdkVersion = sdkVersion;
+
+    code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
+
+    if (obbDir != NULL) {
+        dirStr = env->GetStringUTFChars(obbDir, NULL);
+        code->obbPathObj = dirStr;
+        env->ReleaseStringUTFChars(obbDir, dirStr);
+    }
+    code->obbPath = code->obbPathObj.string();
+
+    jbyte* rawSavedState = NULL;
+    jsize rawSavedSize = 0;
+    if (savedState != NULL) {
+        rawSavedState = env->GetByteArrayElements(savedState, NULL);
+        rawSavedSize = env->GetArrayLength(savedState);
+    }
+
+    code->createActivityFunc(code.get(), rawSavedState, rawSavedSize);
+
+    if (rawSavedState != NULL) {
+        env->ReleaseByteArrayElements(savedState, rawSavedState, 0);
+    }
+
     return (jlong)code.release();
 }
 
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 9c35054..04a7543 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -341,13 +341,12 @@
         jlong paintHandle, jint dstDensity, jint srcDensity) {
 
     Canvas* canvas = get_canvas(canvasHandle);
-    SkBitmap skiaBitmap;
-    bitmap::toSkBitmap(bitmapHandle, &skiaBitmap);
+    Bitmap& bitmap = android::bitmap::toBitmap(env, bitmapHandle);
     const android::Res_png_9patch* chunk = reinterpret_cast<android::Res_png_9patch*>(chunkHandle);
     const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
 
     if (CC_LIKELY(dstDensity == srcDensity || dstDensity == 0 || srcDensity == 0)) {
-        canvas->drawNinePatch(skiaBitmap, *chunk, left, top, right, bottom, paint);
+        canvas->drawNinePatch(bitmap, *chunk, left, top, right, bottom, paint);
     } else {
         canvas->save(SaveFlags::MatrixClip);
 
@@ -361,7 +360,7 @@
         }
         filteredPaint.setFilterQuality(kLow_SkFilterQuality);
 
-        canvas->drawNinePatch(skiaBitmap, *chunk, 0, 0, (right-left)/scale, (bottom-top)/scale,
+        canvas->drawNinePatch(bitmap, *chunk, 0, 0, (right-left)/scale, (bottom-top)/scale,
                 &filteredPaint);
 
         canvas->restore();
@@ -407,8 +406,7 @@
                              jlong matrixHandle, jlong paintHandle) {
     const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
     const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
-    SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
     get_canvas(canvasHandle)->drawBitmap(bitmap, *matrix, paint);
 }
 
@@ -419,8 +417,7 @@
     Canvas* canvas = get_canvas(canvasHandle);
     const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
 
-    SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
     if (screenDensity != 0 && screenDensity != bitmapDensity) {
         Paint filteredPaint;
         if (paint) {
@@ -466,8 +463,7 @@
     AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount);
 
     const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
-    SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
     get_canvas(canvasHandle)->drawBitmapMesh(bitmap, meshWidth, meshHeight,
                                              vertA.ptr(), colorA.ptr(), paint);
 }
diff --git a/core/jni/android_hardware_Radio.cpp b/core/jni/android_hardware_Radio.cpp
index ec6471e..42ceec4 100644
--- a/core/jni/android_hardware_Radio.cpp
+++ b/core/jni/android_hardware_Radio.cpp
@@ -245,16 +245,17 @@
         radio_metadata_key_t key;
         radio_metadata_type_t type;
         void *value;
-        unsigned int size;
+        size_t size;
         if (radio_metadata_get_at_index(nMetadata, i , &key, &type, &value, &size) != 0) {
             continue;
         }
         switch (type) {
             case RADIO_METADATA_TYPE_INT: {
                 ALOGV("%s RADIO_METADATA_TYPE_INT %d", __FUNCTION__, key);
+                int32_t val = *(int32_t *)value;
                 jStatus = env->CallIntMethod(*jMetadata,
                                    gRadioMetadataMethods.putIntFromNative,
-                                   key, *(jint *)value);
+                                   key, (jint)val);
                 if (jStatus == 0) {
                     jCount++;
                 }
@@ -271,7 +272,7 @@
                 env->DeleteLocalRef(jText);
             } break;
             case RADIO_METADATA_TYPE_RAW: {
-                ALOGV("%s RADIO_METADATA_TYPE_RAW %d size %u", __FUNCTION__, key, size);
+                ALOGV("%s RADIO_METADATA_TYPE_RAW %d size %zu", __FUNCTION__, key, size);
                 if (size == 0) {
                     break;
                 }
@@ -720,7 +721,7 @@
     if (module == NULL) {
         return RADIO_STATUS_NO_INIT;
     }
-    status_t status = module->tune((unsigned int)channel, (unsigned int)subChannel);
+    status_t status = module->tune((uint32_t)channel, (uint32_t)subChannel);
     return (jint)status;
 }
 
diff --git a/core/jni/android_hardware_UsbDeviceConnection.cpp b/core/jni/android_hardware_UsbDeviceConnection.cpp
index 7ec17bf..6814506 100644
--- a/core/jni/android_hardware_UsbDeviceConnection.cpp
+++ b/core/jni/android_hardware_UsbDeviceConnection.cpp
@@ -24,12 +24,17 @@
 
 #include <usbhost/usbhost.h>
 
+#include <chrono>
+
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 
 using namespace android;
+using namespace std::chrono;
+
+static const int USB_CONTROL_READ_TIMEOUT_MS = 200;
 
 static jfieldID field_context;
 
@@ -215,7 +220,7 @@
 }
 
 static jobject
-android_hardware_UsbDeviceConnection_request_wait(JNIEnv *env, jobject thiz)
+android_hardware_UsbDeviceConnection_request_wait(JNIEnv *env, jobject thiz, jint timeoutMillis)
 {
     struct usb_device* device = get_device_from_object(env, thiz);
     if (!device) {
@@ -223,11 +228,33 @@
         return NULL;
     }
 
-    struct usb_request* request = usb_request_wait(device);
-    if (request)
+    struct usb_request* request;
+    if (timeoutMillis == -1) {
+        request = usb_request_wait(device, -1);
+    } else {
+        steady_clock::time_point currentTime = steady_clock::now();
+        steady_clock::time_point endTime = currentTime + std::chrono::milliseconds(timeoutMillis);
+
+        // Poll the existence of a request via usb_request_wait until we get a result, an unexpected
+        // error or time out. As several threads can listen on the same fd, we might get wakeups
+        // without data.
+        while (1) {
+            request = usb_request_wait(device, duration_cast<std::chrono::milliseconds>(endTime
+                               - currentTime).count());
+
+            int error = errno;
+            currentTime = steady_clock::now();
+            if (request != NULL || error != EAGAIN || currentTime >= endTime) {
+                break;
+            }
+        };
+    }
+
+    if (request) {
         return (jobject)request->client_data;
-    else
+    } else {
         return NULL;
+    }
 }
 
 static jstring
@@ -238,7 +265,8 @@
         ALOGE("device is closed in native_get_serial");
         return NULL;
     }
-    char* serial = usb_device_get_serial(device);
+    char* serial = usb_device_get_serial(device,
+            USB_CONTROL_READ_TIMEOUT_MS);
     if (!serial)
         return NULL;
     jstring result = env->NewStringUTF(serial);
@@ -272,7 +300,7 @@
                                         (void *)android_hardware_UsbDeviceConnection_control_request},
     {"native_bulk_request",     "(I[BIII)I",
                                         (void *)android_hardware_UsbDeviceConnection_bulk_request},
-    {"native_request_wait",             "()Landroid/hardware/usb/UsbRequest;",
+    {"native_request_wait",             "(I)Landroid/hardware/usb/UsbRequest;",
                                         (void *)android_hardware_UsbDeviceConnection_request_wait},
     { "native_get_serial",      "()Ljava/lang/String;",
                                         (void*)android_hardware_UsbDeviceConnection_get_serial },
diff --git a/core/jni/android_hardware_UsbRequest.cpp b/core/jni/android_hardware_UsbRequest.cpp
index 4cbe3e4..4b7e0dd 100644
--- a/core/jni/android_hardware_UsbRequest.cpp
+++ b/core/jni/android_hardware_UsbRequest.cpp
@@ -166,6 +166,38 @@
     return JNI_TRUE;
 }
 
+static jboolean
+android_hardware_UsbRequest_enqueue(JNIEnv *env, jobject thiz, jobject buffer, jint offset,
+        jint length)
+{
+    struct usb_request* request = get_request_from_object(env, thiz);
+    if (!request) {
+        ALOGE("request is closed in native_queue");
+        return JNI_FALSE;
+    }
+
+    if (buffer == NULL) {
+        request->buffer = NULL;
+        request->buffer_length = 0;
+    } else {
+        request->buffer = (void *)((char *)env->GetDirectBufferAddress(buffer) + offset);
+        request->buffer_length = length;
+    }
+
+    // Save a reference to ourselves so UsbDeviceConnection.waitRequest() can find us.
+    // We also need this to make sure our native buffer is not deallocated while IO is active.
+    request->client_data = (void *)env->NewGlobalRef(thiz);
+
+    int err = usb_request_queue(request);
+
+    if (err != 0) {
+        request->buffer = NULL;
+        env->DeleteGlobalRef((jobject)request->client_data);
+        return JNI_FALSE;
+    }
+    return JNI_TRUE;
+}
+
 static jint
 android_hardware_UsbRequest_dequeue_direct(JNIEnv *env, jobject thiz)
 {
@@ -194,6 +226,8 @@
     {"native_init",             "(Landroid/hardware/usb/UsbDeviceConnection;IIII)Z",
                                             (void *)android_hardware_UsbRequest_init},
     {"native_close",            "()V",      (void *)android_hardware_UsbRequest_close},
+    {"native_enqueue",         "(Ljava/nio/ByteBuffer;II)Z",
+                                            (void *)android_hardware_UsbRequest_enqueue},
     {"native_queue_array",      "([BIZ)Z",  (void *)android_hardware_UsbRequest_queue_array},
     {"native_dequeue_array",    "([BIZ)I",  (void *)android_hardware_UsbRequest_dequeue_array},
     {"native_queue_direct",     "(Ljava/nio/ByteBuffer;IZ)Z",
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 06f22dd..aa4570f 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -291,7 +291,8 @@
                 whichHeap = HEAP_TTF;
                 is_swappable = true;
             } else if ((nameLen > 4 && strstr(name, ".dex") != NULL) ||
-                       (nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0)) {
+                       (nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0) ||
+                       (nameLen > 5 && strcmp(name+nameLen-5, ".vdex") == 0)) {
                 whichHeap = HEAP_DEX;
                 is_swappable = true;
             } else if (nameLen > 4 && strcmp(name+nameLen-4, ".oat") == 0) {
diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp
index 13e3f0d..816d5df 100644
--- a/core/jni/android_os_HwBinder.cpp
+++ b/core/jni/android_os_HwBinder.cpp
@@ -196,19 +196,32 @@
 }
 
 static void JHwBinder_native_registerService(
-        JNIEnv *env, jobject thiz, jstring serviceNameObj) {
+        JNIEnv *env,
+        jobject thiz,
+        jstring serviceNameObj,
+        jint versionMajor,
+        jint versionMinor) {
     if (serviceNameObj == NULL) {
         jniThrowException(env, "java/lang/NullPointerException", NULL);
         return;
     }
 
+    if (versionMajor < 0
+            || versionMajor > 65535
+            || versionMinor < 0
+            || versionMinor > 65535) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return;
+    }
+
     const jchar *serviceName = env->GetStringCritical(serviceNameObj, NULL);
 
     if (serviceName == NULL) {
         return;  // XXX exception already pending?
     }
 
-    const hardware::hidl_version kVersion = hardware::make_hidl_version(1, 0);
+    const hardware::hidl_version kVersion =
+        hardware::make_hidl_version(versionMajor, versionMinor);
 
     sp<hardware::IBinder> binder = JHwBinder::GetNativeContext(env, thiz);
 
@@ -231,19 +244,32 @@
 }
 
 static jobject JHwBinder_native_getService(
-        JNIEnv *env, jclass /* clazzObj */, jstring serviceNameObj) {
+        JNIEnv *env,
+        jclass /* clazzObj */,
+        jstring serviceNameObj,
+        jint versionMajor,
+        jint versionMinor) {
     if (serviceNameObj == NULL) {
         jniThrowException(env, "java/lang/NullPointerException", NULL);
         return NULL;
     }
 
+    if (versionMajor < 0
+            || versionMajor > 65535
+            || versionMinor < 0
+            || versionMinor > 65535) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return NULL;
+    }
+
     const jchar *serviceName = env->GetStringCritical(serviceNameObj, NULL);
 
     if (serviceName == NULL) {
         return NULL;  // XXX exception already pending?
     }
 
-    const hardware::hidl_version kVersion = hardware::make_hidl_version(1, 0);
+    const hardware::hidl_version kVersion =
+        hardware::make_hidl_version(versionMajor, versionMinor);
 
     LOG(INFO) << "looking for service '"
               << String8(String16(
@@ -280,10 +306,10 @@
         "(IL" PACKAGE_PATH "/HwParcel;L" PACKAGE_PATH "/HwParcel;I)V",
         (void *)JHwBinder_native_transact },
 
-    { "registerService", "(Ljava/lang/String;)V",
+    { "registerService", "(Ljava/lang/String;II)V",
         (void *)JHwBinder_native_registerService },
 
-    { "getService", "(Ljava/lang/String;)L" PACKAGE_PATH "/IHwBinder;",
+    { "getService", "(Ljava/lang/String;II)L" PACKAGE_PATH "/IHwBinder;",
         (void *)JHwBinder_native_getService },
 };
 
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index bc2604e..a58bc90 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -164,7 +164,7 @@
                 }
 
                 // Generic idmap parameters
-                const char* argv[7];
+                const char* argv[8];
                 int argc = 0;
                 struct stat st;
 
@@ -175,10 +175,10 @@
                 argv[argc++] = AssetManager::TARGET_APK_PATH;
                 argv[argc++] = AssetManager::IDMAP_DIR;
 
-                // Directories to scan for overlays: if OVERLAY_SKU_DIR_PROPERTY is defined,
-                // use OVERLAY_DIR/<value of OVERLAY_SKU_DIR_PROPERTY> in addition to OVERLAY_DIR.
+                // Directories to scan for overlays: if OVERLAY_THEME_DIR_PROPERTY is defined,
+                // use OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to OVERLAY_DIR.
                 char subdir[PROP_VALUE_MAX];
-                int len = __system_property_get(AssetManager::OVERLAY_SKU_DIR_PROPERTY, subdir);
+                int len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PROPERTY, subdir);
                 if (len > 0) {
                     String8 overlayPath = String8(AssetManager::OVERLAY_DIR) + "/" + subdir;
                     if (stat(overlayPath.string(), &st) == 0) {
@@ -192,7 +192,7 @@
                 // Finally, invoke idmap (if any overlay directory exists)
                 if (argc > 5) {
                     execv(AssetManager::IDMAP_BIN, (char* const*)argv);
-                    ALOGE("failed to execl for idmap: %s", strerror(errno));
+                    ALOGE("failed to execv for idmap: %s", strerror(errno));
                     exit(1); // should never get here
                 } else {
                     exit(0);
diff --git a/core/jni/android_util_jar_StrictJarFile.cpp b/core/jni/android_util_jar_StrictJarFile.cpp
index bfdea8f..2e31c8b 100644
--- a/core/jni/android_util_jar_StrictJarFile.cpp
+++ b/core/jni/android_util_jar_StrictJarFile.cpp
@@ -51,14 +51,16 @@
                         static_cast<jlong>(entry.offset));
 }
 
-static jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring fileName) {
-  ScopedUtfChars fileChars(env, fileName);
-  if (fileChars.c_str() == NULL) {
+static jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring name, jint fd) {
+  // Name argument is used for logging, and can be any string.
+  ScopedUtfChars nameChars(env, name);
+  if (nameChars.c_str() == NULL) {
     return static_cast<jlong>(-1);
   }
 
   ZipArchiveHandle handle;
-  int32_t error = OpenArchive(fileChars.c_str(), &handle);
+  int32_t error = OpenArchiveFd(fd, nameChars.c_str(), &handle,
+      false /* owned by Java side */);
   if (error) {
     CloseArchive(handle);
     throwIoException(env, error);
@@ -154,7 +156,7 @@
 }
 
 static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(StrictJarFile, nativeOpenJarFile, "(Ljava/lang/String;)J"),
+  NATIVE_METHOD(StrictJarFile, nativeOpenJarFile, "(Ljava/lang/String;I)J"),
   NATIVE_METHOD(StrictJarFile, nativeStartIteration, "(JLjava/lang/String;)J"),
   NATIVE_METHOD(StrictJarFile, nativeNextEntry, "(J)Ljava/util/zip/ZipEntry;"),
   NATIVE_METHOD(StrictJarFile, nativeFindEntry, "(JLjava/lang/String;)Ljava/util/zip/ZipEntry;"),
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c346849..b38bb1e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -723,7 +723,7 @@
         android:permissionGroup="android.permission-group.LOCATION"
         android:label="@string/permlab_accessFineLocation"
         android:description="@string/permdesc_accessFineLocation"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous|ephemeral" />
 
     <!-- Allows an app to access approximate location.
          <p>Protection level: dangerous
@@ -732,7 +732,7 @@
         android:permissionGroup="android.permission-group.LOCATION"
         android:label="@string/permlab_accessCoarseLocation"
         android:description="@string/permdesc_accessCoarseLocation"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous|ephemeral" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device telephony                         -->
@@ -763,7 +763,7 @@
         android:permissionGroup="android.permission-group.PHONE"
         android:label="@string/permlab_readPhoneState"
         android:description="@string/permdesc_readPhoneState"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="dangerous|ephemeral" />
 
     <!-- Allows an application to initiate a phone call without going through
         the Dialer user interface for the user to confirm the call.
@@ -1164,7 +1164,7 @@
     <permission android:name="android.permission.INTERNET"
         android:description="@string/permdesc_createNetworkSockets"
         android:label="@string/permlab_createNetworkSockets"
-        android:protectionLevel="normal" />
+        android:protectionLevel="normal|ephemeral" />
 
     <!-- Allows applications to access information about networks.
          <p>Protection level: normal
@@ -1354,7 +1354,7 @@
     <permission android:name="android.permission.VIBRATE"
         android:label="@string/permlab_vibrate"
         android:description="@string/permdesc_vibrate"
-        android:protectionLevel="normal" />
+        android:protectionLevel="normal|ephemeral" />
 
     <!-- Allows using PowerManager WakeLocks to keep processor from sleeping or screen
          from dimming.
@@ -1363,7 +1363,7 @@
     <permission android:name="android.permission.WAKE_LOCK"
         android:label="@string/permlab_wakeLock"
         android:description="@string/permdesc_wakeLock"
-        android:protectionLevel="normal" />
+        android:protectionLevel="normal|ephemeral" />
 
     <!-- Allows using the device's IR transmitter, if available.
          <p>Protection level: normal
@@ -1712,11 +1712,6 @@
     <permission android:name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE"
         android:protectionLevel="signature|privileged|development" />
 
-    <!-- @SystemApi @hide Allows an application to retrieve a package's importance.
-         This permission is not available to third party applications. -->
-    <permission android:name="android.permission.GET_PACKAGE_IMPORTANCE"
-        android:protectionLevel="signature|privileged" />
-
     <!-- Allows use of PendingIntent.getIntent().
          @hide -->
     <permission android:name="android.permission.GET_INTENT_SENDER_INTENT"
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
index 39d2c95f..3a9031e 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
index 3a9031e..39d2c95f 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png
index b9c364c..217ea4e 100644
--- a/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png
index 217ea4e..b9c364c 100644
--- a/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png
+++ b/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-watch/scrollbar_vertical_thumb.xml b/core/res/res/drawable-watch/scrollbar_vertical_thumb.xml
new file mode 100644
index 0000000..51aced2
--- /dev/null
+++ b/core/res/res/drawable-watch/scrollbar_vertical_thumb.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="?attr/colorControlNormal"
+    android:shape="rectangle">
+    <solid android:color="#39757575" />
+    <size android:height="10dp" />
+    <corners android:radius="2dp" />
+</shape>
diff --git a/core/res/res/drawable-watch/scrollbar_vertical_track.xml b/core/res/res/drawable-watch/scrollbar_vertical_track.xml
new file mode 100644
index 0000000..5a04b1c
--- /dev/null
+++ b/core/res/res/drawable-watch/scrollbar_vertical_track.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="?attr/colorControlNormal"
+    android:shape="rectangle">
+    <solid android:color="#39ffffff" />
+    <size android:width="4dp" />
+</shape>
diff --git a/core/res/res/drawable-xhdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-xhdpi/stat_sys_upload_anim1.png
index cd0ca73..e443f45 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-xhdpi/stat_sys_upload_anim2.png
index e443f45..cd0ca73 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_upload_anim2.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim1.png
index 39dd3b8..b828430 100644
--- a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim2.png
index b828430..39dd3b8 100644
--- a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim2.png
+++ b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/layout-round-watch/alert_dialog_title_material.xml b/core/res/res/layout-round-watch/alert_dialog_title_material.xml
index e543c9b..aefe28f 100644
--- a/core/res/res/layout-round-watch/alert_dialog_title_material.xml
+++ b/core/res/res/layout-round-watch/alert_dialog_title_material.xml
@@ -14,25 +14,31 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<FrameLayout
+<LinearLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:gravity="top|center_horizontal"
-        android:minHeight="@dimen/alert_dialog_title_height">
-    <ImageView android:id="@+id/icon"
+        android:orientation="vertical"
+        android:gravity="top|center_horizontal">
+    <FrameLayout
             android:adjustViewBounds="true"
-            android:maxHeight="24dp"
-            android:maxWidth="24dp"
-            android:layout_marginTop="12dp"
-            android:layout_gravity="center_horizontal"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:src="@null" />
+            android:minHeight="@dimen/screen_percentage_15">
+        <ImageView android:id="@+id/icon"
+                android:adjustViewBounds="true"
+                android:maxHeight="24dp"
+                android:maxWidth="24dp"
+                android:layout_marginTop="@dimen/screen_percentage_10"
+                android:layout_marginBottom="8dp"
+                android:layout_gravity="center_horizontal"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@null" />
+    </FrameLayout>
     <TextView android:id="@+id/alertTitle"
             style="?android:attr/windowTitleStyle"
-            android:layout_marginTop="36dp"
             android:layout_marginBottom="8dp"
             android:layout_width="match_parent"
             android:layout_height="wrap_content" />
-</FrameLayout>
+</LinearLayout>
diff --git a/core/res/res/layout-watch/progress_dialog_material.xml b/core/res/res/layout-watch/progress_dialog_material.xml
index 228f724..96bda1d 100644
--- a/core/res/res/layout-watch/progress_dialog_material.xml
+++ b/core/res/res/layout-watch/progress_dialog_material.xml
@@ -32,14 +32,15 @@
 
         <ProgressBar
             android:id="@id/progress"
-            style="?android:attr/progressBarStyleSmall"
+            style="?android:attr/progressBarStyle"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:max="10000"
-            android:layout_marginEnd="?attr/dialogPreferredPadding" />
+            android:layout_marginEnd="8dp" />
 
         <TextView
             android:id="@+id/message"
+            android:textAppearance="?attr/textAppearanceListItem"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical" />
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 09b55d9..1e5f6a1 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1570,7 +1570,7 @@
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Supprimé par votre administrateur"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Pour améliorer l\'autonomie de la batterie, l\'économiseur de batterie réduit les performances et désactive le vibreur, les services de localisation et la plupart des données en arrière-plan. Les messageries électroniques ou autres applications utilisant la synchronisation pourraient ne pas se mettre à jour, sauf si vous les ouvrez.\n\nL\'économiseur de batterie s\'éteint automatiquement lorsque l\'appareil est en charge."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Pour réduire la consommation des données, l\'économiseur de données empêche certaines applications d\'envoyer ou de recevoir des données en arrière-plan. Ainsi, une application que vous utilisez actuellement peut accéder à des données, mais moins souvent. Par exemple, il se peut que les images ne s\'affichent pas tant que vous n\'appuyez pas dessus."</string>
-    <string name="data_saver_enable_title" msgid="4674073932722787417">"Activer sauvegarde données ?"</string>
+    <string name="data_saver_enable_title" msgid="4674073932722787417">"Activer l\'économiseur de données ?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Activer"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">Pendant %1$d minute (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 7cdc9bb..5a1ad70 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -214,7 +214,7 @@
     <string name="global_actions" product="default" msgid="2406416831541615258">"Հեռախոսի ընտրանքներ"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Էկրանի փական"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Անջատել"</string>
-    <string name="global_action_emergency" msgid="7112311161137421166">"Արտակարգ իրավիճակ"</string>
+    <string name="global_action_emergency" msgid="7112311161137421166">"Շտապ կանչ"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Վրիպակի զեկույց"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Գրել սխալի զեկույց"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Սա տեղեկություններ կհավաքագրի ձեր սարքի առկա կարգավիճակի մասին և կուղարկի այն էլեկտրոնային նամակով: Որոշակի ժամանակ կպահանջվի վրիպակի մասին զեկուցելու պահից սկսած մինչ ուղարկելը: Խնդրում ենք փոքր-ինչ համբերատար լինել:"</string>
@@ -250,7 +250,7 @@
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Օրացույց"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"օգտագործել օրացույցը"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"Կարճ հաղորդագրություն"</string>
-    <string name="permgroupdesc_sms" msgid="4656988620100940350">"ուղարկել և դիտել SMS հաղորդ․-ները"</string>
+    <string name="permgroupdesc_sms" msgid="4656988620100940350">"ուղարկել և դիտել SMS-ները"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Պահոց"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"օգտագործել լուսանկարները, մեդիա ֆայլերը և ձեր սարքում պահվող մյուս ֆայլերը"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Բարձրախոս"</string>
@@ -674,7 +674,7 @@
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Ապակողպելու կամ շտապ կանչ անելու համար սեղմեք «Ընտրացանկ»"</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Ապակողպելու համար սեղմեք Ցանկը:"</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Հավաքեք սխեման` ապակողպելու համար"</string>
-    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Արտակարգ իրավիճակ"</string>
+    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Շտապ կանչ"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Վերադառնալ զանգին"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Ճիշտ է:"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Կրկին փորձեք"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 5305b1f..02736ec 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -512,8 +512,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"携帯通信会社のSMSサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"携帯通信会社のサービスへのバインド"</string>
     <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"携帯通信会社のサービスにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
-    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"[通知を非表示]へのアクセス"</string>
-    <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"[通知を非表示]の設定の読み取りと書き込みをアプリに許可します。"</string>
+    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"マナーモードへのアクセス"</string>
+    <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"マナーモード設定の読み取りと書き込みをアプリに許可します。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"画面ロックのパスワードとPINの長さと使用できる文字を制御します。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"画面ロック解除試行の監視"</string>
@@ -1607,10 +1607,10 @@
     <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>まで"</string>
     <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>(次のアラーム)まで"</string>
     <string name="zen_mode_forever" msgid="7420011936770086993">"ユーザーがOFFにするまで"</string>
-    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"[通知を非表示]をOFFにするまで"</string>
+    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"マナーモードを OFF にするまで"</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"折りたたむ"</string>
-    <string name="zen_mode_feature_name" msgid="5254089399895895004">"通知を非表示"</string>
+    <string name="zen_mode_feature_name" msgid="5254089399895895004">"マナーモード"</string>
     <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ダウンタイム"</string>
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"平日の夜"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"週末"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index b8c90d7..732a321 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -958,9 +958,9 @@
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಚಾಲನೆಯಲ್ಲಿದೆ"</string>
     <string name="app_running_notification_text" msgid="1197581823314971177">"ಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ನಿಲ್ಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="ok" msgid="5970060430562524910">"ಸರಿ"</string>
-    <string name="cancel" msgid="6442560571259935130">"ರದ್ದುಮಾಡು"</string>
+    <string name="cancel" msgid="6442560571259935130">"ರದ್ದುಮಾಡಿ"</string>
     <string name="yes" msgid="5362982303337969312">"ಸರಿ"</string>
-    <string name="no" msgid="5141531044935541497">"ರದ್ದುಮಾಡು"</string>
+    <string name="no" msgid="5141531044935541497">"ರದ್ದುಮಾಡಿ"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"ಗಮನಿಸಿ"</string>
     <string name="loading" msgid="7933681260296021180">"ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
     <string name="capital_on" msgid="1544682755514494298">"ಆನ್ ಮಾಡು"</string>
@@ -1118,7 +1118,7 @@
     <string name="sms_short_code_details" msgid="5873295990846059400">"ಇದು ನಿಮ್ಮ ಮೊಬೈಲ್ ಖಾತೆಯಲ್ಲಿ "<b>"ಶುಲ್ಕಗಳನ್ನು ವಿಧಿಸುವುದಕ್ಕೆ ಕಾರಣವಾಗಬಹುದು"</b>"."</string>
     <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"ಇದು ನಿಮ್ಮ ಮೊಬೈಲ್ ಖಾತೆಯಲ್ಲಿ ಶುಲ್ಕಗಳನ್ನು ವಿಧಿಸುವುದಕ್ಕೆ ಕಾರಣವಾಗುತ್ತದೆ."</b></string>
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"ಕಳುಹಿಸು"</string>
-    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"ರದ್ದುಮಾಡು"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"ರದ್ದುಮಾಡಿ"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"ನನ್ನ ಆಯ್ಕೆಯನ್ನು ನೆನಪಿಡು"</string>
     <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"ನೀವು ಇದನ್ನು ನಂತರದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್‍‍ಗಳು &gt; ಅಪ್ಲಿಕೇಶನ್‍‍ಗಳಲ್ಲಿ ಬದಲಾಯಿಸಬಹುದು"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"ಯಾವಾಗಲೂ ಅನುಮತಿಸು"</string>
@@ -1303,7 +1303,7 @@
     <string name="date_picker_prev_month_button" msgid="2858244643992056505">"ಹಿಂದಿನ ತಿಂಗಳು"</string>
     <string name="date_picker_next_month_button" msgid="5559507736887605055">"ಮುಂದಿನ ತಿಂಗಳು"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
-    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ರದ್ದುಮಾಡು"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ರದ್ದುಮಾಡಿ"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ಅಳಿಸು"</string>
     <string name="keyboardview_keycode_done" msgid="1992571118466679775">"ಮುಗಿದಿದೆ"</string>
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ಮೋಡ್ ಬದಲಾವಣೆ"</string>
@@ -1673,7 +1673,7 @@
     <string name="demo_restarting_message" msgid="952118052531642451">"ಸಾಧನ ಮರುಹೊಂದಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"ಸಾಧನವನ್ನು ಮರುಹೊಂದಿಸುವುದೇ?"</string>
     <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"ನೀವು ಯಾವುದೇ ಬದಲಾವಣೆಗಳನ್ನು ಕಳೆದುಕೊಳ್ಳುತ್ತೀರಿ ಮತ್ತು <xliff:g id="TIMEOUT">%1$s</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಡೆಮೋ ಮತ್ತೆ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ..."</string>
-    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"ರದ್ದುಮಾಡು"</string>
+    <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"ರದ್ದುಮಾಡಿ"</string>
     <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ಈಗಲೇ ಮರುಹೊಂದಿಸು"</string>
     <string name="audit_safemode_notification" msgid="6416076898350685856">"ನಿರ್ಬಂಧಗಳು ಇಲ್ಲದೆಯೇ ಈ ಸಾಧನವನ್ನು ಬಳಸಲು ಫ್ಯಾಕ್ಟರಿ ಮರುಹೊಂದಿಸಿ"</string>
     <string name="audit_safemode_notification_details" msgid="1860601176690176413">"ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಸ್ಪರ್ಶಿಸಿ."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 4191865..f0cfd0b 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -260,7 +260,7 @@
     <string name="permgrouplab_phone" msgid="5229115638567440675">"전화"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"통화 상태를 관리하거나 전화를 걸 수 있도록"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"신체 센서"</string>
-    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"생체 신호에 관한 센서 데이터에 접근할 수 있도록"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"생체 신호에 관한 센서 데이터에 액세스"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"창 콘텐츠 가져오기"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"상호작용 중인 창의 콘텐츠를 검사합니다."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"터치하여 탐색 사용"</string>
diff --git a/core/res/res/values-ldrtl-television/config.xml b/core/res/res/values-ldrtl-television/config.xml
index e237acc..503b902 100644
--- a/core/res/res/values-ldrtl-television/config.xml
+++ b/core/res/res/values-ldrtl-television/config.xml
@@ -21,7 +21,8 @@
      for TV products.  Do not translate. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-    <!-- Default bounds [left top right bottom] on screen for picture-in-picture windows. -->
-    <string translatable="false" name="config_defaultPictureInPictureBounds">"112 54 592 324"</string>
+    <!-- The default gravity for the picture-in-picture window.
+         Currently, this maps to Gravity.TOP | Gravity.LEFT -->
+    <integer name="config_defaultPictureInPictureGravity">0x33</integer>
 
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 9ff7803..0371543 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1328,7 +1328,7 @@
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB-stasjon"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB-stasjon"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-lagring"</string>
-    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Rediger"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Endre"</string>
     <string name="data_usage_warning_title" msgid="3620440638180218181">"Varsel om databruk"</string>
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Trykk for å se bruken og innstillingene."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Datagrensen for 2G-3G er nådd"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 66f085f..ac74164 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -667,7 +667,7 @@
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Ange lösenord för att låsa upp"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Ange PIN-kod för att låsa upp"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Fel PIN-kod."</string>
-    <string name="keyguard_label_text" msgid="861796461028298424">"Tryck på Menu och sedan på 0 om du vill låsa upp."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Tryck på Menu och sedan på 0 för att låsa upp."</string>
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Nödsamtalsnummer"</string>
     <string name="lockscreen_carrier_default" msgid="6169005837238288522">"Ingen tjänst"</string>
     <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Skärmen har låsts."</string>
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml
index c0716e9..c27cb06 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -24,6 +24,15 @@
     <!-- Flags enabling default window features. See Window.java -->
     <bool name="config_defaultWindowFeatureOptionsPanel">false</bool>
 
-    <!-- Default bounds [left top right bottom] on screen for picture-in-picture windows. -->
-    <string translatable="false" name="config_defaultPictureInPictureBounds">"1328 54 1808 324"</string>
+    <!-- Max default size [WIDTHxHEIGHT] on screen for picture-in-picture windows to fit inside.
+         These values are in DPs and will be converted to pixel sizes internally. -->
+    <string translatable="false" name="config_defaultPictureInPictureSize">240x135</string>
+
+    <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
+         These values are in DPs and will be converted to pixel sizes internally. -->
+    <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">56x27</string>
+
+    <!-- The default gravity for the picture-in-picture window.
+         Currently, this maps to Gravity.TOP | Gravity.RIGHT -->
+    <integer name="config_defaultPictureInPictureGravity">0x35</integer>
 </resources>
diff --git a/core/res/res/values-watch/colors_device_defaults.xml b/core/res/res/values-watch/colors_device_defaults.xml
index 9150cc4..15786b4 100644
--- a/core/res/res/values-watch/colors_device_defaults.xml
+++ b/core/res/res/values-watch/colors_device_defaults.xml
@@ -18,4 +18,7 @@
      overlaying new theme colors. -->
 <resources>
     <color name="button_normal_device_default_dark">@color/btn_default_material_dark</color>
+    <!-- Use the same value as for accent_device_default_dark but start with #99,
+         i.e. 60% opacity -->
+    <color name="accent_device_default_dark_60_percent_opacity">#995E97f6</color>
 </resources>
diff --git a/core/res/res/values-watch/config_material.xml b/core/res/res/values-watch/config_material.xml
index 104d122..529f18b 100644
--- a/core/res/res/values-watch/config_material.xml
+++ b/core/res/res/values-watch/config_material.xml
@@ -29,4 +29,8 @@
 
     <!-- Always overscan by default to ensure onApplyWindowInsets will always be called. -->
     <bool name="config_windowOverscanByDefault">true</bool>
+
+    <!-- Style the scrollbars accoridngly. -->
+    <drawable name="config_scrollbarThumbVertical">@drawable/scrollbar_vertical_thumb</drawable>
+    <drawable name="config_scrollbarTrackVertical">@drawable/scrollbar_vertical_track</drawable>
 </resources>
diff --git a/core/res/res/values-watch/dimens_material.xml b/core/res/res/values-watch/dimens_material.xml
index b48cde6..3c4904c 100644
--- a/core/res/res/values-watch/dimens_material.xml
+++ b/core/res/res/values-watch/dimens_material.xml
@@ -39,4 +39,9 @@
     <!-- Date and time picker legacy dimens -->
     <dimen name="picker_top_margin">1dip</dimen>
     <dimen name="picker_bottom_margin">1dip</dimen>
+
+    <!-- Progress bar dimens -->
+    <dimen name="progress_bar_size_small">16dip</dimen>
+    <dimen name="progress_bar_size_medium">32dip</dimen>
+    <dimen name="progress_bar_size_large">64dip</dimen>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index b67d6e2..68e87c2 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -195,7 +195,7 @@
     <string name="silent_mode_ring" msgid="8592241816194074353">"振铃器开启"</string>
     <string name="reboot_to_update_title" msgid="6212636802536823850">"Android 系统更新"</string>
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"正在准备更新…"</string>
-    <string name="reboot_to_update_package" msgid="3871302324500927291">"正在处理更新文件包…"</string>
+    <string name="reboot_to_update_package" msgid="3871302324500927291">"正在处理更新软件包…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"正在重新启动…"</string>
     <string name="reboot_to_reset_title" msgid="4142355915340627490">"恢复出厂设置"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"正在重新启动…"</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index cad5854..967c4ad 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -242,6 +242,9 @@
         <!-- Additional flag from base permission type: this permission can be automatically
             granted to the setup wizard app -->
         <flag name="setup" value="0x800" />
+        <!-- Additional flag from base permission type: this permission can be granted to ephemeral
+             apps -->
+        <flag name="ephemeral" value="0x1000" />
     </attr>
 
     <!-- Flags indicating more context for a permission group. -->
@@ -575,6 +578,20 @@
          transtion from one VR activity to another. -->
     <attr name="enableVrMode" format="string" />
 
+    <!-- Flag allowing the activity to specify which screen rotation animation
+         it desires.  Valid values are "rotate", "crossfade", and "jumpcut"
+         as described in {@link android.view.WindowManager.LayoutParams#rotationAnimation}.
+         Specifying your Rotation animation in the WindowManager.LayoutParams
+         may be racy with app startup and updattransitions occuring during application startup and thusly
+         the manifest attribute is preferred.
+    -->
+    <attr name="rotationAnimation">
+      <flag name="rotate" value= "0" />
+      <flag name="crossfade" value = "1" />
+      <flag name="jumpcut" value = "2" />
+      <flag name="seamless" value = "3" />
+    </attr>
+
     <!-- Specify the order in which content providers hosted by a process
          are instantiated when that process is created.  Not needed unless
          you have providers with dependencies between each other, to make
@@ -1923,6 +1940,7 @@
         <!-- @hide This activity is a launcher which should always show up on the top of others.
              This attribute is ignored if the activity isn't a launcher. -->
         <attr name="onTopLauncher" format="boolean" />
+        <attr name="rotationAnimation"/>
     </declare-styleable>
 
     <!-- The <code>activity-alias</code> tag declares a new
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 092109b..567e920 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1368,6 +1368,9 @@
     <!-- Whether supported profiles should be reloaded upon enabling bluetooth -->
     <bool name="config_bluetooth_reload_supported_profiles_when_enabled">false</bool>
 
+    <!-- Enabling autoconnect over pan -->
+    <bool name="config_bluetooth_pan_enable_autoconnect">false</bool>
+
     <!-- The default data-use polling period. -->
     <integer name="config_datause_polling_period_sec">600</integer>
 
@@ -2472,8 +2475,17 @@
          -->
     <integer name="config_navBarOpacityMode">0</integer>
 
-    <!-- Default bounds [left top right bottom] on screen for picture-in-picture windows. -->
-    <string translatable="false" name="config_defaultPictureInPictureBounds">"0 0 100 100"</string>
+    <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
+         These values are in DPs and will be converted to pixel sizes internally. -->
+    <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">10x10</string>
+
+    <!-- Max default size [WIDTHxHEIGHT] on screen for picture-in-picture windows to fit inside.
+         These values are in DPs and will be converted to pixel sizes internally. -->
+    <string translatable="false" name="config_defaultPictureInPictureSize">216x135</string>
+
+    <!-- The default gravity for the picture-in-picture window.
+         Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT -->
+    <integer name="config_defaultPictureInPictureGravity">0x55</integer>
 
     <!-- Controls the snap mode for the docked stack divider
              0 - 3 snap targets: left/top has 16:9 ratio, 1:1, and right/bottom has 16:9 ratio
diff --git a/core/res/res/values/config_material.xml b/core/res/res/values/config_material.xml
index 29494db..840a551 100644
--- a/core/res/res/values/config_material.xml
+++ b/core/res/res/values/config_material.xml
@@ -37,4 +37,8 @@
 
     <!-- The amount to offset when scrolling to a selection in an AlertDialog -->
     <dimen name="config_alertDialogSelectionScrollOffset">0dp</dimen>
+
+    <!-- Style the scrollbars accoridngly. -->
+    <drawable name="config_scrollbarThumbVertical">@drawable/scrollbar_handle_material</drawable>
+    <drawable name="config_scrollbarTrackVertical">@null</drawable>
 </resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index ae31165..30e7b31 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -193,4 +193,9 @@
     <!-- Date and time picker legacy dimens -->
     <dimen name="picker_top_margin">16dip</dimen>
     <dimen name="picker_bottom_margin">16dip</dimen>
+
+    <!-- Progress bar dimens -->
+    <dimen name="progress_bar_size_small">16dip</dimen>
+    <dimen name="progress_bar_size_medium">48dp</dimen>
+    <dimen name="progress_bar_size_large">76dp</dimen>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 7999e7e..c06a93d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2765,4 +2765,5 @@
     </public-group>
 
     <public type="attr" name="min" />
+    <public type="attr" name="rotationAnimation" />
 </resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 22bdf7e..a1e12d2 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -739,6 +739,10 @@
 
     <style name="Widget.Material.ProgressBar" parent="Widget.ProgressBar">
         <item name="indeterminateDrawable">@drawable/progress_medium_material</item>
+        <item name="minWidth">@dimen/progress_bar_size_medium</item>
+        <item name="maxWidth">@dimen/progress_bar_size_medium</item>
+        <item name="minHeight">@dimen/progress_bar_size_medium</item>
+        <item name="maxHeight">@dimen/progress_bar_size_medium</item>
     </style>
 
     <style name="Widget.Material.ProgressBar.Inverse"/>
@@ -752,6 +756,10 @@
 
     <style name="Widget.Material.ProgressBar.Small" parent="Widget.ProgressBar.Small">
         <item name="indeterminateDrawable">@drawable/progress_small_material</item>
+        <item name="minWidth">@dimen/progress_bar_size_small</item>
+        <item name="maxWidth">@dimen/progress_bar_size_small</item>
+        <item name="minHeight">@dimen/progress_bar_size_small</item>
+        <item name="maxHeight">@dimen/progress_bar_size_small</item>
     </style>
 
     <style name="Widget.Material.ProgressBar.Small.Inverse"/>
@@ -759,6 +767,10 @@
 
     <style name="Widget.Material.ProgressBar.Large" parent="Widget.ProgressBar.Large">
         <item name="indeterminateDrawable">@drawable/progress_large_material</item>
+        <item name="minWidth">@dimen/progress_bar_size_large</item>
+        <item name="maxWidth">@dimen/progress_bar_size_large</item>
+        <item name="minHeight">@dimen/progress_bar_size_large</item>
+        <item name="maxHeight">@dimen/progress_bar_size_large</item>
     </style>
 
     <style name="Widget.Material.ProgressBar.Large.Inverse"/>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ad3e204..e946136 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -310,7 +310,9 @@
   <java-symbol type="bool" name="config_guestUserEphemeral" />
   <java-symbol type="bool" name="config_localDisplaysMirrorContent" />
   <java-symbol type="bool" name="config_enableAppWidgetService" />
-  <java-symbol type="string" name="config_defaultPictureInPictureBounds" />
+  <java-symbol type="string" name="config_defaultPictureInPictureScreenEdgeInsets" />
+  <java-symbol type="string" name="config_defaultPictureInPictureSize" />
+  <java-symbol type="integer" name="config_defaultPictureInPictureGravity" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_threshold" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_factor" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_threshold" />
@@ -366,6 +368,7 @@
   <java-symbol type="integer" name="config_bluetooth_rx_cur_ma" />
   <java-symbol type="integer" name="config_bluetooth_tx_cur_ma" />
   <java-symbol type="integer" name="config_bluetooth_operating_voltage_mv" />
+  <java-symbol type="bool" name="config_bluetooth_pan_enable_autoconnect" />
   <java-symbol type="bool" name="config_bluetooth_reload_supported_profiles_when_enabled" />
   <java-symbol type="integer" name="config_cursorWindowSize" />
   <java-symbol type="integer" name="config_drawLockTimeoutMillis" />
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 0eb4c8d..ff8693b 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -212,9 +212,9 @@
         <item name="scrollbarDefaultDelayBeforeFade">400</item>
         <item name="scrollbarSize">10dp</item>
         <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_material</item>
-        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_material</item>
+        <item name="scrollbarThumbVertical">@drawable/config_scrollbarThumbVertical</item>
         <item name="scrollbarTrackHorizontal">@null</item>
-        <item name="scrollbarTrackVertical">@null</item>
+        <item name="scrollbarTrackVertical">@drawable/config_scrollbarTrackVertical</item>
 
         <!-- Text selection handle attributes -->
         <item name="textSelectHandleLeft">@drawable/text_select_handle_left_material</item>
@@ -573,9 +573,9 @@
         <item name="scrollbarDefaultDelayBeforeFade">400</item>
         <item name="scrollbarSize">10dp</item>
         <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_material</item>
-        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_material</item>
+        <item name="scrollbarThumbVertical">@drawable/config_scrollbarThumbVertical</item>
         <item name="scrollbarTrackHorizontal">@null</item>
-        <item name="scrollbarTrackVertical">@null</item>
+        <item name="scrollbarTrackVertical">@drawable/config_scrollbarTrackVertical</item>
 
         <!-- Text selection handle attributes -->
         <item name="textSelectHandleLeft">@drawable/text_select_handle_left_material</item>
diff --git a/core/tests/benchmarks/README b/core/tests/benchmarks/README
index 0a41bcc..e4d2dce 100644
--- a/core/tests/benchmarks/README
+++ b/core/tests/benchmarks/README
@@ -5,4 +5,21 @@
 http://code.google.com/p/caliper/
 http://code.google.com/p/vogar/
 
-$ vogar --benchmark path/to/Benchmark.java
+-------------------------
+
+Quick Command Line Reference:
+
+# Build vogar and dependencies.
+$> mmma -j32 external/vogar
+
+# First make sure art has permissions to dalvik-cache, otherwise it will run slower with interpreter.
+$> adb root
+
+# Run vogar in benchmark mode, telling it to use app_process (not dalvikvm which is default)
+# Otherwise you will likely crash with UnsatisfiedLinkError despite having correct JNI code.
+
+$> vogar --mode app_process --benchmark path/to/Benchmark.java
+
+# Sometimes your benchmarks might time out, if so increase the timeout:
+# (--timeout goes to vogar, and --time-limit goes to caliper)
+$> vogar --timeout 1000 --mode app_process --benchmark path/to/Benchmark -- --time-limit 9999s
diff --git a/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java
new file mode 100644
index 0000000..e9e3a18
--- /dev/null
+++ b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app.admin;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/** Unit tests for {@link PasswordMetrics}. */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class PasswordMetricsTest {
+
+    @Test
+    public void testIsDefault() {
+        final PasswordMetrics metrics = new PasswordMetrics();
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, metrics.quality);
+        assertEquals(0, metrics.length);
+        assertEquals(0, metrics.letters);
+        assertEquals(0, metrics.upperCase);
+        assertEquals(0, metrics.lowerCase);
+        assertEquals(0, metrics.numeric);
+        assertEquals(0, metrics.symbols);
+        assertEquals(0, metrics.nonLetter);
+        assertTrue("default constructor does not produce default metrics", metrics.isDefault());
+    }
+
+    @Test
+    public void testIsNotDefault() {
+        final PasswordMetrics metrics = new PasswordMetrics(
+                DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, 12);
+        assertFalse("non-default metrics are repoted as default", metrics.isDefault());
+    }
+
+    @Test
+    public void testComputeForEmptyPassword() {
+        final PasswordMetrics metrics = PasswordMetrics.computeForPassword("");
+        assertTrue("empty password has default metrics", metrics.isDefault());
+    }
+
+    @Test
+    public void testParceling() {
+        final int quality = 0;
+        final int length = 1;
+        final int letters = 2;
+        final int upperCase = 3;
+        final int lowerCase = 4;
+        final int numeric = 5;
+        final int symbols = 6;
+        final int nonLetter = 7;
+
+        final Parcel parcel = Parcel.obtain();
+        final PasswordMetrics metrics;
+        try {
+            new PasswordMetrics(
+                    quality, length, letters, upperCase, lowerCase, numeric, symbols, nonLetter)
+                    .writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            metrics = PasswordMetrics.CREATOR.createFromParcel(parcel);
+        } finally {
+            parcel.recycle();
+        }
+
+        assertEquals(quality, metrics.quality);
+        assertEquals(length, metrics.length);
+        assertEquals(letters, metrics.letters);
+        assertEquals(upperCase, metrics.upperCase);
+        assertEquals(lowerCase, metrics.lowerCase);
+        assertEquals(numeric, metrics.numeric);
+        assertEquals(symbols, metrics.symbols);
+        assertEquals(nonLetter, metrics.nonLetter);
+
+    }
+
+    @Test
+    public void testComputeForPassword_metrics() {
+        final PasswordMetrics metrics = PasswordMetrics.computeForPassword("6B~0z1Z3*8A");
+        assertEquals(11, metrics.length);
+        assertEquals(4, metrics.letters);
+        assertEquals(3, metrics.upperCase);
+        assertEquals(1, metrics.lowerCase);
+        assertEquals(5, metrics.numeric);
+        assertEquals(2, metrics.symbols);
+        assertEquals(7, metrics.nonLetter);
+    }
+
+    @Test
+    public void testComputeForPassword_quality() {
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
+                PasswordMetrics.computeForPassword("a1").quality);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC,
+                PasswordMetrics.computeForPassword("a").quality);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC,
+                PasswordMetrics.computeForPassword("*~&%$").quality);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX,
+                PasswordMetrics.computeForPassword("1").quality);
+        // contains a long sequence so isn't complex
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
+                PasswordMetrics.computeForPassword("1234").quality);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                PasswordMetrics.computeForPassword("").quality);
+    }
+
+    @Test
+    public void testMaxLengthSequence() {
+        assertEquals(4, PasswordMetrics.maxLengthSequence("1234"));
+        assertEquals(5, PasswordMetrics.maxLengthSequence("13579"));
+        assertEquals(4, PasswordMetrics.maxLengthSequence("1234abd"));
+        assertEquals(3, PasswordMetrics.maxLengthSequence("aabc"));
+        assertEquals(1, PasswordMetrics.maxLengthSequence("qwertyuio"));
+        assertEquals(3, PasswordMetrics.maxLengthSequence("@ABC"));
+        // anything that repeats
+        assertEquals(4, PasswordMetrics.maxLengthSequence(";;;;"));
+        // ordered, but not composed of alphas or digits
+        assertEquals(1, PasswordMetrics.maxLengthSequence(":;<=>"));
+    }
+}
diff --git a/core/tests/coretests/src/android/provider/DocumentsProviderTest.java b/core/tests/coretests/src/android/provider/DocumentsProviderTest.java
index 0b4675c..71546e4 100644
--- a/core/tests/coretests/src/android/provider/DocumentsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/DocumentsProviderTest.java
@@ -86,25 +86,18 @@
         assertNull(DocumentsContract.findPath(mResolver, docUri));
     }
 
-    public void testFindPath_treeUri_throwsOnNonNullRootId() throws Exception {
+    public void testFindPath_treeUri_erasesNonNullRootId() throws Exception {
         mProvider.nextIsChildDocument = true;
 
         mProvider.nextPath = new Path(ROOT_ID, Arrays.asList(PARENT_DOCUMENT_ID, DOCUMENT_ID));
 
         final Uri docUri = buildTreeDocumentUri(
                 TestDocumentsProvider.AUTHORITY, PARENT_DOCUMENT_ID, DOCUMENT_ID);
-        assertNull(DocumentsContract.findPath(mResolver, docUri));
-    }
-
-    public void testFindPath_treeUri_throwsOnDifferentParentDocId() throws Exception {
-        mProvider.nextIsChildDocument = true;
-
-        mProvider.nextPath = new Path(
-                null, Arrays.asList(ANCESTOR_DOCUMENT_ID, PARENT_DOCUMENT_ID, DOCUMENT_ID));
-
-        final Uri docUri = buildTreeDocumentUri(
-                TestDocumentsProvider.AUTHORITY, PARENT_DOCUMENT_ID, DOCUMENT_ID);
-        assertNull(DocumentsContract.findPath(mResolver, docUri));
+        try (ContentProviderClient client =
+                     mResolver.acquireUnstableContentProviderClient(docUri)) {
+            Path path = DocumentsContract.findPath(client, docUri);
+            assertNull(path.getRootId());
+        }
     }
 
     private static Uri buildTreeDocumentUri(String authority, String parentDocId, String docId) {
diff --git a/core/tests/coretests/src/android/util/TokenBucketTest.java b/core/tests/coretests/src/android/util/TokenBucketTest.java
new file mode 100644
index 0000000..f7ac20c
--- /dev/null
+++ b/core/tests/coretests/src/android/util/TokenBucketTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2016 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 android.os.SystemClock;
+import android.text.format.DateUtils;
+import junit.framework.TestCase;
+
+public class TokenBucketTest extends TestCase {
+
+    static final int FILL_DELTA_VERY_SHORT  = 1;
+    static final int FILL_DELTA_VERY_LONG   = Integer.MAX_VALUE;
+
+    public void testArgumentValidation() {
+        assertThrow(() -> new TokenBucket(0, 1, 1));
+        assertThrow(() -> new TokenBucket(1, 0, 1));
+        assertThrow(() -> new TokenBucket(1, 1, 0));
+        assertThrow(() -> new TokenBucket(0, 1));
+        assertThrow(() -> new TokenBucket(1, 0));
+        assertThrow(() -> new TokenBucket(-1, 1, 1));
+        assertThrow(() -> new TokenBucket(1, -1, 1));
+        assertThrow(() -> new TokenBucket(1, 1, -1));
+        assertThrow(() -> new TokenBucket(-1, 1));
+        assertThrow(() -> new TokenBucket(1, -1));
+
+        new TokenBucket(1000, 100, 0);
+        new TokenBucket(1000, 100, 10);
+        new TokenBucket(5000, 50);
+        new TokenBucket(5000, 1);
+    }
+
+    public void testInitialCapacity() {
+        drain(new TokenBucket(FILL_DELTA_VERY_LONG, 1), 1);
+        drain(new TokenBucket(FILL_DELTA_VERY_LONG, 10), 10);
+        drain(new TokenBucket(FILL_DELTA_VERY_LONG, 1000), 1000);
+
+        drain(new TokenBucket(FILL_DELTA_VERY_LONG, 10, 0), 0);
+        drain(new TokenBucket(FILL_DELTA_VERY_LONG, 10, 3), 3);
+        drain(new TokenBucket(FILL_DELTA_VERY_LONG, 10, 10), 10);
+
+        drain(new TokenBucket(FILL_DELTA_VERY_LONG, 10, 100), 10);
+
+        drain(new TokenBucket((int)DateUtils.MINUTE_IN_MILLIS, 50), 50);
+        drain(new TokenBucket((int)DateUtils.HOUR_IN_MILLIS, 10), 10);
+        drain(new TokenBucket((int)DateUtils.DAY_IN_MILLIS, 200), 200);
+    }
+
+    public void testReset() {
+        TokenBucket tb = new TokenBucket(FILL_DELTA_VERY_LONG, 100, 10);
+        drain(tb, 10);
+
+        tb.reset(50);
+        drain(tb, 50);
+
+        tb.reset(50);
+        getOneByOne(tb, 10);
+        assertTrue(tb.has());
+
+        tb.reset(30);
+        drain(tb, 30);
+    }
+
+    public void testFill() throws Exception {
+        int delta = 50;
+        TokenBucket tb = new TokenBucket(delta, 10, 0);
+
+        assertEmpty(tb);
+
+        Thread.sleep(3 * delta / 2);
+
+        assertTrue(tb.has());
+    }
+
+    public void testRefill() throws Exception {
+        TokenBucket tb = new TokenBucket(FILL_DELTA_VERY_SHORT, 10, 10);
+
+        assertEquals(5, tb.get(5));
+        assertEquals(5, tb.get(5));
+
+        while (tb.available() < 10) {
+            Thread.sleep(2);
+        }
+
+        assertEquals(10, tb.get(10));
+
+        while (tb.available() < 10) {
+            Thread.sleep(2);
+        }
+
+        assertEquals(10, tb.get(100));
+    }
+
+    public void testAverage() throws Exception {
+        final int delta = 3;
+        final int want = 60;
+
+        long start = SystemClock.elapsedRealtime();
+        TokenBucket tb = new TokenBucket(delta, 20, 0);
+
+        for (int i = 0; i < want; i++) {
+            while (!tb.has()) {
+                Thread.sleep(5 * delta);
+            }
+            tb.get();
+        }
+
+        assertDuration(want * delta, SystemClock.elapsedRealtime() - start);
+    }
+
+    public void testBurst() throws Exception {
+        final int delta = 2;
+        final int capacity = 20;
+        final int want = 100;
+
+        long start = SystemClock.elapsedRealtime();
+        TokenBucket tb = new TokenBucket(delta, capacity, 0);
+
+        int total = 0;
+        while (total < want) {
+            while (!tb.has()) {
+                Thread.sleep(capacity * delta - 2);
+            }
+            total += tb.get(tb.available());
+        }
+
+        assertDuration(total * delta, SystemClock.elapsedRealtime() - start);
+    }
+
+    static void getOneByOne(TokenBucket tb, int n) {
+        while (n > 0) {
+            assertTrue(tb.has());
+            assertTrue(tb.available() >= n);
+            assertTrue(tb.get());
+            assertTrue(tb.available() >= n - 1);
+            n--;
+        }
+    }
+
+    void assertEmpty(TokenBucket tb) {
+        assertFalse(tb.has());
+        assertEquals(0, tb.available());
+        assertFalse(tb.get());
+    }
+
+    void drain(TokenBucket tb, int n) {
+        getOneByOne(tb, n);
+        assertEmpty(tb);
+    }
+
+    void assertDuration(long expected, long elapsed) {
+        String msg = String.format(
+            "expected elapsed time at least %d ms, but was %d ms", expected, elapsed);
+        elapsed += 1; // one millisecond extra guard
+        assertTrue(msg, elapsed >= expected);
+    }
+
+    void assertThrow(Fn fn)     {
+      try {
+          fn.call();
+          fail("expected n exception to be thrown.");
+      } catch (Throwable t) {}
+    }
+
+    interface Fn { void call(); }
+}
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index ea22cd1..71dd526 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -17,7 +17,6 @@
 package android.widget;
 
 import static android.widget.espresso.CustomViewActions.longPressAtRelativeCoordinates;
-import static android.support.test.espresso.action.ViewActions.longClick;
 import static android.widget.espresso.DragHandleUtils.assertNoSelectionHandles;
 import static android.widget.espresso.DragHandleUtils.onHandleView;
 import static android.widget.espresso.TextViewActions.clickOnTextAtIndex;
@@ -37,6 +36,7 @@
 import static android.widget.espresso.FloatingToolbarEspressoUtils.sleepForFloatingToolbarPopup;
 import static android.support.test.espresso.Espresso.onView;
 import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.action.ViewActions.longClick;
 import static android.support.test.espresso.action.ViewActions.pressKey;
 import static android.support.test.espresso.action.ViewActions.replaceText;
 import static android.support.test.espresso.action.ViewActions.typeTextIntoFocusedView;
@@ -44,24 +44,25 @@
 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
 import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.Matchers.is;
 
 import android.widget.espresso.CustomViewActions.RelativeCoordinatesProvider;
-import com.android.frameworks.coretests.R;
 
 import android.support.test.espresso.action.EspressoKey;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.text.Selection;
 import android.text.Spannable;
 import android.text.InputType;
 import android.view.KeyEvent;
 
-import static org.hamcrest.Matchers.anyOf;
-import static org.hamcrest.Matchers.is;
+import com.android.frameworks.coretests.R;
 
 /**
  * Tests the TextView widget from an Activity
  */
+@MediumTest
 public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextViewActivity>{
 
     public TextViewActivityTest() {
@@ -74,7 +75,6 @@
         getActivity();
     }
 
-    @SmallTest
     public void testTypedTextIsOnScreen() throws Exception {
         final String helloWorld = "Hello world!";
         onView(withId(R.id.textview)).perform(click());
@@ -83,7 +83,6 @@
         onView(withId(R.id.textview)).check(matches(withText(helloWorld)));
     }
 
-    @SmallTest
     public void testPositionCursorAtTextAtIndex() throws Exception {
         final String helloWorld = "Hello world!";
         onView(withId(R.id.textview)).perform(click());
@@ -95,7 +94,6 @@
         onView(withId(R.id.textview)).check(matches(withText("Hello orld!")));
     }
 
-    @SmallTest
     public void testPositionCursorAtTextAtIndex_arabic() throws Exception {
         // Arabic text. The expected cursorable boundary is
         // | \u0623 \u064F | \u067A | \u0633 \u0652 |
@@ -117,7 +115,6 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(5));
     }
 
-    @SmallTest
     public void testPositionCursorAtTextAtIndex_devanagari() throws Exception {
         // Devanagari text. The expected cursorable boundary is | \u0915 \u093E |
         final String text = "\u0915\u093E";
@@ -132,7 +129,6 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(2));
     }
 
-    @SmallTest
     public void testLongPressToSelect() throws Exception {
         final String helloWorld = "Hello Kirk!";
         onView(withId(R.id.textview)).perform(click());
@@ -143,7 +139,6 @@
         onView(withId(R.id.textview)).check(hasSelection("Kirk"));
     }
 
-    @SmallTest
     public void testLongPressEmptySpace() throws Exception {
         final String helloWorld = "Hello big round sun!";
         onView(withId(R.id.textview)).perform(click());
@@ -158,7 +153,6 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(helloWorld.length()));
     }
 
-    @SmallTest
     public void testLongPressAndDragToSelect() throws Exception {
         final String helloWorld = "Hello little handsome boy!";
         onView(withId(R.id.textview)).perform(click());
@@ -169,7 +163,20 @@
         onView(withId(R.id.textview)).check(hasSelection("little handsome"));
     }
 
-    @SmallTest
+    public void testLongPressAndDragToSelect_emoji() throws Exception {
+        final String text = "\uD83D\uDE00\uD83D\uDE01\uD83D\uDE02\uD83D\uDE03";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(replaceText(text));
+
+        onView(withId(R.id.textview)).perform(longPressAndDragOnText(4, 6));
+        onView(withId(R.id.textview)).check(hasSelection("\uD83D\uDE02"));
+
+        onView(withId(R.id.textview)).perform(click());
+
+        onView(withId(R.id.textview)).perform(longPressAndDragOnText(4, 2));
+        onView(withId(R.id.textview)).check(hasSelection("\uD83D\uDE01"));
+    }
+
     public void testDragAndDrop() throws Exception {
         final String text = "abc def ghi.";
         onView(withId(R.id.textview)).perform(click());
@@ -191,7 +198,6 @@
         onView(withId(R.id.textview)).check(matches(withText(text)));
     }
 
-    @SmallTest
     public void testDoubleTapToSelect() throws Exception {
         final String helloWorld = "Hello SuetYi!";
         onView(withId(R.id.textview)).perform(click());
@@ -202,7 +208,6 @@
         onView(withId(R.id.textview)).check(hasSelection("SuetYi"));
     }
 
-    @SmallTest
     public void testDoubleTapAndDragToSelect() throws Exception {
         final String helloWorld = "Hello young beautiful girl!";
         onView(withId(R.id.textview)).perform(click());
@@ -213,7 +218,6 @@
         onView(withId(R.id.textview)).check(hasSelection("young beautiful"));
     }
 
-    @SmallTest
     public void testDoubleTapAndDragToSelect_multiLine() throws Exception {
         final String helloWorld = "abcd\n" + "efg\n" + "hijklm\n" + "nop";
         onView(withId(R.id.textview)).perform(click());
@@ -223,7 +227,6 @@
         onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijklm"));
     }
 
-    @SmallTest
     public void testSelectBackwordsByTouch() throws Exception {
         final String helloWorld = "Hello king of the Jungle!";
         onView(withId(R.id.textview)).perform(click());
@@ -234,7 +237,6 @@
         onView(withId(R.id.textview)).check(hasSelection("king of the"));
     }
 
-    @SmallTest
     public void testToolbarAppearsAfterSelection() throws Exception {
         final String text = "Toolbar appears after selection.";
         onView(withId(R.id.textview)).perform(click());
@@ -251,7 +253,6 @@
         assertFloatingToolbarIsNotDisplayed();
     }
 
-    @SmallTest
     public void testToolbarAppearsAfterSelection_withFirstStringLtrAlgorithmAndRtlHint()
             throws Exception {
         // after the hint layout change, the floating toolbar was not visible in the case below
@@ -279,7 +280,6 @@
         assertFloatingToolbarIsDisplayed();
     }
 
-    @SmallTest
     public void testToolbarAndInsertionHandle() throws Exception {
         final String text = "text";
         onView(withId(R.id.textview)).perform(click());
@@ -299,7 +299,6 @@
                 getActivity().getString(com.android.internal.R.string.cut));
     }
 
-    @SmallTest
     public void testToolbarAndSelectionHandle() throws Exception {
         final String text = "abcd efg hijk";
         onView(withId(R.id.textview)).perform(click());
@@ -335,7 +334,6 @@
                 getActivity().getString(com.android.internal.R.string.cut));
     }
 
-    @SmallTest
     public void testInsertionHandle() throws Exception {
         final String text = "abcd efg hijk ";
         onView(withId(R.id.textview)).perform(click());
@@ -355,7 +353,6 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
     }
 
-    @SmallTest
     public void testInsertionHandle_multiLine() throws Exception {
         final String text = "abcd\n" + "efg\n" + "hijk\n";
         onView(withId(R.id.textview)).perform(click());
@@ -375,7 +372,6 @@
         onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
     }
 
-    @SmallTest
     public void testSelectionHandles() throws Exception {
         final String text = "abcd efg hijk lmn";
         onView(withId(R.id.textview)).perform(click());
@@ -400,7 +396,6 @@
         onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk"));
     }
 
-    @SmallTest
     public void testSelectionHandles_bidi() throws Exception {
         final String text = "abc \u0621\u0622\u0623 def";
         onView(withId(R.id.textview)).perform(click());
@@ -445,7 +440,6 @@
         onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623 def"));
     }
 
-    @SmallTest
     public void testSelectionHandles_multiLine() throws Exception {
         final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
         onView(withId(R.id.textview)).perform(click());
@@ -470,7 +464,6 @@
         onView(withId(R.id.textview)).check(hasSelection("abcd\nefg\nhijk\nlmn\nopqr"));
     }
 
-    @SmallTest
     public void testSelectionHandles_multiLine_rtl() throws Exception {
         // Arabic text.
         final String text = "\u062A\u062B\u062C\n" + "\u062D\u062E\u062F\n"
@@ -503,7 +496,6 @@
     }
 
 
-    @SmallTest
     public void testSelectionHandles_doesNotPassAnotherHandle() throws Exception {
         final String text = "abcd efg hijk lmn";
         onView(withId(R.id.textview)).perform(click());
@@ -521,7 +513,6 @@
         onView(withId(R.id.textview)).check(hasSelection("e"));
     }
 
-    @SmallTest
     public void testSelectionHandles_doesNotPassAnotherHandle_multiLine() throws Exception {
         final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
         onView(withId(R.id.textview)).perform(click());
@@ -539,7 +530,6 @@
         onView(withId(R.id.textview)).check(hasSelection("h"));
     }
 
-    @SmallTest
     public void testSelectionHandles_snapToWordBoundary() throws Exception {
         final String text = "abcd efg hijk lmn opqr";
         onView(withId(R.id.textview)).perform(click());
@@ -592,7 +582,6 @@
         onView(withId(R.id.textview)).check(hasSelection("hijk lmn opq"));
     }
 
-    @SmallTest
     public void testSelectionHandles_snapToWordBoundary_multiLine() throws Exception {
         final String text = "abcd efg\n" + "hijk lmn\n" + "opqr stu";
         onView(withId(R.id.textview)).perform(click());
@@ -628,7 +617,6 @@
         onView(withId(R.id.textview)).check(hasSelection("hijk"));
     }
 
-    @SmallTest
     public void testSetSelectionAndActionMode() throws Exception {
         final String text = "abc def";
         onView(withId(R.id.textview)).perform(click());
@@ -692,7 +680,6 @@
                 getActivity().getString(com.android.internal.R.string.copy));
     }
 
-    @SmallTest
     public void testTransientState() throws Exception {
         final String text = "abc def";
         onView(withId(R.id.textview)).perform(click());
diff --git a/core/tests/utiltests/Android.mk b/core/tests/utiltests/Android.mk
index de962fa..6e415f4 100644
--- a/core/tests/utiltests/Android.mk
+++ b/core/tests/utiltests/Android.mk
@@ -14,6 +14,7 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
+    frameworks-base-testutils \
     mockito-target-minus-junit4
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
diff --git a/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProviderTest.java b/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java
similarity index 97%
rename from services/tests/servicestests/src/com/android/internal/util/FakeSettingsProviderTest.java
rename to core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java
index 05de0a5..f2be109 100644
--- a/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProviderTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.util;
+package com.android.internal.util.test;
 
 import android.content.ContentResolver;
 import android.database.ContentObserver;
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index 6185dab..7daf85c 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -1237,7 +1237,7 @@
 - from: /r/studio-ui/run-with-work-profile.html
   to: /studio/run/index.html?utm_source=android-studio#ir-work-profile
 - from: /r/studio-ui/am-gpu-debugger.html
-  to: /studio/profile/am-gpu.html?utm_source=android-studio
+  to: /studio/debug/am-gpu-debugger.html?utm_source=android-studio
 - from: /r/studio-ui/theme-editor.html
   to: /studio/write/theme-editor.html?utm_source=android-studio
 - from: /r/studio-ui/translations-editor.html
diff --git a/docs/html/google/play/billing/billing_integrate.jd b/docs/html/google/play/billing/billing_integrate.jd
index 5d6b3a8..506a440 100755
--- a/docs/html/google/play/billing/billing_integrate.jd
+++ b/docs/html/google/play/billing/billing_integrate.jd
@@ -9,18 +9,18 @@
   <h2>In this document</h2>
   <ol>
     <li><a href="#billing-add-aidl">Adding the AIDL file</a></li>
-    <li><a href="#billing-permission">Updating Your Manifest</a></li>
+    <li><a href="#billing-permission">Updating your manifest</a></li>
     <li><a href="#billing-service">Creating a ServiceConnection</a></li>
-    <li><a href="#billing-requests">Making In-app Billing Requests</a>
+    <li><a href="#billing-requests">Making In-app Billing requests</a>
        <ol>
-       <li><a href="#QueryDetails">Querying Items Available for Purchase</a><li>
-       <li><a href="#Purchase">Purchasing an Item</a></li>
-       <li><a href="#QueryPurchases">Querying Purchased Items</a></li>
-       <li><a href="#Consume">Consuming a Purchase</a></li>
-       <li><a href="#Subs">Implementing Subscriptions</a></li>
+       <li><a href="#QueryDetails">Querying items available for purchase</a><li>
+       <li><a href="#Purchase">Purchasing an item</a></li>
+       <li><a href="#QueryPurchases">Querying purchased items</a></li>
+       <li><a href="#Consume">Consuming a purchase</a></li>
+       <li><a href="#Subs">Implementing subscriptions</a></li>
        </ol>
     </li>
-    <li><a href="#billing-security">Securing Your App</a>
+    <li><a href="#billing-security">Securing your app</a>
   </ol>
   <h2>Reference</h2>
   <ol>
@@ -42,7 +42,7 @@
   In-app Billing on Google Play provides a straightforward, simple interface
   for sending In-app Billing requests and managing In-app Billing transactions
   using Google Play. The information below covers the basics of how to make
-  calls from your application to the In-app Billing service using the Version 3
+  calls from your application to the In-app Billing service using the In-app Billing Version 3
   API.
 </p>
 
@@ -51,26 +51,25 @@
   your application, see the <a href=
   "{@docRoot}training/in-app-billing/index.html">Selling In-app Products</a>
   training class. The training class provides a complete sample In-app Billing
-  application, including convenience classes to handle key tasks related to
-  setting up your connection, sending billing requests and processing responses
+  application, including convenience classes to handle key tasks that are related to
+  setting up your connection, sending billing requests, processing responses
   from Google Play, and managing background threading so that you can make
   In-app Billing calls from your main activity.
 </p>
 
 <p>
-  Before you start, be sure that you read the <a href=
+  Before you start, read the <a href=
   "{@docRoot}google/play/billing/billing_overview.html">In-app Billing
-  Overview</a> to familiarize yourself with concepts that will make it easier
+  Overview</a> to familiarize yourself with concepts that make it easier
   for you to implement In-app Billing.
 </p>
 
-<p>To implement In-app Billing in your application, you need to do the
-following:</p>
+<p>Complete these steps to implement In-app Billing in your application:</p>
 
 <ol>
   <li>Add the In-app Billing library to your project.</li>
   <li>Update your {@code AndroidManifest.xml} file.</li>
-  <li>Create a {@code ServiceConnection} and bind it to
+  <li>Create a {@code ServiceConnection} and bind it to the
 {@code IInAppBillingService}.</li>
   <li>Send In-app Billing requests from your application to
 {@code IInAppBillingService}.</li>
@@ -79,55 +78,56 @@
 
 <h2 id="billing-add-aidl">Adding the AIDL file to your project</h2>
 
-<p>{@code IInAppBillingService.aidl} is an Android Interface Definition
+<p>The {@code IInAppBillingService.aidl} is an Android Interface Definition
 Language (AIDL) file that defines the interface to the In-app Billing Version
-3 service. You will use this interface to make billing requests by invoking IPC
+3 service. You can use this interface to make billing requests by invoking IPC
 method calls.</p>
-<p>To get the AIDL file:</p>
+
+<p>Complete these steps to get the AIDL file:</p>
 <ol>
 <li>Open the <a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a>.</li>
 <li>In the SDK Manager, expand the {@code Extras} section.</li>
 <li>Select <strong>Google Play Billing Library</strong>.</li>
 <li>Click <strong>Install packages</strong> to complete the download.</li>
 </ol>
-<p>The {@code IInAppBillingService.aidl} file will be installed to {@code <sdk>/extras/google/play_billing/}.</p>
+<p>The {@code IInAppBillingService.aidl} file will be installed to {@code &lt;sdk&gt;/extras/google/play_billing/}.</p>
 
-<p>To add the AIDL to your project:</p>
+<p>Complete these steps to add the AIDL to your project:</p>
 
 <ol>
-  <li>First, download the Google Play Billing Library to your Android project:
+  <li>Download the Google Play Billing Library to your Android project:
       <ol type="a">
       <li>Select <strong>Tools > Android > SDK Manager</strong>.</li>
       <li>Under <strong>Appearance & Behavior > System Settings > Android SDK</strong>,
           select the <em>SDK Tools</em> tab to select and download <em>Google Play Billing
           Library</em>.</li></ol>
 
-  <li>Next, copy the {@code IInAppBillingService.aidl} file to your project.
+  <li>Copy the {@code IInAppBillingService.aidl} file to your project.
     <ul>
-      <li>If you are using Android Studio:
+      <li>If you are using Android Studio, complete these steps to copy the file:
         <ol type="a">
           <li>Navigate to {@code src/main} in the Project tool window.</li>
 
-          <li>Select <strong>File > New > Directory</strong> and enter {@code aidl} in the
-          <em>New Directory</em> window, then select <strong>OK</strong>.
+          <li>Select <strong>File > New > Directory</strong>, enter {@code aidl} in the
+          <em>New Directory</em> window, and select <strong>OK</strong>.
 
-          <li>Select <strong>File > New > Package</strong> and enter
-          {@code com.android.vending.billing} in the <em>New Package</em> window, then select
+          <li>Select <strong>File > New > Package</strong>, enter
+          {@code com.android.vending.billing} in the <em>New Package</em> window, and select
           <strong>OK</strong>.</li>
 
           <li>Using your operating system file explorer, navigate to
-          {@code <sdk>/extras/google/play_billing/}, copy the
+          {@code &lt;sdk&gt;/extras/google/play_billing/}, copy the
           {@code IInAppBillingService.aidl} file, and paste it into the
           {@code com.android.vending.billing} package in your project.
           </li>
         </ol>
       </li>
 
-      <li>If you are developing in a non-Android Studio environment: Create the
-      following directory {@code /src/com/android/vending/billing} and copy the
-      {@code IInAppBillingService.aidl} file into this directory. Put the AIDL
-      file into your project and use the Gradle tool to build your project so that
-      the <code>IInAppBillingService.java</code> file gets generated.
+      <li>If you are developing in a non-Android Studio environment, create the
+      following directory: {@code /src/com/android/vending/billing}. Copy the
+      {@code IInAppBillingService.aidl} file into this directory. Place the AIDL
+      file in your project and use the Gradle tool to build your project so that
+      the <code>IInAppBillingService.java</code> file is generated.
       </li>
     </ul>
   </li>
@@ -137,16 +137,16 @@
   </li>
 </ol>
 
-<h2 id="billing-permission">Updating Your App's Manifest</h2>
+<h2 id="billing-permission">Updating your app's manifest</h2>
 
 <p>
   In-app billing relies on the Google Play application, which handles all
-  communication between your application and the Google Play server. To use the
+  of the communication between your application and the Google Play server. To use the
   Google Play application, your application must request the proper permission.
   You can do this by adding the {@code com.android.vending.BILLING} permission
   to your AndroidManifest.xml file. If your application does not declare the
   In-app Billing permission, but attempts to send billing requests, Google Play
-  will refuse the requests and respond with an error.
+  refuses the requests and responds with an error.
 </p>
 
 <p>
@@ -182,7 +182,7 @@
   onServiceDisconnected} and {@link
   android.content.ServiceConnection#onServiceConnected onServiceConnected}
   methods to get a reference to the {@code IInAppBillingService} instance after
-  a connection has been established.
+  a connection is established.
 </p>
 
 <pre>
@@ -208,20 +208,25 @@
   bindService} method. Pass the method an {@link android.content.Intent} that
   references the In-app Billing service and an instance of the {@link
   android.content.ServiceConnection} that you created, and explicitly set the
-  Intent's target package name to <code>com.android.vending</code> — the
+  Intent's target package name to <code>com.android.vending</code>&mdash;the
   package name of Google Play app.
 </p>
 
 <p class="caution">
   <strong>Caution:</strong> To protect the security of billing transactions,
-  always make sure to explicitly set the intent's target package name to
+  always explicitly set the intent's target package name to
   <code>com.android.vending</code>, using {@link
-  android.content.Intent#setPackage(java.lang.String) setPackage()} as shown in
-  the example below. Setting the package name explicitly ensures that
+  android.content.Intent#setPackage(java.lang.String) setPackage()}.
+  Setting the package name explicitly ensures that
   <em>only</em> the Google Play app can handle billing requests from your app,
   preventing other apps from intercepting those requests.
 </p>
 
+<p>
+  The following code sample demonstrates how to set the intent's target package
+  to protect the security of transactions:
+</p>
+
 <pre>&#64;Override
 public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
@@ -233,6 +238,13 @@
 }
 </pre>
 
+<p class="caution"><strong>Caution</strong>: To ensure that your app is secure, always use an
+explicit intent when starting a {@link android.app.Service} and do not declare intent filters for
+your services. Using an implicit intent to start a service is a security hazard because you cannot
+be certain of the service that will respond to the intent, and the user cannot see which service
+starts. Beginning with Android 5.0 (API level 21), the system throws an exception if you call
+{@link android.content.Context#bindService bindService()} with an implicit intent.</p>
+
 <p>
   You can now use the mService reference to communicate with the Google Play
   service.
@@ -242,10 +254,14 @@
   <strong>Important:</strong> Remember to unbind from the In-app Billing
   service when you are done with your {@link android.app.Activity}. If you
   don’t unbind, the open service connection could cause your device’s
-  performance to degrade. This example shows how to perform the unbind
+  performance to degrade.
+</p>
+
+<p>
+  This example shows how to perform the unbind
   operation on a service connection to In-app Billing called {@code
   mServiceConn} by overriding the activity’s {@link
-  android.app.Activity#onDestroy onDestroy} method.
+  android.app.Activity#onDestroy onDestroy} method:
 </p>
 
 <pre>
@@ -264,29 +280,29 @@
   "{@docRoot}training/in-app-billing/preparing-iab-app.html">Selling In-app
   Products</a> training class and associated sample.
 </p>
-<h2 id="billing-requests">Making In-app Billing Requests</h2>
+<h2 id="billing-requests">Making In-app Billing requests</h2>
 <p>
-  Once your application is connected to Google Play, you can initiate purchase
+  After your application is connected to Google Play, you can initiate purchase
   requests for in-app products. Google Play provides a checkout interface for
-  users to enter their payment method, so your application does not need to
+  users to enter their payment method, so your application doesn't need to
   handle payment transactions directly. When an item is purchased, Google Play
   recognizes that the user has ownership of that item and prevents the user
   from purchasing another item with the same product ID until it is consumed.
-  You can control how the item is consumed in your application, and notify
+  You can control how the item is consumed in your application and notify
   Google Play to make the item available for purchase again. You can also query
-  Google Play to quickly retrieve the list of purchases that were made by the
-  user. This is useful, for example, when you want to restore the user's
+  Google Play to quickly retrieve the list of purchases that the
+  user made. This is useful, for example, when you want to restore the user's
   purchases when your user launches your app.
 </p>
 
-<h3 id="QueryDetails">Querying for Items Available for Purchase</h3>
+<h3 id="QueryDetails">Querying for items available for purchase</h3>
 
 <p>
   In your application, you can query the item details from Google Play using
   the In-app Billing Version 3 API. To pass a request to the In-app Billing
-  service, first create a {@link android.os.Bundle} that contains a String
+  service, create a {@link android.os.Bundle} that contains a String
   {@link java.util.ArrayList} of product IDs with key "ITEM_ID_LIST", where
-  each string is a product ID for an purchasable item.
+  each string is a product ID for an purchasable item. Here is an example:
 </p>
 
 <pre>
@@ -299,9 +315,9 @@
 
 <p>
   To retrieve this information from Google Play, call the {@code getSkuDetails}
-  method on the In-app Billing Version 3 API, and pass the method the In-app
+  method on the In-app Billing Version 3 API and pass the In-app
   Billing API version (“3”), the package name of your calling app, the purchase
-  type (“inapp”), and the {@link android.os.Bundle} that you created.
+  type (“inapp”), and the {@link android.os.Bundle} that you created, into the method:
 </p>
 
 <pre>
@@ -310,35 +326,35 @@
 </pre>
 
 <p>
-  If the request is successful, the returned {@link android.os.Bundle}has a
+  If the request is successful, the returned {@link android.os.Bundle} has a
   response code of {@code BILLING_RESPONSE_RESULT_OK} (0).
 </p>
 
 <p class="note">
-  <strong>Warning:</strong> Do not call the {@code getSkuDetails} method on the
-  main thread. Calling this method triggers a network request which could block
+  <strong>Warning:</strong> Don't call the {@code getSkuDetails} method on the
+  main thread. Calling this method triggers a network request that could block
   your main thread. Instead, create a separate thread and call the {@code
-  getSkuDetails} method from inside that thread.
+  getSkuDetails} method from inside of that thread.
 </p>
 
 <p>
-  To see all the possible response codes from Google Play, see <a href=
+  To view all of the possible response codes from Google Play, see <a href=
   "{@docRoot}google/play/billing/billing_reference.html#billing-codes">In-app
   Billing Reference</a>.
 </p>
 
 <p>
   The query results are stored in a String ArrayList with key {@code
-  DETAILS_LIST}. The purchase information is stored in the String in JSON
-  format. To see the types of product detail information that are returned, see
+  DETAILS_LIST}. The purchase information is stored within the String in JSON
+  format. To view the types of product detail information that are returned, see
   <a href=
   "{@docRoot}google/play/billing/billing_reference.html#getSkuDetails">In-app
   Billing Reference</a>.
 </p>
 
 <p>
-  In this example, you are retrieving the prices for your in-app items from the
-  skuDetails {@link android.os.Bundle} returned from the previous code snippet.
+  In this example shows how to retrieve the prices for your in-app items from the
+  skuDetails {@link android.os.Bundle} that is returned from the previous code snippet:
 </p>
 
 <pre>
@@ -357,15 +373,15 @@
 }
 </pre>
 
-<h3 id="Purchase">Purchasing an Item</h3>
+<h3 id="Purchase">Purchasing an item</h3>
 <p>
   To start a purchase request from your app, call the {@code getBuyIntent}
-  method on the In-app Billing service. Pass in to the method the In-app
+  method on the In-app Billing service. Pass the In-app
   Billing API version (“3”), the package name of your calling app, the product
   ID for the item to purchase, the purchase type (“inapp” or "subs"), and a
-  {@code developerPayload} String. The {@code developerPayload} String is used
+  {@code developerPayload} String into the method. The {@code developerPayload} String is used
   to specify any additional arguments that you want Google Play to send back
-  along with the purchase information.
+  along with the purchase information. Here is an example:
 </p>
 
 <pre>
@@ -377,10 +393,13 @@
   If the request is successful, the returned {@link android.os.Bundle} has a
   response code of {@code BILLING_RESPONSE_RESULT_OK} (0) and a {@link
   android.app.PendingIntent} that you can use to start the purchase flow. To
-  see all the possible response codes from Google Play, see <a href=
+  view all of the possible response codes from Google Play, see <a href=
   "{@docRoot}google/play/billing/billing_reference.html#billing-codes">In-app
-  Billing Reference</a>. Next, extract a {@link android.app.PendingIntent} from
-  the response {@link android.os.Bundle} with key {@code BUY_INTENT}.
+  Billing Reference</a>.
+
+<p>
+  The next step is to extract a {@link android.app.PendingIntent} from
+  the response {@link android.os.Bundle} with key {@code BUY_INTENT}, as shown here:
 </p>
 
 <pre>
@@ -390,8 +409,8 @@
 <p>
   To complete the purchase transaction, call the {@link
   android.app.Activity#startIntentSenderForResult startIntentSenderForResult}
-  method and use the {@link android.app.PendingIntent} that you created. In
-  this example, you are using an arbitrary value of 1001 for the request code.
+  method and use the {@link android.app.PendingIntent} that you created. This
+  example uses an arbitrary value of 1001 for the request code:
 </p>
 
 <pre>
@@ -404,9 +423,9 @@
   Google Play sends a response to your {@link android.app.PendingIntent} to the
   {@link android.app.Activity#onActivityResult onActivityResult} method of your
   application. The {@link android.app.Activity#onActivityResult
-  onActivityResult} method will have a result code of {@code
-  Activity.RESULT_OK} (1) or {@code Activity.RESULT_CANCELED} (0). To see the
-  types of order information that is returned in the response {@link
+  onActivityResult} method has a result code of {@code
+  Activity.RESULT_OK} (1) or {@code Activity.RESULT_CANCELED} (0). To view the
+  types of order information that are returned in the response {@link
   android.content.Intent}, see <a href=
   "{@docRoot}google/play/billing/billing_reference.html#getBuyIntent">In-app
   Billing Reference</a>.
@@ -415,7 +434,7 @@
 <p>
   The purchase data for the order is a String in JSON format that is mapped to
   the {@code INAPP_PURCHASE_DATA} key in the response {@link
-  android.content.Intent}, for example:
+  android.content.Intent}. Here is an example:
 </p>
 
 <pre>
@@ -436,13 +455,13 @@
   long. Pass this entire token to other methods, such as when you consume the
   purchase, as described in <a href=
   "{@docRoot}training/in-app-billing/purchase-iab-products.html#Consume">Consume
-  a Purchase</a>. Do not abbreviate or truncate this token; you must save and
+  a Purchase</a>. Don't abbreviate or truncate this token; you must save and
   return the entire token.
 </p>
 
 <p>
-  Continuing from the previous example, you get the response code, purchase
-  data, and signature from the response {@link android.content.Intent}.
+  Continuing from the previous example, you receive the response code, purchase
+  data, and signature from the response {@link android.content.Intent}:
 </p>
 
 <pre>
@@ -472,23 +491,23 @@
 <p class="note">
   <strong>Security Recommendation:</strong> When you send a purchase request,
   create a String token that uniquely identifies this purchase request and
-  include this token in the {@code developerPayload}.You can use a randomly
-  generated string as the token. When you receive the purchase response from
-  Google Play, make sure to check the returned data signature, the {@code
+  include this token in the {@code developerPayload}. You can use a randomly-generated
+  string as the token. When you receive the purchase response from
+  Google Play, ensure that you check the returned data signature, the {@code
   orderId}, and the {@code developerPayload} String. For added security, you
-  should perform the checking on your own secure server. Make sure to verify
+  should perform the checking on your own secure server. Verify
   that the {@code orderId} is a unique value that you have not previously
-  processed, and the {@code developerPayload} String matches the token that you
+  processed and that the {@code developerPayload} String matches the token that you
   sent previously with the purchase request.
 </p>
 
-<h3 id="QueryPurchases">Querying for Purchased Items</h3>
+<h3 id="QueryPurchases">Querying for purchased items</h3>
 
 <p>
-  To retrieve information about purchases made by a user from your app, call
+  To retrieve information about purchases that are made by a user from your app, call
   the {@code getPurchases} method on the In-app Billing Version 3 service. Pass
-  in to the method the In-app Billing API version (“3”), the package name of
-  your calling app, and the purchase type (“inapp” or "subs").
+  the In-app Billing API version (“3”), the package name of
+  your calling app, and the purchase type (“inapp” or "subs") into the method. Here is an example:
 </p>
 
 <pre>
@@ -507,18 +526,18 @@
   To improve performance, the In-app Billing service returns only up to 700
   products that are owned by the user when {@code getPurchase} is first called.
   If the user owns a large number of products, Google Play includes a String
-  token mapped to the key {@code INAPP_CONTINUATION_TOKEN} in the response
+  token that is mapped to the key {@code INAPP_CONTINUATION_TOKEN} in the response
   {@link android.os.Bundle} to indicate that more products can be retrieved.
-  Your application can then make a subsequent {@code getPurchases} call, and
+  Your application can then make a subsequent {@code getPurchases} call and
   pass in this token as an argument. Google Play continues to return a
   continuation token in the response {@link android.os.Bundle} until all
-  products that are owned by the user has been sent to your app.
+  of the products that are owned by the user are sent to your app.
 </p>
 
-<p>For more information about the data returned by {@code getPurchases}, see
+<p>For more information about the data that is returned by {@code getPurchases}, see
   <a href="{@docRoot}google/play/billing/billing_reference.html#getPurchases">
   In-app Billing Reference</a>. The following example shows how you can
-  retrieve this data from the response.
+  retrieve this data from the response:
 </p>
 
 <pre>
@@ -548,26 +567,26 @@
 </pre>
 
 
-<h3 id="Consume">Consuming a Purchase</h3>
+<h3 id="Consume">Consuming a purchase</h3>
 
 <p>
   You can use the In-app Billing Version 3 API to track the ownership of
   purchased in-app products in Google Play. Once an in-app product is
-  purchased, it is considered to be "owned" and cannot be purchased from Google
+  purchased, it is considered to be <em>owned</em> and cannot be purchased from Google
   Play. You must send a consumption request for the in-app product before
   Google Play makes it available for purchase again.
 </p>
 
-<p class="caution">
+<p class="note">
   <strong>Important</strong>: Managed in-app products are consumable, but
   subscriptions are not.
 </p>
 
 <p>
-  How you use the consumption mechanism in your app is up to you. Typically,
-  you would implement consumption for in-app products with temporary benefits
+  The way that you use the consumption mechanism in your app is up to you. Typically,
+  you implement consumption for in-app products with temporary benefits
   that users may want to purchase multiple times (for example, in-game currency
-  or equipment). You would typically not want to implement consumption for
+  or equipment). You typically don't want to implement consumption for
   in-app products that are purchased once and provide a permanent effect (for
   example, a premium upgrade).
 </p>
@@ -576,21 +595,21 @@
   To record a purchase consumption, send the {@code consumePurchase} method to
   the In-app Billing service and pass in the {@code purchaseToken} String value
   that identifies the purchase to be removed. The {@code purchaseToken} is part
-  of the data returned in the {@code INAPP_PURCHASE_DATA} String by the Google
-  Play service following a successful purchase request. In this example, you
-  are recording the consumption of a product that is identified with the {@code
-  purchaseToken} in the {@code token} variable.
+  of the data that is returned in the {@code INAPP_PURCHASE_DATA} String by the Google
+  Play service following a successful purchase request. This example
+  records the consumption of a product that is identified with the {@code
+  purchaseToken} in the {@code token} variable:
 </p>
 
 <pre>
 int response = mService.consumePurchase(3, getPackageName(), token);
 </pre>
 
-<p class="note">
-  <strong>Warning:</strong> Do not call the {@code consumePurchase} method on
-  the main thread. Calling this method triggers a network request which could
+<p class="caution">
+  <strong>Warning:</strong> Don't call the {@code consumePurchase} method on
+  the main thread. Calling this method triggers a network request that could
   block your main thread. Instead, create a separate thread and call the {@code
-  consumePurchase} method from inside that thread.
+  consumePurchase} method from inside of that thread.
 </p>
 
 <p>
@@ -600,20 +619,20 @@
   purchased.
 </p>
 
-<p class="note">
-  <strong>Security Recommendation:</strong> You must send a consumption request
+<p class="caution">
+  <strong>Security Recommendation:</strong> Send a consumption request
   before provisioning the benefit of the consumable in-app purchase to the
-  user. Make sure that you have received a successful consumption response from
+  user. Ensure that you receive a successful consumption response from
   Google Play before you provision the item.
 </p>
 
-<h3 id="Subs">Implementing Subscriptions</h3>
+<h3 id="Subs">Implementing subscriptions</h3>
 
 <p>Launching a purchase flow for a subscription is similar to launching the
 purchase flow for a product, with the exception that the product type must be set
 to "subs". The purchase result is delivered to your Activity's
 {@link android.app.Activity#onActivityResult onActivityResult} method, exactly
-as in the case of in-app products.</p>
+as in the case of in-app products. Here is an example:</p>
 
 <pre>
 Bundle bundle = mService.getBuyIntent(3, "com.example.myapp",
@@ -629,18 +648,18 @@
 </pre>
 
 <p>To query for active subscriptions, use the {@code getPurchases} method, again
-with the product type parameter set to "subs".</p>
+with the product type parameter set to "subs":</p>
 
 <pre>
 Bundle activeSubs = mService.getPurchases(3, "com.example.myapp",
                    "subs", continueToken);
 </pre>
 
-<p>The call returns a {@code Bundle} with all the active subscriptions owned by
-the user. Once a subscription expires without renewal, it will no longer appear
+<p>The call returns a {@code Bundle} with all of the active subscriptions that are owned by
+the user. When a subscription expires without renewal, it no longer appears
 in the returned {@code Bundle}.</p>
 
-<h2 id="billing-security">Securing Your Application</h2>
+<h2 id="billing-security">Securing your application</h2>
 
 <p>To help ensure the integrity of the transaction information that is sent to
 your application, Google Play signs the JSON string that contains the response
@@ -648,21 +667,21 @@
 with your application in the Developer Console to create this signature. The
 Developer Console generates an RSA key pair for each application.<p>
 
-<p class="note"><strong>Note:</strong>To find the public key portion of this key
-pair, open your application's details in the Developer Console, then click on
-<strong>Services &amp; APIs</strong>, and look at the field titled
+<p class="note"><strong>Note:</strong> To find the public key portion of this key
+pair, open your application's details in the Developer Console, click
+<strong>Services &amp; APIs</strong>, and review the field titled
 <strong>Your License Key for This Application</strong>.</p>
 
-<p>The Base64-encoded RSA public key generated by Google Play is in binary
+<p>The Base64-encoded RSA public key that is generated by Google Play is in binary
 encoded, X.509 subjectPublicKeyInfo DER SEQUENCE format. It is the same public
 key that is used with Google Play licensing.</p>
 
-<p>When your application receives this signed response you can
+<p>When your application receives this signed response, you can
 use the public key portion of your RSA key pair to verify the signature.
-By performing signature verification you can detect responses that have
+By performing signature verification, you can detect any responses that have
 been tampered with or that have been spoofed. You can perform this signature
 verification step in your application; however, if your application connects
-to a secure remote server then we recommend that you perform the signature
+to a secure remote server, Google recommends that you perform the signature
 verification on that server.</p>
 
 <p>For more information about best practices for security and design, see <a
diff --git a/docs/html/guide/components/bound-services.jd b/docs/html/guide/components/bound-services.jd
index f71ba87..2ee2061 100644
--- a/docs/html/guide/components/bound-services.jd
+++ b/docs/html/guide/components/bound-services.jd
@@ -8,19 +8,19 @@
 <ol id="qv">
 <h2>In this document</h2>
 <ol>
-  <li><a href="#Basics">The Basics</a></li>
-  <li><a href="#Creating">Creating a Bound Service</a>
+  <li><a href="#Basics">The basics</a></li>
+  <li><a href="#Creating">Creating a bound service</a>
     <ol>
       <li><a href="#Binder">Extending the Binder class</a></li>
       <li><a href="#Messenger">Using a Messenger</a></li>
     </ol>
   </li>
-  <li><a href="#Binding">Binding to a Service</a>
+  <li><a href="#Binding">Binding to a service</a>
     <ol>
       <li><a href="#Additional_Notes">Additional notes</a></li>
     </ol>
   </li>
-  <li><a href="#Lifecycle">Managing the Lifecycle of a Bound Service</a></li>
+  <li><a href="#Lifecycle">Managing the lifecycle of a bound service</a></li>
 </ol>
 
 <h2>Key classes</h2>
@@ -32,9 +32,13 @@
 
 <h2>Samples</h2>
 <ol>
-  <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
+  <li><a
+ href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">
+  {@code
       RemoteService}</a></li>
-  <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
+  <li><a
+ href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">
+ {@code
       LocalService}</a></li>
 </ol>
 
@@ -45,19 +49,23 @@
 </div>
 
 
-<p>A bound service is the server in a client-server interface. A bound service allows components
-(such as activities) to bind to the service, send requests, receive responses, and even perform
+<p>A bound service is the server in a client-server interface. It allows components
+(such as activities) to bind to the service, send requests, receive responses, and perform
 interprocess communication (IPC). A bound service typically lives only while it serves another
 application component and does not run in the background indefinitely.</p>
 
-<p>This document shows you how to create a bound service, including how to bind
-to the service from other application components. However, you should also refer to the <a
-href="{@docRoot}guide/components/services.html">Services</a> document for additional
-information about services in general, such as how to deliver notifications from a service, set
-the service to run in the foreground, and more.</p>
+<p class="note"><strong>Note:</strong> If your app targets Android 5.0 (API level 21) or later,
+it's recommended that you use the {@link android.app.job.JobScheduler} to execute background
+ services. For more information about {@link android.app.job.JobScheduler}, see its
+ {@link android.app.job.JobScheduler API-reference documentation}.</p>
 
+<p>This document describes how to create a bound service, including how to bind
+to the service from other application components. For additional information about services in
+ general, such as how to deliver notifications from a service and set the service to run
+ in the foreground, refer to the <a href="{@docRoot}guide/components/services.html">
+ Services</a> document.</p>
 
-<h2 id="Basics">The Basics</h2>
+<h2 id="Basics">The basics</h2>
 
 <p>A bound service is an implementation of the {@link android.app.Service} class that allows
 other applications to bind to it and interact with it. To provide binding for a
@@ -67,57 +75,61 @@
 
 <div class="sidebox-wrapper">
 <div class="sidebox">
-  <h3>Binding to a Started Service</h3>
+  <h3>Binding to a started service</h3>
 
 <p>As discussed in the <a href="{@docRoot}guide/components/services.html">Services</a>
-document, you can create a service that is both started and bound. That is, the service can be
-started by calling {@link android.content.Context#startService startService()}, which allows the
-service to run indefinitely, and also allow a client to bind to the service by calling {@link
+document, you can create a service that is both started and bound. That is, you can start a
+ service by calling {@link android.content.Context#startService startService()}, which allows the
+service to run indefinitely, and you can also allow a client to bind to the service by
+ calling {@link
 android.content.Context#bindService bindService()}.
   <p>If you do allow your service to be started and bound, then when the service has been
-started, the system does <em>not</em> destroy the service when all clients unbind. Instead, you must
-explicitly stop the service, by calling {@link android.app.Service#stopSelf stopSelf()} or {@link
+started, the system does <em>not</em> destroy the service when all clients unbind.
+ Instead, you must
+explicitly stop the service by calling {@link android.app.Service#stopSelf stopSelf()} or {@link
 android.content.Context#stopService stopService()}.</p>
 
-<p>Although you should usually implement either {@link android.app.Service#onBind onBind()}
-<em>or</em> {@link android.app.Service#onStartCommand onStartCommand()}, it's sometimes necessary to
+<p>Although you usually implement either {@link android.app.Service#onBind onBind()}
+<em>or</em> {@link android.app.Service#onStartCommand onStartCommand()}, it's sometimes
+ necessary to
 implement both. For example, a music player might find it useful to allow its service to run
 indefinitely and also provide binding. This way, an activity can start the service to play some
 music and the music continues to play even if the user leaves the application. Then, when the user
-returns to the application, the activity can bind to the service to regain control of playback.</p>
+returns to the application, the activity can bind to the service to regain control of
+ playback.</p>
 
-<p>Be sure to read the section about <a href="#Lifecycle">Managing the Lifecycle of a Bound
-Service</a>, for more information about the service lifecycle when adding binding to a
-started service.</p>
+<p>For more information about the service lifecycle when adding binding to a started service,
+ see <a href="#Lifecycle">Managing the lifecycle of a bound Service</a>.</p>
 </div>
 </div>
 
-<p>A client can bind to the service by calling {@link android.content.Context#bindService
+<p>A client can bind to a service by calling {@link android.content.Context#bindService
 bindService()}. When it does, it must provide an implementation of {@link
 android.content.ServiceConnection}, which monitors the connection with the service. The {@link
-android.content.Context#bindService bindService()} method returns immediately without a value, but
+android.content.Context#bindService bindService()} method returns immediately without a
+ value, but
 when the Android system creates the connection between the
 client and service, it calls {@link
 android.content.ServiceConnection#onServiceConnected onServiceConnected()} on the {@link
 android.content.ServiceConnection}, to deliver the {@link android.os.IBinder} that
 the client can use to communicate with the service.</p>
 
-<p>Multiple clients can connect to the service at once. However, the system calls your service's
-{@link android.app.Service#onBind onBind()} method to retrieve the {@link android.os.IBinder} only
+<p>Multiple clients can connect to a service simultaneously. However, the system calls your service's
+{@link android.app.Service#onBind onBind()} method to retrieve the
+ {@link android.os.IBinder} only
 when the first client binds. The system then delivers the same {@link android.os.IBinder} to any
-additional clients that bind, without calling {@link android.app.Service#onBind onBind()} again.</p>
+additional clients that bind, without calling {@link android.app.Service#onBind onBind()}
+ again.</p>
 
-<p>When the last client unbinds from the service, the system destroys the service (unless the
-service was also started by {@link android.content.Context#startService startService()}).</p>
+<p>When the last client unbinds from the service, the system destroys the service, unless the
+service was also started by {@link android.content.Context#startService startService()}.</p>
 
-<p>When you implement your bound service, the most important part is defining the interface
-that your {@link android.app.Service#onBind onBind()} callback method returns. There are a few
-different ways you can define your service's {@link android.os.IBinder} interface and the following
-section discusses each technique.</p>
+<p>The most important part of your bound service implementation is defining the interface
+that your {@link android.app.Service#onBind onBind()} callback method returns. The following
+section discusses several different ways that you can define your service's
+ {@link android.os.IBinder} interface.</p>
 
-
-
-<h2 id="Creating">Creating a Bound Service</h2>
+<h2 id="Creating">Creating a bound service</h2>
 
 <p>When creating a service that provides binding, you must provide an {@link android.os.IBinder}
 that provides the programming interface that clients can use to interact with the service. There
@@ -125,12 +137,14 @@
 
 <dl>
   <dt><a href="#Binder">Extending the Binder class</a></dt>
-  <dd>If your service is private to your own application and runs in the same process as the client
-(which is common), you should create your interface by extending the {@link android.os.Binder} class
+  <dd>If your service is private to your own application and runs in the same process
+  as the client
+(which is common), you should create your interface by extending the {@link android.os.Binder}
+ class
 and returning an instance of it from
 {@link android.app.Service#onBind onBind()}. The client receives the {@link android.os.Binder} and
 can use it to directly access public methods available in either the {@link android.os.Binder}
-implementation or even the {@link android.app.Service}.
+implementation or the {@link android.app.Service}.
   <p>This is the preferred technique when your service is merely a background worker for your own
 application. The only reason you would not create your interface this way is because
 your service is used by other applications or across separate processes.</dd>
@@ -143,20 +157,20 @@
 is the basis for a {@link android.os.Messenger} that can then share an {@link android.os.IBinder}
 with the client, allowing the client to send commands to the service using {@link
 android.os.Message} objects. Additionally, the client can define a {@link android.os.Messenger} of
-its own so the service can send messages back.
+its own, so the service can send messages back.
   <p>This is the simplest way to perform interprocess communication (IPC), because the {@link
 android.os.Messenger} queues all requests into a single thread so that you don't have to design
 your service to be thread-safe.</p>
   </dd>
 
-  <dt>Using AIDL</dt>
-  <dd>AIDL (Android Interface Definition Language) performs all the work to decompose objects into
-primitives that the operating system can understand and marshall them across processes to perform
+  <dt><a href="{@docRoot}guide/components/aidl.html">Using AIDL</a></dt>
+  <dd>Android Interface Definition Language (AIDL) decomposes objects into
+primitives that the operating system can understand and marshals them across processes to perform
 IPC. The previous technique, using a {@link android.os.Messenger}, is actually based on AIDL as
 its underlying structure. As mentioned above, the {@link android.os.Messenger} creates a queue of
 all the client requests in a single thread, so the service receives requests one at a time. If,
 however, you want your service to handle multiple requests simultaneously, then you can use AIDL
-directly. In this case, your service must be capable of multi-threading and be built thread-safe.
+directly. In this case, your service must be thread-safe and capable of multi-threading.
   <p>To use AIDL directly, you must
 create an {@code .aidl} file that defines the programming interface. The Android SDK tools use
 this file to generate an abstract class that implements the interface and handles IPC, which you
@@ -164,19 +178,18 @@
   </dd>
 </dl>
 
-  <p class="note"><strong>Note:</strong> Most applications <strong>should not</strong> use AIDL to
+  <p class="note"><strong>Note:</strong> Most applications <em>shouldn't</em> use AIDL to
 create a bound service, because it may require multithreading capabilities and
-can result in a more complicated implementation. As such, AIDL is not suitable for most applications
+can result in a more complicated implementation. As such, AIDL is not suitable for
+ most applications
 and this document does not discuss how to use it for your service. If you're certain that you need
 to use AIDL directly, see the <a href="{@docRoot}guide/components/aidl.html">AIDL</a>
 document.</p>
 
-
-
-
 <h3 id="Binder">Extending the Binder class</h3>
 
-<p>If your service is used only by the local application and does not need to work across processes,
+<p>If your service is used only by the local application and does not need to
+ work across processes,
 then you can implement your own {@link android.os.Binder} class that provides your client direct
 access to public methods in the service.</p>
 
@@ -187,13 +200,14 @@
 
 <p>Here's how to set it up:</p>
 <ol>
-  <li>In your service, create an instance of {@link android.os.Binder} that either:
+  <li>In your service, create an instance of {@link android.os.Binder} that does
+  one of the following:
     <ul>
-      <li>contains public methods that the client can call</li>
-      <li>returns the current {@link android.app.Service} instance, which has public methods the
-client can call</li>
-      <li>or, returns an instance of another class hosted by the service with public methods the
-client can call</li>
+      <li>Contains public methods that the client can call.</li>
+      <li>Returns the current {@link android.app.Service} instance, which has public methods the
+client can call.</li>
+      <li>Returns an instance of another class hosted by the service with public methods the
+client can call.</li>
     </ul>
   <li>Return this instance of {@link android.os.Binder} from the {@link
 android.app.Service#onBind onBind()} callback method.</li>
@@ -202,12 +216,13 @@
 make calls to the bound service using the methods provided.</li>
 </ol>
 
-<p class="note"><strong>Note:</strong> The reason the service and client must be in the same
-application is so the client can cast the returned object and properly call its APIs. The service
+<p class="note"><strong>Note:</strong> The service and client must be in the same
+application so that the client can cast the returned object and properly call its APIs.
+ The service
 and client must also be in the same process, because this technique does not perform any
-marshalling across processes.</p>
+marshaling across processes.</p>
 
-<p>For example, here's a service that provides clients access to methods in the service through
+<p>For example, here's a service that provides clients with access to methods in the service through
 a {@link android.os.Binder} implementation:</p>
 
 <pre>
@@ -316,32 +331,30 @@
 <p class="note"><strong>Note:</strong> In the example above, the
 {@link android.app.Activity#onStop onStop()} method unbinds the client from the service. Clients
 should unbind from services at appropriate times, as discussed in
-<a href="#Additional_Notes">Additional Notes</a>.
+<a href="#Additional_Notes">Additional notes</a>.
 </p>
 
 <p>For more sample code, see the <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">
+{@code
 LocalService.java}</a> class and the <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.html">{@code
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.html">
+{@code
 LocalServiceActivities.java}</a> class in <a
 href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
 
-
-
-
-
 <h3 id="Messenger">Using a Messenger</h3>
 
 <div class="sidebox-wrapper">
 <div class="sidebox">
   <h4>Compared to AIDL</h4>
   <p>When you need to perform IPC, using a {@link android.os.Messenger} for your interface is
-simpler than implementing it with AIDL, because {@link android.os.Messenger} queues
-all calls to the service, whereas, a pure AIDL interface sends simultaneous requests to the
+simpler than using AIDL, because {@link android.os.Messenger} queues
+all calls to the service. A pure AIDL interface sends simultaneous requests to the
 service, which must then handle multi-threading.</p>
   <p>For most applications, the service doesn't need to perform multi-threading, so using a {@link
 android.os.Messenger} allows the service to handle one call at a time. If it's important
-that your service be multi-threaded, then you should use <a
+that your service be multi-threaded, use <a
 href="{@docRoot}guide/components/aidl.html">AIDL</a> to define your interface.</p>
 </div>
 </div>
@@ -352,10 +365,11 @@
 
 <p>Here's a summary of how to use a {@link android.os.Messenger}:</p>
 
-<ul>
+<ol>
   <li>The service implements a {@link android.os.Handler} that receives a callback for each
 call from a client.</li>
-  <li>The {@link android.os.Handler} is used to create a {@link android.os.Messenger} object
+  <li>The service uses the {@link android.os.Handler} to create a {@link android.os.Messenger}
+  object
 (which is a reference to the {@link android.os.Handler}).</li>
   <li>The {@link android.os.Messenger} creates an {@link android.os.IBinder} that the service
 returns to clients from {@link android.app.Service#onBind onBind()}.</li>
@@ -365,11 +379,12 @@
   <li>The service receives each {@link android.os.Message} in its {@link
 android.os.Handler}&mdash;specifically, in the {@link android.os.Handler#handleMessage
 handleMessage()} method.</li>
-</ul>
+</ol>
 
 
-<p>In this way, there are no "methods" for the client to call on the service. Instead, the
-client delivers "messages" ({@link android.os.Message} objects) that the service receives in
+<p>In this way, there are no <em>methods</em> for the client to call on the service. Instead, the
+client delivers <em>messages</em> ({@link android.os.Message} objects) that the service
+ receives in
 its {@link android.os.Handler}.</p>
 
 <p>Here's a simple example service that uses a {@link android.os.Messenger} interface:</p>
@@ -488,41 +503,42 @@
 }
 </pre>
 
-<p>Notice that this example does not show how the service can respond to the client. If you want the
-service to respond, then you need to also create a {@link android.os.Messenger} in the client. Then
-when the client receives the {@link android.content.ServiceConnection#onServiceConnected
+<p>Notice that this example does not show how the service can respond to the client.
+ If you want the
+service to respond, you need to also create a {@link android.os.Messenger} in the client.
+When the client receives the {@link android.content.ServiceConnection#onServiceConnected
 onServiceConnected()} callback, it sends a {@link android.os.Message} to the service that includes
 the client's {@link android.os.Messenger} in the {@link android.os.Message#replyTo} parameter
 of the {@link android.os.Messenger#send send()} method.</p>
 
 <p>You can see an example of how to provide two-way messaging in the <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html">{@code
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html">
+{@code
 MessengerService.java}</a> (service) and <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.html">{@code
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.html">
+{@code
 MessengerServiceActivities.java}</a> (client) samples.</p>
 
-
-
-
-
-<h2 id="Binding">Binding to a Service</h2>
+<h2 id="Binding">Binding to a service</h2>
 
 <p>Application components (clients) can bind to a service by calling
 {@link android.content.Context#bindService bindService()}. The Android
 system then calls the service's {@link android.app.Service#onBind
-onBind()} method, which returns an {@link android.os.IBinder} for interacting with the service.</p>
+onBind()} method, which returns an {@link android.os.IBinder} for interacting with
+ the service.</p>
 
-<p>The binding is asynchronous. {@link android.content.Context#bindService
-bindService()} returns immediately and does <em>not</em> return the {@link android.os.IBinder} to
-the client. To receive the {@link android.os.IBinder}, the client must create an instance of {@link
+<p>The binding is asynchronous, and {@link android.content.Context#bindService
+bindService()} returns immediately without <em>not</em> returning the {@link android.os.IBinder} to
+the client. To receive the {@link android.os.IBinder}, the client must create an
+ instance of {@link
 android.content.ServiceConnection} and pass it to {@link android.content.Context#bindService
 bindService()}. The {@link android.content.ServiceConnection} includes a callback method that the
 system calls to deliver the {@link android.os.IBinder}.</p>
 
 <p class="note"><strong>Note:</strong> Only activities, services, and content providers can bind
-to a service&mdash;you <strong>cannot</strong> bind to a service from a broadcast receiver.</p>
+to a service&mdash;you <strong>can't</strong> bind to a service from a broadcast receiver.</p>
 
-<p>So, to bind to a service from your client, you must: </p>
+<p>To bind to a service from your client, follow these steps: </p>
 <ol>
   <li>Implement {@link android.content.ServiceConnection}.
     <p>Your implementation must override two callback methods:</p>
@@ -533,7 +549,8 @@
       <dt>{@link android.content.ServiceConnection#onServiceDisconnected
 onServiceDisconnected()}</dt>
         <dd>The Android system calls this when the connection to the service is unexpectedly
-lost, such as when the service has crashed or has been killed. This is <em>not</em> called when the
+lost, such as when the service has crashed or has been killed. This is <em>not</em>
+ called when the
 client unbinds.</dd>
     </dl>
   </li>
@@ -548,12 +565,12 @@
   <p>If your client is still bound to a service when your app destroys the client, destruction
 causes the client to unbind. It is better practice to unbind the client as soon as it is done
 interacting with the service. Doing so allows the idle service to shut down. For more information
-about appropriate times to bind and unbind, see <a href="#Additional_Notes">Additional Notes</a>.
+about appropriate times to bind and unbind, see <a href="#Additional_Notes">Additional notes</a>.
 </p>
   </li>
 </ol>
 
-<p>For example, the following snippet connects the client to the service created above by
+<p>The following example connects the client to the service created above by
 <a href="#Binder">extending the Binder class</a>, so all it must do is cast the returned
 {@link android.os.IBinder} to the {@code LocalService} class and request the {@code
 LocalService} instance:</p>
@@ -579,8 +596,9 @@
 };
 </pre>
 
-<p>With this {@link android.content.ServiceConnection}, the client can bind to a service by passing
-it to {@link android.content.Context#bindService bindService()}. For example:</p>
+<p>With this {@link android.content.ServiceConnection}, the client can bind to a service
+ by passing
+it to {@link android.content.Context#bindService bindService()}, as shown in the following example:</p>
 
 <pre>
 Intent intent = new Intent(this, LocalService.class);
@@ -589,11 +607,21 @@
 
 <ul>
   <li>The first parameter of {@link android.content.Context#bindService bindService()} is an
-{@link android.content.Intent} that explicitly names the service to bind (thought the intent
-could be implicit).</li>
+{@link android.content.Intent} that explicitly names the service to bind.
+<p class="caution"><strong>Caution:</strong> If you use an intent to bind to a
+ {@link android.app.Service}, ensure that your app is secure by using an <a href="{@docRoot}guide/components/intents-filters.html#Types">explicit</a>
+intent. Using an implicit intent to start a service is a
+security hazard because you can't be certain what service will respond to the intent,
+and the user can't see which service starts. Beginning with Android 5.0 (API level 21),
+ the system
+throws an exception if you call {@link android.content.Context#bindService bindService()}
+with an implicit intent.</p>
+</li>
+
 <li>The second parameter is the {@link android.content.ServiceConnection} object.</li>
 <li>The third parameter is a flag indicating options for the binding. It should usually be {@link
-android.content.Context#BIND_AUTO_CREATE} in order to create the service if its not already alive.
+android.content.Context#BIND_AUTO_CREATE} in order to create the service if it's not already
+ alive.
 Other possible values are {@link android.content.Context#BIND_DEBUG_UNBIND}
 and {@link android.content.Context#BIND_NOT_FOREGROUND}, or {@code 0} for none.</li>
 </ul>
@@ -606,10 +634,11 @@
   <li>You should always trap {@link android.os.DeadObjectException} exceptions, which are thrown
 when the connection has broken. This is the only exception thrown by remote methods.</li>
   <li>Objects are reference counted across processes. </li>
-  <li>You should usually pair the binding and unbinding during
-matching bring-up and tear-down moments of the client's lifecycle. For example:
+  <li>You usually pair the binding and unbinding during
+matching bring-up and tear-down moments of the client's lifecycle, as described in the
+ following examples:
     <ul>
-      <li>If you only need to interact with the service while your activity is visible, you
+      <li>If you need to interact with the service only while your activity is visible, you
 should bind during {@link android.app.Activity#onStart onStart()} and unbind during {@link
 android.app.Activity#onStop onStop()}.</li>
       <li>If you want your activity to receive responses even while it is stopped in the
@@ -619,33 +648,34 @@
 the service is in another process, then you increase the weight of the process and it becomes
 more likely that the system will kill it.</li>
     </ul>
-    <p class="note"><strong>Note:</strong> You should usually <strong>not</strong> bind and unbind
+    <p class="note"><strong>Note:</strong> You <em>don't</em> usually bind and unbind
 during your activity's {@link android.app.Activity#onResume onResume()} and {@link
-android.app.Activity#onPause onPause()}, because these callbacks occur at every lifecycle transition
+android.app.Activity#onPause onPause()}, because these callbacks occur at every
+ lifecycle transition
 and you should keep the processing that occurs at these transitions to a minimum. Also, if
-multiple activities in your application bind to the same service and there is a transition between
-two of those activities, the service may be destroyed and recreated as the current activity unbinds
-(during pause) before the next one binds (during resume). (This activity transition for how
+multiple activities in your application bind to the same service and there is a
+ transition between
+two of those activities, the service may be destroyed and recreated as the current
+ activity unbinds
+(during pause) before the next one binds (during resume). This activity transition for how
 activities coordinate their lifecycles is described in the <a
 href="{@docRoot}guide/components/activities.html#CoordinatingActivities">Activities</a>
-document.)</p>
+document.</p>
 </ul>
 
 <p>For more sample code, showing how to bind to a service, see the <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">
+{@code
 RemoteService.java}</a> class in <a
 href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
 
-
-
-
-
-<h2 id="Lifecycle">Managing the Lifecycle of a Bound Service</h2>
+<h2 id="Lifecycle">Managing the lifecycle of a bound service</h2>
 
 <p>When a service is unbound from all clients, the Android system destroys it (unless it was also
 started with {@link android.app.Service#onStartCommand onStartCommand()}). As such, you don't have
 to manage the lifecycle of your service if it's purely a bound
-service&mdash;the Android system manages it for you based on whether it is bound to any clients.</p>
+service&mdash;the Android system manages it for you based on whether it is bound to
+ any clients.</p>
 
 <p>However, if you choose to implement the {@link android.app.Service#onStartCommand
 onStartCommand()} callback method, then you must explicitly stop the service, because the
@@ -660,17 +690,11 @@
 onRebind()} the next time a client binds to the service. {@link android.app.Service#onRebind
 onRebind()} returns void, but the client still receives the {@link android.os.IBinder} in its
 {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback.
-Below, figure 1 illustrates the logic for this kind of lifecycle.</p>
-
+The following figure illustrates the logic for this kind of lifecycle.</p>
 
 <img src="{@docRoot}images/fundamentals/service_binding_tree_lifecycle.png" alt="" />
 <p class="img-caption"><strong>Figure 1.</strong> The lifecycle for a service that is started
 and also allows binding.</p>
 
-
 <p>For more information about the lifecycle of a started service, see the <a
 href="{@docRoot}guide/components/services.html#Lifecycle">Services</a> document.</p>
-
-
-
-
diff --git a/docs/html/guide/components/fundamentals.jd b/docs/html/guide/components/fundamentals.jd
index ed3ba7d..eaa82c8 100644
--- a/docs/html/guide/components/fundamentals.jd
+++ b/docs/html/guide/components/fundamentals.jd
@@ -6,28 +6,29 @@
 
 <h2>In this document</h2>
 <ol>
-<li><a href="#Components">App Components</a>
+<li><a href="#Components">App components</a>
   <ol>
     <li><a href="#ActivatingComponents">Activating components</a></li>
   </ol>
 </li>
-<li><a href="#Manifest">The Manifest File</a>
+<li><a href="#Manifest">The manifest file</a>
   <ol>
     <li><a href="#DeclaringComponents">Declaring components</a></li>
     <li><a href="#DeclaringRequirements">Declaring app requirements</a></li>
   </ol>
 </li>
-<li><a href="#Resources">App Resources</a></li>
+<li><a href="#Resources">App resources</a></li>
 </ol>
 </div>
 </div>
 
 <p>Android apps are written in the Java programming language. The Android SDK tools compile
-your code&mdash;along with any data and resource files&mdash;into an APK: an <i>Android package</i>,
+your code along with any data and resource files into an APK, an <i>Android package</i>,
 which is an archive file with an {@code .apk} suffix. One APK file contains all the contents
 of an Android app and is the file that Android-powered devices use to install the app.</p>
 
-<p>Once installed on a device, each Android app lives in its own security sandbox: </p>
+<p>Each Android app lives in its own security sandbox, protected by
+ the following Android security features: </p>
 
 <ul>
  <li>The Android operating system is a multi-user Linux system in which each app is a
@@ -40,54 +41,61 @@
 <li>Each process has its own virtual machine (VM), so an app's code runs in isolation from
 other apps.</li>
 
-<li>By default, every app runs in its own Linux process. Android starts the process when any
-of the app's components need to be executed, then shuts down the process when it's no longer
+<li>By default, every app runs in its own Linux process. The Android system starts
+ the process when any
+of the app's components need to be executed, and then shuts down the process
+ when it's no longer
 needed or when the system must recover memory for other apps.</li>
 </ul>
 
-<p>In this way, the Android system implements the <em>principle of least privilege</em>. That is,
+<p>The Android system implements the <em>principle of least privilege</em>. That is,
 each app, by default, has access only to the components that it requires to do its work and
 no more. This creates a very secure environment in which an app cannot access parts of
-the system for which it is not given permission.</p>
-
-<p>However, there are ways for an app to share data with other apps and for an
+the system for which it is not given permission. However, there are ways for an app to share
+ data with other apps and for an
 app to access system services:</p>
 
 <ul>
   <li>It's possible to arrange for two apps to share the same Linux user ID, in which case
 they are able to access each other's files.  To conserve system resources, apps with the
-same user ID can also arrange to run in the same Linux process and share the same VM (the
-apps must also be signed with the same certificate).</li>
+same user ID can also arrange to run in the same Linux process and share the same VM. The
+apps must also be signed with the same certificate.</li>
   <li>An app can request permission to access device data such as the user's
-contacts, SMS messages, the mountable storage (SD card), camera, Bluetooth, and more. The user has
+contacts, SMS messages, the mountable storage (SD card), camera, and Bluetooth. The user has
 to explicitly grant these permissions. For more information, see
 <a href="{@docRoot}training/permissions/index.html">Working with System Permissions</a>.</li>
 </ul>
 
-<p>That covers the basics regarding how an Android app exists within the system. The rest of
-this document introduces you to:</p>
+<p>The rest of this document introduces the following concepts:</p>
 <ul>
   <li>The core framework components that define your app.</li>
-  <li>The manifest file in which you declare components and required device features for your
+  <li>The manifest file in which you declare the components and the required device
+  features for your
 app.</li>
-  <li>Resources that are separate from the app code and allow your app to
+  <li>Resources that are separate from the app code and that allow your app to
 gracefully optimize its behavior for a variety of device configurations.</li>
 </ul>
 
 
 
-<h2 id="Components">App Components</h2>
+<h2 id="Components">App components</h2>
 
 <p>App components are the essential building blocks of an Android app. Each
 component is a different point through which the system can enter your app. Not all
-components are actual entry points for the user and some depend on each other, but each one exists
-as its own entity and plays a specific role&mdash;each one is a unique building block that
-helps define your app's overall behavior.</p>
+components are actual entry points for the user and some depend on each other,
+ but each one exists
+as its own entity and plays a specific role.</p>
 
-<p>There are four different types of app components. Each type serves a distinct purpose
-and has a distinct lifecycle that defines how the component is created and destroyed.</p>
-
-<p>Here are the four types of app components:</p>
+<p>There are four different types of app components:
+<ul>
+<li>Activities.</li>
+<li>Services.</li>
+<li>Content providers.</li>
+<li>Broadcast receivers.</li>
+</ul></p>
+Each type serves a distinct purpose
+and has a distinct lifecycle that defines how the component is created and destroyed.
+ The following sections describe the four types of app components.</p>
 
 <dl>
 
@@ -98,11 +106,12 @@
 emails, another activity to compose an email, and another activity for reading emails. Although
 the activities work together to form a cohesive user experience in the email app, each one
 is independent of the others. As such, a different app can start any one of these
-activities (if the email app allows it). For example, a camera app can start the
-activity in the email app that composes new mail, in order for the user to share a picture.
+activities if the email app allows it. For example, a camera app can start the
+activity in the email app that composes new mail to allow the user to share a picture.
 
-<p>An activity is implemented as a subclass of {@link android.app.Activity} and you can learn more
-about it in the <a href="{@docRoot}guide/components/activities.html">Activities</a>
+<p>An activity is implemented as a subclass of {@link android.app.Activity}. You can learn more
+about  {@link android.app.Activity} in the
+ <a href="{@docRoot}guide/components/activities.html">Activities</a>
 developer guide.</p>
 </dd>
 
@@ -111,13 +120,16 @@
 
 <dd>A <i>service</i> is a component that runs in the background to perform long-running
 operations or to perform work for remote processes. A service
-does not provide a user interface. For example, a service might play music in the background while
+does not provide a user interface. For example, a service might play music in the
+ background while
 the user is in a different app, or it might fetch data over the network without
-blocking user interaction with an activity. Another component, such as an activity, can start the
+blocking user interaction with an activity. Another component, such as an activity,
+ can start the
 service and let it run or bind to it in order to interact with it.
 
-<p>A service is implemented as a subclass of {@link android.app.Service} and you can learn more
-about it in the <a href="{@docRoot}guide/components/services.html">Services</a> developer
+<p>A service is implemented as a subclass of {@link android.app.Service}. You can learn more
+about  {@link android.app.Service} in the <a href="{@docRoot}guide/components/services.html">
+Services</a> developer
 guide.</p>
 </dd>
 
@@ -125,12 +137,14 @@
 <dt><b>Content providers</b></dt>
 
 <dd>A <i>content provider</i> manages a shared set of app data. You can store the data in
-the file system, an SQLite database, on the web, or any other persistent storage location your
-app can access. Through the content provider, other apps can query or even modify
-the data (if the content provider allows it). For example, the Android system provides a content
+the file system, in a SQLite database, on the web, or on any other persistent storage
+ location that your
+app can access. Through the content provider, other apps can query or modify
+the data if the content provider allows it. For example, the Android system provides a content
 provider that manages the user's contact information. As such, any app with the proper
-permissions can query part of the content provider (such as {@link
-android.provider.ContactsContract.Data}) to read and write information about a particular person.
+permissions can query part of the content provider, such as {@link
+android.provider.ContactsContract.Data}, to read and write information about
+ a particular person.
 
 <p>Content providers are also useful for reading and writing data that is private to your
 app and not shared. For example, the <a
@@ -148,15 +162,17 @@
 <dt><b>Broadcast receivers</b></dt>
 
 <dd>A <i>broadcast receiver</i> is a component that responds to system-wide broadcast
-announcements.  Many broadcasts originate from the system&mdash;for example, a broadcast announcing
+announcements.  Many broadcasts originate from the system&mdash;for example,
+ a broadcast announcing
 that the screen has turned off, the battery is low, or a picture was captured.
 Apps can also initiate broadcasts&mdash;for example, to let other apps know that
-some data has been downloaded to the device and is available for them to use. Although broadcast
+some data has been downloaded to the device and is available for them to use.
+ Although broadcast
 receivers don't display a user interface, they may <a
 href="{@docRoot}guide/topics/ui/notifiers/notifications.html">create a status bar notification</a>
 to alert the user when a broadcast event occurs. More commonly, though, a broadcast receiver is
-just a "gateway" to other components and is intended to do a very minimal amount of work. For
-instance, it might initiate a service to perform some work based on the event.
+just a <em>gateway</em> to other components and is intended to do a very minimal amount of work.
+ For instance, it might initiate a service to perform some work based on the event.
 
 <p>A broadcast receiver is implemented as a subclass of {@link android.content.BroadcastReceiver}
 and each broadcast is delivered as an {@link android.content.Intent} object. For more information,
@@ -170,52 +186,59 @@
 <p>A unique aspect of the Android system design is that any app can start another
 app’s component. For example, if you want the user to capture a
 photo with the device camera, there's probably another app that does that and your
-app can use it, instead of developing an activity to capture a photo yourself. You don't
+app can use it instead of developing an activity to capture a photo yourself. You don't
 need to incorporate or even link to the code from the camera app.
 Instead, you can simply start the activity in the camera app that captures a
 photo. When complete, the photo is even returned to your app so you can use it. To the user,
 it seems as if the camera is actually a part of your app.</p>
 
-<p>When the system starts a component, it starts the process for that app (if it's not
-already running) and instantiates the classes needed for the component. For example, if your
+<p>When the system starts a component, it starts the process for that app if it's not
+already running and instantiates the classes needed for the component. For example, if your
 app starts the activity in the camera app that captures a photo, that activity
 runs in the process that belongs to the camera app, not in your app's process.
 Therefore, unlike apps on most other systems, Android apps don't have a single entry
-point (there's no {@code main()} function, for example).</p>
+point (there's no {@code main()} function).</p>
 
 <p>Because the system runs each app in a separate process with file permissions that
 restrict access to other apps, your app cannot directly activate a component from
-another app. The Android system, however, can. So, to activate a component in
-another app, you must deliver a message to the system that specifies your <em>intent</em> to
+another app. However, the Android system can. To activate a component in
+another app, deliver a message to the system that specifies your <em>intent</em> to
 start a particular component. The system then activates the component for you.</p>
 
 
-<h3 id="ActivatingComponents">Activating Components</h3>
+<h3 id="ActivatingComponents">Activating components</h3>
 
 <p>Three of the four component types&mdash;activities, services, and
 broadcast receivers&mdash;are activated by an asynchronous message called an <em>intent</em>.
-Intents bind individual components to each other at runtime (you can think of them
-as the messengers that request an action from other components), whether the component belongs
+Intents bind individual components to each other at runtime. You can think of them
+as the messengers that request an action from other components, whether the component belongs
 to your app or another.</p>
 
-<p>An intent is created with an {@link android.content.Intent} object, which defines a message to
-activate either a specific component or a specific <em>type</em> of component&mdash;an intent
-can be either explicit or implicit, respectively.</p>
+<p class="note"><strong>Note:</strong> If your app targets Android 5.0 (API level 21) or later,
+ use the {@link android.app.job.JobScheduler} to execute background
+ services. For more information about using this class, see the
+ {@link android.app.job.JobScheduler} reference documentation.</p>
 
-<p>For activities and services, an intent defines the action to perform (for example, to "view" or
-"send" something) and may specify the URI of the data to act on (among other things that the
-component being started might need to know). For example, an intent might convey a request for an
+<p>An intent is created with an {@link android.content.Intent} object, which defines a message to
+activate either a specific component (explicit intent) or a specific <em>type</em> of component
+ (implicit intent).</p>
+
+<p>For activities and services, an intent defines the action to perform (for example, to
+ <em>view</em> or
+<em>send</em> something) and may specify the URI of the data to act on, among other things that the
+component being started might need to know. For example, an intent might convey a request for an
 activity to show an image or to open a web page. In some cases, you can start an
-activity to receive a result, in which case, the activity also returns
-the result in an {@link android.content.Intent} (for example, you can issue an intent to let
-the user pick a personal contact and have it returned to you&mdash;the return intent includes a
-URI pointing to the chosen contact).</p>
+activity to receive a result, in which case the activity also returns
+the result in an {@link android.content.Intent}. For example, you can issue an intent to let
+the user pick a personal contact and have it returned to you. The return intent includes a
+URI pointing to the chosen contact.</p>
 
 <p>For broadcast receivers, the intent simply defines the
-announcement being broadcast (for example, a broadcast to indicate the device battery is low
-includes only a known action string that indicates "battery is low").</p>
+announcement being broadcast. For example, a broadcast to indicate the device battery is low
+includes only a known action string that indicates <em>battery is low</em>.</p>
 
-<p>The other component type, content provider, is not activated by intents. Rather, it is
+<p>Unlike activities, services, and broadcast receivers, content providers are not activated
+ by intents. Rather, they are
 activated when targeted by a request from a {@link android.content.ContentResolver}. The content
 resolver handles all direct transactions with the content provider so that the component that's
 performing transactions with the provider doesn't need to and instead calls methods on the {@link
@@ -224,15 +247,19 @@
 
 <p>There are separate methods for activating each type of component:</p>
 <ul>
-  <li>You can start an activity (or give it something new to do) by
+  <li>You can start an activity or give it something new to do by
 passing an {@link android.content.Intent} to {@link android.content.Context#startActivity
 startActivity()} or {@link android.app.Activity#startActivityForResult startActivityForResult()}
 (when you want the activity to return a result).</li>
-  <li>You can start a service (or give new instructions to an ongoing service) by
+
+
+  <li>With Android 5.0 (API level 21) and later, you can start a service with
+  {@link android.app.job.JobScheduler}. For earlier Android versions, you can start
+  a service (or give new instructions to an ongoing service) by
 passing an {@link android.content.Intent} to {@link android.content.Context#startService
-startService()}. Or you can bind to the service by passing an {@link android.content.Intent} to
-{@link android.content.Context#bindService bindService()}.</li>
-  <li>You can initiate a broadcast by passing an {@link android.content.Intent} to methods like
+startService()}. You can bind to the service by passing an {@link android.content.Intent} to
+{@link android.content.Context#bindService bindService()}. </li>
+  <li>You can initiate a broadcast by passing an {@link android.content.Intent} to methods such as
 {@link android.content.Context#sendBroadcast(Intent) sendBroadcast()}, {@link
 android.content.Context#sendOrderedBroadcast(Intent, String) sendOrderedBroadcast()}, or {@link
 android.content.Context#sendStickyBroadcast sendStickyBroadcast()}.</li>
@@ -242,35 +269,35 @@
 
 <p>For more information about using intents, see the <a
 href="{@docRoot}guide/components/intents-filters.html">Intents and
-Intent Filters</a> document. More information about activating specific components is also provided
-in the following documents: <a
-href="{@docRoot}guide/components/activities.html">Activities</a>, <a
-href="{@docRoot}guide/components/services.html">Services</a>, {@link
-android.content.BroadcastReceiver} and <a
-href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.</p>
+Intent Filters</a> document.
+ The following documents provide more information about activating specifc components:
+ <a href="{@docRoot}guide/components/activities.html">Activities</a>,
+ <a href="{@docRoot}guide/components/services.html">Services
+ {@link android.content.BroadcastReceiver}, and
+ <a ref="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.</p>
 
-
-<h2 id="Manifest">The Manifest File</h2>
+<h2 id="Manifest">The manifest file</h2>
 
 <p>Before the Android system can start an app component, the system must know that the
-component exists by reading the app's {@code AndroidManifest.xml} file (the "manifest"
-file). Your app must declare all its components in this file, which must be at the root of
-the app project directory.</p>
+component exists by reading the app's <em>manifest file</em>, {@code AndroidManifest.xml}.
+ Your app must declare all its components in this file, which must be at the root of the
+ app project directory.</p>
 
 <p>The manifest does a number of things in addition to declaring the app's components,
-such as:</p>
+such as the following:</p>
 <ul>
-  <li>Identify any user permissions the app requires, such as Internet access or
+  <li>Identifies any user permissions the app requires, such as Internet access or
 read-access to the user's contacts.</li>
-  <li>Declare the minimum <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API Level</a>
+  <li>Declares the minimum
+  <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API Level</a>
 required by the app, based on which APIs the app uses.</li>
-  <li>Declare hardware and software features used or required by the app, such as a camera,
+  <li>Declares hardware and software features used or required by the app, such as a camera,
 bluetooth services, or a multitouch screen.</li>
-  <li>API libraries the app needs to be linked against (other than the Android framework
+  <li>Declares API libraries the app needs to be linked against (other than the Android framework
 APIs), such as the <a
-href="http://code.google.com/android/add-ons/google-apis/maps-overview.html">Google Maps
-library</a>.</li>
-  <li>And more</li>
+href="http://code.google.com/android/add-ons/google-apis/maps-overview.html">
+Google Maps library</a>.</li>
+
 </ul>
 
 
@@ -301,47 +328,59 @@
 android.app.Activity} subclass and the {@code android:label} attribute specifies a string
 to use as the user-visible label for the activity.</p>
 
-<p>You must declare all app components this way:</p>
+<p>You must declare all app components using the following elements:</p>
 <ul>
   <li><code><a
 href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code> elements
-for activities</li>
+for activities.</li>
   <li><code><a
 href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code> elements for
-services</li>
+services.</li>
   <li><code><a
 href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code> elements
-for broadcast receivers</li>
+for broadcast receivers.</li>
   <li><code><a
 href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code> elements
-for content providers</li>
+for content providers.</li>
 </ul>
 
 <p>Activities, services, and content providers that you include in your source but do not declare
 in the manifest are not visible to the system and, consequently, can never run.  However,
 broadcast
-receivers can be either declared in the manifest or created dynamically in code (as
-{@link android.content.BroadcastReceiver} objects) and registered with the system by calling
+receivers can be either declared in the manifest or created dynamically in code as
+{@link android.content.BroadcastReceiver} objects and registered with the system by calling
 {@link android.content.Context#registerReceiver registerReceiver()}.</p>
 
 <p>For more about how to structure the manifest file for your app, see <a
 href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml File</a>
 documentation. </p>
 
-
-
 <h3 id="DeclaringComponentCapabilities">Declaring component capabilities</h3>
 
-<p>As discussed above, in <a href="#ActivatingComponents">Activating Components</a>, you can use an
-{@link android.content.Intent} to start activities, services, and broadcast receivers. You can do so
-by explicitly naming the target component (using the component class name) in the intent. However,
-the real power of intents lies in the concept of <em>implicit intents</em>. An implicit intent
-simply describes the type of action to perform (and, optionally, the data upon which you’d like to
-perform the action) and allows the system to find a component on the device that can perform the
-action and start it. If there are multiple components that can perform the action described by the
-intent, then the user selects which one to use.</p>
+<p>As discussed above, in <a href="#ActivatingComponents">Activating components</a>, you can use an
+{@link android.content.Intent} to start activities, services, and broadcast receivers.
 
-<p>The way the system identifies the components that can respond to an intent is by comparing the
+
+
+You can use an {@link android.content.Intent}
+ by explicitly naming the target component (using the component class name) in the intent.
+ You can also use an implicit intent, which
+describes the type of action to perform and, optionally, the data upon which you’d like to
+perform the action. The implicit intent allows the system to find a component on the device
+ that can perform the
+action and start it. If there are multiple components that can perform the action described by the
+intent, the user selects which one to use.</p>
+
+<p class="caution"><strong>Caution:</strong> If you use an intent to start a
+ {@link android.app.Service}, ensure that your app is secure by using an
+ <a href="{@docRoot}guide/components/intents-filters.html#Types">explicit</a>
+intent. Using an implicit intent to start a service is a
+security hazard because you cannot be certain what service will respond to the intent,
+and the user cannot see which service starts. Beginning with Android 5.0 (API level 21), the system
+throws an exception if you call {@link android.content.Context#bindService bindService()}
+with an implicit intent. Do not declare intent filters for your services. </p>
+
+<p>The system identifies the components that can respond to an intent by comparing the
 intent received to the <i>intent filters</i> provided in the manifest file of other apps on
 the device.</p>
 
@@ -351,8 +390,9 @@
 adding an <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
 <intent-filter>}</a> element as a child of the component's declaration element.</p>
 
-<p>For example, if you've built an email app with an activity for composing a new email, you can
-declare an intent filter to respond to "send" intents (in order to send a new email) like this:</p>
+<p>For example, if you build an email app with an activity for composing a new email, you can
+declare an intent filter to respond to "send" intents (in order to send a new email),
+ as shown in the following example:</p>
 <pre>
 &lt;manifest ... >
     ...
@@ -368,8 +408,9 @@
 &lt;/manifest>
 </pre>
 
-<p>Then, if another app creates an intent with the {@link
-android.content.Intent#ACTION_SEND} action and passes it to {@link android.app.Activity#startActivity
+<p>If another app creates an intent with the {@link
+android.content.Intent#ACTION_SEND} action and passes it to
+ {@link android.app.Activity#startActivity
 startActivity()}, the system may start your activity so the user can draft and send an
 email.</p>
 
@@ -382,7 +423,7 @@
 <h3 id="DeclaringRequirements">Declaring app requirements</h3>
 
 <p>There are a variety of devices powered by Android and not all of them provide the
-same features and capabilities. In order to prevent your app from being installed on devices
+same features and capabilities. To prevent your app from being installed on devices
 that lack features needed by your app, it's important that you clearly define a profile for
 the types of devices your app supports by declaring device and software requirements in your
 manifest file. Most of these declarations are informational only and the system does not read
@@ -391,7 +432,7 @@
 
 <p>For example, if your app requires a camera and uses APIs introduced in Android 2.1 (<a
 href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API Level</a> 7),
-you should declare these as requirements in your manifest file like this:</p>
+you must declare these as requirements in your manifest file as shown in the following example:</p>
 
 <pre>
 &lt;manifest ... >
@@ -402,10 +443,10 @@
 &lt;/manifest>
 </pre>
 
-<p>Now, devices that do <em>not</em> have a camera and have an
-Android version <em>lower</em> than 2.1 cannot install your app from Google Play.</p>
-
-<p>However, you can also declare that your app uses the camera, but does not
+<p>With the declarations shown in the example, devices that do <em>not</em> have a
+ camera and have an
+Android version <em>lower</em> than 2.1 cannot install your app from Google Play.
+ However, you can declare that your app uses the camera, but does not
 <em>require</em> it. In that case, your app must set the <a href=
 "{@docRoot}guide/topics/manifest/uses-feature-element.html#required">{@code required}</a>
 attribute to {@code "false"} and check at runtime whether
@@ -417,15 +458,15 @@
 
 
 
-<h2 id="Resources">App Resources</h2>
+<h2 id="Resources">App resources</h2>
 
 <p>An Android app is composed of more than just code&mdash;it requires resources that are
 separate from the source code, such as images, audio files, and anything relating to the visual
-presentation of the app. For example, you should define animations, menus, styles, colors,
+presentation of the app. For example, you can define animations, menus, styles, colors,
 and the layout of activity user interfaces with XML files. Using app resources makes it easy
-to update various characteristics of your app without modifying code and&mdash;by providing
-sets of alternative resources&mdash;enables you to optimize your app for a  variety of
-device configurations (such as different languages and screen sizes).</p>
+to update various characteristics of your app without modifying code. Providing
+sets of alternative resources enables you to optimize your app for a variety of
+device configurations, such as different languages and screen sizes.</p>
 
 <p>For every resource that you include in your Android project, the SDK build tools define a unique
 integer ID, which you can use to reference the resource from your app code or from
@@ -435,20 +476,22 @@
 user interface.</p>
 
 <p>One of the most important aspects of providing resources separate from your source code
-is the ability for you to provide alternative resources for different device
-configurations. For example, by defining UI strings in XML, you can translate the strings into other
-languages and save those strings in separate files. Then, based on a language <em>qualifier</em>
+is the ability to provide alternative resources for different device
+configurations. For example, by defining UI strings in XML, you can translate
+ the strings into other
+languages and save those strings in separate files. Then Android applies the
+ appropriate language strings
+to your UI based on a language <em>qualifier</em>
 that you append to the resource directory's name (such as {@code res/values-fr/} for French string
-values) and the user's language setting, the Android system applies the appropriate language strings
-to your UI.</p>
+values) and the user's language setting.</p>
 
 <p>Android supports many different <em>qualifiers</em> for your alternative resources. The
 qualifier is a short string that you include in the name of your resource directories in order to
-define the device configuration for which those resources should be used. As another
-example, you should often create different layouts for your activities, depending on the
-device's screen orientation and size. For example, when the device screen is in portrait
+define the device configuration for which those resources should be used. For
+example, you should create different layouts for your activities, depending on the
+device's screen orientation and size. When the device screen is in portrait
 orientation (tall), you might want a layout with buttons to be vertical, but when the screen is in
-landscape orientation (wide), the buttons should be aligned horizontally. To change the layout
+landscape orientation (wide), the buttons could be aligned horizontally. To change the layout
 depending on the orientation, you can define two different layouts and apply the appropriate
 qualifier to each layout's directory name. Then, the system automatically applies the appropriate
 layout depending on the current device orientation.</p>
@@ -465,15 +508,15 @@
   <dl>
     <dt><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
     </dt>
-    <dd>Information about how to use the {@link android.content.Intent} APIs to
+    <dd>How to use the {@link android.content.Intent} APIs to
     activate app components, such as activities and services, and how to make your app components
     available for use by other apps.</dd>
     <dt><a href="{@docRoot}guide/components/activities.html">Activities</a></dt>
-    <dd>Information about how to create an instance of the {@link android.app.Activity} class,
+    <dd>How to create an instance of the {@link android.app.Activity} class,
     which provides a distinct screen in your application with a user interface.</dd>
     <dt><a
 href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a></dt>
-    <dd>Information about how Android apps are structured to separate app resources from the
+    <dd>How Android apps are structured to separate app resources from the
    app code, including how you can provide alternative resources for specific device
    configurations.
     </dd>
@@ -484,14 +527,13 @@
   <dl>
     <dt><a href="{@docRoot}guide/practices/compatibility.html"
         >Device Compatibility</a></dt>
-    <dd>Information about Android works on different types of devices and an introduction
+    <dd>How Android works on different types of devices and an introduction
     to how you can optimize your app for each device or restrict your app's availability
     to different devices.</dd>
     <dt><a href="{@docRoot}guide/topics/security/permissions.html"
         >System Permissions</a></dt>
-    <dd>Information about how Android restricts app access to certain APIs with a permission
+    <dd>How Android restricts app access to certain APIs with a permission
     system that requires the user's consent for your app to use those APIs.</dd>
   </dl>
 </div>
 </div>
-
diff --git a/docs/html/guide/components/intents-filters.jd b/docs/html/guide/components/intents-filters.jd
index d1d8c78..8f41bc3 100644
--- a/docs/html/guide/components/intents-filters.jd
+++ b/docs/html/guide/components/intents-filters.jd
@@ -7,21 +7,21 @@
 
 <h2>In this document</h2>
 <ol>
-  <li><a href="#Types">Intent Types</a></li>
-  <li><a href="#Building">Building an Intent</a>
+  <li><a href="#Types">Intent types</a></li>
+  <li><a href="#Building">Building an intent</a>
     <ol>
       <li><a href="#ExampleExplicit">Example explicit intent</a></li>
       <li><a href="#ExampleSend">Example implicit intent</a></li>
       <li><a href="#ForceChooser">Forcing an app chooser</a></li>
     </ol>
   </li>
-  <li><a href="#Receiving">Receiving an Implicit Intent</a>
+  <li><a href="#Receiving">Receiving an implicit intent</a>
     <ol>
       <li><a href="#ExampleFilters">Example filters</a></li>
     </ol>
   </li>
-  <li><a href="#PendingIntent">Using a Pending Intent</a></li>
-  <li><a href="#Resolution">Intent Resolution</a>
+  <li><a href="#PendingIntent">Using a pending intent</a></li>
+  <li><a href="#Resolution">Intent resolution</a>
     <ol>
       <li><a href="#ActionTest">Action test</a></li>
       <li><a href="#CategoryTest">Category test</a></li>
@@ -46,13 +46,14 @@
 <p>An {@link android.content.Intent} is a messaging object you can use to request an action
 from another <a href="{@docRoot}guide/components/fundamentals.html#Components">app component</a>.
 Although intents facilitate communication between components in several ways, there are three
-fundamental use-cases:</p>
+fundamental use cases:</p>
 
 <ul>
-<li><b>To start an activity:</b>
+<li><b>Starting an activity</b>
 <p>An {@link android.app.Activity} represents a single screen in an app. You can start a new
 instance of an {@link android.app.Activity} by passing an {@link android.content.Intent}
-to {@link android.content.Context#startActivity startActivity()}. The {@link android.content.Intent}
+to {@link android.content.Context#startActivity startActivity()}.
+ The {@link android.content.Intent}
 describes the activity to start and carries any necessary data.</p>
 
 <p>If you want to receive a result from the activity when it finishes,
@@ -63,10 +64,16 @@
 For more information, see the <a
 href="{@docRoot}guide/components/activities.html">Activities</a> guide.</p></li>
 
-<li><b>To start a service:</b>
+<li><b>Starting a service</b>
 <p>A {@link android.app.Service} is a component that performs operations in the background
-without a user interface. You can start a service to perform a one-time operation
-(such as download a file) by passing an {@link android.content.Intent}
+without a user interface. With Android 5.0 (API level 21) and later, you can start a service
+ with {@link android.app.job.JobScheduler}. For more information
+ about {@link android.app.job.JobScheduler}, see its
+    {@link android.app.job.JobScheduler API-reference documentation}.</p>
+<p>For versions earlier than Android 5.0 (API level 21), you can start a service by using
+methods of the  {@link android.app.Service} class. You can start a service
+ to perform a one-time operation
+(such as downloading a file) by passing an {@link android.content.Intent}
 to {@link android.content.Context#startService startService()}. The {@link android.content.Intent}
 describes the service to start and carries any necessary data.</p>
 
@@ -75,7 +82,7 @@
 android.content.Context#bindService bindService()}</code>. For more information, see the <a
 href="{@docRoot}guide/components/services.html">Services</a> guide.</p></li>
 
-<li><b>To deliver a broadcast:</b>
+<li><b>Delivering a broadcast</b>
 <p>A broadcast is a message that any app can receive. The system delivers various
 broadcasts for system events, such as when the system boots up or the device starts charging.
 You can deliver a broadcast to other apps by passing an {@link android.content.Intent}
@@ -89,7 +96,7 @@
 
 
 
-<h2 id="Types">Intent Types</h2>
+<h2 id="Types">Intent types</h2>
 
 <p>There are two types of intents:</p>
 
@@ -97,7 +104,7 @@
 <li><b>Explicit intents</b> specify the component to start by name (the
 fully-qualified class name). You'll typically use an explicit intent to start a component in
 your own app, because you know the class name of the activity or service you want to start. For
-example, start a new activity in response to a user action or start a service to download
+example, you can start a new activity in response to a user action or start a service to download
 a file in the background.</li>
 
 <li><b>Implicit intents</b> do not name a specific component, but instead declare a general action
@@ -106,12 +113,13 @@
 app show a specified location on a map.</li>
 </ul>
 
-<p>When you create an explicit intent to start an activity or service, the system immediately
+<p>Figure 1 shows how an intent is delivered to start an activity. When you create an
+ explicit intent to start an activity or service, the system immediately
 starts the app component specified in the {@link android.content.Intent} object.</p>
 
 <div class="figure" style="width:446px">
 <img src="{@docRoot}images/components/intent-filters@2x.png" width="446" alt=""/>
-<p class="img-caption"><strong>Figure 1.</strong> Illustration of how an implicit intent is
+<p class="img-caption"><strong>Figure 1.</strong> How an implicit intent is
 delivered through the system to start another activity: <b>[1]</b> <em>Activity A</em> creates an
 {@link android.content.Intent} with an action description and passes it to {@link
 android.content.Context#startActivity startActivity()}. <b>[2]</b> The Android System searches all
@@ -135,11 +143,12 @@
 Likewise, if you do <em>not</em> declare any intent filters for an activity, then it can be started
 only with an explicit intent.</p>
 
-<p class="caution"><strong>Caution:</strong> To ensure your app is secure, always use an explicit
+<p class="caution"><strong>Caution:</strong> To ensure that your app is secure, always
+ use an explicit
 intent when starting a {@link android.app.Service} and do not
 declare intent filters for your services. Using an implicit intent to start a service is a
-security hazard because you cannot be certain what service will respond to the intent,
-and the user cannot see which service starts. Beginning with Android 5.0 (API level 21), the system
+security hazard because you can't be certain what service will respond to the intent,
+and the user can't see which service starts. Beginning with Android 5.0 (API level 21), the system
 throws an exception if you call {@link android.content.Context#bindService bindService()}
 with an implicit intent.</p>
 
@@ -147,7 +156,7 @@
 
 
 
-<h2 id="Building">Building an Intent</h2>
+<h2 id="Building">Building an intent</h2>
 
 <p>An {@link android.content.Intent} object carries information that the Android system uses
 to determine which component to start (such as the exact component name or component
@@ -163,22 +172,23 @@
 <dd>The name of the component to start.
 
 <p>This is optional, but it's the critical piece of information that makes an intent
-<b>explicit</b>, meaning that the intent should be delivered only to the app component
-defined by the component name. Without a component name, the intent is <b>implicit</b> and the
+<em>explicit</em>, meaning that the intent should be delivered only to the app component
+defined by the component name. Without a component name, the intent is <em>implicit</em> and the
 system decides which component should receive the intent based on the other intent information
-(such as the action, data, and category&mdash;described below). So if you need to start a specific
+(such as the action, data, and category&mdash;described below). If you need to start a specific
 component in your app, you should specify the component name.</p>
 
-<p class="note"><strong>Note:</strong> When starting a {@link android.app.Service}, you should
-<strong>always specify the component name</strong>. Otherwise, you cannot be certain what service
+<p class="note"><strong>Note:</strong> When starting a {@link android.app.Service},
+ <em>always specify the component name</em>. Otherwise, you cannot be certain what service
 will respond to the intent, and the user cannot see which service starts.</p>
 
 <p>This field of the {@link android.content.Intent} is a
 {@link android.content.ComponentName} object, which you can specify using a fully
-qualified class name of the target component, including the package name of the app. For example,
+qualified class name of the target component, including the package name of the app, for example,
 {@code com.example.ExampleActivity}. You can set the component name with {@link
 android.content.Intent#setComponent setComponent()}, {@link android.content.Intent#setClass
-setClass()}, {@link android.content.Intent#setClassName(String, String) setClassName()}, or with the
+setClass()}, {@link android.content.Intent#setClassName(String, String) setClassName()},
+ or with the
 {@link android.content.Intent} constructor.</p>
 
 </dd>
@@ -188,10 +198,10 @@
 
 <p>In the case of a broadcast intent, this is the action that took place and is being reported.
 The action largely determines how the rest of the intent is structured&mdash;particularly
-what is contained in the data and extras.
+the information that is contained in the data and extras.
 
 <p>You can specify your own actions for use by intents within your app (or for use by other
-apps to invoke components in your app), but you should usually use action constants
+apps to invoke components in your app), but you usually specify action constants
 defined by the {@link android.content.Intent} class or other framework classes. Here are some
 common actions for starting an activity:</p>
 
@@ -203,7 +213,7 @@
    view in a map app.</dd>
 
 <dt>{@link android.content.Intent#ACTION_SEND}</dt>
-   <dd>Also known as the "share" intent, you should use this in an intent with {@link
+   <dd>Also known as the <em>share</em> intent, you should use this in an intent with {@link
    android.content.Context#startActivity startActivity()} when you have some data that the user can
    share through another app, such as an email app or social sharing app.</dd>
 </dl>
@@ -217,12 +227,13 @@
 setAction()} or with an {@link android.content.Intent} constructor.</p>
 
 <p>If you define your own actions, be sure to include your app's package name
-as a prefix. For example:</p>
+as a prefix, as shown in the following example:</p>
 <pre>static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";</pre>
 </dd>
 
 <dt><b>Data</b></dt>
-<dd>The URI (a {@link android.net.Uri} object) that references the data to be acted on and/or the
+<dd>The URI (a {@link android.net.Uri} object) that references the data to
+ be acted on and/or the
 MIME type of that data. The type of data supplied is generally dictated by the intent's action. For
 example, if the action is {@link android.content.Intent#ACTION_EDIT}, the data should contain the
 URI of the document to edit.
@@ -231,10 +242,11 @@
 it's often important to specify the type of data (its MIME type) in addition to its URI.
 For example, an activity that's able to display images probably won't be able
 to play an audio file, even though the URI formats could be similar.
-So specifying the MIME type of your data helps the Android
+Specifying the MIME type of your data helps the Android
 system find the best component to receive your intent.
 However, the MIME type can sometimes be inferred from the URI&mdash;particularly when the data is a
-{@code content:} URI, which indicates the data is located on the device and controlled by a
+{@code content:} URI. A {@code content:} URI indicates the data is located on the device
+ and controlled by a
 {@link android.content.ContentProvider}, which makes the data MIME type visible to the system.</p>
 
 <p>To set only the data URI, call {@link android.content.Intent#setData setData()}.
@@ -243,7 +255,7 @@
 android.content.Intent#setDataAndType setDataAndType()}.</p>
 
 <p class="caution"><strong>Caution:</strong> If you want to set both the URI and MIME type,
-<strong>do not</strong> call {@link android.content.Intent#setData setData()} and
+<em>don't</em> call {@link android.content.Intent#setData setData()} and
 {@link android.content.Intent#setType setType()} because they each nullify the value of the other.
 Always use {@link android.content.Intent#setDataAndType setDataAndType()} to set both
 URI and MIME type.</p>
@@ -258,7 +270,7 @@
 <dl>
 <dt>{@link android.content.Intent#CATEGORY_BROWSABLE}</dt>
   <dd>The target activity allows itself to be started by a web browser to display data
-       referenced by a link&mdash;such as an image or an e-mail message.
+       referenced by a link, such as an image or an e-mail message.
   </dd>
 <dt>{@link android.content.Intent#CATEGORY_LAUNCHER}</dt>
   <dd>The activity is the initial activity of a task and is listed in
@@ -276,14 +288,14 @@
 
 <p>These properties listed above (component name, action, data, and category) represent the
 defining characteristics of an intent. By reading these properties, the Android system
-is able to resolve which app component it should start.</p>
-
-<p>However, an intent can carry additional information that does not affect
-how it is resolved to an app component. An intent can also supply:</p>
+is able to resolve which app component it should start. However, an intent can carry
+ additional information that does not affect
+how it is resolved to an app component. An intent can also supply the following information:</p>
 
 <dl>
 <dt><b>Extras</b></dt>
-<dd>Key-value pairs that carry additional information required to accomplish the requested action.
+<dd>Key-value pairs that carry additional information required to accomplish
+ the requested action.
 Just as some actions use particular kinds of data URIs, some actions also use particular extras.
 
 <p>You can add extra data with various {@link android.content.Intent#putExtra putExtra()} methods,
@@ -293,21 +305,22 @@
 android.content.Intent#putExtras putExtras()}.</p>
 
 <p>For example, when creating an intent to send an email with
-{@link android.content.Intent#ACTION_SEND}, you can specify the "to" recipient with the
-{@link android.content.Intent#EXTRA_EMAIL} key, and specify the "subject" with the
+{@link android.content.Intent#ACTION_SEND}, you can specify the <em>to</em> recipient with the
+{@link android.content.Intent#EXTRA_EMAIL} key, and specify the <em>subject</em> with the
 {@link android.content.Intent#EXTRA_SUBJECT} key.</p>
 
 <p>The {@link android.content.Intent} class specifies many {@code EXTRA_*} constants
 for standardized data types. If you need to declare your own extra keys (for intents that
 your app receives), be sure to include your app's package name
-as a prefix. For example:</p>
+as a prefix, as shown in the following example:</p>
 <pre>static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";</pre>
 </dd>
 
 <dt><b>Flags</b></dt>
-<dd>Flags defined in the {@link android.content.Intent} class that function as metadata for the
+<dd>Flags are defined in the {@link android.content.Intent} class that function as metadata for the
 intent. The flags may instruct the Android system how to launch an activity (for example, which
-<a href="{@docRoot}guide/components/tasks-and-back-stack.html">task</a> the activity should belong
+<a href="{@docRoot}guide/components/tasks-and-back-stack.html">task</a>
+ the activity should belong
 to) and how to treat it after it's launched (for example, whether it belongs in the list of recent
 activities).
 
@@ -354,7 +367,8 @@
 to perform the action. Using an implicit intent is useful when your app cannot perform the
 action, but other apps probably can and you'd like the user to pick which app to use.</p>
 
-<p>For example, if you have content you want the user to share with other people, create an intent
+<p>For example, if you have content that you want the user to share with other people,
+ create an intent
 with the {@link android.content.Intent#ACTION_SEND} action
 and add extras that specify the content to share. When you call
 {@link android.content.Context#startActivity startActivity()} with that intent, the user can
@@ -362,13 +376,15 @@
 
 <p class="caution"><strong>Caution:</strong> It's possible that a user won't have <em>any</em>
 apps that handle the implicit intent you send to {@link android.content.Context#startActivity
-startActivity()}. If that happens, the call will fail and your app will crash. To verify
+startActivity()}. If that happens, the call fails and your app crashes. To verify
 that an activity will receive the intent, call {@link android.content.Intent#resolveActivity
 resolveActivity()} on your {@link android.content.Intent} object. If the result is non-null,
-then there is at least one app that can handle the intent and it's safe to call
+ there is at least one app that can handle the intent and it's safe to call
 {@link android.content.Context#startActivity startActivity()}. If the result is null,
-you should not use the intent and, if possible, you should disable the feature that issues
-the intent.</p>
+ do not use the intent and, if possible, you should disable the feature that issues
+the intent. The following example shows how to verify that the intent resolves
+to an activity. This example doesn't use a URI, but the intent's data type
+is declared to specify the content carried by the extras.</p>
 
 
 <pre>
@@ -384,8 +400,7 @@
 }
 </pre>
 
-<p class="note"><strong>Note:</strong> In this case, a URI is not used, but the intent's data type
-is declared to specify the content carried by the extras.</p>
+
 
 
 <p>When {@link android.content.Context#startActivity startActivity()} is called, the system
@@ -393,7 +408,7 @@
 intent with the {@link android.content.Intent#ACTION_SEND} action and that carries "text/plain"
 data). If there's only one app that can handle it, that app opens immediately and is given the
 intent. If multiple activities accept the intent, the system
-displays a dialog so the user can pick which app to use..</p>
+displays a dialog such as the one shown in Figure 2, so the user can pick which app to use.</p>
 
 
 <div class="figure" style="width:200px">
@@ -405,23 +420,26 @@
 
 <p>When there is more than one app that responds to your implicit intent,
 the user can select which app to use and make that app the default choice for the
-action. This is nice when performing an action for which the user
-probably wants to use the same app from now on, such as when opening a web page (users
-often prefer just one web browser) .</p>
+action. The ability to select a default is helpful when performing an action for which the user
+probably wants to use the same app every time, such as when opening a web page (users
+often prefer just one web browser).</p>
 
 <p>However, if multiple apps can respond to the intent and the user might want to use a different
 app each time, you should explicitly show a chooser dialog. The chooser dialog asks the
-user to select which app to use for the action every time (the user cannot select a default app for
+user to select which app to use for the action (the user cannot select a default app for
 the action). For example, when your app performs "share" with the {@link
 android.content.Intent#ACTION_SEND} action, users may want to share using a different app depending
-on their current situation, so you should always use the chooser dialog, as shown in figure 2.</p>
+on their current situation, so you should always use the chooser dialog, as shown in Figure 2.</p>
 
 
 
 
 <p>To show the chooser, create an {@link android.content.Intent} using {@link
 android.content.Intent#createChooser createChooser()} and pass it to {@link
-android.app.Activity#startActivity startActivity()}. For example:</p>
+android.app.Activity#startActivity startActivity()}, as shown in the following example.
+ This example displays a dialog with a list of apps that respond to the intent passed to the {@link
+android.content.Intent#createChooser createChooser()} method and uses the supplied text as the
+dialog title.</p>
 
 <pre>
 Intent sendIntent = new Intent(Intent.ACTION_SEND);
@@ -439,26 +457,16 @@
 }
 </pre>
 
-<p>This displays a dialog with a list of apps that respond to the intent passed to the {@link
-android.content.Intent#createChooser createChooser()} method and uses the supplied text as the
-dialog title.</p>
 
 
-
-
-
-
-
-
-
-<h2 id="Receiving">Receiving an Implicit Intent</h2>
+<h2 id="Receiving">Receiving an implicit intent</h2>
 
 <p>To advertise which implicit intents your app can receive, declare one or more intent filters for
 each of your app components with an <a href=
-"{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a>
+"{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a>
 element in your <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">manifest file</a>.
 Each intent filter specifies the type of intents it accepts based on the intent's action,
-data, and category. The system will deliver an implicit intent to your app component only if the
+data, and category. The system delivers an implicit intent to your app component only if the
 intent can pass through one of your intent filters.</p>
 
 <p class="note"><strong>Note:</strong> An explicit intent is always delivered to its target,
@@ -471,28 +479,28 @@
 in the {@link android.content.Intent} (such as to show the editor controls or not).</p>
 
 <p>Each intent filter is defined by an <a
-href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a>
+href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter>}</a>
 element in the app's manifest file, nested in the corresponding app component (such
-as an <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>
+as an <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity>}</a>
 element). Inside the <a
-href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a>,
+href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter>}</a>,
 you can specify the type of intents to accept using one or more
 of these three elements:</p>
 
 <dl>
-<dt><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a></dt>
+<dt><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action>}</a></dt>
   <dd>Declares the intent action accepted, in the {@code name} attribute. The value
   must be the literal string value of an action, not the class constant.</dd>
-<dt><a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a></dt>
+<dt><a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data>}</a></dt>
   <dd>Declares the type of data accepted, using one or more attributes that specify various
   aspects of the data URI (<code>scheme</code>, <code>host</code>, <code>port</code>,
-  <code>path</code>, etc.) and MIME type.</dd>
-<dt><a href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a></dt>
+  <code>path</code>) and MIME type.</dd>
+<dt><a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category>}</a></dt>
   <dd>Declares the intent category accepted, in the {@code name} attribute. The value
   must be the literal string value of an action, not the class constant.
 
-  <p class="note"><strong>Note:</strong> In order to receive implicit intents, you
-  <strong>must include</strong> the
+  <p class="note"><strong>Note:</strong> To receive implicit intents, you
+  <em>must include</em> the
   {@link android.content.Intent#CATEGORY_DEFAULT} category in the intent filter. The methods
   {@link android.app.Activity#startActivity startActivity()} and
   {@link android.app.Activity#startActivityForResult startActivityForResult()} treat all intents
@@ -515,12 +523,12 @@
 &lt;/activity>
 </pre>
 
-<p>It's okay to create a filter that includes more than one instance of
-<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a>,
-<a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a>, or
-<a href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a>.
-If you do, you simply need to be certain that the component can handle any and all combinations
-of those filter elements.</p>
+<p>You can create a filter that includes more than one instance of
+<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action>}</a>,
+<a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data>}</a>, or
+<a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category>}</a>.
+If you do, you need to be certain that the component can handle any and all
+combinations of those filter elements.</p>
 
 <p>When you want to handle multiple kinds of intents, but only in specific combinations of
 action, data, and category type, then you need to create multiple intent filters.</p>
@@ -569,8 +577,8 @@
 
 <h3 id="ExampleFilters">Example filters</h3>
 
-<p>To better understand some of the intent filter behaviors, look at the following snippet
-from the manifest file of a social-sharing app.</p>
+<p>To demonstrate some of the intent filter behaviors, here is an example
+from the manifest file of a social-sharing app:</p>
 
 <pre>
 &lt;activity android:name="MainActivity">
@@ -607,9 +615,9 @@
   indicates this is the main entry point and does not expect any intent data.</li>
   <li>The {@link android.content.Intent#CATEGORY_LAUNCHER} category indicates that this activity's
   icon should be placed in the system's app launcher. If the <a
-  href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element
+  href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity>}</a> element
   does not specify an icon with {@code icon}, then the system uses the icon from the <a
-  href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>
+  href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application>}</a>
   element.</li>
 </ul>
 <p>These two must be paired together in order for the activity to appear in the app launcher.</p>
@@ -620,7 +628,7 @@
 intent matching one of the two intent filters.</p>
 
 <p class="note"><strong>Note:</strong> The MIME type,
-<a href="https://developers.google.com/panorama/android/">{@code
+<a href="https://developers.google.com/panorama/android/" class="external-link">{@code
 application/vnd.google.panorama360+jpg}</a>, is a special data type that specifies
 panoramic photos, which you can handle with the <a
 href="{@docRoot}reference/com/google/android/gms/panorama/package-summary.html">Google
@@ -638,7 +646,7 @@
 
 
 
-<h2 id="PendingIntent">Using a Pending Intent</h2>
+<h2 id="PendingIntent">Using a pending intent</h2>
 
 <p>A {@link android.app.PendingIntent} object is a wrapper around an {@link
 android.content.Intent} object. The primary purpose of a {@link android.app.PendingIntent}
@@ -646,25 +654,25 @@
 to use the contained {@link android.content.Intent} as if it were executed from your
 app's own process.</p>
 
-<p>Major use cases for a pending intent include:</p>
+<p>Major use cases for a pending intent include the following:</p>
 <ul>
-  <li>Declare an intent to be executed when the user performs an action with your <a
+  <li>Declaring an intent to be executed when the user performs an action with your <a
   href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notification</a>
   (the Android system's {@link android.app.NotificationManager}
   executes the {@link android.content.Intent}).
-  <li>Declare an intent to be executed when the user performs an action with your
+  <li>Declaring an intent to be executed when the user performs an action with your
   <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widget</a>
   (the Home screen app executes the {@link android.content.Intent}).
-  <li>Declare an intent to be executed at a specified time in the future (the Android
+  <li>Declaring an intent to be executed at a specified future time (the Android
   system's {@link android.app.AlarmManager} executes the {@link android.content.Intent}).
 </ul>
 
-<p>Because each {@link android.content.Intent} object is designed to be handled by a specific
+<p>Just as each {@link android.content.Intent} object is designed to be handled by a specific
 type of app component (either an {@link android.app.Activity}, a {@link android.app.Service}, or
 a {@link android.content.BroadcastReceiver}), so too must a {@link android.app.PendingIntent} be
-created with the same consideration. When using a pending intent, your app will not
+created with the same consideration. When using a pending intent, your app doesn't
 execute the intent with a call such as {@link android.content.Context#startActivity
-startActivity()}. You must instead declare the intended component type when you create the
+startActivity()}. Instead, you must declare the intended component type when you create the
 {@link android.app.PendingIntent} by calling the respective creator method:</p>
 
 <ul>
@@ -677,14 +685,14 @@
 </ul>
 
 <p>Unless your app is <em>receiving</em> pending intents from other apps,
-the above methods to create a {@link android.app.PendingIntent} are the only
-{@link android.app.PendingIntent} methods you'll probably ever need.</p>
+the above methods to create a {@link android.app.PendingIntent} are probably the only
+{@link android.app.PendingIntent} methods you'll ever need.</p>
 
 <p>Each method takes the current app {@link android.content.Context}, the
 {@link android.content.Intent} you want to wrap, and one or more flags that specify
 how the intent should be used (such as whether the intent can be used more than once).</p>
 
-<p>More information about using pending intents is provided with the documentation for each
+<p>For more information about using pending intents, see the documentation for each
 of the respective use cases, such as in the <a
 href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a>
 and <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widgets</a> API guides.</p>
@@ -695,27 +703,27 @@
 
 
 
-<h2 id="Resolution">Intent Resolution</h2>
+<h2 id="Resolution">Intent resolution</h2>
 
 
 <p>When the system receives an implicit intent to start an activity, it searches for the
-best activity for the intent by comparing the intent to intent filters based on three aspects:</p>
+best activity for the intent by comparing the it to intent filters based on three aspects:</p>
 
 <ul>
-  <li>The intent action
-  <li>The intent data (both URI and data type)
-  <li>The intent category
+  <li>Action.
+  <li>Data (both URI and data type).
+  <li>Category.
 </ul>
 
-<p>The following sections describe how intents are matched to the appropriate component(s)
-in terms of how the intent filter is declared in an app's manifest file.</p>
+<p>The following sections describe how intents are matched to the appropriate components
+according to the intent filter declaration in an app's manifest file.</p>
 
 
 <h3 id="ActionTest">Action test</h3>
 
 <p>To specify accepted intent actions, an intent filter can declare zero or more
 <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
-<action>}</a> elements.  For example:</p>
+&lt;action&gt;}</a> elements, as shown in the following example:</p>
 
 <pre>
 &lt;intent-filter&gt;
@@ -725,13 +733,13 @@
 &lt;/intent-filter&gt;
 </pre>
 
-<p>To get through this filter, the action specified in the {@link android.content.Intent}
+<p>To pass this filter, the action specified in the {@link android.content.Intent}
   must match one of the actions listed in the filter.</p>
 
 <p>If the filter does not list any actions, there is nothing for an
 intent to match, so all intents fail the test. However, if an {@link android.content.Intent}
-does not specify an action, it will pass the test (as long as the filter
-contains at least one action).</p>
+does not specify an action, it passes the test as long as the filter
+contains at least one action.</p>
 
 
 
@@ -739,7 +747,7 @@
 
 <p>To specify accepted intent categories, an intent filter can declare zero or more
 <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code
-<category>}</a> elements.  For example:</p>
+<category>}</a> elements, as shown in the following example:</p>
 
 <pre>
 &lt;intent-filter&gt;
@@ -752,17 +760,17 @@
 <p>For an intent to pass the category test, every category in the {@link android.content.Intent}
 must match a category in the filter. The reverse is not necessary&mdash;the intent filter may
 declare more categories than are specified in the {@link android.content.Intent} and the
-{@link android.content.Intent} will still pass. Therefore, an intent with no categories should
-always pass this test, regardless of what categories are declared in the filter.</p>
+{@link android.content.Intent} still passes. Therefore, an intent with no categories
+always passes this test, regardless of what categories are declared in the filter.</p>
 
 <p class="note"><strong>Note:</strong>
-Android automatically applies the the {@link android.content.Intent#CATEGORY_DEFAULT} category
+Android automatically applies the {@link android.content.Intent#CATEGORY_DEFAULT} category
 to all implicit intents passed to {@link
 android.content.Context#startActivity startActivity()} and {@link
 android.app.Activity#startActivityForResult startActivityForResult()}.
-So if you want your activity to receive implicit intents, it must
-include a category for {@code "android.intent.category.DEFAULT"} in its intent filters (as
-shown in the previous {@code <intent-filter>} example.</p>
+If you want your activity to receive implicit intents, it must
+include a category for {@code "android.intent.category.DEFAULT"} in its intent filters, as
+shown in the previous {@code &lt;intent-filter>} example.</p>
 
 
 
@@ -770,7 +778,7 @@
 
 <p>To specify accepted intent data, an intent filter can declare zero or more
 <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
-<data>}</a> elements.  For example:</p>
+&lt;data&gt;}</a> elements, as shown in the following example:</p>
 
 <pre>
 &lt;intent-filter&gt;
@@ -781,15 +789,16 @@
 </pre>
 
 <p>Each <code><a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data&gt;</a></code>
-element can specify a URI structure and a data type (MIME media type).  There are separate
-attributes &mdash; {@code scheme}, {@code host}, {@code port},
-and {@code path} &mdash; for each part of the URI:
+element can specify a URI structure and a data type (MIME media type).
+ Each part of the URI is a separate
+attribute: {@code scheme}, {@code host}, {@code port},
+and {@code path}:
 </p>
 
-<p style="margin-left: 2em">{@code <scheme>://<host>:<port>/<path>}</p>
+<p style="margin-left: 2em">{@code &lt;scheme>://&lt;host>:&lt;port>/&lt;path>}</p>
 
 <p>
-For example:
+The following example shows possible values for these attributes:
 </p>
 
 <p style="margin-left: 2em">{@code content://com.example.project:200/folder/subfolder/etc}</p>
@@ -799,7 +808,7 @@
 </p>
 
 <p>Each of these attributes is optional in a <a
-href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> element,
+href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data>}</a> element,
 but there are linear dependencies:</p>
 <ul>
   <li>If a scheme is not specified, the host is ignored.</li>
@@ -842,17 +851,17 @@
 either if its URI matches a URI in the filter or if it has a {@code content:}
 or {@code file:} URI and the filter does not specify a URI.  In other words,
 a component is presumed to support {@code content:} and {@code file:} data if
-its filter lists <em>only</em> a MIME type.</p></li>
+its filter lists <em>only</em> a MIME type.</li>
 </ol>
 
 <p>
 This last rule, rule (d), reflects the expectation
 that components are able to get local data from a file or content provider.
-Therefore, their filters can list just a data type and do not need to explicitly
+Therefore, their filters can list just a data type and don't need to explicitly
 name the {@code content:} and {@code file:} schemes.
-This is a typical case.  A <a
-href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> element
-like the following, for example, tells Android that the component can get image data from a content
+The following example shows a typical case in which a <a
+href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data>}</a> element
+ tells Android that the component can get image data from a content
 provider and display it:
 </p>
 
@@ -863,14 +872,15 @@
 &lt;/intent-filter&gt;</pre>
 
 <p>
-Because most available data is dispensed by content providers, filters that
-specify a data type but not a URI are perhaps the most common.
+Filters that
+specify a data type but not a URI are perhaps the most common because most available
+ data is dispensed by content providers.
 </p>
 
 <p>
-Another common configuration is filters with a scheme and a data type.  For
+Another common configuration is a filter with a scheme and a data type.  For
 example, a <a
-href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a>
+href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data>}</a>
 element like the following tells Android that
 the component can retrieve video data from the network in order to perform the action:
 </p>
@@ -894,7 +904,7 @@
 
 <p>Your application can use intent matching in a similar way.
 The {@link android.content.pm.PackageManager} has a set of {@code query...()}
-methods that return all components that can accept a particular intent, and
+methods that return all components that can accept a particular intent and
 a similar series of {@code resolve...()} methods that determine the best
 component to respond to an intent.  For example,
 {@link android.content.pm.PackageManager#queryIntentActivities
@@ -907,7 +917,3 @@
 {@link android.content.pm.PackageManager#queryBroadcastReceivers
 queryBroadcastReceivers()}, for broadcast receivers.
 </p>
-
-
-
-
diff --git a/docs/html/guide/components/services.jd b/docs/html/guide/components/services.jd
index e646a17..a7ed718 100644
--- a/docs/html/guide/components/services.jd
+++ b/docs/html/guide/components/services.jd
@@ -5,11 +5,11 @@
 <ol id="qv">
 <h2>In this document</h2>
 <ol>
-<li><a href="#Basics">The Basics</a></li>
+<li><a href="#Basics">The basics</a></li>
 <ol>
   <li><a href="#Declaring">Declaring a service in the manifest</a></li>
 </ol>
-<li><a href="#CreatingAService">Creating a Started Service</a>
+<li><a href="#CreatingAService">Creating a started service</a>
   <ol>
     <li><a href="#ExtendingIntentService">Extending the IntentService class</a></li>
     <li><a href="#ExtendingService">Extending the Service class</a></li>
@@ -17,10 +17,10 @@
     <li><a href="#Stopping">Stopping a service</a></li>
   </ol>
 </li>
-<li><a href="#CreatingBoundService">Creating a Bound Service</a></li>
-<li><a href="#Notifications">Sending Notifications to the User</a></li>
-<li><a href="#Foreground">Running a Service in the Foreground</a></li>
-<li><a href="#Lifecycle">Managing the Lifecycle of a Service</a>
+<li><a href="#CreatingBoundService">Creating a bound service</a></li>
+<li><a href="#Notifications">Sending notifications to the user</a></li>
+<li><a href="#Foreground">Running a service in the foreground</a></li>
+<li><a href="#Lifecycle">Managing the lifecycle of a service</a>
 <ol>
   <li><a href="#LifecycleCallbacks">Implementing the lifecycle callbacks</a></li>
 </ol>
@@ -48,70 +48,80 @@
 
 </div>
 
-
 <p>A {@link android.app.Service} is an application component that can perform
-long-running operations in the background and does not provide a user interface. Another
-application component can start a service and it will continue to run in the background even if the
+long-running operations in the background, and it does not provide a user interface. Another
+application component can start a service, and it continues to run in the background even if the
 user switches to another application. Additionally, a component can bind to a service to
-interact with it and even perform interprocess communication (IPC). For example, a service might
+interact with it and even perform interprocess communication (IPC). For example, a service can
 handle network transactions, play music, perform file I/O, or interact with a content provider, all
 from the background.</p>
 
-<p>A service can essentially take two forms:</p>
+<p>These are the three different types of services:</p>
 
 <dl>
+  <dt>Scheduled</dt>
+  <dd>A service is <em>scheduled</em> when an API such as the {@link android.app.job.JobScheduler},
+  introduced in Android 5.0 (API level 21), launches the service. You can use the
+  {@link android.app.job.JobScheduler} by registering jobs and specifying their requirements for
+  network and timing. The system then gracefully schedules the jobs for execution at the
+  appropriate times. The {@link android.app.job.JobScheduler} provides many methods to define
+  service-execution conditions.
+    <p class="note"><strong>Note:</strong> If your app targets Android 5.0 (API level 21), Google
+    recommends that you use the {@link android.app.job.JobScheduler} to execute background
+    services. For more information about using this class, see the
+    {@link android.app.job.JobScheduler} reference documentation.</p></dd>
   <dt>Started</dt>
-  <dd>A service is "started" when an application component (such as an activity) starts it by
-calling {@link android.content.Context#startService startService()}. Once started, a service
-can run in the background indefinitely, even if the component that started it is destroyed. Usually,
-a started service performs a single operation and does not return a result to the caller.
-For example, it might download or upload a file over the network. When the operation is done, the
-service should stop itself.</dd>
+  <dd>A service is <em>started</em> when an application component (such as an activity)
+  calls {@link android.content.Context#startService startService()}. After it's started, a
+  service can run in the background indefinitely, even if the component that started it is
+  destroyed. Usually, a started service performs a single operation and does not return a result to
+  the caller. For example, it can download or upload a file over the network. When the operation is
+  complete, the service should stop itself.</dd>
   <dt>Bound</dt>
-  <dd>A service is "bound" when an application component binds to it by calling {@link
-android.content.Context#bindService bindService()}. A bound service offers a client-server
-interface that allows components to interact with the service, send requests, get results, and even
-do so across processes with interprocess communication (IPC). A bound service runs only as long as
-another application component is bound to it. Multiple components can bind to the service at once,
-but when all of them unbind, the service is destroyed.</dd>
+  <dd>A service is <em>bound</em> when an application component binds to it by calling {@link
+  android.content.Context#bindService bindService()}. A bound service offers a client-server
+  interface that allows components to interact with the service, send requests, receive results,
+  and even do so across processes with interprocess communication (IPC). A bound service runs only
+  as long as another application component is bound to it. Multiple components can bind to the
+  service at once, but when all of them unbind, the service is destroyed.</dd>
 </dl>
 
-<p>Although this documentation generally discusses these two types of services separately, your
-service can work both ways&mdash;it can be started (to run indefinitely) and also allow binding.
-It's simply a matter of whether you implement a couple callback methods: {@link
+<p>Although this documentation generally discusses started and bound services separately,
+your service can work both ways&mdash;it can be started (to run indefinitely) and also allow
+binding. It's simply a matter of whether you implement a couple of callback methods: {@link
 android.app.Service#onStartCommand onStartCommand()} to allow components to start it and {@link
 android.app.Service#onBind onBind()} to allow binding.</p>
 
 <p>Regardless of whether your application is started, bound, or both, any application component
-can use the service (even from a separate application), in the same way that any component can use
+can use the service (even from a separate application) in the same way that any component can use
 an activity&mdash;by starting it with an {@link android.content.Intent}. However, you can declare
-the service as private, in the manifest file, and block access from other applications. This is
-discussed more in the section about <a href="#Declaring">Declaring the service in the
+the service as <em>private</em> in the manifest file and block access from other applications.
+This is discussed more in the section about <a href="#Declaring">Declaring the service in the
 manifest</a>.</p>
 
 <p class="caution"><strong>Caution:</strong> A service runs in the
-main thread of its hosting process&mdash;the service does <strong>not</strong> create its own thread
-and does <strong>not</strong> run in a separate process (unless you specify otherwise). This means
-that, if your service is going to do any CPU intensive work or blocking operations (such as MP3
-playback or networking), you should create a new thread within the service to do that work. By using
-a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the
-application's main thread can remain dedicated to user interaction with your activities.</p>
+main thread of its hosting process; the service does <strong>not</strong> create its own
+thread and does <strong>not</strong> run in a separate process unless you specify otherwise. If
+your service is going to perform any CPU-intensive work or blocking operations, such as MP3
+playback or networking, you should create a new thread within the service to complete that work.
+By using a separate thread, you can reduce the risk of Application Not Responding (ANR) errors,
+and the application's main thread can remain dedicated to user interaction with your
+activities.</p>
 
-
-<h2 id="Basics">The Basics</h2>
+<h2 id="Basics">The basics</h2>
 
 <div class="sidebox-wrapper">
 <div class="sidebox">
   <h3>Should you use a service or a thread?</h3>
-  <p>A service is simply a component that can run in the background even when the user is not
-interacting with your application. Thus, you should create a service only if that is what you
+  <p>A service is simply a component that can run in the background, even when the user is not
+interacting with your application, so you should create a service only if that is what you
 need.</p>
-  <p>If you need to perform work outside your main thread, but only while the user is interacting
-with your application, then you should probably instead create a new thread and not a service. For
-example, if you want to play some music, but only while your activity is running, you might create
+  <p>If you must perform work outside of your main thread, but only while the user is interacting
+with your application, you should instead create a new thread. For example, if you want to
+play some music, but only while your activity is running, you might create
 a thread in {@link android.app.Activity#onCreate onCreate()}, start running it in {@link
-android.app.Activity#onStart onStart()}, then stop it in {@link android.app.Activity#onStop
-onStop()}. Also consider using {@link android.os.AsyncTask} or {@link android.os.HandlerThread},
+android.app.Activity#onStart onStart()}, and stop it in {@link android.app.Activity#onStop
+onStop()}. Also consider using {@link android.os.AsyncTask} or {@link android.os.HandlerThread}
 instead of the traditional {@link java.lang.Thread} class. See the <a
 href="{@docRoot}guide/components/processes-and-threads.html#Threads">Processes and
 Threading</a> document for more information about threads.</p>
@@ -121,78 +131,81 @@
 </div>
 </div>
 
-<p>To create a service, you must create a subclass of {@link android.app.Service} (or one
-of its existing subclasses). In your implementation, you need to override some callback methods that
-handle key aspects of the service lifecycle and provide a mechanism for components to bind to
-the service, if appropriate. The most important callback methods you should override are:</p>
+<p>To create a service, you must create a subclass of {@link android.app.Service} or use one
+of its existing subclasses. In your implementation, you must override some callback methods that
+handle key aspects of the service lifecycle and provide a mechanism that allows the components to
+bind to the service, if appropriate. These are the most important callback methods that you should
+override:</p>
 
 <dl>
   <dt>{@link android.app.Service#onStartCommand onStartCommand()}</dt>
-    <dd>The system calls this method when another component, such as an activity,
-requests that the service be started, by calling {@link android.content.Context#startService
-startService()}. Once this method executes, the service is started and can run in the
+    <dd>The system invokes this method by calling {@link android.content.Context#startService
+startService()} when another component (such as an activity) requests that the service be started.
+When this method executes, the service is started and can run in the
 background indefinitely. If you implement this, it is your responsibility to stop the service when
-its work is done, by calling {@link android.app.Service#stopSelf stopSelf()} or {@link
-android.content.Context#stopService stopService()}. (If you only want to provide binding, you don't
-need to implement this method.)</dd>
+its work is complete by calling {@link android.app.Service#stopSelf stopSelf()} or {@link
+android.content.Context#stopService stopService()}. If you only want to provide binding, you don't
+need to implement this method.</dd>
   <dt>{@link android.app.Service#onBind onBind()}</dt>
-    <dd>The system calls this method when another component wants to bind with the
-service (such as to perform RPC), by calling {@link android.content.Context#bindService
-bindService()}. In your implementation of this method, you must provide an interface that clients
-use to communicate with the service, by returning an {@link android.os.IBinder}. You must always
-implement this method, but if you don't want to allow binding, then you should return null.</dd>
+    <dd>The system invokes this method by calling {@link android.content.Context#bindService
+bindService()} when another component wants to bind with the service (such as to perform RPC).
+In your implementation of this method, you must provide an interface that clients
+use to communicate with the service by returning an {@link android.os.IBinder}. You must always
+implement this method; however, if you don't want to allow binding, you should return
+null.</dd>
   <dt>{@link android.app.Service#onCreate()}</dt>
-    <dd>The system calls this method when the service is first created, to perform one-time setup
-procedures (before it calls either {@link android.app.Service#onStartCommand onStartCommand()} or
+    <dd>The system invokes this method to perform one-time setup procedures when the service is
+initially created (before it calls either
+{@link android.app.Service#onStartCommand onStartCommand()} or
 {@link android.app.Service#onBind onBind()}). If the service is already running, this method is not
 called.</dd>
   <dt>{@link android.app.Service#onDestroy()}</dt>
-    <dd>The system calls this method when the service is no longer used and is being destroyed.
+    <dd>The system invokes this method when the service is no longer used and is being destroyed.
 Your service should implement this to clean up any resources such as threads, registered
-listeners, receivers, etc. This is the last call the service receives.</dd>
+listeners, or receivers. This is the last call that the service receives.</dd>
 </dl>
 
 <p>If a component starts the service by calling {@link
 android.content.Context#startService startService()} (which results in a call to {@link
-android.app.Service#onStartCommand onStartCommand()}), then the service
-remains running until it stops itself with {@link android.app.Service#stopSelf()} or another
+android.app.Service#onStartCommand onStartCommand()}), the service
+continues to run until it stops itself with {@link android.app.Service#stopSelf()} or another
 component stops it by calling {@link android.content.Context#stopService stopService()}.</p>
 
 <p>If a component calls
-{@link android.content.Context#bindService bindService()} to create the service (and {@link
-android.app.Service#onStartCommand onStartCommand()} is <em>not</em> called), then the service runs
-only as long as the component is bound to it. Once the service is unbound from all clients, the
-system destroys it.</p>
+{@link android.content.Context#bindService bindService()} to create the service and {@link
+android.app.Service#onStartCommand onStartCommand()} is <em>not</em> called, the service runs
+only as long as the component is bound to it. After the service is unbound from all of its clients,
+the system destroys it.</p>
 
-<p>The Android system will force-stop a service only when memory is low and it must recover system
+<p>The Android system force-stops a service only when memory is low and it must recover system
 resources for the activity that has user focus. If the service is bound to an activity that has user
-focus, then it's less likely to be killed, and if the service is declared to <a
-href="#Foreground">run in the foreground</a> (discussed later), then it will almost never be killed.
-Otherwise, if the service was started and is long-running, then the system will lower its position
-in the list of background tasks over time and the service will become highly susceptible to
-killing&mdash;if your service is started, then you must design it to gracefully handle restarts
+focus, it's less likely to be killed; if the service is declared to <a
+href="#Foreground">run in the foreground</a>, it's rarely killed.
+If the service is started and is long-running, the system lowers its position
+in the list of background tasks over time, and the service becomes highly susceptible to
+killing&mdash;if your service is started, you must design it to gracefully handle restarts
 by the system. If the system kills your service, it restarts it as soon as resources become
-available again (though this also depends on the value you return from {@link
-android.app.Service#onStartCommand onStartCommand()}, as discussed later). For more information
+available, but this also depends on the value that you return from {@link
+android.app.Service#onStartCommand onStartCommand()}. For more information
 about when the system might destroy a service, see the <a
 href="{@docRoot}guide/components/processes-and-threads.html">Processes and Threading</a>
 document.</p>
 
-<p>In the following sections, you'll see how you can create each type of service and how to use
-it from other application components.</p>
-
-
+<p>In the following sections, you'll see how you can create the
+{@link android.content.Context#startService startService()} and
+{@link android.content.Context#bindService bindService()} service methods, as well as how to use
+them from other application components.</p>
 
 <h3 id="Declaring">Declaring a service in the manifest</h3>
 
-<p>Like activities (and other components), you must declare all services in your application's
-manifest file.</p>
+<p>You must declare all services in your application's
+manifest file, just as you do for activities and other components.</p>
 
 <p>To declare your service, add a <a
-href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> element
+href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> element
 as a child of the <a
-href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>
-element. For example:</p>
+href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+element. Here is an example:</p>
 
 <pre>
 &lt;manifest ... &gt;
@@ -205,48 +218,44 @@
 </pre>
 
 <p>See the <a
-href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> element
+href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> element
 reference for more information about declaring your service in the manifest.</p>
 
-<p>There are other attributes you can include in the <a
-href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> element to
-define properties such as permissions required to start the service and the process in
+<p>There are other attributes that you can include in the <a
+href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> element to
+define properties such as the permissions that are required to start the service and the process in
 which the service should run. The <a
 href="{@docRoot}guide/topics/manifest/service-element.html#nm">{@code android:name}</a>
-attribute is the only required attribute&mdash;it specifies the class name of the service. Once
-you publish your application, you should not change this name, because if you do, you risk breaking
+attribute is the only required attribute&mdash;it specifies the class name of the service. After
+you publish your application, leave this name unchanged to avoid the risk of breaking
 code due to dependence on explicit intents to start or bind the service (read the blog post, <a
 href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">Things
 That Cannot Change</a>).
 
-<p>To ensure your app is secure, <strong>always use an explicit intent when starting or binding
-your {@link android.app.Service}</strong> and do not declare intent filters for the service. If
-it's critical that you allow for some amount of ambiguity as to which service starts, you can
-supply intent filters for your services and exclude the component name from the {@link
-android.content.Intent}, but you then must set the package for the intent with {@link
-android.content.Intent#setPackage setPackage()}, which provides sufficient disambiguation for the
-target service.</p>
+<p class="caution"><strong>Caution</strong>: To ensure that your app is secure, always use an
+explicit intent when starting a {@link android.app.Service} and do not declare intent filters for
+your services. Using an implicit intent to start a service is a security hazard because you cannot
+be certain of the service that will respond to the intent, and the user cannot see which service
+starts. Beginning with Android 5.0 (API level 21), the system throws an exception if you call
+{@link android.content.Context#bindService bindService()} with an implicit intent.</p>
 
-<p>Additionally, you can ensure that your service is available to only your app by
+<p>You can ensure that your service is available to only your app by
 including the <a
 href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code android:exported}</a>
-attribute and setting it to {@code "false"}. This effectively stops other apps from starting your
+attribute and setting it to {@code false}. This effectively stops other apps from starting your
 service, even when using an explicit intent.</p>
 
-
-
-
-<h2 id="CreatingStartedService">Creating a Started Service</h2>
+<h2 id="CreatingStartedService">Creating a started service</h2>
 
 <p>A started service is one that another component starts by calling {@link
-android.content.Context#startService startService()}, resulting in a call to the service's
+android.content.Context#startService startService()}, which results in a call to the service's
 {@link android.app.Service#onStartCommand onStartCommand()} method.</p>
 
 <p>When a service is started, it has a lifecycle that's independent of the
-component that started it and the service can run in the background indefinitely, even if
+component that started it. The service can run in the background indefinitely, even if
 the component that started it is destroyed. As such, the service should stop itself when its job
-is done by calling {@link android.app.Service#stopSelf stopSelf()}, or another component can stop it
-by calling {@link android.content.Context#stopService stopService()}.</p>
+is complete by calling {@link android.app.Service#stopSelf stopSelf()}, or another component can
+stop it by calling {@link android.content.Context#stopService stopService()}.</p>
 
 <p>An application component such as an activity can start the service by calling {@link
 android.content.Context#startService startService()} and passing an {@link android.content.Intent}
@@ -254,65 +263,65 @@
 this {@link android.content.Intent} in the {@link android.app.Service#onStartCommand
 onStartCommand()} method.</p>
 
-<p>For instance, suppose an activity needs to save some data to an online database. The activity can
-start a companion service and deliver it the data to save by passing an intent to {@link
+<p>For instance, suppose an activity needs to save some data to an online database. The activity
+can start a companion service and deliver it the data to save by passing an intent to {@link
 android.content.Context#startService startService()}. The service receives the intent in {@link
-android.app.Service#onStartCommand onStartCommand()}, connects to the Internet and performs the
-database transaction. When the transaction is done, the service stops itself and it is
+android.app.Service#onStartCommand onStartCommand()}, connects to the Internet, and performs the
+database transaction. When the transaction is complete, the service stops itself and is
 destroyed.</p>
 
 <p class="caution"><strong>Caution:</strong> A service runs in the same process as the application
-in which it is declared and in the main thread of that application, by default. So, if your service
+in which it is declared and in the main thread of that application by default. If your service
 performs intensive or blocking operations while the user interacts with an activity from the same
-application, the service will slow down activity performance. To avoid impacting application
-performance, you should start a new thread inside the service.</p>
+application, the service slows down activity performance. To avoid impacting application
+performance, start a new thread inside the service.</p>
 
 <p>Traditionally, there are two classes you can extend to create a started service:</p>
+
 <dl>
   <dt>{@link android.app.Service}</dt>
-  <dd>This is the base class for all services. When you extend this class, it's important that
-you create a new thread in which to do all the service's work, because the service uses your
-application's main thread, by default, which could slow the performance of any activity your
+  <dd>This is the base class for all services. When you extend this class, it's important to
+create a new thread in which the service can complete all of its work; the service uses your
+application's main thread by default, which can slow the performance of any activity that your
 application is running.</dd>
   <dt>{@link android.app.IntentService}</dt>
-  <dd>This is a subclass of {@link android.app.Service} that uses a worker thread to handle all
-start requests, one at a time. This is the best option if you don't require that your service
-handle multiple requests simultaneously. All you need to do is implement {@link
+  <dd>This is a subclass of {@link android.app.Service} that uses a worker thread to handle all of
+the start requests, one at a time. This is the best option if you don't require that your service
+handle multiple requests simultaneously. Implement {@link
 android.app.IntentService#onHandleIntent onHandleIntent()}, which receives the intent for each
-start request so you can do the background work.</dd>
+start request so that you can complete the background work.</dd>
 </dl>
 
 <p>The following sections describe how you can implement your service using either one for these
 classes.</p>
 
-
 <h3 id="ExtendingIntentService">Extending the IntentService class</h3>
 
-<p>Because most started services don't need to handle multiple requests simultaneously
-(which can actually be a dangerous multi-threading scenario), it's probably best if you
+<p>Because most of the started services don't need to handle multiple requests simultaneously
+(which can actually be a dangerous multi-threading scenario), it's best that you
 implement your service using the {@link android.app.IntentService} class.</p>
 
-<p>The {@link android.app.IntentService} does the following:</p>
+<p>The {@link android.app.IntentService} class does the following:</p>
 
 <ul>
-  <li>Creates a default worker thread that executes all intents delivered to {@link
-android.app.Service#onStartCommand onStartCommand()} separate from your application's main
+  <li>It creates a default worker thread that executes all of the intents that are delivered to
+{@link android.app.Service#onStartCommand onStartCommand()}, separate from your application's main
 thread.</li>
   <li>Creates a work queue that passes one intent at a time to your {@link
 android.app.IntentService#onHandleIntent onHandleIntent()} implementation, so you never have to
 worry about multi-threading.</li>
-  <li>Stops the service after all start requests have been handled, so you never have to call
+  <li>Stops the service after all of the start requests are handled, so you never have to call
 {@link android.app.Service#stopSelf}.</li>
-  <li>Provides default implementation of {@link android.app.IntentService#onBind onBind()} that
-returns null.</li>
+  <li>Provides a default implementation of {@link android.app.IntentService#onBind onBind()}
+  that returns null.</li>
   <li>Provides a default implementation of {@link android.app.IntentService#onStartCommand
 onStartCommand()} that sends the intent to the work queue and then to your {@link
 android.app.IntentService#onHandleIntent onHandleIntent()} implementation.</li>
 </ul>
 
-<p>All this adds up to the fact that all you need to do is implement {@link
-android.app.IntentService#onHandleIntent onHandleIntent()} to do the work provided by the
-client. (Though, you also need to provide a small constructor for the service.)</p>
+<p>To complete the work that is provided by the client, implement {@link
+android.app.IntentService#onHandleIntent onHandleIntent()}.
+However, you also need to provide a small constructor for the service.</p>
 
 <p>Here's an example implementation of {@link android.app.IntentService}:</p>
 
@@ -352,12 +361,12 @@
 <p>If you decide to also override other callback methods, such as {@link
 android.app.IntentService#onCreate onCreate()}, {@link
 android.app.IntentService#onStartCommand onStartCommand()}, or {@link
-android.app.IntentService#onDestroy onDestroy()}, be sure to call the super implementation, so
+android.app.IntentService#onDestroy onDestroy()}, be sure to call the super implementation so
 that the {@link android.app.IntentService} can properly handle the life of the worker thread.</p>
 
 <p>For example, {@link android.app.IntentService#onStartCommand onStartCommand()} must return
-the default implementation (which is how the intent gets delivered to {@link
-android.app.IntentService#onHandleIntent onHandleIntent()}):</p>
+the default implementation, which is how the intent is delivered to {@link
+android.app.IntentService#onHandleIntent onHandleIntent()}:</p>
 
 <pre>
 &#64;Override
@@ -369,22 +378,21 @@
 
 <p>Besides {@link android.app.IntentService#onHandleIntent onHandleIntent()}, the only method
 from which you don't need to call the super class is {@link android.app.IntentService#onBind
-onBind()} (but you only need to implement that if your service allows binding).</p>
+onBind()}. You need to implement this only if your service allows binding.</p>
 
 <p>In the next section, you'll see how the same kind of service is implemented when extending
-the base {@link android.app.Service} class, which is a lot more code, but which might be
+the base {@link android.app.Service} class, which uses more code, but might be
 appropriate if you need to handle simultaneous start requests.</p>
 
-
 <h3 id="ExtendingService">Extending the Service class</h3>
 
-<p>As you saw in the previous section, using {@link android.app.IntentService} makes your
+<p>Using {@link android.app.IntentService} makes your
 implementation of a started service very simple. If, however, you require your service to
-perform multi-threading (instead of processing start requests through a work queue), then you
+perform multi-threading (instead of processing start requests through a work queue), you
 can extend the {@link android.app.Service} class to handle each intent.</p>
 
-<p>For comparison, the following example code is an implementation of the {@link
-android.app.Service} class that performs the exact same work as the example above using {@link
+<p>For comparison, the following example code shows an implementation of the {@link
+android.app.Service} class that performs the same work as the previous example using {@link
 android.app.IntentService}. That is, for each start request, it uses a worker thread to perform the
 job and processes only one request at a time.</p>
 
@@ -460,20 +468,20 @@
 
 <p>However, because you handle each call to {@link android.app.Service#onStartCommand
 onStartCommand()} yourself, you can perform multiple requests simultaneously. That's not what
-this example does, but if that's what you want, then you can create a new thread for each
-request and run them right away (instead of waiting for the previous request to finish).</p>
+this example does, but if that's what you want, you can create a new thread for each
+request and run them right away instead of waiting for the previous request to finish.</p>
 
 <p>Notice that the {@link android.app.Service#onStartCommand onStartCommand()} method must return an
 integer. The integer is a value that describes how the system should continue the service in the
-event that the system kills it (as discussed above, the default implementation for {@link
-android.app.IntentService} handles this for you, though you are able to modify it). The return value
+event that the system kills it. The default implementation for {@link
+android.app.IntentService} handles this for you, but you are able to modify it. The return value
 from {@link android.app.Service#onStartCommand onStartCommand()} must be one of the following
 constants:</p>
 
 <dl>
   <dt>{@link android.app.Service#START_NOT_STICKY}</dt>
     <dd>If the system kills the service after {@link android.app.Service#onStartCommand
-onStartCommand()} returns, <em>do not</em> recreate the service, unless there are pending
+onStartCommand()} returns, <em>do not</em> recreate the service unless there are pending
 intents to deliver. This is the safest option to avoid running your service when not necessary
 and when your application can simply restart any unfinished jobs.</dd>
   <dt>{@link android.app.Service#START_STICKY}</dt>
@@ -481,9 +489,9 @@
 onStartCommand()} returns, recreate the service and call {@link
 android.app.Service#onStartCommand onStartCommand()}, but <em>do not</em> redeliver the last intent.
 Instead, the system calls {@link android.app.Service#onStartCommand onStartCommand()} with a
-null intent, unless there were pending intents to start the service, in which case,
+null intent unless there are pending intents to start the service. In that case,
 those intents are delivered. This is suitable for media players (or similar services) that are not
-executing commands, but running indefinitely and waiting for a job.</dd>
+executing commands but are running indefinitely and waiting for a job.</dd>
   <dt>{@link android.app.Service#START_REDELIVER_INTENT}</dt>
     <dd>If the system kills the service after {@link android.app.Service#onStartCommand
 onStartCommand()} returns, recreate the service and call {@link
@@ -494,35 +502,35 @@
 <p>For more details about these return values, see the linked reference documentation for each
 constant.</p>
 
-
-
-<h3 id="StartingAService">Starting a Service</h3>
+<h3 id="StartingAService">Starting a service</h3>
 
 <p>You can start a service from an activity or other application component by passing an
 {@link android.content.Intent} (specifying the service to start) to {@link
 android.content.Context#startService startService()}. The Android system calls the service's {@link
 android.app.Service#onStartCommand onStartCommand()} method and passes it the {@link
-android.content.Intent}. (You should never call {@link android.app.Service#onStartCommand
-onStartCommand()} directly.)</p>
+android.content.Intent}.
+
+<p class="note"><strong>Note</strong>: Never call
+{@link android.app.Service#onStartCommand onStartCommand()} directly.</p>
 
 <p>For example, an activity can start the example service in the previous section ({@code
 HelloService}) using an explicit intent with {@link android.content.Context#startService
-startService()}:</p>
+startService()}, as shown here:</p>
 
 <pre>
 Intent intent = new Intent(this, HelloService.class);
 startService(intent);
 </pre>
 
-<p>The {@link android.content.Context#startService startService()} method returns immediately and
+<p>The {@link android.content.Context#startService startService()} method returns immediately, and
 the Android system calls the service's {@link android.app.Service#onStartCommand
 onStartCommand()} method. If the service is not already running, the system first calls {@link
-android.app.Service#onCreate onCreate()}, then calls {@link android.app.Service#onStartCommand
-onStartCommand()}.</p>
+android.app.Service#onCreate onCreate()}, and then it calls
+{@link android.app.Service#onStartCommand onStartCommand()}.</p>
 
-<p>If the service does not also provide binding, the intent delivered with {@link
+<p>If the service does not also provide binding, the intent that is delivered with {@link
 android.content.Context#startService startService()} is the only mode of communication between the
-application component and the service. However, if you want the service to send a result back, then
+application component and the service. However, if you want the service to send a result back,
 the client that starts the service can create a {@link android.app.PendingIntent} for a broadcast
 (with {@link android.app.PendingIntent#getBroadcast getBroadcast()}) and deliver it to the service
 in the {@link android.content.Intent} that starts the service. The service can then use the
@@ -533,109 +541,102 @@
 the service (with {@link android.app.Service#stopSelf stopSelf()} or {@link
 android.content.Context#stopService stopService()}) is required to stop it.</p>
 
-
 <h3 id="Stopping">Stopping a service</h3>
 
 <p>A started service must manage its own lifecycle. That is, the system does not stop or
 destroy the service unless it must recover system memory and the service
-continues to run after {@link android.app.Service#onStartCommand onStartCommand()} returns. So,
-the service must stop itself by calling {@link android.app.Service#stopSelf stopSelf()} or another
+continues to run after {@link android.app.Service#onStartCommand onStartCommand()} returns. The
+service must stop itself by calling {@link android.app.Service#stopSelf stopSelf()}, or another
 component can stop it by calling {@link android.content.Context#stopService stopService()}.</p>
 
 <p>Once requested to stop with {@link android.app.Service#stopSelf stopSelf()} or {@link
 android.content.Context#stopService stopService()}, the system destroys the service as soon as
 possible.</p>
 
-<p>However, if your service handles multiple requests to {@link
-android.app.Service#onStartCommand onStartCommand()} concurrently, then you shouldn't stop the
-service when you're done processing a start request, because you might have since received a new
+<p>If your service handles multiple requests to {@link
+android.app.Service#onStartCommand onStartCommand()} concurrently, you shouldn't stop the
+service when you're done processing a start request, as you might have received a new
 start request (stopping at the end of the first request would terminate the second one). To avoid
 this problem, you can use {@link android.app.Service#stopSelf(int)} to ensure that your request to
 stop the service is always based on the most recent start request. That is, when you call {@link
 android.app.Service#stopSelf(int)}, you pass the ID of the start request (the <code>startId</code>
 delivered to {@link android.app.Service#onStartCommand onStartCommand()}) to which your stop request
-corresponds. Then if the service received a new start request before you were able to call {@link
-android.app.Service#stopSelf(int)}, then the ID will not match and the service will not stop.</p>
+corresponds. Then, if the service receives a new start request before you are able to call {@link
+android.app.Service#stopSelf(int)}, the ID does not match and the service does not stop.</p>
 
-<p class="caution"><strong>Caution:</strong> It's important that your application stops its services
-when it's done working, to avoid wasting system resources and consuming battery power. If necessary,
-other components can stop the service by calling {@link
+<p class="caution"><strong>Caution:</strong> To avoid wasting system resources and consuming
+battery power, ensure that your application stops its services when it's done working.
+If necessary, other components can stop the service by calling {@link
 android.content.Context#stopService stopService()}. Even if you enable binding for the service,
-you must always stop the service yourself if it ever received a call to {@link
+you must always stop the service yourself if it ever receives a call to {@link
 android.app.Service#onStartCommand onStartCommand()}.</p>
 
 <p>For more information about the lifecycle of a service, see the section below about <a
 href="#Lifecycle">Managing the Lifecycle of a Service</a>.</p>
 
-
-
-<h2 id="CreatingBoundService">Creating a Bound Service</h2>
+<h2 id="CreatingBoundService">Creating a bound service</h2>
 
 <p>A bound service is one that allows application components to bind to it by calling {@link
-android.content.Context#bindService bindService()} in order to create a long-standing connection
-(and generally does not allow components to <em>start</em> it by calling {@link
-android.content.Context#startService startService()}).</p>
+android.content.Context#bindService bindService()} to create a long-standing connection.
+It generally doesn't allow components to <em>start</em> it by calling {@link
+android.content.Context#startService startService()}.</p>
 
-<p>You should create a bound service when you want to interact with the service from activities
+<p>Create a bound service when you want to interact with the service from activities
 and other components in your application or to expose some of your application's functionality to
-other applications, through interprocess communication (IPC).</p>
+other applications through interprocess communication (IPC).</p>
 
-<p>To create a bound service, you must implement the {@link
+<p>To create a bound service, implement the {@link
 android.app.Service#onBind onBind()} callback method to return an {@link android.os.IBinder} that
 defines the interface for communication with the service. Other application components can then call
 {@link android.content.Context#bindService bindService()} to retrieve the interface and
 begin calling methods on the service. The service lives only to serve the application component that
-is bound to it, so when there are no components bound to the service, the system destroys it
-(you do <em>not</em> need to stop a bound service in the way you must when the service is started
-through {@link android.app.Service#onStartCommand onStartCommand()}).</p>
+is bound to it, so when there are no components bound to the service, the system destroys it.
+You do <em>not</em> need to stop a bound service in the same way that you must when the service is
+started through {@link android.app.Service#onStartCommand onStartCommand()}.</p>
 
-<p>To create a bound service, the first thing you must do is define the interface that specifies
-how a client can communicate with the service. This interface between the service
+<p>To create a bound service, you must define the interface that specifies how a client can
+communicate with the service. This interface between the service
 and a client must be an implementation of {@link android.os.IBinder} and is what your service must
 return from the {@link android.app.Service#onBind
-onBind()} callback method. Once the client receives the {@link android.os.IBinder}, it can begin
+onBind()} callback method. After the client receives the {@link android.os.IBinder}, it can begin
 interacting with the service through that interface.</p>
 
-<p>Multiple clients can bind to the service at once. When a client is done interacting with the
-service, it calls {@link android.content.Context#unbindService unbindService()} to unbind. Once
-there are no clients bound to the service, the system destroys the service.</p>
+<p>Multiple clients can bind to the service simultaneously. When a client is done interacting with
+the service, it calls {@link android.content.Context#unbindService unbindService()} to unbind.
+When there are no clients bound to the service, the system destroys the service.</p>
 
-<p>There are multiple ways to implement a bound service and the implementation is more
-complicated than a started service, so the bound service discussion appears in a separate
-document about <a
+<p>There are multiple ways to implement a bound service, and the implementation is more
+complicated than a started service. For these reasons, the bound service discussion appears in a
+separate document about <a
 href="{@docRoot}guide/components/bound-services.html">Bound Services</a>.</p>
 
+<h2 id="Notifications">Sending notifications to the user</h2>
 
-
-<h2 id="Notifications">Sending Notifications to the User</h2>
-
-<p>Once running, a service can notify the user of events using <a
+<p>When a service is running, it can notify the user of events using <a
 href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Toast Notifications</a> or <a
 href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>.</p>
 
-<p>A toast notification is a message that appears on the surface of the current window for a
-moment then disappears, while a status bar notification provides an icon in the status bar with a
+<p>A toast notification is a message that appears on the surface of the current window for only a
+moment before disappearing. A status bar notification provides an icon in the status bar with a
 message, which the user can select in order to take an action (such as start an activity).</p>
 
-<p>Usually, a status bar notification is the best technique when some background work has completed
-(such as a file completed
-downloading) and the user can now act on it. When the user selects the notification from the
-expanded view, the notification can start an activity (such as to view the downloaded file).</p>
+<p>Usually, a status bar notification is the best technique to use when background work such as
+a file download has completed, and the user can now act on it. When the user
+selects the notification from the expanded view, the notification can start an activity
+(such as to display the downloaded file).</p>
 
 <p>See the <a
 href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Toast Notifications</a> or <a
 href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
 developer guides for more information.</p>
 
+<h2 id="Foreground">Running a service in the foreground</h2>
 
-
-<h2 id="Foreground">Running a Service in the Foreground</h2>
-
-<p>A foreground service is a service that's considered to be something the
-user is actively aware of and thus not a candidate for the system to kill when low on memory. A
+<p>A foreground service is a service that the
+user is actively aware of and is not a candidate for the system to kill when low on memory. A
 foreground service must provide a notification for the status bar, which is placed under the
-"Ongoing" heading, which means that the notification cannot be dismissed unless the service is
-either stopped or removed from the foreground.</p>
+<em>Ongoing</em> heading. This means that the notification cannot be dismissed unless the service
+is either stopped or removed from the foreground.</p>
 
 <p>For example, a music player that plays music from a service should be set to run in the
 foreground, because the user is explicitly aware
@@ -643,9 +644,9 @@
 the user to launch an activity to interact with the music player.</p>
 
 <p>To request that your service run in the foreground, call {@link
-android.app.Service#startForeground startForeground()}. This method takes two parameters: an integer
-that uniquely identifies the notification and the {@link
-android.app.Notification} for the status bar. For example:</p>
+android.app.Service#startForeground startForeground()}. This method takes two parameters: an
+integer that uniquely identifies the notification and the {@link
+android.app.Notification} for the status bar. Here is an example:</p>
 
 <pre>
 Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
@@ -657,30 +658,27 @@
 startForeground(ONGOING_NOTIFICATION_ID, notification);
 </pre>
 
-<p class="caution"><strong>Caution:</strong> The integer ID you give to {@link
+<p class="caution"><strong>Caution:</strong> The integer ID that you give to {@link
 android.app.Service#startForeground startForeground()} must not be 0.</p>
 
-
 <p>To remove the service from the foreground, call {@link
-android.app.Service#stopForeground stopForeground()}. This method takes a boolean, indicating
+android.app.Service#stopForeground stopForeground()}. This method takes a boolean, which indicates
 whether to remove the status bar notification as well. This method does <em>not</em> stop the
-service. However, if you stop the service while it's still running in the foreground, then the
+service. However, if you stop the service while it's still running in the foreground, the
 notification is also removed.</p>
 
 <p>For more information about notifications, see <a
 href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status Bar
 Notifications</a>.</p>
 
+<h2 id="Lifecycle">Managing the lifecycle of a service</h2>
 
+<p>The lifecycle of a service is much simpler than that of an activity. However, it's even more
+important that you pay close attention to how your service is created and destroyed because a
+service can run in the background without the user being aware.</p>
 
-<h2 id="Lifecycle">Managing the Lifecycle of a Service</h2>
-
-<p>The lifecycle of a service is much simpler than that of an activity. However, it's even more important
-that you pay close attention to how your service is created and destroyed, because a service
-can run in the background without the user being aware.</p>
-
-<p>The service lifecycle&mdash;from when it's created to when it's destroyed&mdash;can follow two
-different paths:</p>
+<p>The service lifecycle&mdash;from when it's created to when it's destroyed&mdash;can follow
+either of these two paths:</p>
 
 <ul>
 <li>A started service
@@ -689,27 +687,26 @@
 stop itself by calling {@link
 android.app.Service#stopSelf() stopSelf()}. Another component can also stop the
 service by calling {@link android.content.Context#stopService
-stopService()}. When the service is stopped, the system destroys it..</p></li>
+stopService()}. When the service is stopped, the system destroys it.</p></li>
 
 <li>A bound service
   <p>The service is created when another component (a client) calls {@link
 android.content.Context#bindService bindService()}. The client then communicates with the service
 through an {@link android.os.IBinder} interface. The client can close the connection by calling
 {@link android.content.Context#unbindService unbindService()}. Multiple clients can bind to
-the same service and when all of them unbind, the system destroys the service. (The service
-does <em>not</em> need to stop itself.)</p></li>
+the same service and when all of them unbind, the system destroys the service. The service
+does <em>not</em> need to stop itself.</p></li>
 </ul>
 
-<p>These two paths are not entirely separate. That is, you can bind to a service that was already
-started with {@link android.content.Context#startService startService()}. For example, a background
-music service could be started by calling {@link android.content.Context#startService
+<p>These two paths are not entirely separate. You can bind to a service that is already
+started with {@link android.content.Context#startService startService()}. For example, you can
+start a background music service by calling {@link android.content.Context#startService
 startService()} with an {@link android.content.Intent} that identifies the music to play. Later,
 possibly when the user wants to exercise some control over the player or get information about the
 current song, an activity can bind to the service by calling {@link
-android.content.Context#bindService bindService()}. In cases like this, {@link
+android.content.Context#bindService bindService()}. In cases such as this, {@link
 android.content.Context#stopService stopService()} or {@link android.app.Service#stopSelf
-stopSelf()} does not actually stop the service until all clients unbind. </p>
-
+stopSelf()} doesn't actually stop the service until all of the clients unbind.</p>
 
 <h3 id="LifecycleCallbacks">Implementing the lifecycle callbacks</h3>
 
@@ -763,20 +760,30 @@
 startService()} and the diagram on the right shows the lifecycle when the service is created
 with {@link android.content.Context#bindService bindService()}.</p>
 
-<p>By implementing these methods, you can monitor two nested loops of the service's lifecycle: </p>
+<p>Figure 2 illustrates the typical callback methods for a service. Although the figure separates
+services that are created by {@link android.content.Context#startService startService()} from those
+created by {@link android.content.Context#bindService bindService()}, keep
+in mind that any service, no matter how it's started, can potentially allow clients to bind to it.
+A service that was initially started with {@link android.app.Service#onStartCommand
+onStartCommand()} (by a client calling {@link android.content.Context#startService startService()})
+can still receive a call to {@link android.app.Service#onBind onBind()} (when a client calls
+{@link android.content.Context#bindService bindService()}).</p>
+
+<p>By implementing these methods, you can monitor these two nested loops of the service's
+lifecycle:</p>
 
 <ul>
-<li>The <strong>entire lifetime</strong> of a service happens between the time {@link
-android.app.Service#onCreate onCreate()} is called and the time {@link
+<li>The <strong>entire lifetime</strong> of a service occurs between the time that {@link
+android.app.Service#onCreate onCreate()} is called and the time that {@link
 android.app.Service#onDestroy} returns. Like an activity, a service does its initial setup in
 {@link android.app.Service#onCreate onCreate()} and releases all remaining resources in {@link
-android.app.Service#onDestroy onDestroy()}.  For example, a
-music playback service could create the thread where the music will be played in {@link
-android.app.Service#onCreate onCreate()}, then stop the thread in {@link
+android.app.Service#onDestroy onDestroy()}. For example, a
+music playback service can create the thread where the music is played in {@link
+android.app.Service#onCreate onCreate()}, and then it can stop the thread in {@link
 android.app.Service#onDestroy onDestroy()}.
 
-<p>The {@link android.app.Service#onCreate onCreate()} and {@link android.app.Service#onDestroy
-onDestroy()} methods are called for all services, whether
+<p class="note"><strong>Note</strong>: The {@link android.app.Service#onCreate onCreate()}
+and {@link android.app.Service#onDestroy onDestroy()} methods are called for all services, whether
 they're created by {@link android.content.Context#startService startService()} or {@link
 android.content.Context#bindService bindService()}.</p></li>
 
@@ -784,8 +791,8 @@
 android.app.Service#onStartCommand onStartCommand()} or {@link android.app.Service#onBind onBind()}.
 Each method is handed the {@link
 android.content.Intent} that was passed to either {@link android.content.Context#startService
-startService()} or {@link android.content.Context#bindService bindService()}, respectively.
-<p>If the service is started, the active lifetime ends the same time that the entire lifetime
+startService()} or {@link android.content.Context#bindService bindService()}.
+<p>If the service is started, the active lifetime ends at the same time that the entire lifetime
 ends (the service is still active even after {@link android.app.Service#onStartCommand
 onStartCommand()} returns). If the service is bound, the active lifetime ends when {@link
 android.app.Service#onUnbind onUnbind()} returns.</p>
@@ -795,26 +802,16 @@
 <p class="note"><strong>Note:</strong> Although a started service is stopped by a call to
 either {@link android.app.Service#stopSelf stopSelf()} or {@link
 android.content.Context#stopService stopService()}, there is not a respective callback for the
-service (there's no {@code onStop()} callback). So, unless the service is bound to a client,
+service (there's no {@code onStop()} callback). Unless the service is bound to a client,
 the system destroys it when the service is stopped&mdash;{@link
 android.app.Service#onDestroy onDestroy()} is the only callback received.</p>
 
-<p>Figure 2 illustrates the typical callback methods for a service. Although the figure separates
-services that are created by {@link android.content.Context#startService startService()} from those
-created by {@link android.content.Context#bindService bindService()}, keep
-in mind that any service, no matter how it's started, can potentially allow clients to bind to it.
-So, a service that was initially started with {@link android.app.Service#onStartCommand
-onStartCommand()} (by a client calling {@link android.content.Context#startService startService()})
-can still receive a call to {@link android.app.Service#onBind onBind()} (when a client calls
-{@link android.content.Context#bindService bindService()}).</p>
-
 <p>For more information about creating a service that provides binding, see the <a
 href="{@docRoot}guide/components/bound-services.html">Bound Services</a> document,
 which includes more information about the {@link android.app.Service#onRebind onRebind()}
 callback method in the section about <a
-href="{@docRoot}guide/components/bound-services.html#Lifecycle">Managing the Lifecycle of
-a Bound Service</a>.</p>
-
+href="{@docRoot}guide/components/bound-services.html#Lifecycle">Managing the lifecycle of
+a bound service</a>.</p>
 
 <!--
 <h2>Beginner's Path</h2>
diff --git a/docs/html/training/articles/security-tips.jd b/docs/html/training/articles/security-tips.jd
index abf6711..9796d9a 100644
--- a/docs/html/training/articles/security-tips.jd
+++ b/docs/html/training/articles/security-tips.jd
@@ -6,34 +6,32 @@
 <div id="tb">
 <h2>In this document</h2>
 <ol class="nolist">
-  <li><a href="#StoringData">Storing Data</a></li>
-  <li><a href="#Permissions">Using Permissions</a></li>
-  <li><a href="#Networking">Using Networking</a></li>
-  <li><a href="#InputValidation">Performing Input Validation</a></li>
-  <li><a href="#UserData">Handling User Data</a></li>
+  <li><a href="#StoringData">Storing data</a></li>
+  <li><a href="#Permissions">Using permissions</a></li>
+  <li><a href="#Networking">Using networking</a></li>
+  <li><a href="#InputValidation">Performing input validation</a></li>
+  <li><a href="#UserData">Handling user data</a></li>
   <li><a href="#WebView">Using WebView</a></li>
-  <li><a href="#Crypto">Using Cryptography</a></li>
-  <li><a href="#IPC">Using Interprocess Communication</a></li>
-  <li><a href="#DynamicCode">Dynamically Loading Code</a></li>
-  <li><a href="#Dalvik">Security in a Virtual Machine</a></li>
-  <li><a href="#Native">Security in Native Code</a></li>
+  <li><a href="#Crypto">Using cryptography</a></li>
+  <li><a href="#IPC">Using interprocess communication</a></li>
+  <li><a href="#DynamicCode">Dynamically loading code</a></li>
+  <li><a href="#Dalvik">Security in a virtual machine</a></li>
+  <li><a href="#Native">Security in native code</a></li>
 </ol>
 <h2>See also</h2>
 <ul>
 <li><a href="http://source.android.com/tech/security/index.html">Android
-Security Overview</a></li>
+  Security Overview</a></li>
 <li><a href="{@docRoot}guide/topics/security/permissions.html">Permissions</a></li>
 </ul>
 </div></div>
 
 
-<p>Android has security features built
-into the operating system that significantly reduce the frequency and impact of
-application security issues. The system is designed so you can typically build your apps with
-default system and file permissions and avoid difficult decisions about security.</p>
+<p>Android has built-in security features that significantly reduce the frequency and impact of
+application security issues. The system is designed so that you can typically build your apps with
+the default system and file permissions and avoid difficult decisions about security.</p>
 
-<p>Some of the core security features that help you build secure apps
-include:
+<p>The following core security features help you build secure apps:
 <ul>
 <li>The Android Application Sandbox, which isolates your app data and code execution
 from other apps.</li>
@@ -43,47 +41,54 @@
 <li>Technologies like ASLR, NX, ProPolice, safe_iop, OpenBSD dlmalloc, OpenBSD
 calloc, and Linux mmap_min_addr to mitigate risks associated with common memory
 management errors.</li>
-<li>An encrypted filesystem that can be enabled to protect data on lost or
+<li>An encrypted file system that can be enabled to protect data on lost or
 stolen devices.</li>
 <li>User-granted permissions to restrict access to system features and user data.</li>
 <li>Application-defined permissions to control application data on a per-app basis.</li>
 </ul>
 
-<p>Nevertheless, it is important that you be familiar with the Android
+<p>It is important that you be familiar with the Android
 security best practices in this document. Following these practices as general coding habits
-will reduce the likelihood of inadvertently introducing security issues that
+ reduces the likelihood of inadvertently introducing security issues that
 adversely affect your users.</p>
 
 
 
-<h2 id="StoringData">Storing Data</h2>
+<h2 id="StoringData">Storing data</h2>
 
 <p>The most common security concern for an application on Android is whether the data
 that you save on the device is accessible to other apps. There are three fundamental
 ways to save data on the device:</p>
 
+<ul>
+<li>Internal storage.</li>
+<li>External storage.</li>
+<li>Content providers.</li>
+</ul>
+
+The following paragraphs describe the security issues associated with each approach.
+
 <h3 id="InternalStorage">Using internal storage</h3>
 
 <p>By default, files that you create on <a
 href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">internal
-storage</a> are accessible only to your app. This
-protection is implemented by Android and is sufficient for most
-applications.</p>
+storage</a> are accessible only to your app.
+ Android implements this protection, and it's sufficient for most applications.</p>
 
-<p>You should generally avoid using the {@link android.content.Context#MODE_WORLD_WRITEABLE} or
+<p>Generally, avoid the {@link android.content.Context#MODE_WORLD_WRITEABLE} or
 {@link android.content.Context#MODE_WORLD_READABLE} modes for
 <acronym title="Interprocess Communication">IPC</acronym> files because they do not provide
 the ability to limit data access to particular applications, nor do they
-provide any control on data format. If you want to share your data with other
-app processes, you might instead consider using a
+provide any control of data format. If you want to share your data with other
+app processes, instead consider using a
 <a href="{@docRoot}guide/topics/providers/content-providers.html">content provider</a>, which
 offers read and write permissions to other apps and can make
 dynamic permission grants on a case-by-case basis.</p>
 
-<p>To provide additional protection for sensitive data, you might
-choose to encrypt local files using a key that is not directly accessible to the
-application. For example, a key can be placed in a {@link java.security.KeyStore}
-and protected with a user password that is not stored on the device.  While this
+<p>To provide additional protection for sensitive data, you can
+ encrypt local files using a key that is not directly accessible to the
+application. For example, you can place a key in a {@link java.security.KeyStore}
+and protect it with a user password that is not stored on the device.  While this
 does not protect data from a root compromise that can monitor the user
 inputting the password,  it can provide protection for a lost device without <a
 href="http://source.android.com/tech/encryption/index.html">file system
@@ -94,14 +99,14 @@
 
 <p>Files created on <a
 href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">external
-storage</a>, such as SD Cards, are globally readable and writable.  Because
+storage</a>, such as SD cards, are globally readable and writable. Because
 external storage can be removed by the user and also modified by any
-application,  you should not store sensitive information using
+application, don't store sensitive information using
 external storage.</p>
 
-<p>As with data from any untrusted source, you should <a href="#InputValidation">perform input
-validation</a> when handling data from external storage.
-We strongly recommend that you not store executables or
+<p>You should <a href="#InputValidation">Perform input validation</a> when handling
+data from external storage as you would with data from any untrusted source.
+You should not store executables or
 class files on external storage prior to dynamic loading.  If your app
 does retrieve executable files from external storage, the files should be signed and
 cryptographically verified prior to dynamic loading.</p>
@@ -117,22 +122,22 @@
 href="{@docRoot}guide/topics/manifest/provider-element.html#exported">
 android:exported=false</a></code> in the application manifest. Otherwise, set the <code><a
 href="{@docRoot}guide/topics/manifest/provider-element.html#exported">android:exported</a></code>
-attribute {@code "true"} to allow other apps to access the stored data.
+attribute to {@code true} to allow other apps to access the stored data.
 </p>
 
 <p>When creating a {@link android.content.ContentProvider}
-that will be exported for use by other applications, you can specify a single
+that is exported for use by other applications, you can specify a single
 <a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">permission
-</a> for reading and writing, or distinct permissions for reading and writing
-within the manifest. We recommend that you limit your permissions to those
+</a> for reading and writing, or you can specify distinct permissions for reading and writing.
+You should limit your permissions to those
 required to accomplish the task at hand. Keep in mind that it’s usually
 easier to add permissions later to expose new functionality than it is to take
-them away and break existing users.</p>
+them away and impact existing users.</p>
 
 <p>If you are using a content provider
 for sharing data between only your own apps, it is preferable to use the
 <a href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">{@code
-android:protectionLevel}</a> attribute set to {@code "signature"} protection.
+android:protectionLevel}</a> attribute set to {@code signature} protection.
 Signature permissions do not require user confirmation,
 so they provide a better user experience and more controlled access to the
 content provider data when the apps accessing the data are
@@ -148,7 +153,7 @@
 that activates the component.  The scope of these permissions can be further
 limited by the <code><a
 href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">
-&lt;grant-uri-permission element&gt;</a></code>.</p>
+&lt;grant-uri-permission&gt;</a></code> element.</p>
 
 <p>When accessing a content provider, use parameterized query methods such as
 {@link android.content.ContentProvider#query(Uri,String[],String,String[],String) query()},
@@ -158,11 +163,11 @@
 sufficient if the <code>selection</code> argument is built by concatenating user data
 prior to submitting it to the method.</p>
 
-<p>Do not have a false sense of security about the write permission.  Consider
-that the write permission allows SQL statements which make it possible for some
+<p>Don't have a false sense of security about the write permission.
+ The write permission allows SQL statements that make it possible for some
 data to be confirmed using creative <code>WHERE</code> clauses and parsing the
-results. For example, an attacker might probe for presence of a specific phone
-number in a call-log by modifying a row only if that phone number already
+results. For example, an attacker might probe for the presence of a specific phone
+number in a call log by modifying a row only if that phone number already
 exists. If the content provider data has predictable structure, the write
 permission may be equivalent to providing both reading and writing.</p>
 
@@ -172,7 +177,7 @@
 
 
 
-<h2 id="Permissions">Using Permissions</h2>
+<h2 id="Permissions">Using permissions</h2>
 
 <p>Because Android sandboxes applications from each other, applications must explicitly
 share resources and data. They do this by declaring the permissions they need for additional
@@ -180,25 +185,25 @@
 the camera.</p>
 
 
-<h3 id="RequestingPermissions">Requesting Permissions</h3>
+<h3 id="RequestingPermissions">Requesting permissions</h3>
 
-<p>We recommend minimizing the number of permissions that your app requests.
-Not having access to sensitive permissions reduces the risk of
-inadvertently misusing those permissions, can improve user adoption, and makes
+<p>You should minimize the number of permissions that your app requests.
+Restricting access to sensitive permissions reduces the risk of
+inadvertently misusing those permissions, improves user adoption, and makes
 your app less vulnerable for attackers. Generally,
-if a permission is not required for your app to function, do not request it.</p>
+if a permission is not required for your app to function, don't request it.</p>
 
 <p>If it's possible to design your application in a way that does not require
 any permissions, that is preferable.  For example, rather than requesting access
 to device information to create a unique identifier, create a <a
 href="{@docRoot}reference/java/util/UUID.html">GUID</a> for your application
-(see the section about <a href="#UserData">Handling User Data</a>). Or, rather than
+(see the section about <a href="#UserData">Handling user data</a>). Or, rather than
 using external storage (which requires permission), store data
 on the internal storage.</p>
 
 <p>In addition to requesting permissions, your application can use the <a
-href="{@docRoot}guide/topics/manifest/permission-element.html">{@code <permissions>}</a>
-to protect IPC that is security sensitive and will be exposed to other
+href="{@docRoot}guide/topics/manifest/permission-element.html">{@code &lt;permission&gt;}</a>
+ element to protect IPC that is security sensitive and is exposed to other
 applications, such as a {@link android.content.ContentProvider}.
 In general, we recommend using access controls
 other than user confirmed permissions where possible because permissions can
@@ -211,13 +216,14 @@
 data over IPC that is available only because your app has permission to access
 that data. The clients of your app's IPC interface may not have that same
 data-access permission. More details on the frequency and potential effects
-of this issue appear in <a class="external-link"
-href="https://www.usenix.org/legacy/event/sec11/tech/full_papers/Felt.pdf"> this
-research paper</a>, published at USENIX.
+of this issue appear in the research paper <a
+href="https://www.usenix.org/legacy/event/sec11/tech/full_papers/Felt.pdf" class="external-link">
+Permission Re-Delegation: Attacks and Defenses
+</a>, published at USENIX.
 
 
 
-<h3 id="CreatingPermissions">Creating Permissions</h3>
+<h3 id="CreatingPermissions">Creating permissions</h3>
 
 <p>Generally, you should strive to define as few permissions as possible while
 satisfying your security requirements.  Creating a new permission is relatively
@@ -228,18 +234,18 @@
 
 <p>If you must create a new permission, consider whether you can accomplish
 your task with a <a
-href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">"signature"
+href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">signature
 protection level</a>.  Signature permissions are transparent
-to the user and only allow access by applications signed by the same developer
-as application performing the permission check.</p>
+to the user and allow access only by applications signed by the same developer
+as the application performing the permission check.</p>
 
 <p>If you create a permission with the <a
-href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">"dangerous"
+href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">dangerous
 protection level</a>, there are a number of complexities
 that you need to consider:
 <ul>
 <li>The permission must have a string that concisely expresses to a user the
-security decision they will be required to make.</li>
+security decision they are required to make.</li>
 <li>The permission string must be localized to many different languages.</li>
 <li>Users may choose not to install an application because a permission is
 confusing or perceived as risky.</li>
@@ -247,28 +253,28 @@
 has not been installed.</li>
 </ul>
 
-<p>Each of these poses a significant non-technical challenge for you as the developer
+<p>Each of these poses a significant nontechnical challenge for you as the developer
 while also confusing your users,
-which is why we discourage the use of the "dangerous" permission level.</p>
+which is why we discourages the use of the <em>dangerous</em> permission level.</p>
 
 
 
 
 
-<h2 id="Networking">Using Networking</h2>
+<h2 id="Networking">Using networking</h2>
 
-<p>Network transactions are inherently risky for security, because it involves transmitting
+<p>Network transactions are inherently risky for security, because they involve transmitting
 data that is potentially private to the user. People are increasingly aware of the privacy
 concerns of a mobile device, especially when the device performs network transactions,
 so it's very important that your app implement all best practices toward keeping the user's
 data secure at all times.</p>
 
-<h3 id="IPNetworking">Using IP Networking</h3>
+<h3 id="IPNetworking">Using IP networking</h3>
 
 <p>Networking on Android is not significantly different from other Linux
 environments.  The key consideration is making sure that appropriate protocols
 are used for sensitive data, such as {@link javax.net.ssl.HttpsURLConnection} for
-secure web traffic.   We prefer use of HTTPS over HTTP anywhere that HTTPS is
+secure web traffic. You should use HTTPS over HTTP anywhere that HTTPS is
 supported on the server, because mobile devices frequently connect on networks
 that are not secured, such as public Wi-Fi hotspots.</p>
 
@@ -278,32 +284,32 @@
 wireless networks using Wi-Fi, the use of secure networking is strongly
 encouraged for all applications that communicate over the network.</p>
 
-<p>We have seen some applications use <a
-href="http://en.wikipedia.org/wiki/Localhost">localhost</a> network ports for
-handling sensitive IPC.  We discourage this approach since these interfaces are
-accessible by other applications on the device.  Instead, you should use an Android IPC
-mechanism where authentication is possible such as with a {@link android.app.Service}.  (Even
-worse than using loopback is to bind to INADDR_ANY since then your application
-may receive requests from anywhere.)</p>
+<p>Some applications use <a
+href="http://en.wikipedia.org/wiki/Localhost" class="external-link">localhost</a> network ports for
+handling sensitive IPC.  You should not use this approach because these interfaces are
+accessible by other applications on the device. Instead, use an Android IPC
+mechanism where authentication is possible, such as with a {@link android.app.Service}.
+Binding to INADDR_ANY is worse than using loopback because then your application
+may receive requests from anywhere.</p>
 
-<p>Also, one common issue that warrants repeating is to make sure that you do
-not trust data downloaded from HTTP or other insecure protocols.  This includes
+<p>Make sure that you don't
+ trust data downloaded from HTTP or other insecure protocols.  This includes
 validation of input in {@link android.webkit.WebView} and
 any responses to intents issued against HTTP.</p>
 
 
-<h3>Using Telephony Networking</h3>
+<h3>Using telephony networking</h3>
 
 <p>The <acronym title="Short Message Service">SMS</acronym> protocol was primarily designed for
 user-to-user communication and is not well-suited for apps that want to transfer data.
-Due to the limitations of SMS, we strongly recommend the use of <a
+Due to the limitations of SMS, you should use <a
 href="{@docRoot}google/gcm/index.html">Google Cloud Messaging</a> (GCM)
 and IP networking for sending data messages from a web server to your app on a user device.</p>
 
 <p>Beware that SMS is neither encrypted nor strongly
-authenticated on either the network or the device.  In particular, any SMS receiver
-should expect that a malicious user may have sent the SMS to your application&mdash;Do
-not rely on unauthenticated SMS data to perform sensitive commands.
+authenticated on either the network or the device. In particular, any SMS receiver
+should expect that a malicious user may have sent the SMS to your application. Don't
+ rely on unauthenticated SMS data to perform sensitive commands.
 Also, you should be aware that SMS may be subject to spoofing and/or
 interception on the network.  On the Android-powered device itself, SMS
 messages are transmitted as broadcast intents, so they may be read or captured
@@ -314,32 +320,32 @@
 
 
 
-<h2 id="InputValidation">Performing Input Validation</h2>
+<h2 id="InputValidation">Performing input validation</h2>
 
 <p>Insufficient input validation is one of the most common security problems
-affecting applications, regardless of what platform they run on. Android does
-have platform-level countermeasures that reduce the exposure of applications to
-input validation issues and you should use those features where possible. Also
-note that selection of type-safe languages tends to reduce the likelihood of
+affecting applications, regardless of what platform they run on. Android
+has platform-level countermeasures that reduce the exposure of applications to
+input validation issues, and you should use those features where possible. Also
+note that the selection of type-safe languages tends to reduce the likelihood of
 input validation issues.</p>
 
-<p>If you are using native code, then any data read from files, received over
+<p>If you are using native code, any data read from files, received over
 the network, or received from an IPC has the potential to introduce a security
 issue.  The most common problems are <a
-href="http://en.wikipedia.org/wiki/Buffer_overflow">buffer overflows</a>, <a
-href="http://en.wikipedia.org/wiki/Double_free#Use_after_free">use after
+href="http://en.wikipedia.org/wiki/Buffer_overflow" class="external-link">buffer overflows</a>, <a
+href="http://en.wikipedia.org/wiki/Double_free#Use_after_free" class="external-link">use after
 free</a>, and <a
-href="http://en.wikipedia.org/wiki/Off-by-one_error">off-by-one errors</a>.
+href="http://en.wikipedia.org/wiki/Off-by-one_error" class="external-link">off-by-one errors</a>.
 Android provides a number of technologies like <acronym
 title="Address Space Layout Randomization">ASLR</acronym> and <acronym
 title="Data Execution Prevention">DEP</acronym> that reduce the
-exploitability of these errors, but they do not solve the underlying problem.
-You can prevent these vulneratbilities by careful handling pointers and managing
+exploitability of these errors, but they don't solve the underlying problem.
+You can prevent these vulnerabilities by carefully handling pointers and managing
 buffers.</p>
 
-<p>Dynamic, string based languages such as JavaScript and SQL are also subject
+<p>Dynamic, string-based languages such as JavaScript and SQL are also subject
 to input validation problems due to escape characters and <a
-href="http://en.wikipedia.org/wiki/Code_injection">script injection</a>.</p>
+href="http://en.wikipedia.org/wiki/Code_injection" class="external-link">script injection</a>.</p>
 
 <p>If you are using data within queries that are submitted to an SQL database or a
 content provider, SQL injection may be an issue.  The best defense is to use
@@ -348,60 +354,59 @@
 Limiting permissions to read-only or write-only can also reduce the potential
 for harm related to SQL injection.</p>
 
-<p>If you cannot use the security features above, we strongly recommend the use
-of well-structured data formats and verifying that the data conforms to the
+<p>If you can't use the security features above, you should make sure to use
+well-structured data formats and verify that the data conforms to the
 expected format. While blacklisting of characters or character-replacement can
-be an effective strategy, these techniques are error-prone in practice and
+be an effective strategy, these techniques are error prone in practice and
 should be avoided when possible.</p>
 
 
 
 
 
-<h2 id="UserData">Handling User Data</h2>
+<h2 id="UserData">Handling user data</h2>
 
 <p>In general, the best approach for user data security is to minimize the use of APIs that access
 sensitive or personal user data. If you have access to user data and can avoid
-storing or transmitting the information, do not store or transmit the data.
-Finally, consider if there is a way that your application logic can be
+storing or transmitting it, don't store or transmit the data.
+Consider if there is a way that your application logic can be
 implemented using a hash or non-reversible form of the data.  For example, your
-application might use the hash of an an email address as a primary key, to
+application might use the hash of an email address as a primary key to
 avoid transmitting or storing the email address.  This reduces the chances of
 inadvertently exposing data, and it also reduces the chance of attackers
 attempting to exploit your application.</p>
 
 <p>If your application accesses personal information such as passwords or
-usernames, keep in mind that some jurisdictions may require you to provide a
-privacy policy explaining your use and storage of that data.  So following the
+user names, keep in mind that some jurisdictions may require you to provide a
+privacy policy explaining your use and storage of that data. Following the
 security best practice of minimizing access to user data may also simplify
 compliance.</p>
 
 <p>You should also consider whether your application might be inadvertently
 exposing personal information to other parties such as third-party components
 for advertising or third-party services used by your application. If you don't
-know why a component or service requires a personal information, don’t
+know why a component or service requires personal information, don’t
 provide it.  In general, reducing the access to personal information by your
-application will reduce the potential for problems in this area.</p>
+application reduces the potential for problems in this area.</p>
 
-<p>If access to sensitive data is required, evaluate whether that information
-must be transmitted to a server, or whether the operation can be performed on
-the client.  Consider running any code using sensitive data on the client to
-avoid transmitting user data.</p>
-
-<p>Also, make sure that you do not inadvertently expose user data to other
-application on the device through overly permissive IPC, world writable files,
-or network sockets. This is a special case of leaking permission-protected data,
+<p>If your app requires access to sensitive data, evaluate whether you need to
+ transmit it to a server or you can run the operation on
+the client. Consider running any code using sensitive data on the client to
+avoid transmitting user data. Also, make sure that you do not inadvertently expose user
+ data to other
+applications on the device through overly permissive IPC, world-writable files,
+or network sockets. Overly permissive IPC is a special case of leaking permission-protected data,
 discussed in the <a href="#RequestingPermissions">Requesting Permissions</a> section.</p>
 
 <p>If a <acronym title="Globally Unique Identifier">GUID</acronym>
-is required, create a large, unique number and store it.  Do not
-use phone identifiers such as the phone number or IMEI which may be associated
+is required, create a large, unique number and store it.  Don't
+use phone identifiers such as the phone number or IMEI, which may be associated
 with personal information.  This topic is discussed in more detail in the <a
-href="http://android-developers.blogspot.com/2011/03/identifying-app-installations.html">Android
-Developer Blog</a>.</p>
+href="http://android-developers.blogspot.com/2011/03/identifying-app-installations.html"
+>Android Developer Blog</a>.</p>
 
 <p>Be careful when writing to on-device logs.
-In Android, logs are a shared resource, and are available
+In Android, logs are a shared resource and are available
 to an application with the {@link android.Manifest.permission#READ_LOGS} permission.
 Even though the phone log data
 is temporary and erased on reboot, inappropriate logging of user information
@@ -414,19 +419,23 @@
 
 <h2 id="WebView">Using WebView</h2>
 
-<p>Because {@link android.webkit.WebView} consumes web content that can include HTML and JavaScript,
+<p>Because {@link android.webkit.WebView} consumes web content that can include HTML
+ and JavaScript,
 improper use can introduce common web security issues such as <a
-href="http://en.wikipedia.org/wiki/Cross_site_scripting">cross-site-scripting</a>
+href="http://en.wikipedia.org/wiki/Cross_site_scripting" class="external-link">
+cross-site-scripting</a>
 (JavaScript injection).  Android includes a number of mechanisms to reduce
-the scope of these potential issues by limiting the capability of {@link android.webkit.WebView} to
+the scope of these potential issues by limiting the capability of
+ {@link android.webkit.WebView} to
 the minimum functionality required by your application.</p>
 
-<p>If your application does not directly use JavaScript within a {@link android.webkit.WebView}, do
-<em>not</em> call {@link android.webkit.WebSettings#setJavaScriptEnabled setJavaScriptEnabled()}.
+<p>If your application doesn't directly use JavaScript within a {@link android.webkit.WebView},
+ <em>do not</em> call
+ {@link android.webkit.WebSettings#setJavaScriptEnabled setJavaScriptEnabled()}.
 Some sample code uses this method, which you might repurpose in production
 application, so remove that method call if it's not required. By default,
 {@link android.webkit.WebView} does
-not execute JavaScript so cross-site-scripting is not possible.</p>
+not execute JavaScript, so cross-site-scripting is not possible.</p>
 
 <p>Use {@link android.webkit.WebView#addJavascriptInterface
 addJavaScriptInterface()} with
@@ -441,55 +450,55 @@
 <p>If your application accesses sensitive data with a
 {@link android.webkit.WebView}, you may want to use the
 {@link android.webkit.WebView#clearCache clearCache()} method to delete any files stored
-locally. Server-side
-headers like <code>no-cache</code> can also be used to indicate that an application should
+locally. You can also use server-side
+headers such as <code>no-cache</code> to indicate that an application should
 not cache particular content.</p>
 
 <p>Devices running platforms older than Android 4.4 (API level 19)
 use a version of {@link android.webkit webkit} that has a number of security issues.
 As a workaround, if your app is running on these devices, it
-should confirm that {@link android.webkit.WebView} objects display only trusted
-content. You should also use the updatable security {@link
-java.security.Provider Provider} object to make sure your app isn’t exposed to
-potential vulnerabilities in SSL, as described in <a
+must confirm that {@link android.webkit.WebView} objects display only trusted
+content. To make sure your app isn’t exposed to
+potential vulnerabilities in SSL, use the updatable security {@link
+java.security.Provider Provider} object as described in <a
 href="{@docRoot}training/articles/security-gms-provider.html">Updating Your
 Security Provider to Protect Against SSL Exploits</a>. If your application must
 render content from the open web, consider providing your own renderer so
 you can keep it up to date with the latest security patches.</p>
 
 
-<h3 id="Credentials">Handling Credentials</h3>
+<h3 id="Credentials">Handling credentials</h3>
 
-<p>In general, we recommend minimizing the frequency of asking for user
-credentials&mdash;to make phishing attacks more conspicuous, and less likely to be
-successful.  Instead use an authorization token and refresh it.</p>
+<p>To make phishing attacks more conspicuous and less likely to be
+successful, minimize the frequency of asking for user
+credentials. Instead use an authorization token and refresh it.</p>
 
-<p>Where possible, username and password should not be stored on the device.
-Instead, perform initial authentication using the username and password
-supplied by the user, and then use a short-lived, service-specific
+<p>Where possible, don't store user names and passwords on the device.
+Instead, perform initial authentication using the user name and password
+ supplied by the user, and then use a short-lived, service-specific
 authorization token.</p>
 
-<p>Services that will be accessible to multiple applications should be accessed
+<p>Services that are accessible to multiple applications should be accessed
 using {@link android.accounts.AccountManager}. If possible, use the
-{@link android.accounts.AccountManager} class to invoke a cloud-based service and do not store
+{@link android.accounts.AccountManager} class to invoke a cloud-based service and don't store
 passwords on the device.</p>
 
 <p>After using {@link android.accounts.AccountManager} to retrieve an
-{@link android.accounts.Account}, {@link android.accounts.Account#CREATOR}
-before passing in any credentials, so that you do not inadvertently pass
+{@link android.accounts.Account}, use {@link android.accounts.Account#CREATOR}
+before passing in any credentials so that you do not inadvertently pass
 credentials to the wrong application.</p>
 
-<p>If credentials are to be used only by applications that you create, then you
-can verify the application which accesses the {@link android.accounts.AccountManager} using
+<p>If credentials are used only by applications that you create, you
+can verify the application that accesses the {@link android.accounts.AccountManager} using
 {@link android.content.pm.PackageManager#checkSignatures checkSignature()}.
-Alternatively, if only one application will use the credential, you might use a
+Alternatively, if only one application uses the credential, you might use a
 {@link java.security.KeyStore} for storage.</p>
 
 
 
 
 
-<h2 id="Crypto">Using Cryptography</h2>
+<h2 id="Crypto">Using cryptography</h2>
 
 <p>In addition to providing data isolation, supporting full-filesystem
 encryption, and providing secure communications channels, Android provides a
@@ -500,21 +509,21 @@
 retrieve a file from a known location, a simple HTTPS URI may be adequate and
 requires no knowledge of cryptography.  If you need a secure
 tunnel, consider using {@link javax.net.ssl.HttpsURLConnection} or
-{@link javax.net.ssl.SSLSocket}, rather than writing your own protocol.</p>
+{@link javax.net.ssl.SSLSocket} rather than writing your own protocol.</p>
 
-<p>If you do find yourself needing to implement your own protocol, we strongly
-recommend that you <em>not</em> implement your own cryptographic algorithms. Use
+<p>If you do need to implement your own protocol, you should <em>not</em>
+implement your own cryptographic algorithms. Use
 existing cryptographic algorithms such as those in the implementation of AES or
 RSA provided in the {@link javax.crypto.Cipher} class.</p>
 
 <p>Use a secure random number generator, {@link java.security.SecureRandom},
-to initialize any cryptographic keys, {@link javax.crypto.KeyGenerator}.
+to initialize any cryptographic keys generated by {@link javax.crypto.KeyGenerator}.
 Use of a key that is not generated with a secure random
-number generator significantly weakens the strength of the algorithm, and may
+number generator significantly weakens the strength of the algorithm and may
 allow offline attacks.</p>
 
-<p>If you need to store a key for repeated use, use a mechanism like
-  {@link java.security.KeyStore} that
+<p>If you need to store a key for repeated use, use a mechanism, such as
+  {@link java.security.KeyStore}, that
 provides a mechanism for long term storage and retrieval of cryptographic
 keys.</p>
 
@@ -522,10 +531,10 @@
 
 
 
-<h2 id="IPC">Using Interprocess Communication</h2>
+<h2 id="IPC">Using interprocess communication</h2>
 
 <p>Some apps attempt to implement IPC using traditional Linux
-techniques such as network sockets and shared files.  We strongly encourage you to instead
+techniques such as network sockets and shared files. However, you should instead
 use Android system functionality for IPC such as {@link android.content.Intent},
 {@link android.os.Binder} or {@link android.os.Messenger} with a {@link
 android.app.Service}, and {@link android.content.BroadcastReceiver}.
@@ -535,19 +544,19 @@
 
 <p>Many of the security elements are shared across IPC mechanisms.
 If your IPC mechanism is not intended for use by other applications, set the
-{@code android:exported} attribute to {@code "false"} in the component's manifest element,
+{@code android:exported} attribute to {@code false} in the component's manifest element,
 such as for the <a
-href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code <service>}</a>
+href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code &lt;service&gt;}</a>
 element.  This is useful for applications that consist of multiple processes
-within the same UID, or if you decide late in development that you do not
-actually want to expose functionality as IPC but you don’t want to rewrite
+within the same UID or if you decide late in development that you don't
+actually want to expose functionality as IPC, but you don’t want to rewrite
 the code.</p>
 
-<p>If your IPC is intended to be accessible to other applications, you can
+<p>If your IPC is accessible to other applications, you can
 apply a security policy by using the <a
-href="{@docRoot}guide/topics/manifest/permission-element.html">{@code <permission>}</a>
+href="{@docRoot}guide/topics/manifest/permission-element.html">{@code &lt;permission>}</a>
 element. If IPC is between your own separate apps that are signed with the same key,
-it is preferable to use {@code "signature"} level permission in the <a
+it is preferable to use {@code signature} level permission in the <a
 href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">{@code
 android:protectionLevel}</a>.</p>
 
@@ -556,31 +565,42 @@
 
 <h3>Using intents</h3>
 
-<p>Intents are the preferred mechanism for asynchronous IPC in Android.
+<p>For activities and broadcast receivers, intents are the preferred mechanism for
+ asynchronous IPC in Android.
 Depending on your application requirements, you might use {@link
 android.content.Context#sendBroadcast sendBroadcast()}, {@link
 android.content.Context#sendOrderedBroadcast sendOrderedBroadcast()},
 or an explicit intent to a specific application component.</p>
 
-<p>Note that ordered broadcasts can be “consumed” by a recipient, so they
-may not be delivered to all applications.  If you are sending an intent that must be delivered
-to a specific receiver, then you must use an explicit intent that declares the receiver
-by nameintent.</p>
+<p class="caution"><strong>Caution:</strong> If you use an intent to bind to a
+ {@link android.app.Service}, ensure that your app is secure by using an
+ <a href="{@docRoot}guide/components/intents-filters.html#Types">explicit</a>
+intent. Using an implicit intent to start a service is a
+security hazard because you can't be certain what service will respond to the intent,
+and the user can't see which service starts. Beginning with Android 5.0 (API level 21),
+ the system
+throws an exception if you call {@link android.content.Context#bindService bindService()}
+with an implicit intent.</p>
 
-<p>Senders of an intent can verify that the recipient has a permission
-specifying a non-Null permission with the method call.  Only applications with that
-permission will receive the intent.  If data within a broadcast intent may be
+<p>Note that ordered broadcasts can be <em>consumed</em> by a recipient, so they
+may not be delivered to all applications.  If you are sending an intent that must be delivered
+to a specific receiver, you must use an explicit intent that declares the receiver
+by name.</p>
+
+<p>Senders of an intent can verify that the recipient has permission
+ by specifying a non-null permission with the method call.  Only applications with that
+permission receive the intent. If data within a broadcast intent may be
 sensitive, you should consider applying a permission to make sure that
-malicious applications cannot register to receive those messages without
-appropriate permissions.  In those circumstances, you may also consider
+malicious applications can't register to receive those messages without
+appropriate permissions. In those circumstances, you may also consider
 invoking the receiver directly, rather than raising a broadcast.</p>
 
 <p class="note"><strong>Note:</strong> Intent filters should not be considered
-a security feature&mdash;components
+a security feature. Components
 can be invoked with explicit intents and may not have data that would conform to the intent
-filter. You should perform input validation within your intent receiver to
+filter. To
 confirm that it is properly formatted for the invoked receiver, service, or
-activity.</p>
+activity, perform input validation within your intent receiver.</p>
 
 
 
@@ -589,26 +609,32 @@
 
 <p>A {@link android.app.Service} is often used to supply functionality for other applications to
 use. Each service class must have a corresponding <a
-href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> declaration in its
+href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a>
+ declaration in its
 manifest file.</p>
 
 <p>By default, services are not exported and cannot be invoked by any other
-application. However, if you add any intent filters to the service declaration, then it is exported
+application. However, if you add any intent filters to the service declaration, it is exported
 by default. It's best if you explicitly declare the <a
 href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code
 android:exported}</a> attribute to be sure it behaves as you'd like.
 Services can also be protected using the <a
 href="{@docRoot}guide/topics/manifest/service-element.html#prmsn">{@code android:permission}</a>
-attribute. By doing so, other applications will need to declare
+attribute. By doing so, other applications need to declare
 a corresponding <code><a
 href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a>
 </code> element in their own manifest to be
 able to start, stop, or bind to the service.</p>
 
+<p class="note"><strong>Note:</strong> If your app targets Android 5.0 (API level 21) or later,
+ you should use the {@link android.app.job.JobScheduler} to execute background
+ services. For more information about {@link android.app.job.JobScheduler}, see its
+ {@link android.app.job.JobScheduler API-reference documentation}.</p>
+
 <p>A service can protect individual IPC calls into it with permissions, by
 calling {@link android.content.Context#checkCallingPermission
 checkCallingPermission()} before executing
-the implementation of that call.  We generally recommend using the
+the implementation of that call. You should use the
 declarative permissions in the manifest, since those are less prone to
 oversight.</p>
 
@@ -620,24 +646,24 @@
 preferred mechanism for RPC-style IPC in Android. They provide a well-defined
 interface that enables mutual authentication of the endpoints, if required.</p>
 
-<p>We strongly encourage designing interfaces in a manner that does not require
-interface specific permission checks. {@link android.os.Binder} and
+<p>You should design your app interfaces in a manner that does not require
+interface-specific permission checks. {@link android.os.Binder} and
 {@link android.os.Messenger} objects are not declared within the
 application manifest, and therefore you cannot apply declarative permissions
 directly to them.  They generally inherit permissions declared in the
 application manifest for the {@link android.app.Service} or {@link
 android.app.Activity} within which they are
 implemented.  If you are creating an interface that requires authentication
-and/or access controls, those controls must be
-explicitly added as code in the {@link android.os.Binder} or {@link android.os.Messenger}
+and/or access controls, you must explicitly add those controls
+ as code in the {@link android.os.Binder} or {@link android.os.Messenger}
 interface.</p>
 
-<p>If providing an interface that does require access controls, use {@link
+<p>If you are providing an interface that does require access controls, use {@link
 android.content.Context#checkCallingPermission checkCallingPermission()}
 to verify whether the
 caller has a required permission. This is especially important
 before accessing a service on behalf of the caller, as the identify of your
-application is passed to other interfaces.  If invoking an interface provided
+application is passed to other interfaces.  If you are invoking an interface provided
 by a {@link android.app.Service}, the {@link
 android.content.Context#bindService bindService()}
  invocation may fail if you do not have permission to access the given service.
@@ -660,8 +686,8 @@
 is intended for use by other applications, you
 may want to apply security permissions to receivers using the <code><a
 href="{@docRoot}guide/topics/manifest/receiver-element.html">
-&lt;receiver&gt;</a></code> element within the application manifest.  This will
-prevent applications without appropriate permissions from sending an intent to
+&lt;receiver&gt;</a></code> element within the application manifest.  This
+prevents applications without appropriate permissions from sending an intent to
 the {@link android.content.BroadcastReceiver}.</p>
 
 
@@ -671,57 +697,58 @@
 
 
 
-<h2 id="DynamicCode">Dynamically Loading Code</h2>
+<h2 id="DynamicCode">Dynamically loading code</h2>
 
 <p>We strongly discourage loading code from outside of your application APK.
 Doing so significantly increases the likelihood of application compromise due
-to code injection or code tampering.  It also adds complexity around version
-management and application testing.  Finally, it can make it impossible to
+to code injection or code tampering. It also adds complexity around version
+management and application testing. It can also make it impossible to
 verify the behavior of an application, so it may be prohibited in some
 environments.</p>
 
 <p>If your application does dynamically load code, the most important thing to
-keep in mind about dynamically loaded code is that it runs with the same
-security permissions as the application APK.  The user made a decision to
-install your application based on your identity, and they are expecting that
+keep in mind about dynamically-loaded code is that it runs with the same
+security permissions as the application APK.  The user makes a decision to
+install your application based on your identity, and the user expects that
 you provide any code run within the application, including code that is
 dynamically loaded.</p>
 
 <p>The major security risk associated with dynamically loading code is that the
 code needs to come from a verifiable source. If the modules are included
-directly within your APK, then they cannot be modified by other applications.
+directly within your APK, they cannot be modified by other applications.
 This is true whether the code is a native library or a class being loaded using
-{@link dalvik.system.DexClassLoader}.  We have seen many instances of applications
-attempting to load code from insecure locations, such as downloaded from the
-network over unencrypted protocols or from world writable locations such as
+{@link dalvik.system.DexClassLoader}.  Many applications
+attempt to load code from insecure locations, such as downloaded from the
+network over unencrypted protocols or from world-writable locations such as
 external storage. These locations could allow someone on the network to modify
-the content in transit, or another application on a users device to modify the
-content on the device, respectively.</p>
+the content in transit or another application on a user's device to modify the
+content on the device.</p>
 
 
 
 
 
-<h2 id="Dalvik">Security in a Virtual Machine</h2>
+<h2 id="Dalvik">Security in a virtual machine</h2>
 
 <p>Dalvik is Android's runtime virtual machine (VM). Dalvik was built specifically for Android,
 but many of the concerns regarding secure code in other virtual machines also apply to Android.
 In general, you shouldn't concern yourself with security issues relating to the virtual machine.
-Your application runs in a secure sandbox environment, so other processes on the system cannnot
+Your application runs in a secure sandbox environment, so other processes on the system can't
 access your code or private data.</p>
 
-<p>If you're interested in diving deeper on the subject of virtual machine security,
-we recommend that you familiarize yourself with some
+<p>If you're interested in learning more about virtual machine security,
+ familiarize yourself with some
 existing literature on the subject. Two of the more popular resources are:
 <ul>
-<li><a href="http://www.securingjava.com/toc.html">
-http://www.securingjava.com/toc.html</a></li>
+<li><a href="http://www.securingjava.com/toc.html" class="external-link">
+Securing Java</a></li>
 <li><a
-href="https://www.owasp.org/index.php/Java_Security_Resources">
-https://www.owasp.org/index.php/Java_Security_Resources</a></li>
+href="https://www.owasp.org/index.php/Category:Java#tab=Related_3rd_Party_Projects"
+ class="external-link">
+Related 3rd party Projects</a></li>
 </ul></p>
 
-<p>This document is focused on the areas which are Android specific or
+<p>This document focuses on areas that are Android specific or
 different from other VM environments.  For developers experienced with VM
 programming in other environments, there are two broad issues that may be
 different about writing apps for Android:
@@ -742,21 +769,19 @@
 
 
 
-<h2 id="Native">Security in Native Code</h2>
+<h2 id="Native">Security in native code</h2>
 
-<p>In general, we encourage developers to use the Android SDK for
+<p>In general, you should use the Android SDK for
 application development, rather than using native code with the
 <a href="{@docRoot}tools/sdk/ndk/index.html">Android NDK</a>.  Applications built
 with native code are more complex, less portable, and more like to include
-common memory corruption errors such as buffer overflows.</p>
+common memory-corruption errors such as buffer overflows.</p>
 
-<p>Android is built using the Linux kernel and being familiar with Linux
-development security best practices is especially useful if you are going to
-use native code. Linux security practices are beyond the scope of this document,
-but one of the most popular resources is “Secure Programming for
-Linux and Unix HOWTO”, available at <a
-href="http://www.dwheeler.com/secure-programs">
-http://www.dwheeler.com/secure-programs</a>.</p>
+<p>Android is built using the Linux kernel, and being familiar with Linux
+development security best practices is especially useful if you are
+using native code. Linux security practices are beyond the scope of this document,
+but one of the most popular resources is <a href="http://www.dwheeler.com/secure-programs"
+ class="external-link">Secure Programming HOWTO - Creating Secure Software</a>.</p>
 
 <p>An important difference between Android and most Linux environments is the
 Application Sandbox.  On Android, all applications run in the Application
@@ -765,6 +790,5 @@
 every application is given a unique <acronym title="User Identifier">UID</acronym>
 with very limited permissions. This is discussed in more detail in the <a
 href="http://source.android.com/tech/security/index.html">Android Security
-Overview</a> and you should be familiar with application permissions even if
+Overview</a>, and you should be familiar with application permissions even if
 you are using native code.</p>
-
diff --git a/docs/html/training/location/display-address.jd b/docs/html/training/location/display-address.jd
index daa6fd3..088e926 100644
--- a/docs/html/training/location/display-address.jd
+++ b/docs/html/training/location/display-address.jd
@@ -7,11 +7,11 @@
 
     <h2>This lesson teaches you how to</h2>
     <ol>
-      <li><a href="#connect">Get a Geographic Location</a></li>
-      <li><a href="#fetch-address">Define an Intent Service to Fetch the
-        Address</a></li>
-      <li><a href="#start-intent">Start the Intent Service</a></li>
-      <li><a href="#result-receiver">Receive the Geocoding Results</a></li>
+      <li><a href="#connect">Get a geographic location</a></li>
+      <li><a href="#fetch-address">Define an intent service to fetch the
+        address</a></li>
+      <li><a href="#start-intent">Start the intent service</a></li>
+      <li><a href="#result-receiver">Receive the geocoding results</a></li>
     </ol>
 
     <h2>You should also read</h2>
@@ -58,7 +58,7 @@
   convert a geographic location to an address. The method returns an estimated
   street address corresponding to a given latitude and longitude.</p>
 
-<h2 id="connect">Get a Geographic Location</h2>
+<h2 id="connect">Get a geographic location</h2>
 
 <p>The last known location of the device is a useful starting point for the
   address lookup feature. The lesson on
@@ -69,12 +69,12 @@
   <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html">fused
   location provider</a> to find the latest location of the device.</p>
 
-<p>To access the fused location provider, you need to create an instance of the
+<p>To access the fused location provider, create an instance of the
   Google Play services API client. To learn how to connect your client, see
   <a href="{@docRoot}training/location/retrieve-current.html#play-services">Connect
   to Google Play Services</a>.</p>
 
-<p>In order for the fused location provider to retrieve a precise street
+<p>To enable the fused location provider to retrieve a precise street
   address, set the location permission in your app manifest to
   {@code ACCESS_FINE_LOCATION}, as shown in the following example:</p>
 
@@ -86,12 +86,12 @@
 &lt;/manifest&gt;
 </pre>
 
-<h2 id="fetch-address">Define an Intent Service to Fetch the Address</h2>
+<h2 id="fetch-address">Define an intent service to fetch the address</h2>
 
 <p>The {@link android.location.Geocoder#getFromLocation getFromLocation()}
   method provided by the {@link android.location.Geocoder} class accepts a
-  latitude and longitude, and returns a list of addresses. The method is
-  synchronous, and may take a long time to do its work, so you should not call
+  latitude and longitude and returns a list of addresses. The method is
+  synchronous and may take a long time to do its work, so you should not call
   it from the main, user interface (UI) thread of your app.</p>
 
 <p>The {@link android.app.IntentService IntentService} class provides a
@@ -100,23 +100,23 @@
   Note that the {@link android.os.AsyncTask AsyncTask} class also allows you to
   perform background operations, but it's designed for short operations. An
   {@link android.os.AsyncTask AsyncTask} shouldn't keep a reference to the UI if
-  the activity is recreated, for example when the device is rotated. In
+  the activity is re-created, such as when the device is rotated. In
   contrast, an {@link android.app.IntentService IntentService} doesn't need to
   be cancelled when the activity is rebuilt.</p>
 
 <p>Define a {@code FetchAddressIntentService} class that extends
   {@link android.app.IntentService}. This class is your address lookup service.
-  The intent service handles an intent asynchronously on a worker thread, and
+  The intent service handles an intent asynchronously on a worker thread and
   stops itself when it runs out of work. The intent extras provide the data
   needed by the service, including a {@link android.location.Location} object
-  for conversion to an address, and a {@link android.os.ResultReceiver} object
+  for conversion to an address and a {@link android.os.ResultReceiver} object
   to handle the results of the address lookup. The service uses a {@link
-  android.location.Geocoder} to fetch the address for the location, and sends
+  android.location.Geocoder} to fetch the address for the location and sends
   the results to the {@link android.os.ResultReceiver}.</p>
 
-<h3>Define the Intent Service in your App Manifest</h3>
+<h3>Define the intent service in your app manifest</h3>
 
-<p>Add an entry to your app manifest defining the intent service:</p>
+<p>Add an entry to your app manifest that defines the intent service, as shown here:</p>
 
 <pre>
 &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
@@ -131,26 +131,26 @@
 &lt;/manifest&gt;
 </pre>
 
-<p class="note"><strong>Note:</strong> The {@code <service>} element in
-  the manifest doesn't need to include an intent filter, because your main
+<p class="note"><strong>Note:</strong> The {@code &lt;service&gt;} element in
+  the manifest doesn't need to include an intent filter because your main
   activity creates an explicit intent by specifying the name of the class to use
   for the intent.</p>
 
-<h3>Create a Geocoder</h3>
+<h3>Create a geocoder</h3>
 
 <p>The process of converting a geographic location to an address is called
-  <em>reverse geocoding</em>. To perform the main work of the intent service,
-  that is, your reverse geocoding request, implement
+  <em>reverse geocoding</em>. To perform the main work of the intent service (your reverse
+  geocoding request), implement
   {@link android.app.IntentService#onHandleIntent onHandleIntent()} within the
   {@code FetchAddressIntentService} class. Create a
   {@link android.location.Geocoder} object to handle the reverse geocoding.</p>
 
 <p>A locale represents a specific geographical or linguistic region. Locale
-  objects are used to adjust the presentation of information, such as numbers or
-  dates, to suit the conventions in the region represented by the locale. Pass a
+  objects adjust the presentation of information, such as numbers or
+  dates, to suit the conventions in the region that is represented by the locale. Pass a
   <a href="{@docRoot}reference/java/util/Locale.html">{@code Locale}</a> object
-  to the {@link android.location.Geocoder} object, to ensure that the resulting
-  address is localized to the user's geographic region.</p>
+  to the {@link android.location.Geocoder} object to ensure that the resulting
+  address is localized to the user's geographic region. Here is an example:</p>
 
 <pre>
 &#64;Override
@@ -162,7 +162,7 @@
 
 <h3 id="retrieve-street-address">Retrieve the street address data</h3>
 
-<p>The next step is to retrieve the street address from the geocoder, handle
+<p>You can now retrieve the street address from the geocoder, handle
   any errors that may occur, and send the results back to the activity that
   requested the address. To report the results of the geocoding
   process, you need two numeric constants that indicate success or failure.
@@ -185,32 +185,34 @@
 
 <p>To get a street address corresponding to a geographical location, call
   {@link android.location.Geocoder#getFromLocation getFromLocation()},
-  passing it the latitude and longitude from the location object, and the
-  maximum number of addresses you want returned. In this case, you want just one
-  address. The geocoder returns an array of addresses. If no addresses were
+  passing it the latitude and longitude from the location object and the
+  maximum number of addresses that you want returned. In this case, you want just one
+  address. The geocoder returns an array of addresses. If no addresses are
   found to match the given location, it returns an empty list. If there is no
   backend geocoding service available, the geocoder returns null.</p>
 
-<p>Check for the following errors as shown in the code sample below. If an error
-  occurs, place the corresponding error message in the {@code errorMessage}
-  variable, so you can send it back to the requesting activity:</p>
+<p>Check for the following errors, as shown in the code sample below:</p>
 
 <ul>
-  <li><strong>No location data provided</strong> - The intent extras do not
-    include the {@link android.location.Location} object required for reverse
+  <li><strong>No location data provided</strong> &ndash; The intent extras do not
+    include the {@link android.location.Location} object that is required for reverse
     geocoding.</li>
-  <li><strong>Invalid latitude or longitude used</strong> - The latitude
-    and/or longitude values provided in the {@link android.location.Location}
+  <li><strong>Invalid latitude or longitude used</strong> &ndash; The latitude
+    and/or longitude values that are provided in the {@link android.location.Location}
     object are invalid.</li>
-  <li><strong>No geocoder available</strong> - The background geocoding service
-    is not available, due to a network error or IO exception.</li>
-  <li><strong>Sorry, no address found</strong> - The geocoder could not find an
+  <li><strong>No geocoder available</strong> &ndash; The background geocoding service
+    is not available due to a network error or IO exception.</li>
+  <li><strong>Sorry, no address found</strong> &ndash; The geocoder can't find an
     address for the given latitude/longitude.</li>
 </ul>
 
+<p>If an error
+  occurs, place the corresponding error message in the {@code errorMessage}
+  variable so that you can send it back to the requesting activity.
+
 <p>To get the individual lines of an address object, use the
   {@link android.location.Address#getAddressLine getAddressLine()}
-  method provided by the {@link android.location.Address} class. Then join the
+  method that is provided by the {@link android.location.Address} class. Join the
   lines into a list of address fragments ready to return to the activity that
   requested the address.</p>
 
@@ -220,7 +222,7 @@
   results consist of the previously-mentioned numeric success/failure code and
   a string. In the case of a successful reverse geocoding, the string contains
   the address. In the case of a failure, the string contains the error message,
-  as shown in the code sample below:</p>
+  as shown in this code sample:</p>
 
 <pre>
 &#64;Override
@@ -280,18 +282,18 @@
 
 <h3 id="return-address">Return the address to the requestor</h3>
 
-<p>The final thing the intent service must do is send the address back to a
+<p>The final action that the intent service must complete is sending the address back to a
   {@link android.os.ResultReceiver} in the activity that started the service.
   The {@link android.os.ResultReceiver} class allows you to send a
   numeric result code as well as a message containing the result data. The
   numeric code is useful for reporting the success or failure of the geocoding
   request. In the case of a successful reverse geocoding, the message contains
   the address. In the case of a failure, the message contains some text
-  describing the reason for failure.</p>
+  describing the reason for the failure.</p>
 
 <p>You have already retrieved the address from the geocoder, trapped any errors
-  that may occur, and called the {@code deliverResultToReceiver()} method. Now
-  you need to define the {@code deliverResultToReceiver()} method that sends
+  that may occur, and called the {@code deliverResultToReceiver()} method, so now
+  you must define the {@code deliverResultToReceiver()} method that sends
   a result code and message bundle to the result receiver.</p>
 
 <p>For the result code, use the value that you've passed to the
@@ -299,7 +301,7 @@
   To construct the message bundle, concatenate the {@code RESULT_DATA_KEY}
   constant from your {@code Constants} class (defined in
   <a href="#retrieve-street-address">Retrieve the street address data</a>) and
-  the value in the {@code message} parameter passed to the
+  the value in the {@code message} parameter that is passed to the
   {@code deliverResultToReceiver()} method, as shown in the following sample:
 </p>
 
@@ -315,26 +317,26 @@
 }
 </pre>
 
-<h2 id="start-intent">Start the Intent Service</h2>
+<h2 id="start-intent">Start the intent service</h2>
 
 <p>The intent service, as defined in the previous section, runs in the
-  background and is responsible for fetching the address corresponding to a
+  background and fetches the address corresponding to a
   given geographic location. When you start the service, the Android framework
-  instantiates and starts the service if it isn't already running, and creates a
-  process if needed. If the service is already running then it remains running.
+  instantiates and starts the service if it isn't already running, and it creates a
+  process if needed. If the service is already running, it remains running.
   Because the service extends {@link android.app.IntentService IntentService},
-  it shuts down automatically when all intents have been processed.</p>
+  it shuts down automatically after all intents are processed.</p>
 
-<p>Start the service from your app's main activity,
+<p>Start the service from your app's main activity
   and create an {@link android.content.Intent} to pass data to the service. You
-  need an <em>explicit</em> intent, because you want only your service
+  need an <em>explicit</em> intent because you want only your service
   to respond to the intent. For more information, see
   <a href="{@docRoot}guide/components/intents-filters.html#Types">Intent
   Types</a>.</p>
 
 <p>To create an explicit intent, specify the name of the
   class to use for the service: {@code FetchAddressIntentService.class}.
-  Pass two pieces of information in the intent extras:</p>
+  Pass this information in the intent extras:</p>
 
 <ul>
   <li>A {@link android.os.ResultReceiver} to handle the results of the address
@@ -362,6 +364,12 @@
 }
 </pre>
 
+<p class="caution"><strong>Caution</strong>: To ensure that your app is secure, always use an
+explicit intent when starting a {@link android.app.Service} and do not declare intent filters for
+your services. Using an implicit intent to start a service is a security hazard because you cannot
+be certain of the service that will respond to the intent, and the user cannot see which service
+starts.</p>
+
 <p>Call the above {@code startIntentService()} method when the
   user takes an action that requires a geocoding address lookup. For example,
   the user may press a <em>Fetch address</em> button on your app's UI. Before
@@ -391,7 +399,7 @@
   app's UI. The following code snippet shows the call to the
   {@code startIntentService()} method in the
   <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">{@code onConnected()}</a>
-  callback provided by the Google API Client:</p>
+  callback that is provided by the Google API Client:</p>
 
 <pre>
 public class MainActivity extends ActionBarActivity implements
@@ -420,9 +428,9 @@
 }
 </pre>
 
-<h2 id="result-receiver">Receive the Geocoding Results</h2>
+<h2 id="result-receiver">Receive the geocoding results</h2>
 
-<p>The intent service has handled the geocoding request, and uses a
+<p>After the intent service handles the geocoding request, it uses a
   {@link android.os.ResultReceiver} to return the results to the activity that
   made the request. In the activity that makes the request, define an
   {@code AddressResultReceiver} that extends {@link android.os.ResultReceiver}
@@ -430,14 +438,14 @@
 
 <p>The result includes a numeric result code (<code>resultCode</code>) as well
   as a message containing the result data (<code>resultData</code>). If the
-  reverse geocoding process was successful, the <code>resultData</code> contains
+  reverse geocoding process is successful, the <code>resultData</code> contains
   the address. In the case of a failure, the <code>resultData</code> contains
-  text describing the reason for failure. For details of the possible errors,
+  text describing the reason for the failure. For details of the possible errors,
   see <a href="#return-address">Return the address to the requestor</a>.</p>
 
 <p>Override the
   {@link android.os.ResultReceiver#onReceiveResult onReceiveResult()} method
-  to handle the results delivered to the result receiver, as shown in the
+  to handle the results that are delivered to the result receiver, as shown in the
   following code sample:</p>
 
 <pre>
diff --git a/docs/html/training/run-background-service/index.jd b/docs/html/training/run-background-service/index.jd
index 22f3fc8..c48c681 100644
--- a/docs/html/training/run-background-service/index.jd
+++ b/docs/html/training/run-background-service/index.jd
@@ -35,16 +35,22 @@
 <!-- ------------------------------------------------------------------------------------------- -->
 <p>
     Unless you specify otherwise, most of the operations you do in an app run in the foreground on
-    a special thread called the UI thread. This can cause problems, because long-running operations
-    will interfere with the responsiveness of your user interface. This annoys your users, and can
+    a special thread called the UI thread. Long-running foreground operations can cause problems
+    and interfere with the responsiveness of your user interface, which annoys your users and can
     even cause system errors. To avoid this, the Android framework offers several classes that
-    help you off-load operations onto a separate thread running in the background. The most useful
-    of these is {@link android.app.IntentService}.
+    help you off-load operations onto a separate thread that runs in the background. The most
+    useful of these is {@link android.app.IntentService}.
 </p>
 <p>
     This class describes how to implement an {@link android.app.IntentService}, send it work
     requests, and report its results to other components.
 </p>
+
+<p class="note"><strong>Note:</strong> If your app targets Android 5.0 (API level 21),
+    you should use {@link android.app.job.JobScheduler} to execute background
+    services. For more information about this class,
+    see the {@link android.app.job.JobScheduler} reference documentation.</p>
+
 <h2>Lessons</h2>
 <dl>
     <dt>
diff --git a/include/androidfw/Asset.h b/include/androidfw/Asset.h
index 52c8637..11709ce 100644
--- a/include/androidfw/Asset.h
+++ b/include/androidfw/Asset.h
@@ -26,11 +26,12 @@
 
 #include <utils/Compat.h>
 #include <utils/Errors.h>
-#include <utils/FileMap.h>
 #include <utils/String8.h>
 
 namespace android {
 
+class FileMap;
+
 /*
  * Instances of this class provide read-only operations on a byte stream.
  *
diff --git a/include/androidfw/AssetManager.h b/include/androidfw/AssetManager.h
index 7aec323..4377213 100644
--- a/include/androidfw/AssetManager.h
+++ b/include/androidfw/AssetManager.h
@@ -70,11 +70,11 @@
     static const char* IDMAP_BIN;
     static const char* OVERLAY_DIR;
     /*
-     * If OVERLAY_SKU_DIR_PROPERTY is set, search for runtime resource overlay
-     * APKs in OVERLAY_DIR/<value of OVERLAY_SKU_DIR_PROPERTY> in addition to
+     * If OVERLAY_THEME_DIR_PROPERTY is set, search for runtime resource overlay
+     * APKs in OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to
      * OVERLAY_DIR.
      */
-    static const char* OVERLAY_SKU_DIR_PROPERTY;
+    static const char* OVERLAY_THEME_DIR_PROPERTY;
     static const char* TARGET_PACKAGE_NAME;
     static const char* TARGET_APK_PATH;
     static const char* IDMAP_DIR;
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 6349e86..08d6591 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -22,7 +22,6 @@
 
 #include <androidfw/Asset.h>
 #include <androidfw/LocaleData.h>
-#include <utils/ByteOrder.h>
 #include <utils/Errors.h>
 #include <utils/String16.h>
 #include <utils/Vector.h>
diff --git a/include/androidfw/TypeWrappers.h b/include/androidfw/TypeWrappers.h
index 7bdf8af..4233b6b 100644
--- a/include/androidfw/TypeWrappers.h
+++ b/include/androidfw/TypeWrappers.h
@@ -18,6 +18,7 @@
 #define __TYPE_WRAPPERS_H
 
 #include <androidfw/ResourceTypes.h>
+#include <utils/ByteOrder.h>
 
 namespace android {
 
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 371bc9a..46fc9d4 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -73,7 +73,7 @@
 const char* AssetManager::RESOURCES_FILENAME = "resources.arsc";
 const char* AssetManager::IDMAP_BIN = "/system/bin/idmap";
 const char* AssetManager::OVERLAY_DIR = "/vendor/overlay";
-const char* AssetManager::OVERLAY_SKU_DIR_PROPERTY = "ro.boot.vendor.overlay.sku";
+const char* AssetManager::OVERLAY_THEME_DIR_PROPERTY = "ro.boot.vendor.overlay.theme";
 const char* AssetManager::TARGET_PACKAGE_NAME = "android";
 const char* AssetManager::TARGET_APK_PATH = "/system/framework/framework-res.apk";
 const char* AssetManager::IDMAP_DIR = "/data/resource-cache";
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 0aa7808..06eb829 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -18,6 +18,12 @@
     hwui/MinikinUtils.cpp \
     hwui/PaintImpl.cpp \
     hwui/Typeface.cpp \
+    pipeline/skia/GLFunctorDrawable.cpp \
+    pipeline/skia/LayerDrawable.cpp \
+    pipeline/skia/RenderNodeDrawable.cpp \
+    pipeline/skia/ReorderBarrierDrawables.cpp \
+    pipeline/skia/SkiaDisplayList.cpp \
+    pipeline/skia/SkiaRecordingCanvas.cpp \
     renderstate/Blend.cpp \
     renderstate/MeshState.cpp \
     renderstate/OffscreenBufferPool.cpp \
@@ -38,7 +44,6 @@
     utils/Blur.cpp \
     utils/GLUtils.cpp \
     utils/LinearAllocator.cpp \
-    utils/NinePatchImpl.cpp \
     utils/StringUtils.cpp \
     utils/TestWindowContext.cpp \
     utils/VectorDrawableUtils.cpp \
@@ -80,6 +85,7 @@
     PathParser.cpp \
     PathTessellator.cpp \
     PixelBuffer.cpp \
+    ProfileRenderer.cpp \
     Program.cpp \
     ProgramCache.cpp \
     Properties.cpp \
@@ -94,7 +100,6 @@
     ShadowTessellator.cpp \
     SkiaCanvas.cpp \
     SkiaCanvasProxy.cpp \
-    SkiaDisplayList.cpp \
     SkiaShader.cpp \
     Snapshot.cpp \
     SpotShadow.cpp \
@@ -169,6 +174,7 @@
 hwui_c_includes += \
     external/skia/include/private \
     external/skia/src/core \
+    external/skia/src/effects \
     external/harfbuzz_ng/src \
     external/freetype/include
 
@@ -265,6 +271,7 @@
     tests/unit/BakedOpDispatcherTests.cpp \
     tests/unit/BakedOpRendererTests.cpp \
     tests/unit/BakedOpStateTests.cpp \
+    tests/unit/CanvasContextTests.cpp \
     tests/unit/CanvasStateTests.cpp \
     tests/unit/ClipAreaTests.cpp \
     tests/unit/DamageAccumulatorTests.cpp \
@@ -283,6 +290,7 @@
     tests/unit/MeshStateTests.cpp \
     tests/unit/OffscreenBufferPoolTests.cpp \
     tests/unit/OpDumperTests.cpp \
+    tests/unit/RenderNodeDrawableTests.cpp \
     tests/unit/RecordingCanvasTests.cpp \
     tests/unit/RenderNodeTests.cpp \
     tests/unit/RenderPropertiesTests.cpp \
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 840c79d..6079d5d 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -46,7 +46,7 @@
         const MergedBakedOpList& opList) {
 
     const BakedOpState& firstState = *(opList.states[0]);
-    const SkBitmap* bitmap = (static_cast<const BitmapOp*>(opList.states[0]->op))->bitmap;
+    Bitmap* bitmap = (static_cast<const BitmapOp*>(opList.states[0]->op))->bitmap;
 
     Texture* texture = renderer.caches().textureCache.get(bitmap);
     if (!texture) return;
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index ac7a600..e8972aa 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -181,7 +181,7 @@
     if (!mRenderTarget.frameBufferId) mHasDrawn = true;
 }
 
-Texture* BakedOpRenderer::getTexture(const SkBitmap* bitmap) {
+Texture* BakedOpRenderer::getTexture(Bitmap* bitmap) {
     return mCaches.textureCache.get(bitmap);
 }
 
diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h
index 62bc564..4d76a3d 100644
--- a/libs/hwui/BakedOpRenderer.h
+++ b/libs/hwui/BakedOpRenderer.h
@@ -74,7 +74,7 @@
     void endLayer();
     WARN_UNUSED_RESULT OffscreenBuffer* copyToLayer(const Rect& area);
 
-    Texture* getTexture(const SkBitmap* bitmap);
+    Texture* getTexture(Bitmap* bitmap);
     const LightInfo& getLightInfo() const { return mLightInfo; }
 
     void renderGlop(const BakedOpState& state, const Glop& glop) {
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 6e7d11f..5213d48 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -106,9 +106,9 @@
 bool DisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLayer,
         std::function<void(RenderNode*, TreeInfo&, bool)> childFn) {
     TextureCache& cache = Caches::getInstance().textureCache;
-    for (auto&& bitmapResource : bitmapResources) {
+    for (auto& bitmapResource : bitmapResources) {
         void* ownerToken = &info.canvasContext;
-        info.prepareTextures = cache.prefetchAndMarkInUse(ownerToken, bitmapResource);
+        info.prepareTextures = cache.prefetchAndMarkInUse(ownerToken, bitmapResource.get());
     }
     for (auto&& op : children) {
         RenderNode* childNode = op->renderNode;
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 06b0891..cab092f 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -38,6 +38,7 @@
 #include "Matrix.h"
 #include "RenderProperties.h"
 #include "TreeInfo.h"
+#include "hwui/Bitmap.h"
 
 #include <vector>
 
@@ -101,7 +102,7 @@
 
     const LsaVector<NodeOpType*>& getChildren() const { return children; }
 
-    const LsaVector<const SkBitmap*>& getBitmapResources() const { return bitmapResources; }
+    const LsaVector<sk_sp<Bitmap>>& getBitmapResources() const { return bitmapResources; }
 
     size_t addChild(NodeOpType* childOp);
 
@@ -140,7 +141,7 @@
     LsaVector<NodeOpType*> children;
 
     // Resources - Skia objects + 9 patches referred to by this DisplayList
-    LsaVector<const SkBitmap*> bitmapResources;
+    LsaVector<sk_sp<Bitmap>> bitmapResources;
     LsaVector<const SkPath*> pathResources;
     LsaVector<const Res_png_9patch*> patchResources;
     LsaVector<std::unique_ptr<const SkPaint>> paints;
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index f35d605..245db1d 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -631,7 +631,7 @@
 }
 
 void FrameBuilder::deferVectorDrawableOp(const VectorDrawableOp& op) {
-    const SkBitmap& bitmap = op.vectorDrawable->getBitmapUpdateIfDirty();
+    Bitmap& bitmap = op.vectorDrawable->getBitmapUpdateIfDirty();
     SkPaint* paint = op.vectorDrawable->getPaint();
     const BitmapRectOp* resolvedOp = mAllocator.create_trivial<BitmapRectOp>(op.unmappedBounds,
             op.localMatrix,
diff --git a/libs/hwui/FrameInfoVisualizer.cpp b/libs/hwui/FrameInfoVisualizer.cpp
index 570322d..d3adc32 100644
--- a/libs/hwui/FrameInfoVisualizer.cpp
+++ b/libs/hwui/FrameInfoVisualizer.cpp
@@ -16,6 +16,7 @@
 #include "FrameInfoVisualizer.h"
 
 #include "BakedOpRenderer.h"
+#include "IProfileRenderer.h"
 #include "utils/Color.h"
 
 #include <cutils/compiler.h>
@@ -88,7 +89,7 @@
     }
 }
 
-void FrameInfoVisualizer::draw(ContentRenderer* renderer) {
+void FrameInfoVisualizer::draw(IProfileRenderer& renderer) {
     RETURN_IF_DISABLED();
 
     if (mShowDirtyRegions) {
@@ -96,8 +97,8 @@
         if (mFlashToggle) {
             SkPaint paint;
             paint.setColor(0x7fff0000);
-            renderer->drawRect(mDirtyRegion.fLeft, mDirtyRegion.fTop,
-                    mDirtyRegion.fRight, mDirtyRegion.fBottom, &paint);
+            renderer.drawRect(mDirtyRegion.fLeft, mDirtyRegion.fTop,
+                    mDirtyRegion.fRight, mDirtyRegion.fBottom, paint);
         }
     }
 
@@ -111,7 +112,7 @@
         info.markSwapBuffers();
         info.markFrameCompleted();
 
-        initializeRects(renderer->getViewportHeight(), renderer->getViewportWidth());
+        initializeRects(renderer.getViewportHeight(), renderer.getViewportWidth());
         drawGraph(renderer);
         drawThreshold(renderer);
     }
@@ -194,26 +195,26 @@
     }
 }
 
-void FrameInfoVisualizer::drawGraph(ContentRenderer* renderer) {
+void FrameInfoVisualizer::drawGraph(IProfileRenderer& renderer) {
     SkPaint paint;
     for (size_t i = 0; i < Bar.size(); i++) {
         nextBarSegment(Bar[i].start, Bar[i].end);
         paint.setColor(Bar[i].color & BAR_FAST_MASK);
-        renderer->drawRects(mFastRects.get(), mNumFastRects * 4, &paint);
+        renderer.drawRects(mFastRects.get(), mNumFastRects * 4, paint);
         paint.setColor(Bar[i].color & BAR_JANKY_MASK);
-        renderer->drawRects(mJankyRects.get(), mNumJankyRects * 4, &paint);
+        renderer.drawRects(mJankyRects.get(), mNumJankyRects * 4, paint);
     }
 }
 
-void FrameInfoVisualizer::drawThreshold(ContentRenderer* renderer) {
+void FrameInfoVisualizer::drawThreshold(IProfileRenderer& renderer) {
     SkPaint paint;
     paint.setColor(THRESHOLD_COLOR);
-    float yLocation = renderer->getViewportHeight() - (FRAME_THRESHOLD * mVerticalUnit);
-    renderer->drawRect(0.0f,
+    float yLocation = renderer.getViewportHeight() - (FRAME_THRESHOLD * mVerticalUnit);
+    renderer.drawRect(0.0f,
             yLocation - mThresholdStroke/2,
-            renderer->getViewportWidth(),
+            renderer.getViewportWidth(),
             yLocation + mThresholdStroke/2,
-            &paint);
+            paint);
 }
 
 bool FrameInfoVisualizer::consumeProperties() {
diff --git a/libs/hwui/FrameInfoVisualizer.h b/libs/hwui/FrameInfoVisualizer.h
index d60c002..b98f501 100644
--- a/libs/hwui/FrameInfoVisualizer.h
+++ b/libs/hwui/FrameInfoVisualizer.h
@@ -28,8 +28,7 @@
 namespace android {
 namespace uirenderer {
 
-class BakedOpRenderer;
-typedef BakedOpRenderer ContentRenderer;
+class IProfileRenderer;
 
 // TODO: This is a bit awkward as it needs to match the thing in CanvasContext
 // A better abstraction here would be nice but iterators are painful
@@ -47,7 +46,7 @@
     void setDensity(float density);
 
     void unionDirty(SkRect* dirty);
-    void draw(ContentRenderer* renderer);
+    void draw(IProfileRenderer& renderer);
 
     void dumpData(int fd);
 
@@ -57,8 +56,8 @@
 
     void initializeRects(const int baseline, const int width);
     void nextBarSegment(FrameInfoIndex start, FrameInfoIndex end);
-    void drawGraph(ContentRenderer* renderer);
-    void drawThreshold(ContentRenderer* renderer);
+    void drawGraph(IProfileRenderer& renderer);
+    void drawThreshold(IProfileRenderer& renderer);
 
     inline float durationMS(size_t index, FrameInfoIndex start, FrameInfoIndex end) {
         float duration = mFrameSource[index].duration(start, end) * 0.000001f;
diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h
index 46dd598..b396e22 100644
--- a/libs/hwui/Glop.h
+++ b/libs/hwui/Glop.h
@@ -119,7 +119,6 @@
 
         struct TextureData {
             Texture* texture;
-            GLenum target;
             GLenum filter;
             GLenum clamp;
             Matrix4* textureTransform;
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index f14b50a..3b5fc71 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -308,8 +308,7 @@
 
     GLenum filter = (textureFillFlags & TextureFillFlags::ForceFilter)
             ? GL_LINEAR : PaintUtils::getFilter(paint);
-    mOutGlop->fill.texture = { &texture,
-            GL_TEXTURE_2D, filter, GL_CLAMP_TO_EDGE, nullptr };
+    mOutGlop->fill.texture = { &texture, filter, GL_CLAMP_TO_EDGE, nullptr };
 
     if (paint) {
         int color = paint->getColor();
@@ -352,10 +351,10 @@
 
     if (CC_LIKELY(!shadowInterp)) {
         mOutGlop->fill.texture = {
-                nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
+                nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
     } else {
         mOutGlop->fill.texture = {
-                mCaches.textureState().getShadowLutTexture(), GL_TEXTURE_2D,
+                mCaches.textureState().getShadowLutTexture(),
                 GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
     }
 
@@ -373,7 +372,7 @@
     REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
 
     //specify invalid filter/clamp, since these are always static for PathTextures
-    mOutGlop->fill.texture = { &texture, GL_TEXTURE_2D, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
+    mOutGlop->fill.texture = { &texture, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
 
     setFill(paint.getColor(), alphaScale,
             paint.getBlendMode(), Blend::ModeOrderSwap::NoSwap,
@@ -390,7 +389,7 @@
     REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
 
     //specify invalid filter/clamp, since these are always static for ShadowTextures
-    mOutGlop->fill.texture = { &texture, GL_TEXTURE_2D, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
+    mOutGlop->fill.texture = { &texture, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
 
     const int ALPHA_BITMASK = SK_ColorBLACK;
     const int COLOR_BITMASK = ~ALPHA_BITMASK;
@@ -412,7 +411,7 @@
     TRIGGER_STAGE(kFillStage);
     REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
 
-    mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
+    mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
     setFill(SK_ColorBLACK, 1.0f, SkBlendMode::kSrcOver, Blend::ModeOrderSwap::NoSwap,
             nullptr, nullptr);
     return *this;
@@ -422,7 +421,7 @@
     TRIGGER_STAGE(kFillStage);
     REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
 
-    mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
+    mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
     setFill(SK_ColorBLACK, 1.0f, SkBlendMode::kClear, Blend::ModeOrderSwap::NoSwap,
             nullptr, nullptr);
     return *this;
@@ -433,8 +432,7 @@
     TRIGGER_STAGE(kFillStage);
     REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
 
-    mOutGlop->fill.texture = { &texture,
-            GL_TEXTURE_2D, GL_LINEAR, GL_CLAMP_TO_EDGE, nullptr };
+    mOutGlop->fill.texture = { &texture, GL_LINEAR, GL_CLAMP_TO_EDGE, nullptr };
 
     setFill(SK_ColorWHITE, alpha, mode, modeUsage, nullptr, colorFilter);
 
@@ -447,7 +445,7 @@
     REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
 
     mOutGlop->fill.texture = { &(layer.getTexture()),
-            layer.getRenderTarget(), GL_LINEAR, GL_CLAMP_TO_EDGE, &layer.getTexTransform() };
+            GL_LINEAR, GL_CLAMP_TO_EDGE, &layer.getTexTransform() };
 
     setFill(SK_ColorWHITE, alpha, layer.getMode(), Blend::ModeOrderSwap::NoSwap,
             nullptr, layer.getColorFilter());
@@ -461,9 +459,7 @@
     TRIGGER_STAGE(kFillStage);
     REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
 
-    mOutGlop->fill.texture = { &texture,
-            GL_TEXTURE_EXTERNAL_OES, GL_LINEAR, GL_CLAMP_TO_EDGE,
-            &textureTransform };
+    mOutGlop->fill.texture = { &texture, GL_LINEAR, GL_CLAMP_TO_EDGE, &textureTransform };
 
     setFill(SK_ColorWHITE, 1.0f, SkBlendMode::kSrc, Blend::ModeOrderSwap::NoSwap,
             nullptr, nullptr);
@@ -603,7 +599,7 @@
 void GlopBuilder::build() {
     REQUIRE_STAGES(kAllStages);
     if (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) {
-        if (mOutGlop->fill.texture.target == GL_TEXTURE_2D) {
+        if (mOutGlop->fill.texture.texture->target() == GL_TEXTURE_2D) {
             mDescription.hasTexture = true;
         } else {
             mDescription.hasExternalTexture = true;
@@ -668,7 +664,8 @@
     ALOGD("    program %p", fill.program);
     if (fill.texture.texture) {
         ALOGD("    texture %p, target %d, filter %d, clamp %d",
-                fill.texture.texture, fill.texture.target, fill.texture.filter, fill.texture.clamp);
+                fill.texture.texture, fill.texture.texture->target(),
+                fill.texture.filter, fill.texture.clamp);
         if (fill.texture.textureTransform) {
             fill.texture.textureTransform->dump("texture transform");
         }
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
index d511ccb..8a8b652 100644
--- a/libs/hwui/GlopBuilder.h
+++ b/libs/hwui/GlopBuilder.h
@@ -72,9 +72,8 @@
     GlopBuilder& setFillLayer(Texture& texture, const SkColorFilter* colorFilter,
             float alpha, SkBlendMode mode, Blend::ModeOrderSwap modeUsage);
     GlopBuilder& setFillTextureLayer(Layer& layer, float alpha);
-    // TODO: Texture should probably know and own its target.
-    // setFillLayer() forces it to GL_TEXTURE which isn't always correct.
-    // Similarly setFillLayer normally forces its own wrap & filter mode
+    // TODO: setFillLayer normally forces its own wrap & filter mode,
+    // which isn't always correct.
     GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform);
 
     GlopBuilder& setTransform(const Matrix4& canvas, const int transformFlags);
diff --git a/libs/hwui/IProfileRenderer.h b/libs/hwui/IProfileRenderer.h
new file mode 100644
index 0000000..947ed34
--- /dev/null
+++ b/libs/hwui/IProfileRenderer.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 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 "SkPaint.h"
+
+namespace android {
+namespace uirenderer {
+
+class IProfileRenderer {
+public:
+    virtual void drawRect(float left, float top, float right, float bottom,
+            const SkPaint& paint) = 0;
+    virtual void drawRects(const float* rects, int count, const SkPaint& paint) = 0;
+    virtual uint32_t getViewportWidth() = 0;
+    virtual uint32_t getViewportHeight() = 0;
+
+    virtual ~IProfileRenderer() {}
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 4e12bce..88817ef 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -41,7 +41,6 @@
     // TODO: This is a violation of Android's typical ref counting, but it
     // preserves the old inc/dec ref locations. This should be changed...
     incStrong(nullptr);
-    renderTarget = GL_NONE;  // see DeferredLayerUpdater::updateLayer()
     texture.mWidth = layerWidth;
     texture.mHeight = layerHeight;
     renderState.registerLayer(this);
@@ -66,7 +65,7 @@
 
 void Layer::bindTexture() const {
     if (texture.mId) {
-        caches.textureState().bindTexture(renderTarget, texture.mId);
+        caches.textureState().bindTexture(texture.target(), texture.mId);
     }
 }
 
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 9874ce2..8e71cd1 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -75,7 +75,8 @@
     }
 
     void setSize(uint32_t width, uint32_t height) {
-        texture.updateSize(width, height, texture.internalFormat(), texture.format());
+        texture.updateSize(width, height, texture.internalFormat(), texture.format(),
+                texture.target());
     }
 
     inline void setBlend(bool blend) {
@@ -120,23 +121,23 @@
     }
 
     inline GLenum getRenderTarget() const {
-        return renderTarget;
+        return texture.target();
     }
 
     inline void setRenderTarget(GLenum renderTarget) {
-        this->renderTarget = renderTarget;
+        texture.mTarget = renderTarget;
     }
 
     inline bool isRenderable() const {
-        return renderTarget != GL_NONE;
+        return texture.target() != GL_NONE;
     }
 
     void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
-        texture.setWrap(wrap, bindTexture, force, renderTarget);
+        texture.setWrap(wrap, bindTexture, force);
     }
 
     void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
-        texture.setFilter(filter, bindTexture, force, renderTarget);
+        texture.setFilter(filter, bindTexture, force);
     }
 
     inline SkColorFilter* getColorFilter() const {
@@ -186,11 +187,6 @@
     Texture texture;
 
     /**
-     * Indicates the render target.
-     */
-    GLenum renderTarget = GL_TEXTURE_2D;
-
-    /**
      * Color filter used to draw this layer. Optional.
      */
     SkColorFilter* colorFilter = nullptr;
diff --git a/libs/hwui/NinePatchUtils.h b/libs/hwui/NinePatchUtils.h
new file mode 100644
index 0000000..e989a46
--- /dev/null
+++ b/libs/hwui/NinePatchUtils.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+namespace android {
+namespace NinePatchUtils {
+
+static inline void SetLatticeDivs(SkCanvas::Lattice* lattice, const Res_png_9patch& chunk,
+        int width, int height) {
+    lattice->fXCount = chunk.numXDivs;
+    lattice->fYCount = chunk.numYDivs;
+    lattice->fXDivs = chunk.getXDivs();
+    lattice->fYDivs = chunk.getYDivs();
+
+    // We'll often see ninepatches where the last div is equal to the width or height.
+    // This doesn't provide any additional information and is not supported by Skia.
+    if (lattice->fXCount > 0 && width == lattice->fXDivs[lattice->fXCount - 1]) {
+        lattice->fXCount--;
+    }
+    if (lattice->fYCount > 0 && height == lattice->fYDivs[lattice->fYCount - 1]) {
+        lattice->fYCount--;
+    }
+}
+
+static inline int NumDistinctRects(const SkCanvas::Lattice& lattice) {
+    int xRects;
+    if (lattice.fXCount > 0) {
+        xRects = (0 == lattice.fXDivs[0]) ? lattice.fXCount : lattice.fXCount + 1;
+    } else {
+        xRects = 1;
+    }
+
+    int yRects;
+    if (lattice.fYCount > 0) {
+        yRects = (0 == lattice.fYDivs[0]) ? lattice.fYCount : lattice.fYCount + 1;
+    } else {
+        yRects = 1;
+    }
+    return xRects * yRects;
+}
+
+static inline void SetLatticeFlags(SkCanvas::Lattice* lattice, SkCanvas::Lattice::Flags* flags,
+        int numFlags, const Res_png_9patch& chunk) {
+    lattice->fFlags = flags;
+    sk_bzero(flags, numFlags * sizeof(SkCanvas::Lattice::Flags));
+
+    bool needPadRow = lattice->fYCount > 0 && 0 == lattice->fYDivs[0];
+    bool needPadCol = lattice->fXCount > 0 && 0 == lattice->fXDivs[0];
+
+    int yCount = lattice->fYCount;
+    if (needPadRow) {
+        // Skip flags for the degenerate first row of rects.
+        flags += lattice->fXCount + 1;
+        yCount--;
+    }
+
+    int i = 0;
+    bool setFlags = false;
+    for (int y = 0; y < yCount + 1; y++) {
+        for (int x = 0; x < lattice->fXCount + 1; x++) {
+            if (0 == x && needPadCol) {
+                // First rect of each column is degenerate, skip the flag.
+                flags++;
+                continue;
+            }
+
+            if (0 == chunk.getColors()[i++]) {
+                *flags = SkCanvas::Lattice::kTransparent_Flags;
+                setFlags = true;
+            }
+
+            flags++;
+        }
+    }
+
+    if (!setFlags) {
+        lattice->fFlags = nullptr;
+    }
+}
+
+}; // namespace NinePatchUtils
+}; // namespace android
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index d46c46f93..cc96de7 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -138,11 +138,6 @@
     height = uint32_t(pathHeight + texture->offset * 2.0 + 0.5);
 }
 
-static void initBitmap(SkBitmap& bitmap, uint32_t width, uint32_t height) {
-    bitmap.allocPixels(SkImageInfo::MakeA8(width, height));
-    bitmap.eraseColor(0);
-}
-
 static void initPaint(SkPaint& paint) {
     // Make sure the paint is opaque, color, alpha, filter, etc.
     // will be applied later when compositing the alpha8 texture
@@ -154,7 +149,7 @@
     paint.setBlendMode(SkBlendMode::kSrc);
 }
 
-static SkBitmap* drawPath(const SkPath* path, const SkPaint* paint, PathTexture* texture,
+static sk_sp<Bitmap> drawPath(const SkPath* path, const SkPaint* paint, PathTexture* texture,
         uint32_t maxTextureSize) {
     uint32_t width, height;
     computePathBounds(path, paint, texture, width, height);
@@ -164,13 +159,14 @@
         return nullptr;
     }
 
-    SkBitmap* bitmap = new SkBitmap();
-    initBitmap(*bitmap, width, height);
-
+    sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(width, height));
     SkPaint pathPaint(*paint);
     initPaint(pathPaint);
 
-    SkCanvas canvas(*bitmap);
+    SkBitmap skBitmap;
+    bitmap->getSkBitmap(&skBitmap);
+    skBitmap.eraseColor(0);
+    SkCanvas canvas(skBitmap);
     canvas.translate(-texture->left + texture->offset, -texture->top + texture->offset);
     canvas.drawPath(*path, pathPaint);
     return bitmap;
@@ -227,7 +223,7 @@
 
         // If there is a pending task we must wait for it to return
         // before attempting our cleanup
-        const sp<Task<SkBitmap*> >& task = texture->task();
+        const sp<PathTask>& task = texture->task();
         if (task != nullptr) {
             task->getResult();
             texture->clearTask();
@@ -280,20 +276,20 @@
     ATRACE_NAME("Generate Path Texture");
 
     PathTexture* texture = new PathTexture(Caches::getInstance(), path->getGenerationID());
-    std::unique_ptr<SkBitmap> bitmap(drawPath(path, paint, texture, mMaxTextureSize));
-    if (!bitmap.get()) {
+    sk_sp<Bitmap> bitmap(drawPath(path, paint, texture, mMaxTextureSize));
+    if (!bitmap) {
         delete texture;
         return nullptr;
     }
 
     purgeCache(bitmap->width(), bitmap->height());
-    generateTexture(entry, bitmap.get(), texture);
+    generateTexture(entry, *bitmap, texture);
     return texture;
 }
 
-void PathCache::generateTexture(const PathDescription& entry, SkBitmap* bitmap,
+void PathCache::generateTexture(const PathDescription& entry, Bitmap& bitmap,
         PathTexture* texture, bool addToCache) {
-    generateTexture(*bitmap, texture);
+    generateTexture(bitmap, texture);
 
     // Note here that we upload to a texture even if it's bigger than mMaxSize.
     // Such an entry in mCache will only be temporary, since it will be evicted
@@ -314,7 +310,7 @@
     mCache.clear();
 }
 
-void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) {
+void PathCache::generateTexture(Bitmap& bitmap, Texture* texture) {
     ATRACE_NAME("Upload Path Texture");
     texture->upload(bitmap);
     texture->setFilter(GL_LINEAR);
@@ -325,10 +321,10 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 PathCache::PathProcessor::PathProcessor(Caches& caches):
-        TaskProcessor<SkBitmap*>(&caches.tasks), mMaxTextureSize(caches.maxTextureSize) {
+        TaskProcessor<sk_sp<Bitmap> >(&caches.tasks), mMaxTextureSize(caches.maxTextureSize) {
 }
 
-void PathCache::PathProcessor::onProcess(const sp<Task<SkBitmap*> >& task) {
+void PathCache::PathProcessor::onProcess(const sp<Task<sk_sp<Bitmap> > >& task) {
     PathTask* t = static_cast<PathTask*>(task.get());
     ATRACE_NAME("pathPrecache");
 
@@ -377,13 +373,13 @@
     } else {
         // A bitmap is attached to the texture, this means we need to
         // upload it as a GL texture
-        const sp<Task<SkBitmap*> >& task = texture->task();
+        const sp<PathTask>& task = texture->task();
         if (task != nullptr) {
             // But we must first wait for the worker thread to be done
             // producing the bitmap, so let's wait
-            SkBitmap* bitmap = task->getResult();
+            sk_sp<Bitmap> bitmap = task->getResult();
             if (bitmap) {
-                generateTexture(entry, bitmap, texture, false);
+                generateTexture(entry, *bitmap, texture, false);
                 texture->clearTask();
             } else {
                 texture->clearTask();
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index 18bcc56..7bd190d 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -19,6 +19,7 @@
 
 #include "Debug.h"
 #include "Texture.h"
+#include "hwui/Bitmap.h"
 #include "thread/Task.h"
 #include "thread/TaskProcessor.h"
 #include "utils/Macros.h"
@@ -32,7 +33,6 @@
 
 #include <vector>
 
-class SkBitmap;
 class SkCanvas;
 class SkPaint;
 struct SkRect;
@@ -41,7 +41,6 @@
 namespace uirenderer {
 
 class Caches;
-
 ///////////////////////////////////////////////////////////////////////////////
 // Defines
 ///////////////////////////////////////////////////////////////////////////////
@@ -57,6 +56,21 @@
 // Classes
 ///////////////////////////////////////////////////////////////////////////////
 
+struct PathTexture;
+class PathTask: public Task<sk_sp<Bitmap>> {
+public:
+    PathTask(const SkPath* path, const SkPaint* paint, PathTexture* texture):
+        path(*path), paint(*paint), texture(texture) {
+    }
+
+    // copied, since input path not guaranteed to survive for duration of task
+    const SkPath path;
+
+    // copied, since input paint may not be immutable
+    const SkPaint paint;
+    PathTexture* texture;
+};
+
 /**
  * Alpha texture used to represent a path.
  */
@@ -83,11 +97,11 @@
      */
     float offset = 0;
 
-    sp<Task<SkBitmap*> > task() const {
+    sp<PathTask> task() const {
         return mTask;
     }
 
-    void setTask(const sp<Task<SkBitmap*> >& task) {
+    void setTask(const sp<PathTask>& task) {
         mTask = task;
     }
 
@@ -98,7 +112,7 @@
     }
 
 private:
-    sp<Task<SkBitmap*> > mTask;
+    sp<PathTask> mTask;
 }; // struct PathTexture
 
 enum class ShapeType {
@@ -222,13 +236,12 @@
 private:
     PathTexture* addTexture(const PathDescription& entry,
             const SkPath *path, const SkPaint* paint);
-    PathTexture* addTexture(const PathDescription& entry, SkBitmap* bitmap);
 
     /**
      * Generates the texture from a bitmap into the specified texture structure.
      */
-    void generateTexture(SkBitmap& bitmap, Texture* texture);
-    void generateTexture(const PathDescription& entry, SkBitmap* bitmap, PathTexture* texture,
+    void generateTexture(Bitmap& bitmap, Texture* texture);
+    void generateTexture(const PathDescription& entry, Bitmap& bitmap, PathTexture* texture,
             bool addToCache = true);
 
     PathTexture* get(const PathDescription& entry) {
@@ -245,30 +258,13 @@
 
     void init();
 
-    class PathTask: public Task<SkBitmap*> {
-    public:
-        PathTask(const SkPath* path, const SkPaint* paint, PathTexture* texture):
-            path(*path), paint(*paint), texture(texture) {
-        }
 
-        ~PathTask() {
-            delete future()->get();
-        }
-
-        // copied, since input path not guaranteed to survive for duration of task
-        const SkPath path;
-
-        // copied, since input paint may not be immutable
-        const SkPaint paint;
-        PathTexture* texture;
-    };
-
-    class PathProcessor: public TaskProcessor<SkBitmap*> {
+    class PathProcessor: public TaskProcessor<sk_sp<Bitmap> > {
     public:
         explicit PathProcessor(Caches& caches);
         ~PathProcessor() { }
 
-        virtual void onProcess(const sp<Task<SkBitmap*> >& task) override;
+        virtual void onProcess(const sp<Task<sk_sp<Bitmap> > >& task) override;
 
     private:
         uint32_t mMaxTextureSize;
diff --git a/libs/hwui/ProfileRenderer.cpp b/libs/hwui/ProfileRenderer.cpp
new file mode 100644
index 0000000..0ad484c
--- /dev/null
+++ b/libs/hwui/ProfileRenderer.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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 "ProfileRenderer.h"
+
+namespace android {
+namespace uirenderer {
+
+void ProfileRenderer::drawRect(float left, float top, float right, float bottom,
+        const SkPaint& paint) {
+    mRenderer.drawRect(left, top, right, bottom, &paint);
+}
+
+void ProfileRenderer::drawRects(const float* rects, int count, const SkPaint& paint) {
+    mRenderer.drawRects(rects, count, &paint);
+}
+
+uint32_t ProfileRenderer::getViewportWidth() {
+    return mRenderer.getViewportWidth();
+}
+
+uint32_t ProfileRenderer::getViewportHeight() {
+    return mRenderer.getViewportHeight();
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/ProfileRenderer.h b/libs/hwui/ProfileRenderer.h
new file mode 100644
index 0000000..b9e586f
--- /dev/null
+++ b/libs/hwui/ProfileRenderer.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 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 "IProfileRenderer.h"
+
+#include "BakedOpRenderer.h"
+
+namespace android {
+namespace uirenderer {
+
+class ProfileRenderer : public IProfileRenderer {
+public:
+    ProfileRenderer(BakedOpRenderer& renderer)
+            : mRenderer(renderer) {
+    }
+
+    void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override;
+    void drawRects(const float* rects, int count, const SkPaint& paint) override;
+    uint32_t getViewportWidth() override;
+    uint32_t getViewportHeight() override;
+
+    virtual ~ProfileRenderer() {}
+
+private:
+    BakedOpRenderer& mRenderer;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 22c6dfc..1645218 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -196,8 +196,8 @@
     }
 
     Texture sourceTexture(caches);
-    sourceTexture.wrap(sourceTexId,
-            sourceBuffer->getWidth(), sourceBuffer->getHeight(), 0, 0 /* total lie */);
+    sourceTexture.wrap(sourceTexId, sourceBuffer->getWidth(),
+            sourceBuffer->getHeight(), 0, 0 /* total lie */, GL_TEXTURE_EXTERNAL_OES);
 
     CopyResult copyResult = copyTextureInto(caches, renderThread.renderState(),
             sourceTexture, texTransform, srcRect, bitmap);
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index 3b1caa5..f9a7c36f2 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -211,14 +211,14 @@
 };
 
 struct BitmapOp : RecordedOp {
-    BitmapOp(BASE_PARAMS, const SkBitmap* bitmap)
+    BitmapOp(BASE_PARAMS, Bitmap* bitmap)
             : SUPER(BitmapOp)
             , bitmap(bitmap) {}
-    const SkBitmap* bitmap;
+    Bitmap* bitmap;
 };
 
 struct BitmapMeshOp : RecordedOp {
-    BitmapMeshOp(BASE_PARAMS, const SkBitmap* bitmap, int meshWidth, int meshHeight,
+    BitmapMeshOp(BASE_PARAMS, Bitmap* bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors)
             : SUPER(BitmapMeshOp)
             , bitmap(bitmap)
@@ -226,7 +226,7 @@
             , meshHeight(meshHeight)
             , vertices(vertices)
             , colors(colors) {}
-    const SkBitmap* bitmap;
+    Bitmap* bitmap;
     const int meshWidth;
     const int meshHeight;
     const float* vertices;
@@ -234,11 +234,11 @@
 };
 
 struct BitmapRectOp : RecordedOp {
-    BitmapRectOp(BASE_PARAMS, const SkBitmap* bitmap, const Rect& src)
+    BitmapRectOp(BASE_PARAMS, Bitmap* bitmap, const Rect& src)
             : SUPER(BitmapRectOp)
             , bitmap(bitmap)
             , src(src) {}
-    const SkBitmap* bitmap;
+    Bitmap* bitmap;
     const Rect src;
 };
 
@@ -288,11 +288,11 @@
 };
 
 struct PatchOp : RecordedOp {
-    PatchOp(BASE_PARAMS, const SkBitmap* bitmap, const Res_png_9patch* patch)
+    PatchOp(BASE_PARAMS, Bitmap* bitmap, const Res_png_9patch* patch)
             : SUPER(PatchOp)
             , bitmap(bitmap)
             , patch(patch) {}
-    const SkBitmap* bitmap;
+    Bitmap* bitmap;
     const Res_png_9patch* patch;
 };
 
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 2730ed9..9d18484 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -21,7 +21,6 @@
 #include "RenderNode.h"
 #include "VectorDrawable.h"
 #include "hwui/MinikinUtils.h"
-#include "hwui/Bitmap.h"
 
 namespace android {
 namespace uirenderer {
@@ -470,18 +469,16 @@
 
 // Bitmap-based
 void RecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
-    SkBitmap skBitmap;
-    bitmap.getSkBitmap(&skBitmap);
     save(SaveFlags::Matrix);
     translate(left, top);
-    drawBitmap(&skBitmap, paint);
+    drawBitmap(bitmap, paint);
     restore();
 }
 
-void RecordingCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
+void RecordingCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix,
                             const SkPaint* paint) {
     if (matrix.isIdentity()) {
-        drawBitmap(&bitmap, paint);
+        drawBitmap(bitmap, paint);
     } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask))
             && MathUtils::isPositive(matrix.getScaleX())
             && MathUtils::isPositive(matrix.getScaleY())) {
@@ -495,12 +492,12 @@
     } else {
         save(SaveFlags::Matrix);
         concat(matrix);
-        drawBitmap(&bitmap, paint);
+        drawBitmap(bitmap, paint);
         restore();
     }
 }
 
-void RecordingCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
+void RecordingCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, const SkPaint* paint) {
     if (srcLeft == 0 && srcTop == 0
@@ -511,7 +508,7 @@
         // transform simple rect to rect drawing case into position bitmap ops, since they merge
         save(SaveFlags::Matrix);
         translate(dstLeft, dstTop);
-        drawBitmap(&bitmap, paint);
+        drawBitmap(bitmap, paint);
         restore();
     } else {
         addOp(alloc().create_trivial<BitmapRectOp>(
@@ -523,7 +520,7 @@
     }
 }
 
-void RecordingCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
+void RecordingCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint) {
     int vertexCount = (meshWidth + 1) * (meshHeight + 1);
     addOp(alloc().create_trivial<BitmapMeshOp>(
@@ -535,7 +532,7 @@
             refBuffer<int>(colors, vertexCount))); // 1 color per vertex
 }
 
-void RecordingCanvas::drawNinePatch(const SkBitmap& bitmap, const android::Res_png_9patch& patch,
+void RecordingCanvas::drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& patch,
             float dstLeft, float dstTop, float dstRight, float dstBottom,
             const SkPaint* paint) {
     addOp(alloc().create_trivial<PatchOp>(
@@ -578,12 +575,12 @@
     }
 }
 
-void RecordingCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
+void RecordingCanvas::drawBitmap(Bitmap& bitmap, const SkPaint* paint) {
     addOp(alloc().create_trivial<BitmapOp>(
-            Rect(bitmap->width(), bitmap->height()),
+            Rect(bitmap.width(), bitmap.height()),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
-            refPaint(paint), refBitmap(*bitmap)));
+            refPaint(paint), refBitmap(bitmap)));
 }
 
 void RecordingCanvas::drawRenderNode(RenderNode* renderNode) {
@@ -669,7 +666,8 @@
     SkBitmap bitmap;
     SkShader::TileMode xy[2];
     if (shader->isABitmap(&bitmap, nullptr, xy)) {
-        refBitmap(bitmap);
+        Bitmap* hwuiBitmap = static_cast<Bitmap*>(bitmap.pixelRef());
+        refBitmap(*hwuiBitmap);
         return;
     }
     SkShader::ComposeRec rec;
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index c5ed61c..b6031c4 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -22,10 +22,10 @@
 #include "ResourceCache.h"
 #include "SkiaCanvasProxy.h"
 #include "Snapshot.h"
+#include "hwui/Bitmap.h"
 #include "hwui/Canvas.h"
 #include "utils/LinearAllocator.h"
 #include "utils/Macros.h"
-#include "utils/NinePatch.h"
 
 #include <SkDrawFilter.h>
 #include <SkPaint.h>
@@ -177,14 +177,13 @@
 
     // Bitmap-based
     virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) override;
-    virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
-                            const SkPaint* paint) override;
-    virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
+    virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) override;
+    virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, const SkPaint* paint) override;
-    virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
+    virtual void drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint) override;
-    virtual void drawNinePatch(const SkBitmap& bitmap, const android::Res_png_9patch& chunk,
+    virtual void drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& chunk,
             float dstLeft, float dstTop, float dstRight, float dstBottom,
             const SkPaint* paint) override;
 
@@ -204,7 +203,7 @@
         return mState.writableSnapshot()->mutateClipArea().serializeClip(alloc());
     }
 
-    void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
+    void drawBitmap(Bitmap& bitmap, const SkPaint* paint);
     void drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint);
 
 
@@ -286,14 +285,17 @@
         return cachedRegion;
     }
 
-    inline const SkBitmap* refBitmap(const SkBitmap& bitmap) {
+    inline Bitmap* refBitmap(Bitmap& bitmap) {
         // Note that this assumes the bitmap is immutable. There are cases this won't handle
         // correctly, such as creating the bitmap from scratch, drawing with it, changing its
         // contents, and drawing again. The only fix would be to always copy it the first time,
         // which doesn't seem worth the extra cycles for this unlikely case.
-        SkBitmap* localBitmap = alloc().create<SkBitmap>(bitmap);
-        mDisplayList->bitmapResources.push_back(localBitmap);
-        return localBitmap;
+
+        // this is required because sk_sp's ctor adopts the pointer,
+        // but does not increment the refcount,
+        bitmap.ref();
+        mDisplayList->bitmapResources.emplace_back(&bitmap);
+        return &bitmap;
     }
 
     inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index a05c744..3819c5e 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -32,7 +32,7 @@
 #include "DisplayList.h"
 #include "Matrix.h"
 #include "RenderProperties.h"
-#include "SkiaDisplayList.h"
+#include "pipeline/skia/SkiaDisplayList.h"
 
 #include <vector>
 
@@ -50,7 +50,6 @@
 class FrameBuilder;
 class OffscreenBuffer;
 class Rect;
-class SkiaDisplayList;
 class SkiaShader;
 struct RenderNodeOp;
 
@@ -61,6 +60,10 @@
 class RenderNode;
 }
 
+namespace skiapipeline {
+    class SkiaDisplayList;
+}
+
 /**
  * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties.
  *
@@ -294,14 +297,14 @@
      * Detach and transfer ownership of an already allocated displayList for use
      * in recording updated content for this renderNode
      */
-    std::unique_ptr<SkiaDisplayList> detachAvailableList() {
+    std::unique_ptr<skiapipeline::SkiaDisplayList> detachAvailableList() {
         return std::move(mAvailableDisplayList);
     }
 
     /**
      * Attach unused displayList to this node for potential future reuse.
      */
-    void attachAvailableList(SkiaDisplayList* skiaDisplayList) {
+    void attachAvailableList(skiapipeline::SkiaDisplayList* skiaDisplayList) {
         mAvailableDisplayList.reset(skiaDisplayList);
     }
 
@@ -337,7 +340,7 @@
      *  2) It is replaced with the displayList from the next completed frame
      *  3) It is detached and used to to record a new displayList for a later frame
      */
-    std::unique_ptr<SkiaDisplayList> mAvailableDisplayList;
+    std::unique_ptr<skiapipeline::SkiaDisplayList> mAvailableDisplayList;
 
     /**
      * An offscreen rendering target used to contain the contents this RenderNode
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index c99219f..b6ac48f 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -17,9 +17,11 @@
 #include "SkiaCanvas.h"
 
 #include "CanvasProperty.h"
+#include "NinePatchUtils.h"
 #include "VectorDrawable.h"
 #include "hwui/Bitmap.h"
 #include "hwui/MinikinUtils.h"
+#include "pipeline/skia/AnimatedDrawables.h"
 
 #include <SkDrawable.h>
 #include <SkDevice.h>
@@ -31,11 +33,14 @@
 #include <SkRSXform.h>
 #include <SkShader.h>
 #include <SkTemplates.h>
+#include <SkTextBlob.h>
 
 #include <memory>
 
 namespace android {
 
+using uirenderer::PaintUtils;
+
 Canvas* Canvas::create_canvas(const SkBitmap& bitmap) {
     return new SkiaCanvas(bitmap);
 }
@@ -44,10 +49,17 @@
     return new SkiaCanvas(skiaCanvas);
 }
 
+SkiaCanvas::SkiaCanvas() {}
+
+SkiaCanvas::SkiaCanvas(SkCanvas* canvas)
+    : mCanvas(SkRef(canvas)) {}
+
 SkiaCanvas::SkiaCanvas(const SkBitmap& bitmap) {
     mCanvas.reset(new SkCanvas(bitmap));
 }
 
+SkiaCanvas::~SkiaCanvas() {}
+
 void SkiaCanvas::reset(SkCanvas* skiaCanvas) {
     mCanvas.reset(SkRef(skiaCanvas));
     mSaveStack.reset(nullptr);
@@ -77,21 +89,21 @@
 };
 
 void SkiaCanvas::setBitmap(const SkBitmap& bitmap) {
-    sk_sp<SkCanvas> newCanvas(new SkCanvas(bitmap));
+    SkCanvas* newCanvas = new SkCanvas(bitmap);
 
     if (!bitmap.isNull()) {
         // Copy the canvas matrix & clip state.
         newCanvas->setMatrix(mCanvas->getTotalMatrix());
 
-        ClipCopier copier(newCanvas.get());
+        ClipCopier copier(newCanvas);
         mCanvas->replayClips(&copier);
     }
 
     // unrefs the existing canvas
-    mCanvas = std::move(newCanvas);
+    mCanvas.reset(newCanvas);
 
     // clean up the old save stack
-    mSaveStack.reset(NULL);
+    mSaveStack.reset(nullptr);
 }
 
 // ----------------------------------------------------------------------------
@@ -129,13 +141,8 @@
 // operation. It does this by explicitly saving off the clip & matrix state
 // when requested and playing it back after the SkCanvas::restore.
 void SkiaCanvas::restore() {
-    const SaveRec* rec = (NULL == mSaveStack.get())
-            ? NULL
-            : static_cast<SaveRec*>(mSaveStack->back());
-    int currentSaveCount = mCanvas->getSaveCount();
-    SkASSERT(NULL == rec || currentSaveCount >= rec->saveCount);
-
-    if (NULL == rec || rec->saveCount != currentSaveCount) {
+    const auto* rec = this->currentSaveRec();
+    if (!rec) {
         // Fast path - no record for this frame.
         mCanvas->restore();
         return;
@@ -149,27 +156,18 @@
         savedMatrix = mCanvas->getTotalMatrix();
     }
 
-    SkTArray<SkClipStack::Element> savedClips;
-    int topClipStackFrame = mCanvas->getClipStack()->getSaveCount();
-    if (preserveClip) {
-        saveClipsForFrame(savedClips, topClipStackFrame);
-    }
+    const size_t clipIndex = rec->clipIndex;
 
     mCanvas->restore();
+    mSaveStack->pop_back();
 
     if (preserveMatrix) {
         mCanvas->setMatrix(savedMatrix);
     }
 
-    if (preserveClip && !savedClips.empty() &&
-        topClipStackFrame != mCanvas->getClipStack()->getSaveCount()) {
-        // Only reapply the saved clips if the top clip stack frame was actually
-        // popped by restore().  If it wasn't, it means it doesn't belong to the
-        // restored canvas frame (SkCanvas lazy save/restore kicked in).
-        applyClips(savedClips);
+    if (preserveClip) {
+        this->applyPersistentClips(clipIndex);
     }
-
-    mSaveStack->pop_back();
 }
 
 void SkiaCanvas::restoreToCount(int restoreCount) {
@@ -213,6 +211,56 @@
     return this->saveLayer(left, top, right, bottom, nullptr, flags);
 }
 
+class SkiaCanvas::Clip {
+public:
+    Clip(const SkRect& rect, SkRegion::Op op, const SkMatrix& m)
+        : mType(Type::Rect), mOp(op), mMatrix(m), mRRect(SkRRect::MakeRect(rect)) {}
+    Clip(const SkRRect& rrect, SkRegion::Op op, const SkMatrix& m)
+        : mType(Type::RRect), mOp(op), mMatrix(m), mRRect(rrect) {}
+    Clip(const SkPath& path, SkRegion::Op op, const SkMatrix& m)
+        : mType(Type::Path), mOp(op), mMatrix(m), mPath(&path) {}
+
+    void apply(SkCanvas* canvas) const {
+        canvas->setMatrix(mMatrix);
+        switch (mType) {
+        case Type::Rect:
+            canvas->clipRect(mRRect.rect(), mOp);
+            break;
+        case Type::RRect:
+            canvas->clipRRect(mRRect, mOp);
+            break;
+        case Type::Path:
+            canvas->clipPath(*mPath.get(), mOp);
+            break;
+        }
+    }
+
+private:
+    enum class Type {
+        Rect,
+        RRect,
+        Path,
+    };
+
+    Type            mType;
+    SkRegion::Op    mOp;
+    SkMatrix        mMatrix;
+
+    // These are logically a union (tracked separately due to non-POD path).
+    SkTLazy<SkPath> mPath;
+    SkRRect         mRRect;
+};
+
+const SkiaCanvas::SaveRec* SkiaCanvas::currentSaveRec() const {
+    const SaveRec* rec = mSaveStack
+        ? static_cast<const SaveRec*>(mSaveStack->back())
+        : nullptr;
+    int currentSaveCount = mCanvas->getSaveCount();
+    SkASSERT(!rec || currentSaveCount >= rec->saveCount);
+
+    return (rec && rec->saveCount == currentSaveCount) ? rec : nullptr;
+}
+
 // ----------------------------------------------------------------------------
 // functions to emulate legacy SaveFlags (i.e. independent matrix/clip flags)
 // ----------------------------------------------------------------------------
@@ -229,45 +277,48 @@
         return;
     }
 
-    if (NULL == mSaveStack.get()) {
+    if (!mSaveStack) {
         mSaveStack.reset(new SkDeque(sizeof(struct SaveRec), 8));
     }
 
     SaveRec* rec = static_cast<SaveRec*>(mSaveStack->push_back());
     rec->saveCount = mCanvas->getSaveCount();
     rec->saveFlags = flags;
+    rec->clipIndex = mClipStack.size();
 }
 
-void SkiaCanvas::saveClipsForFrame(SkTArray<SkClipStack::Element>& clips,
-                                   int saveCountToBackup) {
-    // Each SkClipStack::Element stores the index of the canvas save
-    // with which it is associated. Backup only those Elements that
-    // are associated with 'saveCountToBackup'
-    SkClipStack::Iter clipIterator(*mCanvas->getClipStack(),
-                                   SkClipStack::Iter::kTop_IterStart);
-    while (const SkClipStack::Element* elem = clipIterator.prev()) {
-        if (elem->getSaveCount() < saveCountToBackup) {
-            // done with the target save count.
-            break;
-        }
-        SkASSERT(elem->getSaveCount() == saveCountToBackup);
-        clips.push_back(*elem);
+template <typename T>
+void SkiaCanvas::recordClip(const T& clip, SkRegion::Op op) {
+    // Only need tracking when in a partial save frame which
+    // doesn't restore the clip.
+    const SaveRec* rec = this->currentSaveRec();
+    if (rec && !(rec->saveFlags & SaveFlags::Clip)) {
+        mClipStack.emplace_back(clip, op, mCanvas->getTotalMatrix());
     }
 }
 
-void SkiaCanvas::applyClips(const SkTArray<SkClipStack::Element>& clips) {
-    ClipCopier clipCopier(mCanvas.get());
+// Applies and optionally removes all clips >= index.
+void SkiaCanvas::applyPersistentClips(size_t clipStartIndex) {
+    SkASSERT(clipStartIndex <= mClipStack.size());
+    const auto begin = mClipStack.cbegin() + clipStartIndex;
+    const auto end = mClipStack.cend();
 
-    // The clip stack stores clips in device space.
-    SkMatrix origMatrix = mCanvas->getTotalMatrix();
-    mCanvas->resetMatrix();
+    // Clip application mutates the CTM.
+    const SkMatrix saveMatrix = mCanvas->getTotalMatrix();
 
-    // We pushed the clips in reverse order.
-    for (int i = clips.count() - 1; i >= 0; --i) {
-        clips[i].replay(&clipCopier);
+    for (auto clip = begin; clip != end; ++clip) {
+        clip->apply(mCanvas.get());
     }
 
-    mCanvas->setMatrix(origMatrix);
+    mCanvas->setMatrix(saveMatrix);
+
+    // If the current/post-restore save rec is also persisting clips, we
+    // leave them on the stack to be reapplied part of the next restore().
+    // Otherwise we're done and just pop them.
+    const auto* rec = this->currentSaveRec();
+    if (!rec || (rec->saveFlags & SaveFlags::Clip)) {
+        mClipStack.erase(begin, end);
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -343,6 +394,7 @@
 
 bool SkiaCanvas::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
     SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
+    this->recordClip(rect, op);
     mCanvas->clipRect(rect, op);
     return !mCanvas->isClipEmpty();
 }
@@ -350,8 +402,10 @@
 bool SkiaCanvas::clipPath(const SkPath* path, SkRegion::Op op) {
     SkRRect roundRect;
     if (path->isRRect(&roundRect)) {
+        this->recordClip(roundRect, op);
         mCanvas->clipRRect(roundRect, op);
     } else {
+        this->recordClip(*path, op);
         mCanvas->clipPath(*path, op);
     }
     return !mCanvas->isClipEmpty();
@@ -363,10 +417,13 @@
         // The region is specified in device space.
         SkMatrix savedMatrix = mCanvas->getTotalMatrix();
         mCanvas->resetMatrix();
+        this->recordClip(rgnPath, op);
         mCanvas->clipPath(rgnPath, op);
         mCanvas->setMatrix(savedMatrix);
     } else {
-        mCanvas->clipRect(SkRect::MakeEmpty(), op);
+        const auto emptyClip = SkRect::MakeEmpty();
+        this->recordClip(emptyClip, op);
+        mCanvas->clipRect(emptyClip, op);
     }
     return !mCanvas->isClipEmpty();
 }
@@ -401,6 +458,7 @@
 
 void SkiaCanvas::drawPoints(const float* points, int count, const SkPaint& paint,
                             SkCanvas::PointMode mode) {
+    if (CC_UNLIKELY(count < 2 || PaintUtils::paintWillNotDraw(paint))) return;
     // convert the floats into SkPoints
     count >>= 1;    // now it is the number of points
     std::unique_ptr<SkPoint[]> pts(new SkPoint[count]);
@@ -426,45 +484,49 @@
 }
 
 void SkiaCanvas::drawLines(const float* points, int count, const SkPaint& paint) {
+    if (CC_UNLIKELY(count < 4 || PaintUtils::paintWillNotDraw(paint))) return;
     this->drawPoints(points, count, paint, SkCanvas::kLines_PointMode);
 }
 
 void SkiaCanvas::drawRect(float left, float top, float right, float bottom,
         const SkPaint& paint) {
+    if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return;
     mCanvas->drawRectCoords(left, top, right, bottom, paint);
 
 }
 
 void SkiaCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
-    SkRegion::Iterator it(region);
-    while (!it.done()) {
-        mCanvas->drawRect(SkRect::Make(it.rect()), paint);
-        it.next();
-    }
+    if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return;
+    mCanvas->drawRegion(region, paint);
 }
 
 void SkiaCanvas::drawRoundRect(float left, float top, float right, float bottom,
         float rx, float ry, const SkPaint& paint) {
+    if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return;
     SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
     mCanvas->drawRoundRect(rect, rx, ry, paint);
 }
 
 void SkiaCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
+    if (CC_UNLIKELY(radius <= 0 || PaintUtils::paintWillNotDraw(paint))) return;
     mCanvas->drawCircle(x, y, radius, paint);
 }
 
 void SkiaCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) {
+    if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return;
     SkRect oval = SkRect::MakeLTRB(left, top, right, bottom);
     mCanvas->drawOval(oval, paint);
 }
 
 void SkiaCanvas::drawArc(float left, float top, float right, float bottom,
         float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) {
+    if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return;
     SkRect arc = SkRect::MakeLTRB(left, top, right, bottom);
     mCanvas->drawArc(arc, startAngle, sweepAngle, useCenter, paint);
 }
 
 void SkiaCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
+    if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return;
     SkRect rect;
     SkRRect roundRect;
     if (path.isOval(&rect)) {
@@ -497,23 +559,28 @@
     mCanvas->drawBitmap(skBitmap, left, top, paint);
 }
 
-void SkiaCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) {
+void SkiaCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix, const SkPaint* paint) {
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
     SkAutoCanvasRestore acr(mCanvas.get(), true);
     mCanvas->concat(matrix);
     mCanvas->drawBitmap(bitmap, 0, 0, paint);
 }
 
-void SkiaCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
+void SkiaCanvas::drawBitmap(Bitmap& hwuiBitmap, float srcLeft, float srcTop,
                             float srcRight, float srcBottom, float dstLeft, float dstTop,
                             float dstRight, float dstBottom, const SkPaint* paint) {
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
     SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
     SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
     mCanvas->drawBitmapRect(bitmap, srcRect, dstRect, paint);
 }
 
-void SkiaCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
+void SkiaCanvas::drawBitmapMesh(Bitmap& hwuiBitmap, int meshWidth, int meshHeight,
         const float* vertices, const int* colors, const SkPaint* paint) {
-
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
     const int ptCount = (meshWidth + 1) * (meshHeight + 1);
     const int indexCount = meshWidth * meshHeight * 6;
 
@@ -598,23 +665,40 @@
     if (paint) {
         tmpPaint = *paint;
     }
-    sk_sp<SkShader> shader = SkMakeBitmapShader(bitmap,
-                                                SkShader::kClamp_TileMode,
-                                                SkShader::kClamp_TileMode,
-                                                nullptr,
-                                                kNever_SkCopyPixelsMode,
-                                                nullptr);
-    tmpPaint.setShader(std::move(shader));
+
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+    tmpPaint.setShader(image->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode));
 
     mCanvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, (SkPoint*)vertices,
                          texs, (const SkColor*)colors, NULL, indices,
                          indexCount, tmpPaint);
 }
 
-void SkiaCanvas::drawNinePatch(const SkBitmap& bitmap, const Res_png_9patch& chunk,
+void SkiaCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk,
         float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
-    SkRect bounds = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
-    NinePatch::Draw(mCanvas.get(), bounds, bitmap, chunk, paint, nullptr);
+
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
+
+    SkCanvas::Lattice lattice;
+    NinePatchUtils::SetLatticeDivs(&lattice, chunk, bitmap.width(), bitmap.height());
+
+    lattice.fFlags = nullptr;
+    int numFlags = 0;
+    if (chunk.numColors > 0 && chunk.numColors == NinePatchUtils::NumDistinctRects(lattice)) {
+        // We can expect the framework to give us a color for every distinct rect.
+        // Skia requires a flag for every rect.
+        numFlags = (lattice.fXCount + 1) * (lattice.fYCount + 1);
+    }
+
+    SkAutoSTMalloc<25, SkCanvas::Lattice::Flags> flags(numFlags);
+    if (numFlags > 0) {
+        NinePatchUtils::SetLatticeFlags(&lattice, flags.get(), numFlags, chunk);
+    }
+
+    lattice.fBounds = nullptr;
+    SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
+    mCanvas->drawBitmapLattice(bitmap, lattice, dst, paint);
 }
 
 void SkiaCanvas::drawVectorDrawable(VectorDrawableRoot* vectorDrawable) {
@@ -629,9 +713,26 @@
         const SkPaint& paint, float x, float y,
         float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
         float totalAdvance) {
-    static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
-    mCanvas->drawPosText(text, count << 1, reinterpret_cast<const SkPoint*>(positions), paint);
-    drawTextDecorations(x, y, totalAdvance, paint);
+     if (!text || !positions || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return;
+    // Set align to left for drawing, as we don't want individual
+    // glyphs centered or right-aligned; the offset above takes
+    // care of all alignment.
+    SkPaint paintCopy(paint);
+    paintCopy.setTextAlign(SkPaint::kLeft_Align);
+
+    SkRect bounds = SkRect::MakeLTRB(boundsLeft + x, boundsTop + y,
+                                     boundsRight + x, boundsBottom + y);
+
+    SkTextBlobBuilder builder;
+    const SkTextBlobBuilder::RunBuffer& buffer = builder.allocRunPos(paintCopy, count, &bounds);
+    // TODO: we could reduce the number of memcpy's if the this were exposed further up
+    //       in the architecture.
+    memcpy(buffer.glyphs, text, count * sizeof(uint16_t));
+    memcpy(buffer.pos, positions, (count << 1) * sizeof(float));
+
+    sk_sp<SkTextBlob> textBlob(builder.make());
+    mCanvas->drawTextBlob(textBlob, 0, 0, paintCopy);
+    drawTextDecorations(x, y, totalAdvance, paintCopy);
 }
 
 void SkiaCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
@@ -666,69 +767,18 @@
 // Canvas draw operations: Animations
 // ----------------------------------------------------------------------------
 
-class AnimatedRoundRect : public SkDrawable {
- public:
-    AnimatedRoundRect(uirenderer::CanvasPropertyPrimitive* left,
-            uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
-            uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
-            uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* p) :
-            mLeft(left), mTop(top), mRight(right), mBottom(bottom), mRx(rx), mRy(ry), mPaint(p) {}
-
- protected:
-     virtual SkRect onGetBounds() override {
-         return SkRect::MakeLTRB(mLeft->value, mTop->value, mRight->value, mBottom->value);
-     }
-     virtual void onDraw(SkCanvas* canvas) override {
-         SkRect rect = SkRect::MakeLTRB(mLeft->value, mTop->value, mRight->value, mBottom->value);
-         canvas->drawRoundRect(rect, mRx->value, mRy->value, mPaint->value);
-     }
-
- private:
-    sp<uirenderer::CanvasPropertyPrimitive> mLeft;
-    sp<uirenderer::CanvasPropertyPrimitive> mTop;
-    sp<uirenderer::CanvasPropertyPrimitive> mRight;
-    sp<uirenderer::CanvasPropertyPrimitive> mBottom;
-    sp<uirenderer::CanvasPropertyPrimitive> mRx;
-    sp<uirenderer::CanvasPropertyPrimitive> mRy;
-    sp<uirenderer::CanvasPropertyPaint> mPaint;
-};
-
-class AnimatedCircle : public SkDrawable {
- public:
-    AnimatedCircle(uirenderer::CanvasPropertyPrimitive* x, uirenderer::CanvasPropertyPrimitive* y,
-            uirenderer::CanvasPropertyPrimitive* radius, uirenderer::CanvasPropertyPaint* paint) :
-            mX(x), mY(y), mRadius(radius), mPaint(paint) {}
-
- protected:
-     virtual SkRect onGetBounds() override {
-         const float x = mX->value;
-         const float y = mY->value;
-         const float radius = mRadius->value;
-         return SkRect::MakeLTRB(x - radius, y - radius, x + radius, y + radius);
-     }
-     virtual void onDraw(SkCanvas* canvas) override {
-         canvas->drawCircle(mX->value, mY->value, mRadius->value, mPaint->value);
-     }
-
- private:
-    sp<uirenderer::CanvasPropertyPrimitive> mX;
-    sp<uirenderer::CanvasPropertyPrimitive> mY;
-    sp<uirenderer::CanvasPropertyPrimitive> mRadius;
-    sp<uirenderer::CanvasPropertyPaint> mPaint;
-};
-
 void SkiaCanvas::drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
         uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
         uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
         uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* paint) {
-    sk_sp<AnimatedRoundRect> drawable(
-            new AnimatedRoundRect(left, top, right, bottom, rx, ry, paint));
+    sk_sp<uirenderer::skiapipeline::AnimatedRoundRect> drawable(
+            new uirenderer::skiapipeline::AnimatedRoundRect(left, top, right, bottom, rx, ry, paint));
     mCanvas->drawDrawable(drawable.get());
 }
 
 void SkiaCanvas::drawCircle(uirenderer::CanvasPropertyPrimitive* x, uirenderer::CanvasPropertyPrimitive* y,
         uirenderer::CanvasPropertyPrimitive* radius, uirenderer::CanvasPropertyPaint* paint) {
-    sk_sp<AnimatedCircle> drawable(new AnimatedCircle(x, y, radius, paint));
+    sk_sp<uirenderer::skiapipeline::AnimatedCircle> drawable(new uirenderer::skiapipeline::AnimatedCircle(x, y, radius, paint));
     mCanvas->drawDrawable(drawable.get());
 }
 
@@ -736,7 +786,7 @@
 // Canvas draw operations: View System
 // ----------------------------------------------------------------------------
 
-void SkiaCanvas::drawLayer(uirenderer::DeferredLayerUpdater* layer) {
+void SkiaCanvas::drawLayer(uirenderer::DeferredLayerUpdater* layerUpdater) {
     LOG_ALWAYS_FATAL("SkiaCanvas can't directly draw Layers");
 }
 
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 9c4d7c4..a0cdfcb 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -22,8 +22,7 @@
 #include "VectorDrawable.h"
 
 #include <SkCanvas.h>
-#include <SkClipStack.h>
-#include <SkTArray.h>
+#include <SkTLazy.h>
 
 namespace android {
 
@@ -39,10 +38,9 @@
      *      not be NULL. This constructor will ref() the SkCanvas, and unref()
      *      it in its destructor.
      */
-    explicit SkiaCanvas(SkCanvas* canvas) : mCanvas(canvas) {
-        SkASSERT(canvas);
-        canvas->ref();
-    }
+    explicit SkiaCanvas(SkCanvas* canvas);
+
+    virtual ~SkiaCanvas();
 
     virtual SkCanvas* asSkCanvas() override {
         return mCanvas.get();
@@ -125,14 +123,13 @@
             const uint16_t* indices, int indexCount, const SkPaint& paint) override;
 
     virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) override;
-    virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
-            const SkPaint* paint) override;
-    virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
+    virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) override;
+    virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, const SkPaint* paint) override;
-    virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
+    virtual void drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint) override;
-    virtual void drawNinePatch(const SkBitmap& bitmap, const android::Res_png_9patch& chunk,
+    virtual void drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& chunk,
             float dstLeft, float dstTop, float dstRight, float dstBottom,
             const SkPaint* paint) override;
 
@@ -153,7 +150,7 @@
             uirenderer::GlFunctorLifecycleListener* listener) override;
 
 protected:
-    explicit SkiaCanvas() {}
+    SkiaCanvas();
     void reset(SkCanvas* skiaCanvas);
     void drawDrawable(SkDrawable* drawable) { mCanvas->drawDrawable(drawable); }
 
@@ -168,19 +165,26 @@
     struct SaveRec {
         int              saveCount;
         SaveFlags::Flags saveFlags;
+        size_t           clipIndex;
     };
 
     bool mHighContrastText = false;
 
+    const SaveRec* currentSaveRec() const;
     void recordPartialSave(SaveFlags::Flags flags);
-    void saveClipsForFrame(SkTArray<SkClipStack::Element>& clips, int frameSaveCount);
-    void applyClips(const SkTArray<SkClipStack::Element>& clips);
+
+    template<typename T>
+    void recordClip(const T&, SkRegion::Op);
+    void applyPersistentClips(size_t clipStartIndex);
 
     void drawPoints(const float* points, int count, const SkPaint& paint,
             SkCanvas::PointMode mode);
 
-    sk_sp<SkCanvas> mCanvas;
+    class Clip;
+
+    sk_sp<SkCanvas>          mCanvas;
     std::unique_ptr<SkDeque> mSaveStack; // lazily allocated, tracks partial saves.
+    std::vector<Clip>        mClipStack; // tracks persistent clips.
 };
 
 } // namespace android
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index 6620458..863146e 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -107,16 +107,12 @@
 
 void SkiaCanvasProxy::onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
         const SkPaint* paint) {
-    SkPixelRef* pxRef = bitmap.pixelRef();
-
+    sk_sp<Bitmap> hwuiBitmap = Bitmap::createFrom(bitmap.info(), *bitmap.pixelRef());
     // HWUI doesn't support extractSubset(), so convert any subsetted bitmap into
     // a drawBitmapRect(); pass through an un-subsetted bitmap.
-    if (pxRef && bitmap.dimensions() != pxRef->info().dimensions()) {
-        SkBitmap fullBitmap;
-        fullBitmap.setInfo(pxRef->info());
-        fullBitmap.setPixelRef(pxRef, 0, 0);
+    if (hwuiBitmap && bitmap.dimensions() != hwuiBitmap->info().dimensions()) {
         SkIPoint origin = bitmap.pixelRefOrigin();
-        mCanvas->drawBitmap(fullBitmap, origin.fX, origin.fY,
+        mCanvas->drawBitmap(*hwuiBitmap, origin.fX, origin.fY,
                             origin.fX + bitmap.dimensions().width(),
                             origin.fY + bitmap.dimensions().height(),
                             left, top,
@@ -124,16 +120,16 @@
                             top + bitmap.dimensions().height(),
                             paint);
     } else {
-        auto hwuiBitmap= Bitmap::createFrom(bitmap.info(), *pxRef);
         mCanvas->drawBitmap(*hwuiBitmap, left, top, paint);
     }
 }
 
-void SkiaCanvasProxy::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* srcPtr,
+void SkiaCanvasProxy::onDrawBitmapRect(const SkBitmap& skBitmap, const SkRect* srcPtr,
         const SkRect& dst, const SkPaint* paint, SrcRectConstraint) {
-    SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(bitmap.width(), bitmap.height());
+    SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(skBitmap.width(), skBitmap.height());
     // TODO: if bitmap is a subset, do we need to add pixelRefOrigin to src?
-    mCanvas->drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
+   Bitmap* bitmap = reinterpret_cast<Bitmap*>(skBitmap.pixelRef());
+   mCanvas->drawBitmap(*bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
                         dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint);
 }
 
diff --git a/libs/hwui/SkiaDrawables.h b/libs/hwui/SkiaDrawables.h
deleted file mode 100644
index a1ceeaa..0000000
--- a/libs/hwui/SkiaDrawables.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#pragma once
-
-#include "Layer.h"
-#include "RenderNode.h"
-
-#include <SkCanvas.h>
-#include <SkDrawable.h>
-#include <SkMatrix.h>
-
-#include <utils/RefBase.h>
-#include <utils/FatVector.h>
-#include <utils/Functor.h>
-
-namespace android {
-
-class Functor;
-
-namespace uirenderer {
-
-
-class RenderProperties;
-class OffscreenBuffer;
-class GlFunctorLifecycleListener;
-class SkiaDisplayList;
-
-/**
- * This drawable wraps a RenderNode and enables it to be recorded into a list
- * of Skia drawing commands.
- */
-class RenderNodeDrawable : public SkDrawable {
-public:
-    explicit RenderNodeDrawable(RenderNode* node, SkCanvas* canvas)
-            : mRenderNode(node)
-            , mRecordedTransform(canvas->getTotalMatrix()) {}
-
-    /**
-     * The renderNode (and its properties) that is to be drawn
-     */
-    RenderNode* getRenderNode() const { return mRenderNode.get(); }
-
-    /**
-     * Returns the transform on the canvas at time of recording and is used for
-     * computing total transform without rerunning DL contents.
-     */
-    const SkMatrix& getRecordedMatrix() const { return mRecordedTransform; }
-
-protected:
-    virtual SkRect onGetBounds() override {
-        // We don't want to enable a record time quick reject because the properties
-        // of the RenderNode may be updated on subsequent frames.
-        return SkRect::MakeLargest();
-    }
-    virtual void onDraw(SkCanvas* canvas) override { /* TODO */ }
-
-private:
-    sp<RenderNode> mRenderNode;
-    const SkMatrix mRecordedTransform;
-};
-
-/**
- * This drawable wraps a OpenGL functor enabling it to be recorded into a list
- * of Skia drawing commands.
- */
-class GLFunctorDrawable : public SkDrawable {
-public:
-    GLFunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener, SkCanvas* canvas)
-            : mFunctor(functor)
-            , mListener(listener) {
-        canvas->getClipBounds(&mBounds);
-    }
-    virtual ~GLFunctorDrawable() {}
-
-    void syncFunctor() const { (*mFunctor)(DrawGlInfo::kModeSync, nullptr); }
-
- protected:
-    virtual SkRect onGetBounds() override { return mBounds; }
-    virtual void onDraw(SkCanvas* canvas) override { /* TODO */ }
-
- private:
-     Functor* mFunctor;
-     sp<GlFunctorLifecycleListener> mListener;
-     SkRect mBounds;
-};
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 5d9e5c0..489a306 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -21,6 +21,7 @@
 #include "Layer.h"
 #include "Matrix.h"
 #include "Texture.h"
+#include "hwui/Bitmap.h"
 
 #include <SkMatrix.h>
 #include <utils/Log.h>
@@ -206,7 +207,9 @@
         return false;
     }
 
-    outData->bitmapTexture = caches.textureCache.get(&bitmap);
+    // TODO: create  hwui-owned BitmapShader.
+    Bitmap* hwuiBitmap = static_cast<Bitmap*>(bitmap.pixelRef());
+    outData->bitmapTexture = caches.textureCache.get(hwuiBitmap);
     if (!outData->bitmapTexture) return false;
 
     outData->bitmapSampler = (*textureUnit)++;
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index 908f572..c4a65f6 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -48,37 +48,34 @@
     }
 }
 
-void Texture::setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture, bool force,
-        GLenum renderTarget) {
+void Texture::setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture, bool force) {
 
     if (force || wrapS != mWrapS || wrapT != mWrapT) {
         mWrapS = wrapS;
         mWrapT = wrapT;
 
         if (bindTexture) {
-            mCaches.textureState().bindTexture(renderTarget, mId);
+            mCaches.textureState().bindTexture(mTarget, mId);
         }
 
-        glTexParameteri(renderTarget, GL_TEXTURE_WRAP_S, wrapS);
-        glTexParameteri(renderTarget, GL_TEXTURE_WRAP_T, wrapT);
+        glTexParameteri(mTarget, GL_TEXTURE_WRAP_S, wrapS);
+        glTexParameteri(mTarget, GL_TEXTURE_WRAP_T, wrapT);
     }
 }
 
-void Texture::setFilterMinMag(GLenum min, GLenum mag, bool bindTexture, bool force,
-        GLenum renderTarget) {
-
+void Texture::setFilterMinMag(GLenum min, GLenum mag, bool bindTexture, bool force) {
     if (force || min != mMinFilter || mag != mMagFilter) {
         mMinFilter = min;
         mMagFilter = mag;
 
         if (bindTexture) {
-            mCaches.textureState().bindTexture(renderTarget, mId);
+            mCaches.textureState().bindTexture(mTarget, mId);
         }
 
         if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR;
 
-        glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
-        glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
+        glTexParameteri(mTarget, GL_TEXTURE_MIN_FILTER, min);
+        glTexParameteri(mTarget, GL_TEXTURE_MAG_FILTER, mag);
     }
 }
 
@@ -87,15 +84,20 @@
     mId = 0;
 }
 
-bool Texture::updateSize(uint32_t width, uint32_t height, GLint internalFormat, GLint format) {
-    if (mWidth == width && mHeight == height &&
-            mFormat == format && mInternalFormat == internalFormat) {
+bool Texture::updateSize(uint32_t width, uint32_t height, GLint internalFormat,
+        GLint format, GLenum target) {
+    if (mWidth == width
+            && mHeight == height
+            && mFormat == format
+            && mInternalFormat == internalFormat
+            && mTarget == target) {
         return false;
     }
     mWidth = width;
     mHeight = height;
     mFormat = format;
     mInternalFormat = internalFormat;
+    mTarget = target;
     notifySizeChanged(mWidth * mHeight * bytesPerPixel(internalFormat));
     return true;
 }
@@ -110,7 +112,7 @@
 void Texture::upload(GLint internalFormat, uint32_t width, uint32_t height,
         GLenum format, GLenum type, const void* pixels) {
     GL_CHECKPOINT(MODERATE);
-    bool needsAlloc = updateSize(width, height, internalFormat, format);
+    bool needsAlloc = updateSize(width, height, internalFormat, format, GL_TEXTURE_2D);
     if (!mId) {
         glGenTextures(1, &mId);
         needsAlloc = true;
@@ -171,12 +173,6 @@
     }
 }
 
-static void uploadSkBitmapToTexture(const SkBitmap& bitmap,
-        bool resize, GLint internalFormat, GLenum format, GLenum type) {
-    uploadToTexture(resize, internalFormat, format, type, bitmap.rowBytesAsPixels(),
-            bitmap.bytesPerPixel(), bitmap.width(), bitmap.height(), bitmap.getPixels());
-}
-
 static void colorTypeToGlFormatAndType(const Caches& caches, SkColorType colorType,
         bool needSRGB, GLint* outInternalFormat, GLint* outFormat, GLint* outType) {
     switch (colorType) {
@@ -218,9 +214,7 @@
     }
 }
 
-void Texture::upload(const SkBitmap& bitmap) {
-    SkAutoLockPixels alp(bitmap);
-
+void Texture::upload(Bitmap& bitmap) {
     if (!bitmap.readyToDraw()) {
         ALOGE("Cannot generate texture from bitmap");
         return;
@@ -244,12 +238,12 @@
     }
 
     sk_sp<SkColorSpace> sRGB = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
-    bool needSRGB = bitmap.colorSpace() == sRGB.get();
+    bool needSRGB = bitmap.info().colorSpace() == sRGB.get();
 
     GLint internalFormat, format, type;
     colorTypeToGlFormatAndType(mCaches, bitmap.colorType(), needSRGB, &internalFormat, &format, &type);
 
-    if (updateSize(bitmap.width(), bitmap.height(), internalFormat, format)) {
+    if (updateSize(bitmap.width(), bitmap.height(), internalFormat, format, GL_TEXTURE_2D)) {
         needsAlloc = true;
     }
 
@@ -264,15 +258,21 @@
 
         SkBitmap rgbaBitmap;
         rgbaBitmap.allocPixels(SkImageInfo::MakeN32(
-                mWidth, mHeight, bitmap.alphaType(), hasSRGB ? sRGB : nullptr));
+                mWidth, mHeight, bitmap.info().alphaType(), hasSRGB ? sRGB : nullptr));
         rgbaBitmap.eraseColor(0);
 
         SkCanvas canvas(rgbaBitmap);
-        canvas.drawBitmap(bitmap, 0.0f, 0.0f, nullptr);
+        SkBitmap skBitmap;
+        bitmap.getSkBitmap(&skBitmap);
+        canvas.drawBitmap(skBitmap, 0.0f, 0.0f, nullptr);
 
-        uploadSkBitmapToTexture(rgbaBitmap, needsAlloc, internalFormat, format, type);
+        uploadToTexture(needsAlloc, internalFormat, format, type, rgbaBitmap.rowBytesAsPixels(),
+                rgbaBitmap.bytesPerPixel(), rgbaBitmap.width(),
+                rgbaBitmap.height(), rgbaBitmap.getPixels());
+
     } else {
-        uploadSkBitmapToTexture(bitmap, needsAlloc, internalFormat, format, type);
+        uploadToTexture(needsAlloc, internalFormat, format, type, bitmap.rowBytesAsPixels(),
+                bitmap.info().bytesPerPixel(), bitmap.width(), bitmap.height(), bitmap.pixels());
     }
 
     if (canMipMap) {
@@ -288,12 +288,14 @@
     }
 }
 
-void Texture::wrap(GLuint id, uint32_t width, uint32_t height, GLint internalFormat, GLint format) {
+void Texture::wrap(GLuint id, uint32_t width, uint32_t height,
+        GLint internalFormat, GLint format, GLenum target) {
     mId = id;
     mWidth = width;
     mHeight = height;
     mFormat = format;
     mInternalFormat = internalFormat;
+    mTarget = target;
     // We're wrapping an existing texture, so don't double count this memory
     notifySizeChanged(0);
 }
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index aa8a6d3..d73789a 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -18,9 +18,9 @@
 #define ANDROID_HWUI_TEXTURE_H
 
 #include "GpuMemoryTracker.h"
+#include "hwui/Bitmap.h"
 
 #include <GLES2/gl2.h>
-#include <SkBitmap.h>
 
 namespace android {
 namespace uirenderer {
@@ -41,21 +41,19 @@
 
     virtual ~Texture() { }
 
-    inline void setWrap(GLenum wrap, bool bindTexture = false, bool force = false,
-                GLenum renderTarget = GL_TEXTURE_2D) {
-        setWrapST(wrap, wrap, bindTexture, force, renderTarget);
+    inline void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
+        setWrapST(wrap, wrap, bindTexture, force);
     }
 
     virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
-            bool force = false, GLenum renderTarget = GL_TEXTURE_2D);
+            bool force = false);
 
-    inline void setFilter(GLenum filter, bool bindTexture = false, bool force = false,
-                GLenum renderTarget = GL_TEXTURE_2D) {
-        setFilterMinMag(filter, filter, bindTexture, force, renderTarget);
+    inline void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
+        setFilterMinMag(filter, filter, bindTexture, force);
     }
 
     virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
-            bool force = false, GLenum renderTarget = GL_TEXTURE_2D);
+            bool force = false);
 
     /**
      * Convenience method to call glDeleteTextures() on this texture's id.
@@ -74,13 +72,13 @@
     }
 
     /**
-     * Updates this Texture with the contents of the provided SkBitmap,
+     * Updates this Texture with the contents of the provided Bitmap,
      * also setting the appropriate width, height, and format. It is not necessary
      * to call resize() prior to this.
      *
-     * Note this does not set the generation from the SkBitmap.
+     * Note this does not set the generation from the Bitmap.
      */
-    void upload(const SkBitmap& source);
+    void upload(Bitmap& source);
 
     /**
      * Basically glTexImage2D/glTexSubImage2D.
@@ -91,7 +89,8 @@
     /**
      * Wraps an existing texture.
      */
-    void wrap(GLuint id, uint32_t width, uint32_t height, GLint internalFormat, GLint format);
+    void wrap(GLuint id, uint32_t width, uint32_t height, GLint internalFormat,
+            GLint format, GLenum target);
 
     GLuint id() const {
         return mId;
@@ -113,6 +112,10 @@
         return mInternalFormat;
     }
 
+    GLenum target() const {
+        return mTarget;
+    }
+
     /**
      * Generation of the backing bitmap,
      */
@@ -152,7 +155,8 @@
     friend class Layer;
 
     // Returns true if the size changed, false if it was the same
-    bool updateSize(uint32_t width, uint32_t height, GLint internalFormat, GLint format);
+    bool updateSize(uint32_t width, uint32_t height, GLint internalFormat,
+            GLint format, GLenum target);
     void resetCachedParams();
 
     GLuint mId = 0;
@@ -160,6 +164,7 @@
     uint32_t mHeight = 0;
     GLint mFormat = 0;
     GLint mInternalFormat = 0;
+    GLenum mTarget = GL_NONE;
 
     /* See GLES spec section 3.8.14
      * "In the initial state, the value assigned to TEXTURE_MIN_FILTER is
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 5ccdbda..14ffc85 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -23,6 +23,7 @@
 #include "TextureCache.h"
 #include "Properties.h"
 #include "utils/TraceUtils.h"
+#include "hwui/Bitmap.h"
 
 namespace android {
 namespace uirenderer {
@@ -91,7 +92,7 @@
     }
 }
 
-bool TextureCache::canMakeTextureFromBitmap(const SkBitmap* bitmap) {
+bool TextureCache::canMakeTextureFromBitmap(Bitmap* bitmap) {
     if (bitmap->width() > mMaxTextureSize || bitmap->height() > mMaxTextureSize) {
         ALOGW("Bitmap too large to be uploaded into a texture (%dx%d, max=%dx%d)",
                 bitmap->width(), bitmap->height(), mMaxTextureSize, mMaxTextureSize);
@@ -102,8 +103,8 @@
 
 // Returns a prepared Texture* that either is already in the cache or can fit
 // in the cache (and is thus added to the cache)
-Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap) {
-    Texture* texture = mCache.get(bitmap->pixelRef()->getStableID());
+Texture* TextureCache::getCachedTexture(Bitmap* bitmap) {
+    Texture* texture = mCache.get(bitmap->getStableID());
 
     if (!texture) {
         if (!canMakeTextureFromBitmap(bitmap)) {
@@ -134,7 +135,7 @@
             if (mDebugEnabled) {
                 ALOGD("Texture created, size = %d", size);
             }
-            mCache.put(bitmap->pixelRef()->getStableID(), texture);
+            mCache.put(bitmap->getStableID(), texture);
         }
     } else if (!texture->isInUse && bitmap->getGenerationID() != texture->generation) {
         // Texture was in the cache but is dirty, re-upload
@@ -146,7 +147,7 @@
     return texture;
 }
 
-bool TextureCache::prefetchAndMarkInUse(void* ownerToken, const SkBitmap* bitmap) {
+bool TextureCache::prefetchAndMarkInUse(void* ownerToken, Bitmap* bitmap) {
     Texture* texture = getCachedTexture(bitmap);
     if (texture) {
         texture->isInUse = ownerToken;
@@ -154,11 +155,11 @@
     return texture;
 }
 
-bool TextureCache::prefetch(const SkBitmap* bitmap) {
+bool TextureCache::prefetch(Bitmap* bitmap) {
     return getCachedTexture(bitmap);
 }
 
-Texture* TextureCache::get(const SkBitmap* bitmap) {
+Texture* TextureCache::get(Bitmap* bitmap) {
     Texture* texture = getCachedTexture(bitmap);
 
     if (!texture) {
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 88ef771..68a548b 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -28,6 +28,9 @@
 #include <unordered_map>
 
 namespace android {
+
+class Bitmap;
+
 namespace uirenderer {
 
 class Texture;
@@ -73,20 +76,20 @@
      * acquired for the bitmap, false otherwise. If a Texture was acquired it is
      * marked as in use.
      */
-    bool prefetchAndMarkInUse(void* ownerToken, const SkBitmap* bitmap);
+    bool prefetchAndMarkInUse(void* ownerToken, Bitmap* bitmap);
 
     /**
      * Attempts to precache the SkBitmap. Returns true if a Texture was successfully
      * acquired for the bitmap, false otherwise. Does not mark the Texture
      * as in use and won't update currently in-use Textures.
      */
-    bool prefetch(const SkBitmap* bitmap);
+    bool prefetch(Bitmap* bitmap);
 
     /**
      * Returns the texture associated with the specified bitmap from within the cache.
      * If the texture cannot be found in the cache, a new texture is generated.
      */
-    Texture* get(const SkBitmap* bitmap);
+    Texture* get(Bitmap* bitmap);
 
     /**
      * Removes the texture associated with the specified pixelRef. This is meant
@@ -119,9 +122,9 @@
     void flush();
 
 private:
-    bool canMakeTextureFromBitmap(const SkBitmap* bitmap);
+    bool canMakeTextureFromBitmap(Bitmap* bitmap);
 
-    Texture* getCachedTexture(const SkBitmap* bitmap);
+    Texture* getCachedTexture(Bitmap* bitmap);
 
     LruCache<uint32_t, Texture*> mCache;
 
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 715681d..b50647a 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -502,18 +502,18 @@
 }
 
 void Tree::drawStaging(Canvas* outCanvas) {
-    bool redrawNeeded = allocateBitmapIfNeeded(&mStagingCache.bitmap,
+    bool redrawNeeded = allocateBitmapIfNeeded(mStagingCache,
             mStagingProperties.getScaledWidth(), mStagingProperties.getScaledHeight());
     // draw bitmap cache
     if (redrawNeeded || mStagingCache.dirty) {
-        updateBitmapCache(&mStagingCache.bitmap, true);
+        updateBitmapCache(*mStagingCache.bitmap, true);
         mStagingCache.dirty = false;
     }
 
     SkPaint tmpPaint;
     SkPaint* paint = updatePaint(&tmpPaint, &mStagingProperties);
-    outCanvas->drawBitmap(mStagingCache.bitmap, 0, 0,
-            mStagingCache.bitmap.width(), mStagingCache.bitmap.height(),
+    outCanvas->drawBitmap(*mStagingCache.bitmap, 0, 0,
+            mStagingCache.bitmap->width(), mStagingCache.bitmap->height(),
             mStagingProperties.getBounds().left(), mStagingProperties.getBounds().top(),
             mStagingProperties.getBounds().right(), mStagingProperties.getBounds().bottom(), paint);
 }
@@ -535,46 +535,46 @@
     }
 }
 
-const SkBitmap& Tree::getBitmapUpdateIfDirty() {
-    bool redrawNeeded = allocateBitmapIfNeeded(&mCache.bitmap, mProperties.getScaledWidth(),
+Bitmap& Tree::getBitmapUpdateIfDirty() {
+    bool redrawNeeded = allocateBitmapIfNeeded(mCache, mProperties.getScaledWidth(),
             mProperties.getScaledHeight());
     if (redrawNeeded || mCache.dirty) {
-        updateBitmapCache(&mCache.bitmap, false);
+        updateBitmapCache(*mCache.bitmap, false);
         mCache.dirty = false;
     }
-    return mCache.bitmap;
+    return *mCache.bitmap;
 }
 
-void Tree::updateBitmapCache(SkBitmap* outCache, bool useStagingData) {
-    outCache->eraseColor(SK_ColorTRANSPARENT);
-    SkCanvas outCanvas(*outCache);
+void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) {
+    SkBitmap outCache;
+    bitmap.getSkBitmap(&outCache);
+    outCache.eraseColor(SK_ColorTRANSPARENT);
+    SkCanvas outCanvas(outCache);
     float viewportWidth = useStagingData ?
             mStagingProperties.getViewportWidth() : mProperties.getViewportWidth();
     float viewportHeight = useStagingData ?
             mStagingProperties.getViewportHeight() : mProperties.getViewportHeight();
-    float scaleX = outCache->width() / viewportWidth;
-    float scaleY = outCache->height() / viewportHeight;
+    float scaleX = outCache.width() / viewportWidth;
+    float scaleY = outCache.height() / viewportHeight;
     mRootNode->draw(&outCanvas, SkMatrix::I(), scaleX, scaleY, useStagingData);
 }
 
-bool Tree::allocateBitmapIfNeeded(SkBitmap* outCache, int width, int height) {
-    if (!canReuseBitmap(*outCache, width, height)) {
+bool Tree::allocateBitmapIfNeeded(Cache& cache, int width, int height) {
+    if (!canReuseBitmap(cache.bitmap.get(), width, height)) {
 #ifndef ANDROID_ENABLE_LINEAR_BLENDING
         sk_sp<SkColorSpace> colorSpace = nullptr;
 #else
         sk_sp<SkColorSpace> colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
 #endif
         SkImageInfo info = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType, colorSpace);
-        outCache->setInfo(info);
-        // TODO: Count the bitmap cache against app's java heap
-        outCache->allocPixels(info);
+        cache.bitmap = Bitmap::allocateHeapBitmap(info);
         return true;
     }
     return false;
 }
 
-bool Tree::canReuseBitmap(const SkBitmap& bitmap, int width, int height) {
-    return width == bitmap.width() && height == bitmap.height();
+bool Tree::canReuseBitmap(Bitmap* bitmap, int width, int height) {
+    return bitmap && width == bitmap->width() && height == bitmap->height();
 }
 
 void Tree::onPropertyChanged(TreeProperties* prop) {
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index e68fbf4..e9a9c71 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -18,6 +18,7 @@
 #define ANDROID_HWUI_VPATH_H
 
 #include "hwui/Canvas.h"
+#include "hwui/Bitmap.h"
 #include "DisplayList.h"
 
 #include <SkBitmap.h>
@@ -561,7 +562,7 @@
             const SkRect& bounds, bool needsMirroring, bool canReuseCache);
     void drawStaging(Canvas* canvas);
 
-    const SkBitmap& getBitmapUpdateIfDirty();
+    Bitmap& getBitmapUpdateIfDirty();
     void setAllowCaching(bool allowCaching) {
         mAllowCaching = allowCaching;
     }
@@ -691,11 +692,15 @@
     void setPropertyChangeWillBeConsumed(bool willBeConsumed) { mWillBeConsumed = willBeConsumed; }
 
 private:
+    struct Cache {
+        sk_sp<Bitmap> bitmap;
+        bool dirty = true;
+    };
 
     SkPaint* updatePaint(SkPaint* outPaint, TreeProperties* prop);
-    bool allocateBitmapIfNeeded(SkBitmap* outCache, int width, int height);
-    bool canReuseBitmap(const SkBitmap&, int width, int height);
-    void updateBitmapCache(SkBitmap* outCache, bool useStagingData);
+    bool allocateBitmapIfNeeded(Cache& cache, int width, int height);
+    bool canReuseBitmap(Bitmap*, int width, int height);
+    void updateBitmapCache(Bitmap& outCache, bool useStagingData);
     // Cap the bitmap size, such that it won't hurt the performance too much
     // and it won't crash due to a very large scale.
     // The drawable will look blurry above this size.
@@ -708,10 +713,6 @@
     TreeProperties mStagingProperties = TreeProperties(this);
 
     SkPaint mPaint;
-    struct Cache {
-        SkBitmap bitmap;
-        bool dirty = true;
-    };
 
     Cache mStagingCache;
     Cache mCache;
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 341ece3..31fbe68 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -23,9 +23,9 @@
 
 namespace android {
 
-static bool computeAllocationSize(const SkBitmap& bitmap, size_t* size) {
-    int32_t rowBytes32 = SkToS32(bitmap.rowBytes());
-    int64_t bigSize = (int64_t)bitmap.height() * rowBytes32;
+static bool computeAllocationSize(size_t rowBytes, int height, size_t* size) {
+    int32_t rowBytes32 = SkToS32(rowBytes);
+    int64_t bigSize = (int64_t) height * rowBytes32;
     if (rowBytes32 < 0 || !sk_64_isS32(bigSize)) {
         return false; // allocation will be too large
     }
@@ -45,13 +45,14 @@
     }
 
     size_t size;
-    if (!computeAllocationSize(*bitmap, &size)) {
-        return nullptr;
-    }
 
     // we must respect the rowBytes value already set on the bitmap instead of
     // attempting to compute our own.
     const size_t rowBytes = bitmap->rowBytes();
+    if (!computeAllocationSize(rowBytes, bitmap->height(), &size)) {
+        return nullptr;
+    }
+
     auto wrapper = alloc(size, info, rowBytes, ctable);
     if (wrapper) {
         wrapper->getSkBitmap(bitmap);
@@ -62,15 +63,11 @@
     return wrapper;
 }
 
-sk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
-   return allocateBitmap(bitmap, ctable, &Bitmap::allocateHeapBitmap);
-}
-
 sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
    return allocateBitmap(bitmap, ctable, &Bitmap::allocateAshmemBitmap);
 }
 
-sk_sp<Bitmap> Bitmap::allocateHeapBitmap(size_t size, const SkImageInfo& info, size_t rowBytes,
+static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& info, size_t rowBytes,
         SkColorTable* ctable) {
     void* addr = calloc(size, 1);
     if (!addr) {
@@ -79,6 +76,19 @@
     return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes, ctable));
 }
 
+sk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
+   return allocateBitmap(bitmap, ctable, &android::allocateHeapBitmap);
+}
+
+sk_sp<Bitmap> Bitmap::allocateHeapBitmap(const SkImageInfo& info) {
+    size_t size;
+    if (!computeAllocationSize(info.minRowBytes(), info.height(), &size)) {
+        LOG_ALWAYS_FATAL("trying to allocate too large bitmap");
+        return nullptr;
+    }
+    return android::allocateHeapBitmap(size, info, info.minRowBytes(), nullptr);
+}
+
 sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(size_t size, const SkImageInfo& info,
         size_t rowBytes, SkColorTable* ctable) {
     // Create new ashmem region with read/write priv
@@ -259,4 +269,9 @@
     outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
 }
 
+void Bitmap::getBounds(SkRect* bounds) const {
+    SkASSERT(bounds);
+    bounds->set(0, 0, SkIntToScalar(info().width()), SkIntToScalar(info().height()));
+}
+
 } // namespace android
\ No newline at end of file
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 2a5d00b..c175690 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -34,8 +34,7 @@
 class ANDROID_API Bitmap : public SkPixelRef {
 public:
     static sk_sp<Bitmap> allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable);
-    static sk_sp<Bitmap> allocateHeapBitmap(size_t allocSize, const SkImageInfo& info,
-        size_t rowBytes, SkColorTable* ctable);
+    static sk_sp<Bitmap> allocateHeapBitmap(const SkImageInfo& info);
 
     static sk_sp<Bitmap> allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable);
     static sk_sp<Bitmap> allocateAshmemBitmap(size_t allocSize, const SkImageInfo& info,
@@ -58,6 +57,11 @@
     // doing on a Bitmap type, not a SkPixelRef, so static
     // dispatching will do what we want.
     size_t rowBytes() const { return mRowBytes; }
+
+    int rowBytesAsPixels() const {
+        return mRowBytes >> info().shiftPerPixel();
+    }
+
     void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
     void reconfigure(const SkImageInfo& info);
     void setAlphaType(SkAlphaType alphaType);
@@ -70,6 +74,13 @@
     void setHasHardwareMipMap(bool hasMipMap);
     bool hasHardwareMipMap() const;
 
+    bool isOpaque() const {return info().isOpaque(); }
+    SkColorType colorType() const { return info().colorType(); }
+    void getBounds(SkRect* bounds) const;
+
+    bool readyToDraw() const {
+        return this->colorType() != kIndex_8_SkColorType || mColorTable;
+    }
 protected:
     virtual bool onNewLockPixels(LockRec* rec) override;
     virtual void onUnlockPixels() override { };
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 8d08608..d7839b4 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -21,7 +21,7 @@
 
 #include "GlFunctorLifecycleListener.h"
 #include "utils/Macros.h"
-#include "utils/NinePatch.h"
+#include <androidfw/ResourceTypes.h>
 
 #include <SkBitmap.h>
 #include <SkCanvas.h>
@@ -220,14 +220,14 @@
     // Bitmap-based
     virtual void drawBitmap(Bitmap& bitmap, float left, float top,
             const SkPaint* paint) = 0;
-    virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
+    virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix,
             const SkPaint* paint) = 0;
-    virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
+    virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, const SkPaint* paint) = 0;
-    virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
+    virtual void drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint) = 0;
-    virtual void drawNinePatch(const SkBitmap& bitmap, const android::Res_png_9patch& chunk,
+    virtual void drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& chunk,
             float dstLeft, float dstTop, float dstRight, float dstBottom,
             const SkPaint* paint) = 0;
 
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index f172473..a52abfc 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -65,6 +65,23 @@
     bounds->mBottom = skBounds.fBottom;
 }
 
+const void* MinikinFontSkia::GetTable(uint32_t tag, size_t* size,
+        minikin::MinikinDestroyFunc* destroy) {
+    // we don't have a buffer to the font data, copy to own buffer
+    const size_t tableSize = mTypeface->getTableSize(tag);
+    *size = tableSize;
+    if (tableSize == 0) {
+        return nullptr;
+    }
+    void* buf = malloc(tableSize);
+    if (buf == nullptr) {
+        return nullptr;
+    }
+    mTypeface->getTableData(tag, 0, tableSize, buf);
+    *destroy = free;
+    return buf;
+}
+
 SkTypeface *MinikinFontSkia::GetSkTypeface() const {
     return mTypeface.get();
 }
diff --git a/libs/hwui/hwui/MinikinSkia.h b/libs/hwui/hwui/MinikinSkia.h
index 3ee916c..1ea99fd 100644
--- a/libs/hwui/hwui/MinikinSkia.h
+++ b/libs/hwui/hwui/MinikinSkia.h
@@ -37,6 +37,8 @@
     void GetBounds(minikin::MinikinRect* bounds, uint32_t glyph_id,
         const minikin::MinikinPaint &paint) const;
 
+    const void* GetTable(uint32_t tag, size_t* size, minikin::MinikinDestroyFunc* destroy);
+
     SkTypeface* GetSkTypeface() const;
     sk_sp<SkTypeface> RefSkTypeface() const;
 
diff --git a/libs/hwui/pipeline/skia/AnimatedDrawables.h b/libs/hwui/pipeline/skia/AnimatedDrawables.h
new file mode 100644
index 0000000..44c494f
--- /dev/null
+++ b/libs/hwui/pipeline/skia/AnimatedDrawables.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+#include "CanvasProperty.h"
+#include <utils/RefBase.h>
+#include <SkCanvas.h>
+#include <SkDrawable.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+class AnimatedRoundRect : public SkDrawable {
+public:
+    AnimatedRoundRect(uirenderer::CanvasPropertyPrimitive* left,
+            uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
+            uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
+            uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* p)
+            : mLeft(left)
+            , mTop(top)
+            , mRight(right)
+            , mBottom(bottom)
+            , mRx(rx)
+            , mRy(ry)
+            , mPaint(p) {}
+
+protected:
+    virtual SkRect onGetBounds() override {
+        return SkRect::MakeLTRB(mLeft->value, mTop->value, mRight->value, mBottom->value);
+    }
+    virtual void onDraw(SkCanvas* canvas) override {
+        SkRect rect = SkRect::MakeLTRB(mLeft->value, mTop->value, mRight->value, mBottom->value);
+        canvas->drawRoundRect(rect, mRx->value, mRy->value, mPaint->value);
+    }
+
+private:
+    sp<uirenderer::CanvasPropertyPrimitive> mLeft;
+    sp<uirenderer::CanvasPropertyPrimitive> mTop;
+    sp<uirenderer::CanvasPropertyPrimitive> mRight;
+    sp<uirenderer::CanvasPropertyPrimitive> mBottom;
+    sp<uirenderer::CanvasPropertyPrimitive> mRx;
+    sp<uirenderer::CanvasPropertyPrimitive> mRy;
+    sp<uirenderer::CanvasPropertyPaint> mPaint;
+};
+
+class AnimatedCircle : public SkDrawable {
+public:
+    AnimatedCircle(uirenderer::CanvasPropertyPrimitive* x, uirenderer::CanvasPropertyPrimitive* y,
+            uirenderer::CanvasPropertyPrimitive* radius, uirenderer::CanvasPropertyPaint* paint)
+            : mX(x)
+            , mY(y)
+            , mRadius(radius)
+            , mPaint(paint) {}
+
+protected:
+    virtual SkRect onGetBounds() override {
+        const float x = mX->value;
+        const float y = mY->value;
+        const float radius = mRadius->value;
+        return SkRect::MakeLTRB(x - radius, y - radius, x + radius, y + radius);
+    }
+    virtual void onDraw(SkCanvas* canvas) override {
+        canvas->drawCircle(mX->value, mY->value, mRadius->value, mPaint->value);
+    }
+
+private:
+    sp<uirenderer::CanvasPropertyPrimitive> mX;
+    sp<uirenderer::CanvasPropertyPrimitive> mY;
+    sp<uirenderer::CanvasPropertyPrimitive> mRadius;
+    sp<uirenderer::CanvasPropertyPaint> mPaint;
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
new file mode 100644
index 0000000..fb2134c
--- /dev/null
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2016 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 "GLFunctorDrawable.h"
+#include "GlFunctorLifecycleListener.h"
+#include "RenderNode.h"
+#include "SkClipStack.h"
+#include <private/hwui/DrawGlInfo.h>
+#include <SkPath.h>
+#include <GrContext.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+GLFunctorDrawable::~GLFunctorDrawable() {
+    if(mListener.get() != nullptr) {
+        mListener->onGlFunctorReleased(mFunctor);
+    }
+}
+
+void GLFunctorDrawable::syncFunctor() const {
+    (*mFunctor)(DrawGlInfo::kModeSync, nullptr);
+}
+
+static void setScissor(int viewportHeight, const SkIRect& clip) {
+    SkASSERT(!clip.isEmpty());
+    // transform to Y-flipped GL space, and prevent negatives
+    GLint y = viewportHeight - clip.fBottom;
+    GLint height = (viewportHeight - clip.fTop) - y;
+    glScissor(clip.fLeft, y, clip.width(), height);
+}
+
+void GLFunctorDrawable::onDraw(SkCanvas* canvas) {
+    if (canvas->getGrContext() == nullptr) {
+        SkDEBUGF(("Attempting to draw GLFunctor into an unsupported surface"));
+        return;
+    }
+
+    canvas->flush();
+
+    SkImageInfo canvasInfo = canvas->imageInfo();
+    SkMatrix44 mat4(canvas->getTotalMatrix());
+
+    SkIRect ibounds;
+    canvas->getClipDeviceBounds(&ibounds);
+
+    DrawGlInfo info;
+    info.clipLeft = ibounds.fLeft;
+    info.clipTop = ibounds.fTop;
+    info.clipRight = ibounds.fRight;
+    info.clipBottom = ibounds.fBottom;
+    //   info.isLayer = hasLayer();
+    info.isLayer = false;
+    info.width = canvasInfo.width();
+    info.height = canvasInfo.height();
+    mat4.asColMajorf(&info.transform[0]);
+
+    //apply a simple clip with a scissor or a complex clip with a stencil
+    SkRegion clipRegion;
+    SkPath path;
+    canvas->getClipStack()->asPath(&path);
+    clipRegion.setPath(path, SkRegion(ibounds));
+    if (CC_UNLIKELY(clipRegion.isComplex())) {
+        //It is only a temporary solution to use a scissor to draw the stencil.
+        //There is a bug 31489986 to implement efficiently non-rectangular clips.
+        glDisable(GL_SCISSOR_TEST);
+        glDisable(GL_STENCIL_TEST);
+        glStencilMask(0xff);
+        glClearStencil(0);
+        glClear(GL_STENCIL_BUFFER_BIT);
+        glEnable(GL_SCISSOR_TEST);
+        SkRegion::Cliperator it(clipRegion, ibounds);
+        while (!it.done()) {
+            setScissor(info.height, it.rect());
+            glClearStencil(0x1);
+            glClear(GL_STENCIL_BUFFER_BIT);
+            it.next();
+        }
+        glDisable(GL_SCISSOR_TEST);
+        glStencilFunc(GL_EQUAL, 0x1, 0xff);
+        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+        glEnable(GL_STENCIL_TEST);
+    } else if (clipRegion.isEmpty()) {
+        glDisable(GL_STENCIL_TEST);
+        glDisable(GL_SCISSOR_TEST);
+    } else {
+        glDisable(GL_STENCIL_TEST);
+        glEnable(GL_SCISSOR_TEST);
+        setScissor(info.height, clipRegion.getBounds());
+    }
+
+    (*mFunctor)(DrawGlInfo::kModeDraw, &info);
+
+    canvas->getGrContext()->resetContext();
+ }
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.h b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
new file mode 100644
index 0000000..bf39dad
--- /dev/null
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+#include <SkCanvas.h>
+#include <SkDrawable.h>
+
+#include <utils/RefBase.h>
+#include <utils/Functor.h>
+
+namespace android {
+namespace uirenderer {
+
+class GlFunctorLifecycleListener;
+
+namespace skiapipeline {
+
+/**
+ * This drawable wraps a OpenGL functor enabling it to be recorded into a list
+ * of Skia drawing commands.
+ */
+class GLFunctorDrawable : public SkDrawable {
+public:
+    GLFunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener, SkCanvas* canvas)
+            : mFunctor(functor)
+            , mListener(listener) {
+        canvas->getClipBounds(&mBounds);
+    }
+    virtual ~GLFunctorDrawable();
+
+    void syncFunctor() const;
+
+ protected:
+    virtual SkRect onGetBounds() override { return mBounds; }
+    virtual void onDraw(SkCanvas* canvas) override;
+
+ private:
+     Functor* mFunctor;
+     sp<GlFunctorLifecycleListener> mListener;
+     SkRect mBounds;
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
new file mode 100644
index 0000000..f8a181f
--- /dev/null
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 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 "LayerDrawable.h"
+#include "gl/GrGLTypes.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+void LayerDrawable::onDraw(SkCanvas* canvas) {
+    // transform the matrix based on the layer
+    int saveCount = -1;
+    if (!mLayer->getTransform().isIdentity()) {
+        saveCount = canvas->save();
+        SkMatrix transform;
+        mLayer->getTransform().copyTo(transform);
+        canvas->concat(transform);
+    }
+    GrGLTextureInfo externalTexture;
+    externalTexture.fTarget = mLayer->getRenderTarget();
+    externalTexture.fID = mLayer->getTextureId();
+    GrContext* context = canvas->getGrContext();
+    GrBackendTextureDesc textureDescription;
+    textureDescription.fWidth = mLayer->getWidth();
+    textureDescription.fHeight = mLayer->getHeight();
+    textureDescription.fConfig = kRGBA_8888_GrPixelConfig;
+    textureDescription.fOrigin = kTopLeft_GrSurfaceOrigin;
+    textureDescription.fTextureHandle = reinterpret_cast<GrBackendObject>(&externalTexture);
+    sk_sp<SkImage> layerImage(SkImage::NewFromTexture(context, textureDescription));
+    if (layerImage) {
+        SkPaint paint;
+        paint.setAlpha(mLayer->getAlpha());
+        paint.setBlendMode(mLayer->getMode());
+        paint.setColorFilter(mLayer->getColorFilter());
+        canvas->drawImage(layerImage, 0, 0, &paint);
+    }
+    // restore the original matrix
+    if (saveCount >= 0) {
+        canvas->restoreToCount(saveCount);
+    }
+}
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.h b/libs/hwui/pipeline/skia/LayerDrawable.h
new file mode 100644
index 0000000..91e2744
--- /dev/null
+++ b/libs/hwui/pipeline/skia/LayerDrawable.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+#include "Layer.h"
+
+#include <SkCanvas.h>
+#include <SkDrawable.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+/*
+ * Draws a layer backed by an OpenGL texture into a SkCanvas.
+ */
+class LayerDrawable : public SkDrawable {
+ public:
+    explicit LayerDrawable(Layer* layer)
+            : mLayer(layer) {}
+
+ protected:
+     virtual SkRect onGetBounds() override {
+         return SkRect::MakeWH(mLayer->getWidth(), mLayer->getHeight());
+     }
+     virtual void onDraw(SkCanvas* canvas) override;
+
+private:
+    sp<Layer> mLayer;
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
new file mode 100644
index 0000000..cefa893
--- /dev/null
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2016 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 "RenderNodeDrawable.h"
+#include "RenderNode.h"
+#include "SkiaDisplayList.h"
+#include "SkiaFrameRenderer.h"
+#include "utils/TraceUtils.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+static void clipOutline(const Outline& outline, SkCanvas* canvas, const SkRect* pendingClip) {
+    SkASSERT(outline.willClip());
+    Rect possibleRect;
+    float radius;
+    LOG_ALWAYS_FATAL_IF(!outline.getAsRoundRect(&possibleRect, &radius),
+            "clipping outlines should be at most roundedRects");
+    SkRect rect = possibleRect.toSkRect();
+    if (radius != 0.0f) {
+        if (pendingClip && !pendingClip->contains(rect)) {
+            canvas->clipRect(*pendingClip);
+        }
+        canvas->clipRRect(SkRRect::MakeRectXY(rect, radius, radius), SkRegion::kIntersect_Op, true);
+    } else {
+        if (pendingClip) {
+            (void)rect.intersect(*pendingClip);
+        }
+        canvas->clipRect(rect);
+    }
+}
+
+const RenderProperties& RenderNodeDrawable::getNodeProperties() const {
+    return mRenderNode->properties();
+}
+
+void RenderNodeDrawable::onDraw(SkCanvas* canvas) {
+    //negative and positive Z order are drawn out of order
+    if (MathUtils::isZero(mRenderNode->properties().getZ())) {
+        this->forceDraw(canvas);
+    }
+}
+
+void RenderNodeDrawable::forceDraw(SkCanvas* canvas) {
+    RenderNode* renderNode = mRenderNode.get();
+    if (SkiaFrameRenderer::skpCaptureEnabled()) {
+        SkRect dimensions = SkRect::MakeWH(renderNode->getWidth(), renderNode->getHeight());
+        canvas->drawAnnotation(dimensions, renderNode->getName(), nullptr);
+    }
+
+    // We only respect the nothingToDraw check when we are composing a layer. This
+    // ensures that we paint the layer even if it is not currently visible in the
+    // event that the properties change and it becomes visible.
+    if (!renderNode->isRenderable() || (renderNode->nothingToDraw() && mComposeLayer)) {
+        return;
+    }
+
+    SkASSERT(renderNode->getDisplayList()->isSkiaDL());
+    SkiaDisplayList* displayList = (SkiaDisplayList*)renderNode->getDisplayList();
+
+    SkAutoCanvasRestore acr(canvas, true);
+
+    const RenderProperties& properties = this->getNodeProperties();
+    if (displayList->mIsProjectionReceiver) {
+        // this node is a projection receiver. We will gather the projected nodes as we draw our
+        // children, and then draw them on top of this node's content.
+        std::vector<ProjectedChild> newList;
+        for (auto& child : displayList->mChildNodes) {
+            // our direct children are not supposed to project into us (nodes project to, at the
+            // nearest, their grandparents). So we "delay" the list's activation one level by
+            // passing it into mNextProjectedChildrenTarget rather than mProjectedChildrenTarget.
+            child.mProjectedChildrenTarget = mNextProjectedChildrenTarget;
+            child.mNextProjectedChildrenTarget = &newList;
+        }
+        // draw ourselves and our children. As a side effect, this will add projected nodes to
+        // newList.
+        this->drawContent(canvas);
+        bool willClip = properties.getOutline().willClip();
+        if (willClip) {
+            canvas->save();
+            clipOutline(properties.getOutline(), canvas, nullptr);
+        }
+        // draw the collected projected nodes
+        for (auto& projectedChild : newList) {
+            canvas->setMatrix(projectedChild.matrix);
+            projectedChild.node->drawContent(canvas);
+        }
+        if (willClip) {
+            canvas->restore();
+        }
+    } else {
+        if (properties.getProjectBackwards() && mProjectedChildrenTarget) {
+            // We are supposed to project this node, so add it to the list and do not actually draw
+            // yet. It will be drawn by its projection receiver.
+            mProjectedChildrenTarget->push_back({ this, canvas->getTotalMatrix() });
+            return;
+        }
+        for (auto& child : displayList->mChildNodes) {
+            // storing these values in the nodes themselves is a bit ugly; they should "really" be
+            // function parameters, but we have to go through the preexisting draw() method and
+            // therefore cannot add additional parameters to it
+            child.mProjectedChildrenTarget = mNextProjectedChildrenTarget;
+            child.mNextProjectedChildrenTarget = mNextProjectedChildrenTarget;
+        }
+        this->drawContent(canvas);
+    }
+    mProjectedChildrenTarget = nullptr;
+    mNextProjectedChildrenTarget = nullptr;
+}
+
+static bool layerNeedsPaint(const LayerProperties& properties,
+                            float alphaMultiplier, SkPaint* paint) {
+    if (alphaMultiplier < 1.0f
+            || properties.alpha() < 255
+            || properties.xferMode() != SkBlendMode::kSrcOver
+            || properties.colorFilter() != nullptr) {
+        paint->setAlpha(properties.alpha() * alphaMultiplier);
+        paint->setBlendMode(properties.xferMode());
+        paint->setColorFilter(properties.colorFilter());
+        return true;
+    }
+    return false;
+}
+
+void RenderNodeDrawable::drawContent(SkCanvas* canvas) const {
+    RenderNode* renderNode = mRenderNode.get();
+    float alphaMultiplier = 1.0f;
+    const RenderProperties& properties = renderNode->properties();
+
+    // If we are drawing the contents of layer, we don't want to apply any of
+    // the RenderNode's properties during this pass. Those will all be applied
+    // when the layer is composited.
+    if (mComposeLayer) {
+        setViewProperties(properties, canvas, &alphaMultiplier);
+    }
+
+    //TODO should we let the bound of the drawable do this for us?
+    const SkRect bounds = SkRect::MakeWH(properties.getWidth(), properties.getHeight());
+    bool quickRejected = properties.getClipToBounds() && canvas->quickReject(bounds);
+    if (!quickRejected) {
+        SkiaDisplayList* displayList = (SkiaDisplayList*)renderNode->getDisplayList();
+        const LayerProperties& layerProperties = properties.layerProperties();
+        // composing a hardware layer
+        if (renderNode->getLayerSurface() && mComposeLayer) {
+            SkASSERT(properties.effectiveLayerType() == LayerType::RenderLayer);
+            SkPaint* paint = nullptr;
+            SkPaint tmpPaint;
+            if (layerNeedsPaint(layerProperties, alphaMultiplier, &tmpPaint)) {
+                paint = &tmpPaint;
+            }
+            renderNode->getLayerSurface()->draw(canvas, 0, 0, paint);
+        // composing a software layer with alpha
+        } else if (properties.effectiveLayerType() == LayerType::Software) {
+            SkPaint paint;
+            bool needsLayer = layerNeedsPaint(layerProperties, alphaMultiplier, &paint);
+            if (needsLayer) {
+                canvas->saveLayer(bounds, &paint);
+            }
+            canvas->drawDrawable(displayList->mDrawable.get());
+            if (needsLayer) {
+                canvas->restore();
+            }
+        } else {
+            canvas->drawDrawable(displayList->mDrawable.get());
+        }
+    }
+}
+
+void RenderNodeDrawable::setViewProperties(const RenderProperties& properties, SkCanvas* canvas,
+        float* alphaMultiplier) {
+    if (properties.getLeft() != 0 || properties.getTop() != 0) {
+        canvas->translate(properties.getLeft(), properties.getTop());
+    }
+    if (properties.getStaticMatrix()) {
+        canvas->concat(*properties.getStaticMatrix());
+    } else if (properties.getAnimationMatrix()) {
+        canvas->concat(*properties.getAnimationMatrix());
+    }
+    if (properties.hasTransformMatrix()) {
+        if (properties.isTransformTranslateOnly()) {
+            canvas->translate(properties.getTranslationX(), properties.getTranslationY());
+        } else {
+            canvas->concat(*properties.getTransformMatrix());
+        }
+    }
+    const bool isLayer = properties.effectiveLayerType() != LayerType::None;
+    int clipFlags = properties.getClippingFlags();
+    if (properties.getAlpha() < 1) {
+        if (isLayer) {
+            clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer
+        }
+        if (CC_LIKELY(isLayer || !properties.getHasOverlappingRendering())) {
+            *alphaMultiplier = properties.getAlpha();
+        } else {
+            // savelayer needed to create an offscreen buffer
+            Rect layerBounds(0, 0, properties.getWidth(), properties.getHeight());
+            if (clipFlags) {
+                properties.getClippingRectForFlags(clipFlags, &layerBounds);
+                clipFlags = 0; // all clipping done by savelayer
+            }
+            SkRect bounds = SkRect::MakeLTRB(layerBounds.left, layerBounds.top,
+                    layerBounds.right, layerBounds.bottom);
+            canvas->saveLayerAlpha(&bounds, (int) (properties.getAlpha() * 255));
+        }
+
+        if (CC_UNLIKELY(ATRACE_ENABLED() && properties.promotedToLayer())) {
+            // pretend alpha always causes savelayer to warn about
+            // performance problem affecting old versions
+            ATRACE_FORMAT("alpha caused saveLayer %dx%d", properties.getWidth(),
+                    properties.getHeight());
+        }
+    }
+
+    const SkRect* pendingClip = nullptr;
+    SkRect clipRect;
+
+    if (clipFlags) {
+        Rect tmpRect;
+        properties.getClippingRectForFlags(clipFlags, &tmpRect);
+        clipRect = tmpRect.toSkRect();
+        pendingClip = &clipRect;
+    }
+
+    if (properties.getRevealClip().willClip()) {
+        canvas->clipPath(*properties.getRevealClip().getPath(), SkRegion::kIntersect_Op, true);
+    } else if (properties.getOutline().willClip()) {
+        clipOutline(properties.getOutline(), canvas, pendingClip);
+        pendingClip = nullptr;
+    }
+
+    if (pendingClip) {
+        canvas->clipRect(*pendingClip);
+    }
+}
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.h b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
new file mode 100644
index 0000000..0762f37
--- /dev/null
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+#include <SkCanvas.h>
+#include <SkDrawable.h>
+#include <SkMatrix.h>
+#include <utils/RefBase.h>
+
+namespace android {
+namespace uirenderer {
+
+class RenderNode;
+class RenderProperties;
+
+namespace skiapipeline {
+
+/**
+ * This drawable wraps a RenderNode and enables it to be recorded into a list
+ * of Skia drawing commands.
+ */
+class RenderNodeDrawable : public SkDrawable {
+public:
+    /**
+     * This struct contains a pointer to a node that is to be
+     * projected into the drawing order of its closest ancestor
+     * (excluding its parent) that is marked as a projection
+     * receiver. The matrix is used to ensure that the node is
+     * drawn with same matrix as it would have prior to projection.
+     */
+    struct ProjectedChild {
+        const RenderNodeDrawable* node;
+        const SkMatrix matrix;
+    };
+
+    /**
+     * Creates a new RenderNodeDrawable backed by a render node.
+     *
+     * @param node that has to be drawn
+     * @param canvas is a recording canvas used to extract its matrix
+     * @param composeLayer if the node's layer type is RenderLayer this flag determines whether
+     *      we should draw into the contents of the layer or compose the existing contents of the
+     *      layer into the canvas.
+     */
+    explicit RenderNodeDrawable(RenderNode* node, SkCanvas* canvas, bool composeLayer = true)
+            : mRenderNode(node)
+            , mRecordedTransform(canvas->getTotalMatrix())
+            , mComposeLayer(composeLayer) {}
+
+    /**
+     * Draws into the canvas this render node and its children. If the node is marked as a
+     * projection receiver then all projected children (excluding direct children) will be drawn
+     * last. Any projected node not matching those requirements will not be drawn by this function.
+     */
+    void forceDraw(SkCanvas* canvas);
+
+    /**
+     * Returns readonly render properties for this render node.
+     */
+    const RenderProperties& getNodeProperties() const;
+
+    /**
+     * The renderNode (and its properties) that is to be drawn
+     */
+    RenderNode* getRenderNode() const { return mRenderNode.get(); }
+
+    /**
+     * Returns the transform on the canvas at time of recording and is used for
+     * computing total transform without rerunning DL contents.
+     */
+    const SkMatrix& getRecordedMatrix() const { return mRecordedTransform; }
+
+protected:
+    /*
+     * Return the (conservative) bounds of what the drawable will draw.
+     */
+    virtual SkRect onGetBounds() override {
+        // We don't want to enable a record time quick reject because the properties
+        // of the RenderNode may be updated on subsequent frames.
+        return SkRect::MakeLargest();
+    }
+    /**
+     * This function draws into a canvas as forceDraw, but does nothing if the render node has a
+     * non-zero elevation.
+     */
+    virtual void onDraw(SkCanvas* canvas) override;
+
+private:
+    /*
+     * Render node that is wrapped by this class.
+     */
+    sp<RenderNode> mRenderNode;
+
+    /**
+     * Applies the rendering properties of a view onto a SkCanvas.
+     */
+    static void setViewProperties(const RenderProperties& properties, SkCanvas* canvas,
+            float* alphaMultiplier);
+
+    /**
+     * Stores transform on the canvas at time of recording and is used for
+     * computing total transform without rerunning DL contents.
+     */
+    const SkMatrix mRecordedTransform;
+
+    /**
+     * If mRenderNode's layer type is RenderLayer this flag determines whether we
+     * should draw into the contents of the layer or compose the existing contents
+     * of the layer into the canvas.
+     */
+    const bool mComposeLayer;
+
+    /**
+     * List to which we will add any projected children we encounter while walking our descendents.
+     * This pointer is valid only while the node (including its children) is actively being drawn.
+     */
+    std::vector<ProjectedChild>* mProjectedChildrenTarget = nullptr;
+
+    /**
+     * The value to which we should set our children's mProjectedChildrenTarget. We use two pointers
+     * (mProjectedChildrenTarget and mNextProjectedChildrenTarget) because we need to skip over our
+     * parent when looking for a projection receiver.
+     */
+    std::vector<ProjectedChild>* mNextProjectedChildrenTarget = nullptr;
+
+    /*
+     *  Draw the content into a canvas, depending on the render node layer type and mComposeLayer.
+     */
+    void drawContent(SkCanvas* canvas) const;
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
new file mode 100644
index 0000000..8d77938
--- /dev/null
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -0,0 +1,704 @@
+/*
+ * Copyright (C) 2016 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 "ReorderBarrierDrawables.h"
+#include "RenderNode.h"
+#include "SkiaDisplayList.h"
+#include "SkiaFrameRenderer.h"
+
+#include <SkBlurMask.h>
+#include <SkBlurMaskFilter.h>
+#include <SkGaussianEdgeShader.h>
+#include <SkPathOps.h>
+#include <SkRRectsGaussianEdgeShader.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+StartReorderBarrierDrawable::StartReorderBarrierDrawable(SkiaDisplayList* data)
+        : mEndChildIndex(0)
+        , mBeginChildIndex(data->mChildNodes.size())
+        , mDisplayList(data) {
+}
+
+void StartReorderBarrierDrawable::onDraw(SkCanvas* canvas) {
+    if (mChildren.empty()) {
+        //mChildren is allocated and initialized only the first time onDraw is called and cached for
+        //subsequent calls
+        mChildren.reserve(mEndChildIndex - mBeginChildIndex + 1);
+        for (unsigned int i = mBeginChildIndex; i <= mEndChildIndex; i++) {
+            mChildren.push_back(const_cast<RenderNodeDrawable*>(&mDisplayList->mChildNodes[i]));
+        }
+    }
+    std::stable_sort(mChildren.begin(), mChildren.end(),
+        [](RenderNodeDrawable* a, RenderNodeDrawable* b) {
+            const float aZValue = a->getNodeProperties().getZ();
+            const float bZValue = b->getNodeProperties().getZ();
+            return aZValue < bZValue;
+        });
+
+    SkASSERT(!mChildren.empty());
+
+    size_t drawIndex = 0;
+    const size_t endIndex = mChildren.size();
+    while (drawIndex < endIndex) {
+        RenderNodeDrawable* childNode = mChildren[drawIndex];
+        SkASSERT(childNode);
+        const float casterZ = childNode->getNodeProperties().getZ();
+        if (casterZ >= -NON_ZERO_EPSILON) { //draw only children with negative Z
+            return;
+        }
+        childNode->forceDraw(canvas);
+        drawIndex++;
+    }
+}
+
+EndReorderBarrierDrawable::EndReorderBarrierDrawable(StartReorderBarrierDrawable* startBarrier)
+        : mStartBarrier(startBarrier) {
+    mStartBarrier->mEndChildIndex = mStartBarrier->mDisplayList->mChildNodes.size() - 1;
+}
+
+#define SHADOW_DELTA 0.1f
+
+void EndReorderBarrierDrawable::onDraw(SkCanvas* canvas) {
+    auto& zChildren = mStartBarrier->mChildren;
+    SkASSERT(!zChildren.empty());
+
+    /**
+     * Draw shadows and (potential) casters mostly in order, but allow the shadows of casters
+     * with very similar Z heights to draw together.
+     *
+     * This way, if Views A & B have the same Z height and are both casting shadows, the shadows are
+     * underneath both, and neither's shadow is drawn on top of the other.
+     */
+    size_t drawIndex = 0;
+
+    const size_t endIndex = zChildren.size();
+    while (drawIndex < endIndex     //draw only children with positive Z
+            && zChildren[drawIndex]->getNodeProperties().getZ() <= NON_ZERO_EPSILON) drawIndex++;
+    size_t shadowIndex = drawIndex;
+
+    float lastCasterZ = 0.0f;
+    while (shadowIndex < endIndex || drawIndex < endIndex) {
+        if (shadowIndex < endIndex) {
+            const float casterZ = zChildren[shadowIndex]->getNodeProperties().getZ();
+
+            // attempt to render the shadow if the caster about to be drawn is its caster,
+            // OR if its caster's Z value is similar to the previous potential caster
+            if (shadowIndex == drawIndex || casterZ - lastCasterZ < SHADOW_DELTA) {
+                this->drawShadow(canvas, zChildren[shadowIndex]);
+                lastCasterZ = casterZ; // must do this even if current caster not casting a shadow
+                shadowIndex++;
+                continue;
+            }
+        }
+
+        RenderNodeDrawable* childNode = zChildren[drawIndex];
+        SkASSERT(childNode);
+        childNode->forceDraw(canvas);
+
+        drawIndex++;
+    }
+}
+
+/**
+ * @param canvas             the destination for the shadow draws
+ * @param shape              the shape casting the shadow
+ * @param casterZValue       the Z value of the caster RRect
+ * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
+ * @param draw               the function used to draw 'shape'
+ */
+template <typename Shape, typename F>
+static void DrawAmbientShadowGeneral(SkCanvas* canvas, const Shape& shape, float casterZValue,
+        float ambientAlpha, F&& draw) {
+    if (ambientAlpha <= 0) {
+        return;
+    }
+
+    const float kHeightFactor = 1.f/128.f;
+    const float kGeomFactor = 64;
+
+    float umbraAlpha = 1 / (1 + SkMaxScalar(casterZValue*kHeightFactor, 0));
+    float radius = casterZValue*kHeightFactor*kGeomFactor;
+
+    sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
+            SkBlurMask::ConvertRadiusToSigma(radius), SkBlurMaskFilter::kNone_BlurFlag);
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    paint.setMaskFilter(std::move(mf));
+    paint.setARGB(ambientAlpha*umbraAlpha, 0, 0, 0);
+
+    draw(shape, paint);
+}
+
+/**
+ * @param canvas             the destination for the shadow draws
+ * @param shape              the shape casting the shadow
+ * @param casterZValue       the Z value of the caster RRect
+ * @param lightPos           the position of the light casting the shadow
+ * @param lightWidth
+ * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
+ * @param draw               the function used to draw 'shape'
+ */
+template <typename Shape, typename F>
+static void DrawSpotShadowGeneral(SkCanvas* canvas, const Shape& shape, float casterZValue,
+        float spotAlpha, F&& draw) {
+    if (spotAlpha <= 0) {
+        return;
+    }
+
+    const Vector3 lightPos = SkiaFrameRenderer::getLightCenter();
+    float zRatio = casterZValue / (lightPos.z - casterZValue);
+    // clamp
+    if (zRatio < 0.0f) {
+        zRatio = 0.0f;
+    } else if (zRatio > 0.95f) {
+        zRatio = 0.95f;
+    }
+
+    float blurRadius = SkiaFrameRenderer::getLightRadius()*zRatio;
+
+    SkAutoCanvasRestore acr(canvas, true);
+
+    sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
+            SkBlurMask::ConvertRadiusToSigma(blurRadius), SkBlurMaskFilter::kNone_BlurFlag);
+
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    paint.setMaskFilter(std::move(mf));
+    paint.setARGB(spotAlpha, 0, 0, 0);
+
+    // approximate projection by translating and scaling projected offset of bounds center
+    // TODO: compute the actual 2D projection
+    SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
+    canvas->scale(scale, scale);
+    SkPoint center = SkPoint::Make(shape.getBounds().centerX(), shape.getBounds().centerY());
+    SkMatrix ctmInverse;
+    if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
+        ALOGW("Matrix is degenerate. Will not render shadow!");
+        return;
+    }
+    SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
+    ctmInverse.mapPoints(&lightPos2D, 1);
+    canvas->translate(zRatio*(center.fX - lightPos2D.fX), zRatio*(center.fY - lightPos2D.fY));
+
+    draw(shape, paint);
+}
+
+#define MAX_BLUR_RADIUS 16383.75f
+#define MAX_PAD         64
+
+/**
+ * @param casterRect         the rectangle bounds of the RRect casting the shadow
+ * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
+ * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
+ * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
+ * @param casterAlpha        the alpha value of the RRect casting the shadow (0.0-1.0 range)
+ * @param casterZValue       the Z value of the caster RRect
+ * @param scaleFactor        the scale needed to map from src-space to device-space
+ * @param canvas             the destination for the shadow draws
+ */
+static void DrawRRectShadows(const SkRect& casterRect, SkScalar casterCornerRadius,
+        SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterAlpha, SkScalar casterZValue,
+        SkScalar scaleFactor, SkCanvas* canvas) {
+    SkASSERT(cornerRadius >= 0.0f);
+
+    // For all of these, we need to ensure we have a rrect with radius >= 0.5f in device space
+    const SkScalar minRadius = 0.5f / scaleFactor;
+
+    const bool isOval = casterCornerRadius >= std::max(SkScalarHalf(casterRect.width()),
+            SkScalarHalf(casterRect.height()));
+    const bool isRect = casterCornerRadius <= minRadius;
+
+    sk_sp<SkShader> edgeShader(SkGaussianEdgeShader::Make());
+
+    if (ambientAlpha > 0.0f) {
+        static const float kHeightFactor = 1.0f / 128.0f;
+        static const float kGeomFactor = 64.0f;
+
+        SkScalar srcSpaceAmbientRadius = casterZValue * kHeightFactor * kGeomFactor;
+        // the device-space radius sent to the blur shader must fit in 14.2 fixed point
+        if (srcSpaceAmbientRadius*scaleFactor > MAX_BLUR_RADIUS) {
+            srcSpaceAmbientRadius = MAX_BLUR_RADIUS/scaleFactor;
+        }
+        const float umbraAlpha = 1.0f / (1.0f + std::max(casterZValue * kHeightFactor, 0.0f));
+        const SkScalar ambientOffset = srcSpaceAmbientRadius * umbraAlpha;
+
+        // For the ambient rrect, we inset the offset rect by half the srcSpaceAmbientRadius
+        // to get our stroke shape.
+        SkScalar ambientPathOutset = std::max(ambientOffset - srcSpaceAmbientRadius * 0.5f,
+                minRadius);
+
+        SkRRect ambientRRect;
+        const SkRect temp = casterRect.makeOutset(ambientPathOutset, ambientPathOutset);
+        if (isOval) {
+            ambientRRect = SkRRect::MakeOval(temp);
+        } else if (isRect) {
+            ambientRRect = SkRRect::MakeRectXY(temp, ambientPathOutset, ambientPathOutset);
+        } else {
+            ambientRRect = SkRRect::MakeRectXY(temp, casterCornerRadius + ambientPathOutset,
+                    casterCornerRadius + ambientPathOutset);
+        }
+
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setStyle(SkPaint::kStroke_Style);
+        // we outset the stroke a little to cover up AA on the interior edge
+        float pad = 0.5f;
+        paint.setStrokeWidth(srcSpaceAmbientRadius + 2.0f * pad);
+        // handle scale of radius and pad due to CTM
+        pad *= scaleFactor;
+        const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor;
+        SkASSERT(devSpaceAmbientRadius <= MAX_BLUR_RADIUS);
+        SkASSERT(pad < MAX_PAD);
+        // convert devSpaceAmbientRadius to 14.2 fixed point and place in the R & G components
+        // convert pad to 6.2 fixed point and place in the B component
+        uint16_t iDevSpaceAmbientRadius = (uint16_t)(4.0f * devSpaceAmbientRadius);
+        paint.setColor(SkColorSetARGB((unsigned char) ambientAlpha, iDevSpaceAmbientRadius >> 8,
+                iDevSpaceAmbientRadius & 0xff, (unsigned char)(4.0f * pad)));
+
+        paint.setShader(edgeShader);
+        canvas->drawRRect(ambientRRect, paint);
+    }
+
+    if (spotAlpha > 0.0f) {
+        const Vector3 lightPos = SkiaFrameRenderer::getLightCenter();
+        float zRatio = casterZValue / (lightPos.z - casterZValue);
+        // clamp
+        if (zRatio < 0.0f) {
+            zRatio = 0.0f;
+        } else if (zRatio > 0.95f) {
+            zRatio = 0.95f;
+        }
+
+        const SkScalar lightWidth = SkiaFrameRenderer::getLightRadius();
+        SkScalar srcSpaceSpotRadius = 2.0f * lightWidth * zRatio;
+        // the device-space radius sent to the blur shader must fit in 14.2 fixed point
+        if (srcSpaceSpotRadius*scaleFactor > MAX_BLUR_RADIUS) {
+            srcSpaceSpotRadius = MAX_BLUR_RADIUS/scaleFactor;
+        }
+
+        SkRRect spotRRect;
+        if (isOval) {
+            spotRRect = SkRRect::MakeOval(casterRect);
+        } else if (isRect) {
+            spotRRect = SkRRect::MakeRectXY(casterRect, minRadius, minRadius);
+        } else {
+            spotRRect = SkRRect::MakeRectXY(casterRect, casterCornerRadius, casterCornerRadius);
+        }
+
+        SkRRect spotShadowRRect;
+        // Compute the scale and translation for the spot shadow.
+        const SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
+        spotRRect.transform(SkMatrix::MakeScale(scale, scale), &spotShadowRRect);
+
+        SkPoint center = SkPoint::Make(spotShadowRRect.rect().centerX(),
+                                       spotShadowRRect.rect().centerY());
+        SkMatrix ctmInverse;
+        if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
+            ALOGW("Matrix is degenerate. Will not render spot shadow!");
+            return;
+        }
+        SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
+        ctmInverse.mapPoints(&lightPos2D, 1);
+        const SkPoint spotOffset = SkPoint::Make(zRatio*(center.fX - lightPos2D.fX),
+                zRatio*(center.fY - lightPos2D.fY));
+
+        SkAutoCanvasRestore acr(canvas, true);
+
+        // We want to extend the stroked area in so that it meets up with the caster
+        // geometry. The stroked geometry will, by definition already be inset half the
+        // stroke width but we also have to account for the scaling.
+        // We also add 1/2 to cover up AA on the interior edge.
+        SkScalar scaleOffset = (scale - 1.0f) * SkTMax(SkTMax(SkTAbs(casterRect.fLeft),
+                SkTAbs(casterRect.fRight)), SkTMax(SkTAbs(casterRect.fTop),
+                SkTAbs(casterRect.fBottom)));
+        SkScalar insetAmount = spotOffset.length() - (0.5f * srcSpaceSpotRadius) +
+                scaleOffset + 0.5f;
+
+        // Compute area
+        SkScalar strokeWidth = srcSpaceSpotRadius + insetAmount;
+        SkScalar strokedArea = 2.0f*strokeWidth * (spotShadowRRect.width()
+                + spotShadowRRect.height());
+        SkScalar filledArea = (spotShadowRRect.height() + srcSpaceSpotRadius)
+                * (spotShadowRRect.width() + srcSpaceSpotRadius);
+
+        SkPaint paint;
+        paint.setAntiAlias(true);
+
+        // If the area of the stroked geometry is larger than the fill geometry, just fill it.
+        if (strokedArea > filledArea || casterAlpha < 1.0f) {
+            paint.setStyle(SkPaint::kStrokeAndFill_Style);
+            paint.setStrokeWidth(srcSpaceSpotRadius);
+        } else {
+            // Since we can't have unequal strokes, inset the shadow rect so the inner
+            // and outer edges of the stroke will land where we want.
+            SkRect insetRect = spotShadowRRect.rect().makeInset(insetAmount/2.0f, insetAmount/2.0f);
+            SkScalar insetRad = SkTMax(spotShadowRRect.getSimpleRadii().fX - insetAmount/2.0f,
+                    minRadius);
+            spotShadowRRect = SkRRect::MakeRectXY(insetRect, insetRad, insetRad);
+            paint.setStyle(SkPaint::kStroke_Style);
+            paint.setStrokeWidth(strokeWidth);
+        }
+
+        // handle scale of radius and pad due to CTM
+        const SkScalar devSpaceSpotRadius = srcSpaceSpotRadius * scaleFactor;
+        SkASSERT(devSpaceSpotRadius <= MAX_BLUR_RADIUS);
+
+        const SkScalar devSpaceSpotPad = 0;
+        SkASSERT(devSpaceSpotPad < MAX_PAD);
+
+        // convert devSpaceSpotRadius to 14.2 fixed point and place in the R & G
+        // components convert devSpaceSpotPad to 6.2 fixed point and place in the B component
+        uint16_t iDevSpaceSpotRadius = (uint16_t)(4.0f * devSpaceSpotRadius);
+        paint.setColor(SkColorSetARGB((unsigned char) spotAlpha, iDevSpaceSpotRadius >> 8,
+                iDevSpaceSpotRadius & 0xff, (unsigned char)(4.0f * devSpaceSpotPad)));
+        paint.setShader(edgeShader);
+
+        canvas->translate(spotOffset.fX, spotOffset.fY);
+        canvas->drawRRect(spotShadowRRect, paint);
+    }
+}
+
+/**
+ * @param casterRect         the rectangle bounds of the RRect casting the shadow
+ * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
+ * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
+ * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
+ * @param casterZValue       the Z value of the caster RRect
+ * @param scaleFactor        the scale needed to map from src-space to device-space
+ * @param clipRR             the oval or rect with which the drawn roundrect must be intersected
+ * @param canvas             the destination for the shadow draws
+ */
+static void DrawRRectShadowsWithClip(const SkRect& casterRect, SkScalar casterCornerRadius,
+        SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterZValue, SkScalar scaleFactor,
+        const SkRRect& clipRR, SkCanvas* canvas) {
+    SkASSERT(cornerRadius >= 0.0f);
+
+    const bool isOval = casterCornerRadius >= std::max(SkScalarHalf(casterRect.width()),
+            SkScalarHalf(casterRect.height()));
+
+    if (ambientAlpha > 0.0f) {
+        static const float kHeightFactor = 1.0f / 128.0f;
+        static const float kGeomFactor = 64.0f;
+
+        const SkScalar srcSpaceAmbientRadius = casterZValue * kHeightFactor * kGeomFactor;
+        const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor;
+
+        const float umbraAlpha = 1.0f / (1.0f + std::max(casterZValue * kHeightFactor, 0.0f));
+        const SkScalar ambientOffset = srcSpaceAmbientRadius * umbraAlpha;
+
+        const SkRect srcSpaceAmbientRect = casterRect.makeOutset(ambientOffset, ambientOffset);
+        SkRect devSpaceAmbientRect;
+        canvas->getTotalMatrix().mapRect(&devSpaceAmbientRect, srcSpaceAmbientRect);
+
+        SkRRect devSpaceAmbientRRect;
+        if (isOval) {
+            devSpaceAmbientRRect = SkRRect::MakeOval(devSpaceAmbientRect);
+        } else {
+            const SkScalar devSpaceCornerRadius = scaleFactor * (casterCornerRadius + ambientOffset);
+            devSpaceAmbientRRect = SkRRect::MakeRectXY(devSpaceAmbientRect, devSpaceCornerRadius,
+                    devSpaceCornerRadius);
+        }
+
+        const SkRect srcSpaceAmbClipRect = clipRR.rect().makeOutset(ambientOffset, ambientOffset);
+        SkRect devSpaceAmbClipRect;
+        canvas->getTotalMatrix().mapRect(&devSpaceAmbClipRect, srcSpaceAmbClipRect);
+        SkRRect devSpaceAmbientClipRR;
+        if (clipRR.isOval()) {
+            devSpaceAmbientClipRR = SkRRect::MakeOval(devSpaceAmbClipRect);
+        } else {
+            SkASSERT(clipRR.isRect());
+            devSpaceAmbientClipRR = SkRRect::MakeRect(devSpaceAmbClipRect);
+        }
+
+        SkRect cover = srcSpaceAmbClipRect;
+        if (!cover.intersect(srcSpaceAmbientRect)) {
+            return;
+        }
+
+        SkPaint paint;
+        paint.setColor(SkColorSetARGB((unsigned char) ambientAlpha, 0, 0, 0));
+        paint.setShader(SkRRectsGaussianEdgeShader::Make(devSpaceAmbientRRect,
+                devSpaceAmbientClipRR, devSpaceAmbientRadius));
+        canvas->drawRect(cover, paint);
+    }
+
+    if (spotAlpha > 0.0f) {
+        const Vector3 lightPos = SkiaFrameRenderer::getLightCenter();
+        float zRatio = casterZValue / (lightPos.z - casterZValue);
+        // clamp
+        if (zRatio < 0.0f) {
+            zRatio = 0.0f;
+        } else if (zRatio > 0.95f) {
+            zRatio = 0.95f;
+        }
+
+        const SkScalar lightWidth = SkiaFrameRenderer::getLightRadius();
+        const SkScalar srcSpaceSpotRadius = 2.0f * lightWidth * zRatio;
+        const SkScalar devSpaceSpotRadius = srcSpaceSpotRadius * scaleFactor;
+
+        // Compute the scale and translation for the spot shadow.
+        const SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
+        const SkMatrix spotMatrix = SkMatrix::MakeScale(scale, scale);
+
+        SkRect srcSpaceScaledRect = casterRect;
+        spotMatrix.mapRect(&srcSpaceScaledRect);
+        srcSpaceScaledRect.outset(SkScalarHalf(srcSpaceSpotRadius),
+                SkScalarHalf(srcSpaceSpotRadius));
+
+        SkRRect srcSpaceSpotRRect;
+        if (isOval) {
+            srcSpaceSpotRRect = SkRRect::MakeOval(srcSpaceScaledRect);
+        } else {
+            srcSpaceSpotRRect = SkRRect::MakeRectXY(srcSpaceScaledRect, casterCornerRadius * scale,
+                    casterCornerRadius * scale);
+        }
+
+        SkPoint center = SkPoint::Make(srcSpaceSpotRRect.rect().centerX(),
+                srcSpaceSpotRRect.rect().centerY());
+        SkMatrix ctmInverse;
+        if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
+            ALOGW("Matrix is degenerate. Will not render spot shadow!");
+            return;
+        }
+        SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
+        ctmInverse.mapPoints(&lightPos2D, 1);
+        const SkPoint spotOffset = SkPoint::Make(zRatio*(center.fX - lightPos2D.fX),
+                zRatio*(center.fY - lightPos2D.fY));
+
+        SkAutoCanvasRestore acr(canvas, true);
+        canvas->translate(spotOffset.fX, spotOffset.fY);
+
+        SkRect devSpaceScaledRect;
+        canvas->getTotalMatrix().mapRect(&devSpaceScaledRect, srcSpaceScaledRect);
+
+        SkRRect devSpaceSpotRRect;
+        if (isOval) {
+            devSpaceSpotRRect = SkRRect::MakeOval(devSpaceScaledRect);
+        } else {
+            const SkScalar devSpaceScaledCornerRadius = casterCornerRadius * scale * scaleFactor;
+            devSpaceSpotRRect = SkRRect::MakeRectXY(devSpaceScaledRect, devSpaceScaledCornerRadius,
+                    devSpaceScaledCornerRadius);
+        }
+
+        SkPaint paint;
+        paint.setColor(SkColorSetARGB((unsigned char) spotAlpha, 0, 0, 0));
+
+        SkRect srcSpaceScaledClipRect = clipRR.rect();
+        spotMatrix.mapRect(&srcSpaceScaledClipRect);
+        srcSpaceScaledClipRect.outset(SkScalarHalf(srcSpaceSpotRadius),
+                SkScalarHalf(srcSpaceSpotRadius));
+
+        SkRect devSpaceScaledClipRect;
+        canvas->getTotalMatrix().mapRect(&devSpaceScaledClipRect, srcSpaceScaledClipRect);
+        SkRRect devSpaceSpotClipRR;
+        if (clipRR.isOval()) {
+            devSpaceSpotClipRR = SkRRect::MakeOval(devSpaceScaledClipRect);
+        } else {
+            SkASSERT(clipRR.isRect());
+            devSpaceSpotClipRR = SkRRect::MakeRect(devSpaceScaledClipRect);
+        }
+
+        paint.setShader(SkRRectsGaussianEdgeShader::Make(devSpaceSpotRRect, devSpaceSpotClipRR,
+                devSpaceSpotRadius));
+
+        SkRect cover = srcSpaceScaledClipRect;
+        if (!cover.intersect(srcSpaceSpotRRect.rect())) {
+            return;
+        }
+
+        canvas->drawRect(cover, paint);
+    }
+}
+
+/**
+ * @param casterRect         the rectangle bounds of the RRect casting the shadow
+ * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
+ * @param casterClipRect     a rectangular clip that must be intersected with the
+ *                           shadow-casting RRect prior to casting the shadow
+ * @param revealClip         a circular clip that must be interested with the castClipRect
+ *                           and the shadow-casting rect prior to casting the shadow
+ * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
+ * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
+ * @param casterAlpha        the alpha value of the RRect casting the shadow (0.0-1.0 range)
+ * @param casterZValue       the Z value of the caster RRect
+ * @param canvas             the destination for the shadow draws
+ *
+ * We have special cases for 4 round rect shadow draws:
+ *    1) a RRect clipped by a reveal animation
+ *    2) a RRect clipped by a rectangle
+ *    3) an unclipped RRect with non-uniform scale
+ *    4) an unclipped RRect with uniform scale
+ * 1,2 and 4 require that the scale is uniform.
+ * 1 and 2 require that rects stay rects.
+ */
+static bool DrawShadowsAsRRects(const SkRect& casterRect, SkScalar casterCornerRadius,
+        const SkRect& casterClipRect, const RevealClip& revealClip, SkScalar ambientAlpha,
+        SkScalar spotAlpha, SkScalar casterAlpha, SkScalar casterZValue, SkCanvas* canvas) {
+    SkScalar scaleFactors[2];
+    if (!canvas->getTotalMatrix().getMinMaxScales(scaleFactors)) {
+        ALOGW("Matrix is degenerate. Will not render shadow!");
+        return false;
+    }
+
+    // The casterClipRect will contain the casterRect when bounds clipping is disabled
+    bool casterIsClippedByRect = !casterClipRect.contains(casterRect);
+    bool uniformScale = scaleFactors[0] == scaleFactors[1];
+
+    if (revealClip.willClip()) {
+        if (casterIsClippedByRect || !uniformScale || !canvas->getTotalMatrix().rectStaysRect()) {
+            return false;  // Fall back to the slow path since PathOps are required
+        }
+
+        const float revealRadius = revealClip.getRadius();
+        SkRect revealClipRect = SkRect::MakeLTRB(revealClip.getX()-revealRadius,
+                revealClip.getY()-revealRadius, revealClip.getX()+revealRadius,
+                revealClip.getY()+revealRadius);
+        SkRRect revealClipRR = SkRRect::MakeOval(revealClipRect);
+
+        DrawRRectShadowsWithClip(casterRect, casterCornerRadius, ambientAlpha, spotAlpha,
+                casterZValue, scaleFactors[0], revealClipRR, canvas);
+        return true;
+    }
+
+    if (casterIsClippedByRect) {
+        if (!uniformScale || !canvas->getTotalMatrix().rectStaysRect()) {
+            return false;  // Fall back to the slow path since PathOps are required
+        }
+
+        SkRRect casterClipRR = SkRRect::MakeRect(casterClipRect);
+
+        DrawRRectShadowsWithClip(casterRect, casterCornerRadius, ambientAlpha, spotAlpha,
+                casterZValue, scaleFactors[0], casterClipRR, canvas);
+        return true;
+    }
+
+    // The fast path needs uniform scale
+    if (!uniformScale) {
+        SkRRect casterRR = SkRRect::MakeRectXY(casterRect, casterCornerRadius, casterCornerRadius);
+        DrawAmbientShadowGeneral(canvas, casterRR, casterZValue, ambientAlpha,
+                [&](const SkRRect& rrect, const SkPaint& paint) {
+                    canvas->drawRRect(rrect, paint);
+                });
+        DrawSpotShadowGeneral(canvas, casterRR, casterZValue, spotAlpha,
+                [&](const SkRRect& rrect, const SkPaint& paint) {
+                canvas->drawRRect(rrect, paint);
+                });
+        return true;
+    }
+
+    DrawRRectShadows(casterRect, casterCornerRadius, ambientAlpha, spotAlpha, casterAlpha,
+            casterZValue, scaleFactors[0], canvas);
+    return true;
+}
+
+// copied from FrameBuilder::deferShadow
+void EndReorderBarrierDrawable::drawShadow(SkCanvas* canvas, RenderNodeDrawable* caster) {
+    const RenderProperties& casterProperties = caster->getNodeProperties();
+
+    if (casterProperties.getAlpha() <= 0.0f
+            || casterProperties.getOutline().getAlpha() <= 0.0f
+            || !casterProperties.getOutline().getPath()
+            || casterProperties.getScaleX() == 0
+            || casterProperties.getScaleY() == 0) {
+        // no shadow to draw
+        return;
+    }
+
+    const SkScalar casterAlpha = casterProperties.getAlpha()
+            * casterProperties.getOutline().getAlpha();
+    if (casterAlpha <= 0.0f) {
+        return;
+    }
+
+    float ambientAlpha = SkiaFrameRenderer::getAmbientShadowAlpha()*casterAlpha;
+    float spotAlpha = SkiaFrameRenderer::getSpotShadowAlpha()*casterAlpha;
+    const float casterZValue = casterProperties.getZ();
+
+    const RevealClip& revealClip = casterProperties.getRevealClip();
+    const SkPath* revealClipPath = revealClip.getPath();
+    if (revealClipPath && revealClipPath->isEmpty()) {
+        // An empty reveal clip means nothing is drawn
+        return;
+    }
+
+    bool clippedToBounds = casterProperties.getClippingFlags() & CLIP_TO_CLIP_BOUNDS;
+
+    SkRect casterClipRect = SkRect::MakeLargest();
+    if (clippedToBounds) {
+        Rect clipBounds;
+        casterProperties.getClippingRectForFlags(CLIP_TO_CLIP_BOUNDS, &clipBounds);
+        casterClipRect = clipBounds.toSkRect();
+    }
+
+    SkAutoCanvasRestore acr(canvas, true);
+
+    SkMatrix shadowMatrix;
+    mat4 hwuiMatrix(caster->getRecordedMatrix());
+    // TODO we don't pass the optional boolean to treat it as a 4x4 matrix
+    caster->getRenderNode()->applyViewPropertyTransforms(hwuiMatrix);
+    hwuiMatrix.copyTo(shadowMatrix);
+    canvas->concat(shadowMatrix);
+
+    const Outline& casterOutline = casterProperties.getOutline();
+    Rect possibleRect;
+    float radius;
+    if (casterOutline.getAsRoundRect(&possibleRect, &radius)) {
+        if (DrawShadowsAsRRects(possibleRect.toSkRect(), radius, casterClipRect, revealClip,
+                ambientAlpha, spotAlpha, casterAlpha, casterZValue, canvas)) {
+            return;
+        }
+    }
+
+    // Hard cases and calls to general shadow code
+    const SkPath* casterOutlinePath = casterProperties.getOutline().getPath();
+
+    // holds temporary SkPath to store the result of intersections
+    SkPath tmpPath;
+    const SkPath* casterPath = casterOutlinePath;
+
+    // TODO: In to following course of code that calculates the final shape, is there an optimal
+    //       of doing the Op calculations?
+    // intersect the shadow-casting path with the reveal, if present
+    if (revealClipPath) {
+        Op(*casterPath, *revealClipPath, kIntersect_SkPathOp, &tmpPath);
+        casterPath = &tmpPath;
+    }
+
+    // intersect the shadow-casting path with the clipBounds, if present
+    if (clippedToBounds) {
+        SkPath clipBoundsPath;
+        clipBoundsPath.addRect(casterClipRect);
+        Op(*casterPath, clipBoundsPath, kIntersect_SkPathOp, &tmpPath);
+        casterPath = &tmpPath;
+    }
+
+    DrawAmbientShadowGeneral(canvas, *casterPath, casterZValue, ambientAlpha,
+            [&](const SkPath& path, const SkPaint& paint) {
+                canvas->drawPath(path, paint);
+            });
+
+    DrawSpotShadowGeneral(canvas, *casterPath, casterZValue, spotAlpha,
+            [&](const SkPath& path, const SkPaint& paint) {
+                canvas->drawPath(path, paint);
+            });
+}
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
new file mode 100644
index 0000000..298a732
--- /dev/null
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+#include "RenderNodeDrawable.h"
+
+#include <SkCanvas.h>
+#include <SkDrawable.h>
+#include <utils/FatVector.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaDisplayList;
+class EndReorderBarrierDrawable;
+
+/**
+ * StartReorderBarrierDrawable and EndReorderBarrierDrawable work together to define
+ * a sub-list in a display list that need to be drawn out-of-order sorted instead by render
+ * node Z index.
+ * StartReorderBarrierDrawable will sort the entire range and it will draw
+ * render nodes in the range with negative Z index.
+ */
+class StartReorderBarrierDrawable : public SkDrawable {
+public:
+    explicit StartReorderBarrierDrawable(SkiaDisplayList* data);
+
+protected:
+    virtual SkRect onGetBounds() override {
+        return SkRect::MakeLargest();
+    }
+    virtual void onDraw(SkCanvas* canvas) override;
+
+private:
+    size_t mEndChildIndex;
+    size_t mBeginChildIndex;
+    FatVector<RenderNodeDrawable*, 16> mChildren;
+    SkiaDisplayList* mDisplayList;
+
+    friend class EndReorderBarrierDrawable;
+};
+
+/**
+ * See StartReorderBarrierDrawable.
+ * EndReorderBarrierDrawable relies on StartReorderBarrierDrawable to host and sort the render
+ * nodes by Z index. When EndReorderBarrierDrawable is drawn it will draw all render nodes in the
+ * range with positive Z index. It is also responsible for drawing shadows for the nodes
+ * corresponding to their z-index.
+ */
+class EndReorderBarrierDrawable : public SkDrawable {
+public:
+    explicit EndReorderBarrierDrawable(StartReorderBarrierDrawable* startBarrier);
+protected:
+    virtual SkRect onGetBounds() override {
+        return SkRect::MakeLargest();
+    }
+    virtual void onDraw(SkCanvas* canvas) override;
+private:
+    void drawShadow(SkCanvas* canvas, RenderNodeDrawable* caster);
+    StartReorderBarrierDrawable* mStartBarrier;
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
similarity index 98%
rename from libs/hwui/SkiaDisplayList.cpp
rename to libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index d10f306..c734097 100644
--- a/libs/hwui/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -24,6 +24,7 @@
 
 namespace android {
 namespace uirenderer {
+namespace skiapipeline {
 
 SkiaDisplayList::SkiaDisplayList(SkRect bounds) : mDrawable(SkLiteDL::New(bounds)) {
     SkASSERT(projectionReceiveIndex == -1);
@@ -130,5 +131,6 @@
     new (&allocator) LinearAllocator();
 }
 
+}; // namespace skiapipeline
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
similarity index 97%
rename from libs/hwui/SkiaDisplayList.h
rename to libs/hwui/pipeline/skia/SkiaDisplayList.h
index c8a82bd..734aae4a 100644
--- a/libs/hwui/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -17,7 +17,8 @@
 #pragma once
 
 #include "DisplayList.h"
-#include "SkiaDrawables.h"
+#include "GLFunctorDrawable.h"
+#include "RenderNodeDrawable.h"
 
 #include <deque>
 #include <SkLiteDL.h>
@@ -25,6 +26,7 @@
 
 namespace android {
 namespace uirenderer {
+namespace skiapipeline {
 
 /**
  * This class is intended to be self contained, but still subclasses from
@@ -148,5 +150,6 @@
     bool mPinnedImages = false;
 };
 
+}; // namespace skiapipeline
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaFrameRenderer.h b/libs/hwui/pipeline/skia/SkiaFrameRenderer.h
new file mode 100644
index 0000000..70207c1
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaFrameRenderer.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+/**
+ * TODO: this is a stub that will be added in a subsquent CL
+ */
+class SkiaFrameRenderer {
+public:
+
+    static bool skpCaptureEnabled() { return false; }
+
+    // TODO avoids unused compile error but we need to pass this to the reorder drawables!
+    static float getLightRadius() {
+        return 1.0f;
+    }
+
+    static uint8_t getAmbientShadowAlpha() {
+        return 1;
+    }
+
+    static uint8_t getSpotShadowAlpha() {
+        return 1;
+    }
+
+    static Vector3 getLightCenter() {
+        Vector3 result;
+        result.x = result.y = result.z = 1.0f;
+        return result;
+    }
+
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
new file mode 100644
index 0000000..8a42983
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2016 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 "SkiaRecordingCanvas.h"
+
+#include "Layer.h"
+#include "RenderNode.h"
+#include "LayerDrawable.h"
+#include "NinePatchUtils.h"
+#include "pipeline/skia/AnimatedDrawables.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+// ----------------------------------------------------------------------------
+// Recording Canvas Setup
+// ----------------------------------------------------------------------------
+
+void SkiaRecordingCanvas::initDisplayList(uirenderer::RenderNode* renderNode, int width,
+        int height) {
+    mBarrierPending = false;
+    mCurrentBarrier = nullptr;
+    SkASSERT(mDisplayList.get() == nullptr);
+
+    if (renderNode) {
+        mDisplayList = renderNode->detachAvailableList();
+    }
+    SkRect bounds = SkRect::MakeWH(width, height);
+    if (mDisplayList) {
+        mDisplayList->reset(nullptr, bounds);
+    } else {
+        mDisplayList.reset(new SkiaDisplayList(bounds));
+    }
+
+    mRecorder.reset(mDisplayList->mDrawable.get());
+    SkiaCanvas::reset(&mRecorder);
+}
+
+uirenderer::DisplayList* SkiaRecordingCanvas::finishRecording() {
+    // close any existing chunks if necessary
+    insertReorderBarrier(false);
+    mRecorder.restoreToCount(1);
+    return mDisplayList.release();
+}
+
+// ----------------------------------------------------------------------------
+// Recording Canvas draw operations: View System
+// ----------------------------------------------------------------------------
+
+void SkiaRecordingCanvas::drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
+        uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
+        uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
+        uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* paint) {
+    drawDrawable(mDisplayList->allocateDrawable<AnimatedRoundRect>(left, top, right, bottom,
+            rx, ry, paint));
+}
+
+void SkiaRecordingCanvas::drawCircle(uirenderer::CanvasPropertyPrimitive* x,
+        uirenderer::CanvasPropertyPrimitive* y, uirenderer::CanvasPropertyPrimitive* radius,
+        uirenderer::CanvasPropertyPaint* paint) {
+    drawDrawable(mDisplayList->allocateDrawable<AnimatedCircle>(x, y, radius, paint));
+}
+
+void SkiaRecordingCanvas::insertReorderBarrier(bool enableReorder) {
+    mBarrierPending = enableReorder;
+
+    if (nullptr != mCurrentBarrier) {
+        // finish off the existing chunk
+        SkDrawable* drawable =
+                mDisplayList->allocateDrawable<EndReorderBarrierDrawable>(
+                mCurrentBarrier);
+        mCurrentBarrier = nullptr;
+        drawDrawable(drawable);
+    }
+}
+
+void SkiaRecordingCanvas::drawLayer(uirenderer::DeferredLayerUpdater* layerUpdater) {
+    if (layerUpdater != nullptr && layerUpdater->backingLayer() != nullptr) {
+        uirenderer::Layer* layer = layerUpdater->backingLayer();
+        sk_sp<SkDrawable> drawable(new LayerDrawable(layer));
+        drawDrawable(drawable.get());
+    }
+}
+
+void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
+    // lazily create the chunk if needed
+    if (mBarrierPending) {
+        mCurrentBarrier = (StartReorderBarrierDrawable*)
+                mDisplayList->allocateDrawable<StartReorderBarrierDrawable>(
+                mDisplayList.get());
+        drawDrawable(mCurrentBarrier);
+        mBarrierPending = false;
+    }
+
+    // record the child node
+    mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas());
+    drawDrawable(&mDisplayList->mChildNodes.back());
+
+    // use staging property, since recording on UI thread
+    if (renderNode->stagingProperties().isProjectionReceiver()) {
+        mDisplayList->mIsProjectionReceiver = true;
+        // set projectionReceiveIndex so that RenderNode.hasProjectionReceiver returns true
+        mDisplayList->projectionReceiveIndex = mDisplayList->mChildNodes.size() - 1;
+    }
+}
+
+void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor,
+        uirenderer::GlFunctorLifecycleListener* listener) {
+    mDisplayList->mChildFunctors.emplace_back(functor, listener, asSkCanvas());
+    drawDrawable(&mDisplayList->mChildFunctors.back());
+}
+
+class VectorDrawable : public SkDrawable {
+ public:
+    VectorDrawable(VectorDrawableRoot* tree) : mRoot(tree) {}
+
+ protected:
+     virtual SkRect onGetBounds() override {
+         return SkRect::MakeLargest();
+     }
+     virtual void onDraw(SkCanvas* canvas) override {
+         Bitmap& hwuiBitmap = mRoot->getBitmapUpdateIfDirty();
+         SkBitmap bitmap;
+         hwuiBitmap.getSkBitmap(&bitmap);
+         SkPaint* paint = mRoot->getPaint();
+         canvas->drawBitmapRect(bitmap, mRoot->mutateProperties()->getBounds(), paint);
+         /*
+          * TODO we can draw this directly but need to address the following...
+          *
+          * 1) Add drawDirect(SkCanvas*) to VectorDrawableRoot
+          * 2) fix VectorDrawable.cpp's Path::draw to not make a temporary path
+          *    so that we don't break caching
+          * 3) figure out how to set path's as volatile during animation
+          * 4) if mRoot->getPaint() != null either promote to layer (during
+          *    animation) or cache in SkSurface (for static content)
+          *
+          */
+     }
+
+ private:
+    sp<VectorDrawableRoot> mRoot;
+};
+
+void SkiaRecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
+    drawDrawable(mDisplayList->allocateDrawable<VectorDrawable>(tree));
+    mDisplayList->mVectorDrawables.push_back(tree);
+}
+
+// ----------------------------------------------------------------------------
+// Recording Canvas draw operations: Bitmaps
+// ----------------------------------------------------------------------------
+
+inline static const SkPaint* nonAAPaint(const SkPaint* origPaint, SkPaint* tmpPaint) {
+    if (origPaint && origPaint->isAntiAlias()) {
+        *tmpPaint = *origPaint;
+        tmpPaint->setAntiAlias(false);
+        return tmpPaint;
+    } else {
+        return origPaint;
+    }
+}
+
+void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
+    SkBitmap skBitmap;
+    bitmap.getSkBitmap(&skBitmap);
+
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode);
+    if (!skBitmap.isImmutable()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
+    SkPaint tmpPaint;
+    mRecorder.drawImage(image, left, top, nonAAPaint(paint, &tmpPaint));
+}
+
+void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix,
+        const SkPaint* paint) {
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
+    SkAutoCanvasRestore acr(&mRecorder, true);
+    concat(matrix);
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+    if (!bitmap.isImmutable()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
+    SkPaint tmpPaint;
+    mRecorder.drawImage(image, 0, 0, nonAAPaint(paint, &tmpPaint));
+}
+
+void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, float srcLeft, float srcTop,
+        float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight,
+        float dstBottom, const SkPaint* paint) {
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
+    SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
+    SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+    if (!bitmap.isImmutable()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
+    SkPaint tmpPaint;
+    mRecorder.drawImageRect(image, srcRect, dstRect, nonAAPaint(paint, &tmpPaint));
+}
+
+void SkiaRecordingCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk,
+        float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
+
+    SkCanvas::Lattice lattice;
+    NinePatchUtils::SetLatticeDivs(&lattice, chunk, bitmap.width(), bitmap.height());
+
+    lattice.fFlags = nullptr;
+    int numFlags = 0;
+    if (chunk.numColors > 0 && chunk.numColors == NinePatchUtils::NumDistinctRects(lattice)) {
+        // We can expect the framework to give us a color for every distinct rect.
+        // Skia requires placeholder flags for degenerate rects.
+        numFlags = (lattice.fXCount + 1) * (lattice.fYCount + 1);
+    }
+
+    SkAutoSTMalloc<25, SkCanvas::Lattice::Flags> flags(numFlags);
+    if (numFlags > 0) {
+        NinePatchUtils::SetLatticeFlags(&lattice, flags.get(), numFlags, chunk);
+    }
+
+    lattice.fBounds = nullptr;
+    SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+    if (!bitmap.isImmutable()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
+
+    SkPaint tmpPaint;
+    mRecorder.drawImageLattice(image.get(), lattice, dst, nonAAPaint(paint, &tmpPaint));
+}
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
new file mode 100644
index 0000000..8aef97f
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+#pragma once
+
+#include "SkiaCanvas.h"
+#include "SkiaDisplayList.h"
+#include "ReorderBarrierDrawables.h"
+#include <SkLiteRecorder.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+/**
+ * A SkiaCanvas implementation that records drawing operations for deferred rendering backed by a
+ * SkLiteRecorder and a SkiaDisplayList.
+ */
+class SkiaRecordingCanvas : public SkiaCanvas {
+ public:
+    explicit SkiaRecordingCanvas(uirenderer::RenderNode* renderNode, int width, int height) {
+        initDisplayList(renderNode, width, height);
+    }
+
+    virtual void setBitmap(const SkBitmap& bitmap) override {
+        LOG_ALWAYS_FATAL("DisplayListCanvas is not backed by a bitmap.");
+    }
+
+    virtual void resetRecording(int width, int height,
+            uirenderer::RenderNode* renderNode) override {
+        initDisplayList(renderNode, width, height);
+    }
+
+    virtual uirenderer::DisplayList* finishRecording() override;
+
+    virtual void drawBitmap(Bitmap& bitmap, float left, float top,
+            const SkPaint* paint) override;
+    virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix,
+            const SkPaint* paint) override;
+    virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop,
+            float srcRight, float srcBottom, float dstLeft, float dstTop,
+            float dstRight, float dstBottom, const SkPaint* paint) override;
+    virtual void drawNinePatch(Bitmap& hwuiBitmap, const android::Res_png_9patch& chunk,
+            float dstLeft, float dstTop, float dstRight, float dstBottom,
+            const SkPaint* paint) override;
+
+    virtual void drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
+            uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
+            uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
+            uirenderer::CanvasPropertyPrimitive* ry,
+            uirenderer::CanvasPropertyPaint* paint) override;
+    virtual void drawCircle(uirenderer::CanvasPropertyPrimitive* x,
+            uirenderer::CanvasPropertyPrimitive* y, uirenderer::CanvasPropertyPrimitive* radius,
+            uirenderer::CanvasPropertyPaint* paint) override;
+
+    virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
+
+    virtual void insertReorderBarrier(bool enableReorder) override;
+    virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
+    virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
+    virtual void callDrawGLFunction(Functor* functor,
+                                    uirenderer::GlFunctorLifecycleListener* listener) override;
+
+private:
+    SkLiteRecorder mRecorder;
+    std::unique_ptr<SkiaDisplayList> mDisplayList;
+    bool mBarrierPending;
+    StartReorderBarrierDrawable* mCurrentBarrier;
+
+    /**
+     *  A new SkiaDisplayList is created or recycled if available.
+     *
+     *  @param renderNode is optional and used to recycle an old display list.
+     *  @param width used to calculate recording bounds.
+     *  @param height used to calculate recording bounds.
+     */
+    void initDisplayList(uirenderer::RenderNode* renderNode, int width, int height);
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 84ab3f3..72af7c9 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -278,12 +278,12 @@
         // texture always takes slot 0, shader samplers increment from there
         mCaches->textureState().activateTexture(0);
 
-        mCaches->textureState().bindTexture(texture.target, texture.texture->id());
+        mCaches->textureState().bindTexture(texture.texture->target(), texture.texture->id());
         if (texture.clamp != GL_INVALID_ENUM) {
-            texture.texture->setWrap(texture.clamp, false, false, texture.target);
+            texture.texture->setWrap(texture.clamp, false, false);
         }
         if (texture.filter != GL_INVALID_ENUM) {
-            texture.texture->setFilter(texture.filter, false, false, texture.target);
+            texture.texture->setFilter(texture.filter, false, false);
         }
 
         if (texture.textureTransform) {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index fe0f56a..03deb0a 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -19,11 +19,9 @@
 
 #include "AnimationContext.h"
 #include "Caches.h"
-#include "DeferredLayerUpdater.h"
 #include "EglManager.h"
 #include "LayerUpdateQueue.h"
 #include "Properties.h"
-#include "Readback.h"
 #include "RenderThread.h"
 #include "hwui/Canvas.h"
 #include "renderstate/RenderState.h"
@@ -97,6 +95,31 @@
     }
 }
 
+void CanvasContext::invokeFunctor(const RenderThread& thread, Functor* functor) {
+    ATRACE_CALL();
+    auto renderType = Properties::getRenderPipelineType();
+    switch (renderType) {
+        case RenderPipelineType::OpenGL:
+            OpenGLPipeline::invokeFunctor(thread, functor);
+            break;
+        default:
+            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+            break;
+    }
+}
+
+void CanvasContext::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
+    auto renderType = Properties::getRenderPipelineType();
+    switch (renderType) {
+        case RenderPipelineType::OpenGL:
+            OpenGLPipeline::prepareToDraw(thread, bitmap);
+            break;
+        default:
+            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+            break;
+    }
+}
+
 CanvasContext::CanvasContext(RenderThread& thread, bool translucent,
         RenderNode* rootRenderNode, IContextFactory* contextFactory,
         std::unique_ptr<IRenderPipeline> renderPipeline)
@@ -425,8 +448,11 @@
 
     GpuMemoryTracker::onFrameCompleted();
 #ifdef BUGREPORT_FONT_CACHE_USAGE
-    Caches& caches = Caches::getInstance();
-    caches.fontRenderer.getFontRenderer().historyTracker().frameCompleted();
+    auto renderType = Properties::getRenderPipelineType();
+    if (RenderPipelineType::OpenGL == renderType) {
+        Caches& caches = Caches::getInstance();
+        caches.fontRenderer.getFontRenderer().historyTracker().frameCompleted();
+    }
 #endif
 
 }
@@ -456,16 +482,6 @@
     }
 }
 
-void CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) {
-    ATRACE_CALL();
-    DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
-    if (thread.eglManager().hasEglContext()) {
-        mode = DrawGlInfo::kModeProcess;
-    }
-
-    thread.renderState().invokeFunctor(functor, mode, nullptr);
-}
-
 void CanvasContext::markLayerInUse(RenderNode* node) {
     if (mPrefetchedLayers.erase(node)) {
         node->decStrong(nullptr);
@@ -520,10 +536,6 @@
         for (const sp<RenderNode>& node : mRenderNodes) {
             node->destroyHardwareResources(observer);
         }
-        Caches& caches = Caches::getInstance();
-        // Make sure to release all the textures we were owning as there won't
-        // be another draw
-        caches.textureCache.resetMarkInUse(this);
         mRenderPipeline->onDestroyHardwareResources();
     }
 }
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 559ac87..b61eef2 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -85,11 +85,15 @@
      */
     static void destroyLayer(RenderNode* node);
 
+    static void invokeFunctor(const RenderThread& thread, Functor* functor);
+
+    static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
+
     /*
      * If Properties::isSkiaEnabled() is true then this will return the Skia
      * grContext associated with the current RenderPipeline.
      */
-    GrContext* getGrContext() const { return mRenderPipeline->getGrContext(); }
+    GrContext* getGrContext() const { return mRenderThread.getGrContext(); }
 
     // Won't take effect until next EGLSurface creation
     void setSwapBehavior(SwapBehavior swapBehavior);
@@ -121,8 +125,6 @@
     void destroyHardwareResources(TreeObserver* observer);
     static void trimMemory(RenderThread& thread, int level);
 
-    static void invokeFunctor(RenderThread& thread, Functor* functor);
-
     DeferredLayerUpdater* createTextureLayer();
 
     void stopDrawing();
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index beda045..ce48bc0 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -25,6 +25,8 @@
 #include <cutils/log.h>
 #include <cutils/properties.h>
 #include <EGL/eglext.h>
+#include <GrContextOptions.h>
+#include <gl/GrGLInterface.h>
 #include <string>
 
 #define GLES_VERSION 2
@@ -126,6 +128,17 @@
     makeCurrent(mPBufferSurface);
     DeviceInfo::initialize();
     mRenderThread.renderState().onGLContextCreated();
+
+    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
+        sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
+        LOG_ALWAYS_FATAL_IF(!glInterface.get());
+
+        GrContextOptions options;
+        options.fDisableDistanceFieldPaths = true;
+        options.fAllowPathMaskCaching = true;
+        mRenderThread.setGrContext(GrContext::Create(GrBackend::kOpenGL_GrBackend,
+                (GrBackendContext)glInterface.get(), options));
+    }
 }
 
 void EglManager::initExtensions() {
@@ -235,6 +248,7 @@
 void EglManager::destroy() {
     if (mEglDisplay == EGL_NO_DISPLAY) return;
 
+    mRenderThread.setGrContext(nullptr);
     mRenderThread.renderState().onGLContextDestroyed();
     eglDestroyContext(mEglDisplay, mEglContext);
     eglDestroySurface(mEglDisplay, mPBufferSurface);
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index f96c2fd..52894ad 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -73,7 +73,6 @@
     virtual TaskManager* getTaskManager() = 0;
     virtual bool createOrUpdateLayer(RenderNode* node,
             const DamageAccumulator& damageAccumulator) = 0;
-    virtual GrContext* getGrContext() = 0;
 
     virtual ~IRenderPipeline() {}
 };
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index c758f6c..cca0fca 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -18,6 +18,7 @@
 
 #include "DeferredLayerUpdater.h"
 #include "EglManager.h"
+#include "ProfileRenderer.h"
 #include "renderstate/RenderState.h"
 #include "Readback.h"
 
@@ -76,7 +77,8 @@
     BakedOpRenderer renderer(caches, mRenderThread.renderState(),
             opaque, lightInfo);
     frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
-    profiler->draw(&renderer);
+    ProfileRenderer profileRenderer(renderer);
+    profiler->draw(profileRenderer);
     drew = renderer.didDraw();
 
     // post frame cleanup
@@ -163,6 +165,10 @@
 }
 
 void OpenGLPipeline::onDestroyHardwareResources() {
+    Caches& caches = Caches::getInstance();
+    // Make sure to release all the textures we were owning as there won't
+    // be another draw
+    caches.textureCache.resetMarkInUse(this);
     mRenderThread.renderState().flush(Caches::FlushMode::Layers);
 }
 
@@ -223,6 +229,21 @@
     }
 }
 
+void OpenGLPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
+    if (Caches::hasInstance() && thread.eglManager().hasEglContext()) {
+        ATRACE_NAME("Bitmap#prepareToDraw task");
+        Caches::getInstance().textureCache.prefetch(bitmap);
+    }
+}
+
+void OpenGLPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) {
+    DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
+    if (thread.eglManager().hasEglContext()) {
+        mode = DrawGlInfo::kModeProcess;
+    }
+    thread.renderState().invokeFunctor(functor, mode, nullptr);
+}
+
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/renderthread/OpenGLPipeline.h b/libs/hwui/renderthread/OpenGLPipeline.h
index d024aec..8722d59 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.h
+++ b/libs/hwui/renderthread/OpenGLPipeline.h
@@ -56,7 +56,8 @@
     bool createOrUpdateLayer(RenderNode* node,
             const DamageAccumulator& damageAccumulator) override;
     static void destroyLayer(RenderNode* node);
-    GrContext* getGrContext() override { return nullptr; }
+    static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
+    static void invokeFunctor(const RenderThread& thread, Functor* functor);
 
 private:
     EglManager& mEglManager;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index c2ed864..6cb2b9c 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -617,17 +617,14 @@
             reinterpret_cast<intptr_t>( staticPostAndWait(task) ));
 }
 
-CREATE_BRIDGE2(prepareToDraw, RenderThread* thread, SkBitmap* bitmap) {
-    if (Caches::hasInstance() && args->thread->eglManager().hasEglContext()) {
-        ATRACE_NAME("Bitmap#prepareToDraw task");
-        Caches::getInstance().textureCache.prefetch(args->bitmap);
-    }
-    delete args->bitmap;
+CREATE_BRIDGE2(prepareToDraw, RenderThread* thread, Bitmap* bitmap) {
+    CanvasContext::prepareToDraw(*args->thread, args->bitmap);
+    args->bitmap->unref();
     args->bitmap = nullptr;
     return nullptr;
 }
 
-void RenderProxy::prepareToDraw(const SkBitmap& bitmap) {
+void RenderProxy::prepareToDraw(Bitmap& bitmap) {
     // If we haven't spun up a hardware accelerated window yet, there's no
     // point in precaching these bitmaps as it can't impact jank.
     // We also don't know if we even will spin up a hardware-accelerated
@@ -636,7 +633,8 @@
     RenderThread* renderThread = &RenderThread::getInstance();
     SETUP_TASK(prepareToDraw);
     args->thread = renderThread;
-    args->bitmap = new SkBitmap(bitmap);
+    bitmap.ref();
+    args->bitmap = &bitmap;
     nsecs_t lastVsync = renderThread->timeLord().latestVsync();
     nsecs_t estimatedNextVsync = lastVsync + renderThread->timeLord().frameIntervalNanos();
     nsecs_t timeToNextVsync = estimatedNextVsync - systemTime(CLOCK_MONOTONIC);
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 50a6f64..ae9330d 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -128,7 +128,7 @@
 
     ANDROID_API static int copySurfaceInto(sp<Surface>& surface,
             int left, int top, int right, int bottom, SkBitmap* bitmap);
-    ANDROID_API static void prepareToDraw(const SkBitmap& bitmap);
+    ANDROID_API static void prepareToDraw(Bitmap& bitmap);
 
 private:
     RenderThread& mRenderThread;
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 076e3d4..d8677e13 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -22,6 +22,7 @@
 #include "../JankTracker.h"
 #include "TimeLord.h"
 
+#include <GrContext.h>
 #include <cutils/compiler.h>
 #include <ui/DisplayInfo.h>
 #include <utils/Looper.h>
@@ -88,12 +89,15 @@
     void pushBackFrameCallback(IFrameCallback* callback);
 
     TimeLord& timeLord() { return mTimeLord; }
-    RenderState& renderState() { return *mRenderState; }
-    EglManager& eglManager() { return *mEglManager; }
+    RenderState& renderState() const { return *mRenderState; }
+    EglManager& eglManager() const { return *mEglManager; }
     JankTracker& jankTracker() { return *mJankTracker; }
 
     const DisplayInfo& mainDisplayInfo() { return mDisplayInfo; }
 
+    GrContext* getGrContext() const { return mGrContext.get(); }
+    void setGrContext(GrContext* cxt) { mGrContext.reset(cxt); }
+
 protected:
     virtual bool threadLoop() override;
 
@@ -144,6 +148,8 @@
     EglManager* mEglManager;
 
     JankTracker* mJankTracker = nullptr;
+
+    sk_sp<GrContext> mGrContext;
 };
 
 } /* namespace renderthread */
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 5b9b003..9530c79 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -125,5 +125,44 @@
     return utf16;
 }
 
+SkColor TestUtils::getColor(const sk_sp<SkSurface>& surface, int x, int y) {
+    SkPixmap pixmap;
+    if (!surface->peekPixels(&pixmap)) {
+        return 0;
+    }
+    switch (pixmap.colorType()) {
+        case kGray_8_SkColorType: {
+            const uint8_t* addr = pixmap.addr8(x, y);
+            return SkColorSetRGB(*addr, *addr, *addr);
+        }
+        case kAlpha_8_SkColorType: {
+            const uint8_t* addr = pixmap.addr8(x, y);
+            return SkColorSetA(0, addr[0]);
+        }
+        case kRGB_565_SkColorType: {
+            const uint16_t* addr = pixmap.addr16(x, y);
+            return SkPixel16ToColor(addr[0]);
+        }
+        case kARGB_4444_SkColorType: {
+            const uint16_t* addr = pixmap.addr16(x, y);
+            SkPMColor c = SkPixel4444ToPixel32(addr[0]);
+            return SkUnPreMultiply::PMColorToColor(c);
+        }
+        case kBGRA_8888_SkColorType: {
+            const uint32_t* addr = pixmap.addr32(x, y);
+            SkPMColor c = SkSwizzle_BGRA_to_PMColor(addr[0]);
+            return SkUnPreMultiply::PMColorToColor(c);
+        }
+        case kRGBA_8888_SkColorType: {
+            const uint32_t* addr = pixmap.addr32(x, y);
+            SkPMColor c = SkSwizzle_RGBA_to_PMColor(addr[0]);
+            return SkUnPreMultiply::PMColorToColor(c);
+        }
+        default:
+            return 0;
+    }
+    return 0;
+}
+
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index cdfa2f4..0be5a3b 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -125,8 +125,7 @@
     static sk_sp<Bitmap> createBitmap(int width, int height,
             SkColorType colorType = kN32_SkColorType) {
         SkImageInfo info = SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType);
-        size_t size = height * info.minRowBytes();
-        return Bitmap::allocateHeapBitmap(size, info, info.minRowBytes(), nullptr);
+        return Bitmap::allocateHeapBitmap(info);
     }
 
     static sk_sp<Bitmap> createBitmap(int width, int height, SkBitmap* outBitmap) {
@@ -135,17 +134,6 @@
         return Bitmap::allocateHeapBitmap(outBitmap, nullptr);
     }
 
-    static SkBitmap createSkBitmap(int width, int height,
-            SkColorType colorType = kN32_SkColorType) {
-        SkBitmap bitmap;
-        sk_sp<SkColorSpace> colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
-        SkImageInfo info = SkImageInfo::Make(width, height,
-                colorType, kPremul_SkAlphaType, colorSpace);
-        bitmap.setInfo(info);
-        Bitmap::allocateHeapBitmap(&bitmap, nullptr);
-        return bitmap;
-    }
-
     static sp<DeferredLayerUpdater> createTextureLayerUpdater(
             renderthread::RenderThread& renderThread, uint32_t width, uint32_t height,
             const SkMatrix& transform);
@@ -261,6 +249,19 @@
 
     static std::unique_ptr<uint16_t[]> asciiToUtf16(const char* str);
 
+    class MockFunctor : public Functor {
+     public:
+         virtual status_t operator ()(int what, void* data) {
+             mLastMode = what;
+             return DrawGlInfo::kStatusDone;
+         }
+         int getLastMode() const { return mLastMode; }
+     private:
+         int mLastMode = -1;
+     };
+
+    static SkColor getColor(const sk_sp<SkSurface>& surface, int x, int y);
+
 private:
     static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) {
         node->syncProperties();
diff --git a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
index 584f684..8256024 100644
--- a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
@@ -45,12 +45,14 @@
         int x = dp(32);
         for (int i = 0; i < 4; i++) {
             int y = (height / 4) * i;
-            SkBitmap thumb = TestUtils::createSkBitmap(thumbnailSize, thumbnailSize);
-            thumb.eraseColor(COLORS[i]);
-            sp<RenderNode> card = createCard(x, y, cardsize, cardsize, thumb);
+            SkBitmap bitmap;
+            sk_sp<Bitmap> thumb(TestUtils::createBitmap(thumbnailSize, thumbnailSize, &bitmap));
+
+            bitmap.eraseColor(COLORS[i]);
+            sp<RenderNode> card = createCard(x, y, cardsize, cardsize, *thumb);
             card->mutateStagingProperties().setElevation(i * dp(8));
             renderer.drawRenderNode(card.get());
-            mThumbnail = thumb;
+            mThumbnail = bitmap;
             mCards.push_back(card);
         }
 
@@ -68,8 +70,7 @@
     }
 
 private:
-    sp<RenderNode> createCard(int x, int y, int width, int height,
-            const SkBitmap& thumb) {
+    sp<RenderNode> createCard(int x, int y, int width, int height, Bitmap& thumb) {
         return TestUtils::createNode(x, y, x + width, y + height,
                 [&thumb, width, height](RenderProperties& props, Canvas& canvas) {
             props.setElevation(dp(16));
diff --git a/libs/hwui/tests/unit/CanvasContextTests.cpp b/libs/hwui/tests/unit/CanvasContextTests.cpp
new file mode 100644
index 0000000..d3d80a9
--- /dev/null
+++ b/libs/hwui/tests/unit/CanvasContextTests.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 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 <gtest/gtest.h>
+
+#include "AnimationContext.h"
+#include "IContextFactory.h"
+#include "renderthread/CanvasContext.h"
+#include "tests/common/TestUtils.h"
+
+using namespace android;
+using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+
+class ContextFactory : public IContextFactory {
+public:
+    virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override {
+        return new AnimationContext(clock);
+    }
+};
+
+RENDERTHREAD_TEST(CanvasContext, create) {
+    auto rootNode = TestUtils::createNode(0, 0, 200, 400, nullptr);
+    ContextFactory contextFactory;
+    std::unique_ptr<CanvasContext> canvasContext(CanvasContext::create(
+            renderThread, false, rootNode.get(), &contextFactory));
+
+    ASSERT_FALSE(canvasContext->hasSurface());
+
+    canvasContext->destroy(nullptr);
+}
+
+RENDERTHREAD_TEST(CanvasContext, invokeFunctor) {
+    TestUtils::MockFunctor functor;
+    CanvasContext::invokeFunctor(renderThread, &functor);
+    ASSERT_EQ(functor.getLastMode(), DrawGlInfo::kModeProcess);
+}
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index fb6067d..01046e1 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -403,10 +403,10 @@
         void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
             switch(mIndex++) {
             case 0:
-                EXPECT_EQ(opaqueBitmap.get(), op.bitmap->pixelRef());
+                EXPECT_EQ(opaqueBitmap.get(), op.bitmap);
                 break;
             case 1:
-                EXPECT_EQ(transpBitmap.get(), op.bitmap->pixelRef());
+                EXPECT_EQ(transpBitmap.get(), op.bitmap);
                 break;
             default:
                 ADD_FAILURE() << "Only two ops expected.";
diff --git a/libs/hwui/tests/unit/GlopBuilderTests.cpp b/libs/hwui/tests/unit/GlopBuilderTests.cpp
index 67e58e2..ce1db05 100644
--- a/libs/hwui/tests/unit/GlopBuilderTests.cpp
+++ b/libs/hwui/tests/unit/GlopBuilderTests.cpp
@@ -45,7 +45,11 @@
     EXPECT_EQ(expectedFill.skiaShaderData.skiaShaderType, builtFill.skiaShaderData.skiaShaderType);
     EXPECT_EQ(expectedFill.texture.clamp, builtFill.texture.clamp);
     EXPECT_EQ(expectedFill.texture.filter, builtFill.texture.filter);
-    EXPECT_EQ(expectedFill.texture.target, builtFill.texture.target);
+    EXPECT_TRUE((expectedFill.texture.texture && builtFill.texture.texture)
+            || (!expectedFill.texture.texture && !builtFill.texture.texture));
+    if (expectedFill.texture.texture) {
+        EXPECT_EQ(expectedFill.texture.texture->target(), builtFill.texture.texture->target());
+    }
     EXPECT_EQ(expectedFill.texture.textureTransform, builtFill.texture.textureTransform);
 }
 
@@ -108,7 +112,7 @@
     glop->fill.color.set(Color::Black);
     glop->fill.skiaShaderData.skiaShaderType = kNone_SkiaShaderType;
     glop->fill.filterMode = ProgramDescription::ColorFilterMode::None;
-    glop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
+    glop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
     return glop;
 }
 
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 3bfbf12..134497c 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -736,10 +736,12 @@
 }
 
 TEST(RecordingCanvas, refBitmapInShader_bitmapShader) {
-    SkBitmap bitmap = TestUtils::createSkBitmap(100, 100);
+    sk_sp<Bitmap> bitmap = TestUtils::createBitmap(100, 100);
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) {
         SkPaint paint;
-        sk_sp<SkShader> shader = SkMakeBitmapShader(bitmap,
+        SkBitmap skBitmap;
+        bitmap->getSkBitmap(&skBitmap);
+        sk_sp<SkShader> shader = SkMakeBitmapShader(skBitmap,
                 SkShader::TileMode::kClamp_TileMode,
                 SkShader::TileMode::kClamp_TileMode,
                 nullptr,
@@ -753,10 +755,12 @@
 }
 
 TEST(RecordingCanvas, refBitmapInShader_composeShader) {
-    SkBitmap bitmap = TestUtils::createSkBitmap(100, 100);
+    sk_sp<Bitmap> bitmap = TestUtils::createBitmap(100, 100);
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) {
         SkPaint paint;
-        sk_sp<SkShader> shader1 = SkMakeBitmapShader(bitmap,
+        SkBitmap skBitmap;
+        bitmap->getSkBitmap(&skBitmap);
+        sk_sp<SkShader> shader1 = SkMakeBitmapShader(skBitmap,
                 SkShader::TileMode::kClamp_TileMode,
                 SkShader::TileMode::kClamp_TileMode,
                 nullptr,
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
new file mode 100644
index 0000000..19c311c
--- /dev/null
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2016 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 <gtest/gtest.h>
+#include <VectorDrawable.h>
+
+#include "AnimationContext.h"
+#include "DamageAccumulator.h"
+#include "IContextFactory.h"
+#include "pipeline/skia/SkiaDisplayList.h"
+#include "pipeline/skia/SkiaRecordingCanvas.h"
+#include "renderthread/CanvasContext.h"
+#include "tests/common/TestUtils.h"
+#include "SkiaCanvas.h"
+#include <SkLiteRecorder.h>
+#include <string.h>
+
+
+using namespace android;
+using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+using namespace android::uirenderer::skiapipeline;
+
+static sp<RenderNode> createSkiaNode(int left, int top, int right, int bottom,
+        std::function<void(RenderProperties& props, SkiaRecordingCanvas& canvas)> setup,
+        const char* name = nullptr, SkiaDisplayList* displayList = nullptr) {
+#if HWUI_NULL_GPU
+    // if RenderNodes are being sync'd/used, device info will be needed, since
+    // DeviceInfo::maxTextureSize() affects layer property
+    DeviceInfo::initialize();
+#endif
+    sp<RenderNode> node = new RenderNode();
+    if (name) {
+        node->setName(name);
+    }
+    RenderProperties& props = node->mutateStagingProperties();
+    props.setLeftTopRightBottom(left, top, right, bottom);
+    if (displayList) {
+        node->setStagingDisplayList(displayList, nullptr);
+    }
+    if (setup) {
+        std::unique_ptr<SkiaRecordingCanvas> canvas(new SkiaRecordingCanvas(nullptr,
+            props.getWidth(), props.getHeight()));
+        setup(props, *canvas.get());
+        node->setStagingDisplayList(canvas->finishRecording(), nullptr);
+    }
+    node->setPropertyFieldsDirty(0xFFFFFFFF);
+    TestUtils::syncHierarchyPropertiesAndDisplayList(node);
+    return node;
+}
+
+TEST(RenderNodeDrawable, create) {
+    auto rootNode = TestUtils::createNode(0, 0, 200, 400,
+            [](RenderProperties& props, Canvas& canvas) {
+                canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver);
+            });
+
+    auto skLiteDL = SkLiteDL::New(SkRect::MakeWH(1, 1));
+    SkLiteRecorder canvas;
+    canvas.reset(skLiteDL.get());
+    canvas.translate(100, 100);
+    RenderNodeDrawable drawable(rootNode.get(), &canvas);
+
+    ASSERT_EQ(drawable.getRenderNode(), rootNode.get());
+    ASSERT_EQ(&drawable.getNodeProperties(), &rootNode->properties());
+    ASSERT_EQ(drawable.getRecordedMatrix(), canvas.getTotalMatrix());
+}
+
+TEST(RenderNodeDrawable, drawContent) {
+    auto surface = SkSurface::MakeRasterN32Premul(1, 1);
+    SkCanvas& canvas = *surface->getCanvas();
+    canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+
+    //create a RenderNodeDrawable backed by a RenderNode backed by a SkLiteRecorder
+    auto rootNode = createSkiaNode(0, 0, 1, 1,
+        [](RenderProperties& props, SkiaRecordingCanvas& recorder) {
+            recorder.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+        });
+    RenderNodeDrawable drawable(rootNode.get(), &canvas, false);
+
+    //negative and positive Z order are drawn out of order
+    rootNode->animatorProperties().setElevation(10.0f);
+    canvas.drawDrawable(&drawable);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+    rootNode->animatorProperties().setElevation(-10.0f);
+    canvas.drawDrawable(&drawable);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+
+    //zero Z are drawn immediately
+    rootNode->animatorProperties().setElevation(0.0f);
+    canvas.drawDrawable(&drawable);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
+}
+
+//TODO: another test that verifies equal z values are drawn in order, and barriers prevent Z
+//intermixing (model after FrameBuilder zReorder)
+TEST(RenderNodeDrawable, drawAndReorder) {
+    //this test exercises StartReorderBarrierDrawable, EndReorderBarrierDrawable and
+    //SkiaRecordingCanvas
+    auto surface = SkSurface::MakeRasterN32Premul(4, 4);
+    SkCanvas& canvas = *surface->getCanvas();
+
+    canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE);
+
+    //-z draws to all 4 pixels (RED)
+    auto redNode = createSkiaNode(0, 0, 4, 4,
+        [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
+            redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+            props.setElevation(-10.0f);
+        }, "redNode");
+
+    //0z draws to bottom 2 pixels (GREEN)
+    auto bottomHalfGreenNode = createSkiaNode(0, 0, 4, 4,
+            [](RenderProperties& props, SkiaRecordingCanvas& bottomHalfGreenCanvas) {
+                SkPaint greenPaint;
+                greenPaint.setColor(SK_ColorGREEN);
+                greenPaint.setStyle(SkPaint::kFill_Style);
+                bottomHalfGreenCanvas.drawRect(0, 2, 4, 4, greenPaint);
+                props.setElevation(0.0f);
+            }, "bottomHalfGreenNode");
+
+    //+z draws to right 2 pixels (BLUE)
+    auto rightHalfBlueNode = createSkiaNode(0, 0, 4, 4,
+        [](RenderProperties& props, SkiaRecordingCanvas& rightHalfBlueCanvas) {
+            SkPaint bluePaint;
+            bluePaint.setColor(SK_ColorBLUE);
+            bluePaint.setStyle(SkPaint::kFill_Style);
+            rightHalfBlueCanvas.drawRect(2, 0, 4, 4, bluePaint);
+            props.setElevation(10.0f);
+        }, "rightHalfBlueNode");
+
+    auto rootNode = createSkiaNode(0, 0, 4, 4,
+            [&](RenderProperties& props, SkiaRecordingCanvas& rootRecorder) {
+                rootRecorder.insertReorderBarrier(true);
+                //draw in reverse Z order, so Z alters draw order
+                rootRecorder.drawRenderNode(rightHalfBlueNode.get());
+                rootRecorder.drawRenderNode(bottomHalfGreenNode.get());
+                rootRecorder.drawRenderNode(redNode.get());
+            }, "rootNode");
+
+    RenderNodeDrawable drawable3(rootNode.get(), &canvas, false);
+    canvas.drawDrawable(&drawable3);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 3), SK_ColorGREEN);
+    ASSERT_EQ(TestUtils::getColor(surface, 3, 3), SK_ColorBLUE);
+}
+
+TEST(RenderNodeDrawable, composeOnLayer)
+{
+    auto surface = SkSurface::MakeRasterN32Premul(1, 1);
+    SkCanvas& canvas = *surface->getCanvas();
+    canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+
+    auto rootNode = createSkiaNode(0, 0, 1, 1,
+        [](RenderProperties& props, SkiaRecordingCanvas& recorder) {
+            recorder.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+        });
+
+    //attach a layer to the render node
+    auto surfaceLayer = SkSurface::MakeRasterN32Premul(1, 1);
+    auto canvas2 = surfaceLayer->getCanvas();
+    canvas2->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
+    rootNode->setLayerSurface( surfaceLayer  );
+
+    RenderNodeDrawable drawable1(rootNode.get(), &canvas, false);
+    canvas.drawDrawable(&drawable1);
+    ASSERT_EQ(SK_ColorRED, TestUtils::getColor(surface, 0, 0));
+
+    RenderNodeDrawable drawable2(rootNode.get(), &canvas, true);
+    canvas.drawDrawable(&drawable2);
+    ASSERT_EQ(SK_ColorWHITE, TestUtils::getColor(surface, 0, 0));
+
+    RenderNodeDrawable drawable3(rootNode.get(), &canvas, false);
+    canvas.drawDrawable(&drawable3);
+    ASSERT_EQ(SK_ColorRED, TestUtils::getColor(surface, 0, 0));
+
+    rootNode->setLayerSurface( sk_sp<SkSurface>()  );
+}
+
+//TODO: refactor to cover test cases from FrameBuilderTests_projectionReorder
+//validate with bounds and projection path mask.
+//TODO: research if we could hook in and mock/validate different aspects of the drawing,
+//instead of validating pixels
+TEST(RenderNodeDrawable, projectDraw) {
+    auto surface = SkSurface::MakeRasterN32Premul(1, 1);
+    SkCanvas& canvas = *surface->getCanvas();
+    canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+
+    auto redNode = createSkiaNode(0, 0, 1, 1,
+        [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
+            redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+        }, "redNode");
+
+    auto greenNodeWithRedChild = createSkiaNode(0, 0, 1, 1,
+        [&](RenderProperties& props, SkiaRecordingCanvas& greenCanvasWithRedChild) {
+            greenCanvasWithRedChild.drawRenderNode(redNode.get());
+            greenCanvasWithRedChild.drawColor(SK_ColorGREEN, SkBlendMode::kSrcOver);
+        }, "greenNodeWithRedChild");
+
+    auto rootNode = createSkiaNode(0, 0, 1, 1,
+        [&](RenderProperties& props, SkiaRecordingCanvas& rootCanvas) {
+            rootCanvas.drawRenderNode(greenNodeWithRedChild.get());
+        }, "rootNode");
+    SkiaDisplayList* rootDisplayList = static_cast<SkiaDisplayList*>(
+        (const_cast<DisplayList*>(rootNode->getDisplayList())));
+
+    RenderNodeDrawable rootDrawable(rootNode.get(), &canvas, false);
+    canvas.drawDrawable(&rootDrawable);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorGREEN);
+
+    //project redNode on rootNode, which will change the test outcome,
+    //because redNode will draw after greenNodeWithRedChild
+    rootDisplayList->mIsProjectionReceiver = true;
+    redNode->animatorProperties().setProjectBackwards(true);
+    canvas.drawDrawable(&rootDrawable);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
+}
diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
index 451596d..95f9974 100644
--- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp
+++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
@@ -45,7 +45,7 @@
         SkCanvas* skCanvas = recorder.beginRecording(200, 200, NULL, 0);
         std::unique_ptr<Canvas> pictCanvas(Canvas::create_canvas(skCanvas));
         TestUtils::drawUtf8ToCanvas(pictCanvas.get(), text, paint, 25, 25);
-        sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
+        sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
 
         canvas.asSkCanvas()->drawPicture(picture);
     });
diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
index 7f622eb..fe6cea6 100644
--- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
+++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
@@ -20,14 +20,14 @@
 #include "AnimationContext.h"
 #include "DamageAccumulator.h"
 #include "IContextFactory.h"
-#include "SkiaDisplayList.h"
+#include "pipeline/skia/SkiaDisplayList.h"
 #include "renderthread/CanvasContext.h"
 #include "tests/common/TestUtils.h"
 
-
 using namespace android;
 using namespace android::uirenderer;
 using namespace android::uirenderer::renderthread;
+using namespace android::uirenderer::skiapipeline;
 
 TEST(SkiaDisplayList, create) {
     SkRect bounds = SkRect::MakeWH(200, 200);
@@ -91,22 +91,12 @@
     ASSERT_EQ(availableList.get(), nullptr);
 }
 
-class TestFunctor : public Functor {
-public:
-    bool didSync = false;
-
-    virtual status_t operator ()(int what, void* data) {
-        if (what == DrawGlInfo::kModeSync) { didSync = true; }
-        return DrawGlInfo::kStatusDone;
-    }
-};
-
 TEST(SkiaDisplayList, syncContexts) {
     SkRect bounds = SkRect::MakeWH(200, 200);
     SkiaDisplayList skiaDL(bounds);
 
     SkCanvas dummyCanvas;
-    TestFunctor functor;
+    TestUtils::MockFunctor functor;
     skiaDL.mChildFunctors.emplace_back(&functor, nullptr, &dummyCanvas);
 
     VectorDrawableRoot vectorDrawable(new VectorDrawable::Group());
@@ -116,7 +106,7 @@
     // ensure that the functor and vectorDrawable are properly synced
     skiaDL.syncContents();
 
-    ASSERT_TRUE(functor.didSync);
+    ASSERT_EQ(functor.getLastMode(), DrawGlInfo::kModeSync);
     ASSERT_EQ(vectorDrawable.mutateProperties()->getBounds(), bounds);
 }
 
diff --git a/libs/hwui/utils/NinePatch.h b/libs/hwui/utils/NinePatch.h
deleted file mode 100644
index 323e563..0000000
--- a/libs/hwui/utils/NinePatch.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-**
-** 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 ANDROID_GRAPHICS_NINEPATCH_H
-#define ANDROID_GRAPHICS_NINEPATCH_H
-
-#include <androidfw/ResourceTypes.h>
-#include <cutils/compiler.h>
-
-#include "SkCanvas.h"
-#include "SkRegion.h"
-
-namespace android {
-
-class ANDROID_API NinePatch {
-public:
-    static void Draw(SkCanvas* canvas, const SkRect& bounds, const SkBitmap& bitmap,
-            const Res_png_9patch& chunk, const SkPaint* paint, SkRegion** outRegion);
-};
-
-} // namespace android
-
-#endif // ANDROID_GRAPHICS_NINEPATCH_H
diff --git a/libs/hwui/utils/NinePatchImpl.cpp b/libs/hwui/utils/NinePatchImpl.cpp
deleted file mode 100644
index cef214b..0000000
--- a/libs/hwui/utils/NinePatchImpl.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
-**
-** Copyright 2006, 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 "utils/NinePatch.h"
-
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include "SkColorPriv.h"
-#include "SkPaint.h"
-#include "SkUnPreMultiply.h"
-
-#include <utils/Log.h>
-
-namespace android {
-
-static const bool kUseTrace = true;
-static bool gTrace = false;
-
-static bool getColor(const SkBitmap& bitmap, int x, int y, SkColor* c) {
-    switch (bitmap.colorType()) {
-        case kN32_SkColorType:
-            *c = SkUnPreMultiply::PMColorToColor(*bitmap.getAddr32(x, y));
-            break;
-        case kRGB_565_SkColorType:
-            *c = SkPixel16ToPixel32(*bitmap.getAddr16(x, y));
-            break;
-        case kARGB_4444_SkColorType:
-            *c = SkUnPreMultiply::PMColorToColor(
-                                SkPixel4444ToPixel32(*bitmap.getAddr16(x, y)));
-            break;
-        case kIndex_8_SkColorType: {
-            SkColorTable* ctable = bitmap.getColorTable();
-            *c = SkUnPreMultiply::PMColorToColor(
-                                            (*ctable)[*bitmap.getAddr8(x, y)]);
-            break;
-        }
-        default:
-            return false;
-    }
-    return true;
-}
-
-static SkColor modAlpha(SkColor c, int alpha) {
-    int scale = alpha + (alpha >> 7);
-    int a = SkColorGetA(c) * scale >> 8;
-    return SkColorSetA(c, a);
-}
-
-static void drawStretchyPatch(SkCanvas* canvas, SkIRect& src, const SkRect& dst,
-                              const SkBitmap& bitmap, const SkPaint& paint,
-                              SkColor initColor, uint32_t colorHint,
-                              bool hasXfer) {
-    if (colorHint !=  android::Res_png_9patch::NO_COLOR) {
-        ((SkPaint*)&paint)->setColor(modAlpha(colorHint, paint.getAlpha()));
-        canvas->drawRect(dst, paint);
-        ((SkPaint*)&paint)->setColor(initColor);
-    } else if (src.width() == 1 && src.height() == 1) {
-        SkColor c;
-        if (!getColor(bitmap, src.fLeft, src.fTop, &c)) {
-            goto SLOW_CASE;
-        }
-        if (0 != c || hasXfer) {
-            SkColor prev = paint.getColor();
-            ((SkPaint*)&paint)->setColor(c);
-            canvas->drawRect(dst, paint);
-            ((SkPaint*)&paint)->setColor(prev);
-        }
-    } else {
-    SLOW_CASE:
-        canvas->drawBitmapRect(bitmap, SkRect::Make(src), dst, &paint);
-    }
-}
-
-SkScalar calculateStretch(SkScalar boundsLimit, SkScalar startingPoint,
-                          int srcSpace, int numStrechyPixelsRemaining,
-                          int numFixedPixelsRemaining) {
-    SkScalar spaceRemaining = boundsLimit - startingPoint;
-    SkScalar stretchySpaceRemaining =
-                spaceRemaining - SkIntToScalar(numFixedPixelsRemaining);
-    return srcSpace * stretchySpaceRemaining / numStrechyPixelsRemaining;
-}
-
-void NinePatch::Draw(SkCanvas* canvas, const SkRect& bounds,
-                     const SkBitmap& bitmap, const Res_png_9patch& chunk,
-                     const SkPaint* paint, SkRegion** outRegion) {
-    if (canvas && canvas->quickReject(bounds)) {
-        return;
-    }
-
-    SkPaint defaultPaint;
-    if (NULL == paint) {
-        // matches default dither in NinePatchDrawable.java.
-        defaultPaint.setDither(true);
-        paint = &defaultPaint;
-    }
-   
-    const int32_t* xDivs = chunk.getXDivs();
-    const int32_t* yDivs = chunk.getYDivs();
-
-    if (kUseTrace) {
-        gTrace = true;
-    }
-
-    SkASSERT(canvas || outRegion);
-
-    if (kUseTrace) {
-        if (canvas) {
-            const SkMatrix& m = canvas->getTotalMatrix();
-            ALOGV("ninepatch [%g %g %g] [%g %g %g]\n",
-                    SkScalarToFloat(m[0]), SkScalarToFloat(m[1]), SkScalarToFloat(m[2]),
-                    SkScalarToFloat(m[3]), SkScalarToFloat(m[4]), SkScalarToFloat(m[5]));
-        }
-
-        ALOGV("======== ninepatch bounds [%g %g]\n", SkScalarToFloat(bounds.width()),
-                SkScalarToFloat(bounds.height()));
-        ALOGV("======== ninepatch paint bm [%d,%d]\n", bitmap.width(), bitmap.height());
-        ALOGV("======== ninepatch xDivs [%d,%d]\n", xDivs[0], xDivs[1]);
-        ALOGV("======== ninepatch yDivs [%d,%d]\n", yDivs[0], yDivs[1]);
-    }
-
-    if (bounds.isEmpty() ||
-        bitmap.width() == 0 || bitmap.height() == 0 ||
-        (paint && paint->isSrcOver() && paint->getAlpha() == 0))
-    {
-        if (kUseTrace) {
-            ALOGV("======== abort ninepatch draw\n");
-        }
-        return;
-    }
-    
-    // should try a quick-reject test before calling lockPixels 
-
-    SkAutoLockPixels alp(bitmap);
-    // after the lock, it is valid to check getPixels()
-    if (bitmap.getPixels() == NULL)
-        return;
-
-    const bool hasXfer = !paint->isSrcOver();
-    SkRect      dst;
-    SkIRect     src;
-
-    const int32_t x0 = xDivs[0];
-    const int32_t y0 = yDivs[0];
-    const SkColor initColor = ((SkPaint*)paint)->getColor();
-    const uint8_t numXDivs = chunk.numXDivs;
-    const uint8_t numYDivs = chunk.numYDivs;
-    int i;
-    int j;
-    int colorIndex = 0;
-    uint32_t color;
-    bool xIsStretchable;
-    const bool initialXIsStretchable =  (x0 == 0);
-    bool yIsStretchable = (y0 == 0);
-    const int bitmapWidth = bitmap.width();
-    const int bitmapHeight = bitmap.height();
-
-    // Number of bytes needed for dstRights array.
-    // Need to cast numXDivs to a larger type to avoid overflow.
-    const size_t dstBytes = ((size_t) numXDivs + 1) * sizeof(SkScalar);
-    SkScalar* dstRights = (SkScalar*) alloca(dstBytes);
-    bool dstRightsHaveBeenCached = false;
-
-    int numStretchyXPixelsRemaining = 0;
-    for (i = 0; i < numXDivs; i += 2) {
-        numStretchyXPixelsRemaining += xDivs[i + 1] - xDivs[i];
-    }
-    int numFixedXPixelsRemaining = bitmapWidth - numStretchyXPixelsRemaining;
-    int numStretchyYPixelsRemaining = 0;
-    for (i = 0; i < numYDivs; i += 2) {
-        numStretchyYPixelsRemaining += yDivs[i + 1] - yDivs[i];
-    }
-    int numFixedYPixelsRemaining = bitmapHeight - numStretchyYPixelsRemaining;
-
-    if (kUseTrace) {
-        ALOGV("NinePatch [%d %d] bounds [%g %g %g %g] divs [%d %d]\n",
-                bitmap.width(), bitmap.height(),
-                SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
-                SkScalarToFloat(bounds.width()), SkScalarToFloat(bounds.height()),
-                numXDivs, numYDivs);
-    }
-
-    src.fTop = 0;
-    dst.fTop = bounds.fTop;
-    // The first row always starts with the top being at y=0 and the bottom
-    // being either yDivs[1] (if yDivs[0]=0) or yDivs[0].  In the former case
-    // the first row is stretchable along the Y axis, otherwise it is fixed.
-    // The last row always ends with the bottom being bitmap.height and the top
-    // being either yDivs[numYDivs-2] (if yDivs[numYDivs-1]=bitmap.height) or
-    // yDivs[numYDivs-1]. In the former case the last row is stretchable along
-    // the Y axis, otherwise it is fixed.
-    //
-    // The first and last columns are similarly treated with respect to the X
-    // axis.
-    //
-    // The above is to help explain some of the special casing that goes on the
-    // code below.
-
-    // The initial yDiv and whether the first row is considered stretchable or
-    // not depends on whether yDiv[0] was zero or not.
-    for (j = yIsStretchable ? 1 : 0;
-          j <= numYDivs && src.fTop < bitmapHeight;
-          j++, yIsStretchable = !yIsStretchable) {
-        src.fLeft = 0;
-        dst.fLeft = bounds.fLeft;
-        if (j == numYDivs) {
-            src.fBottom = bitmapHeight;
-            dst.fBottom = bounds.fBottom;
-        } else {
-            src.fBottom = yDivs[j];
-            const int srcYSize = src.fBottom - src.fTop;
-            if (yIsStretchable) {
-                dst.fBottom = dst.fTop + calculateStretch(bounds.fBottom, dst.fTop,
-                                                          srcYSize,
-                                                          numStretchyYPixelsRemaining,
-                                                          numFixedYPixelsRemaining);
-                numStretchyYPixelsRemaining -= srcYSize;
-            } else {
-                dst.fBottom = dst.fTop + SkIntToScalar(srcYSize);
-                numFixedYPixelsRemaining -= srcYSize;
-            }
-        }
-
-        xIsStretchable = initialXIsStretchable;
-        // The initial xDiv and whether the first column is considered
-        // stretchable or not depends on whether xDiv[0] was zero or not.
-        const uint32_t* colors = chunk.getColors();
-        for (i = xIsStretchable ? 1 : 0;
-              i <= numXDivs && src.fLeft < bitmapWidth;
-              i++, xIsStretchable = !xIsStretchable) {
-            color = colors[colorIndex++];
-            if (i == numXDivs) {
-                src.fRight = bitmapWidth;
-                dst.fRight = bounds.fRight;
-            } else {
-                src.fRight = xDivs[i];
-                if (dstRightsHaveBeenCached) {
-                    dst.fRight = dstRights[i];
-                } else {
-                    const int srcXSize = src.fRight - src.fLeft;
-                    if (xIsStretchable) {
-                        dst.fRight = dst.fLeft + calculateStretch(bounds.fRight, dst.fLeft,
-                                                                  srcXSize,
-                                                                  numStretchyXPixelsRemaining,
-                                                                  numFixedXPixelsRemaining);
-                        numStretchyXPixelsRemaining -= srcXSize;
-                    } else {
-                        dst.fRight = dst.fLeft + SkIntToScalar(srcXSize);
-                        numFixedXPixelsRemaining -= srcXSize;
-                    }
-                    dstRights[i] = dst.fRight;
-                }
-            }
-            // If this horizontal patch is too small to be displayed, leave
-            // the destination left edge where it is and go on to the next patch
-            // in the source.
-            if (src.fLeft >= src.fRight) {
-                src.fLeft = src.fRight;
-                continue;
-            }
-            // Make sure that we actually have room to draw any bits
-            if (dst.fRight <= dst.fLeft || dst.fBottom <= dst.fTop) {
-                goto nextDiv;
-            }
-            // If this patch is transparent, skip and don't draw.
-            if (color == android::Res_png_9patch::TRANSPARENT_COLOR && !hasXfer) {
-                if (outRegion) {
-                    if (*outRegion == NULL) {
-                        *outRegion = new SkRegion();
-                    }
-                    SkIRect idst;
-                    dst.round(&idst);
-                    //ALOGI("Adding trans rect: (%d,%d)-(%d,%d)\n",
-                    //     idst.fLeft, idst.fTop, idst.fRight, idst.fBottom);
-                    (*outRegion)->op(idst, SkRegion::kUnion_Op);
-                }
-                goto nextDiv;
-            }
-            if (canvas) {
-                if (kUseTrace) {
-                    ALOGV("-- src [%d %d %d %d] dst [%g %g %g %g]\n",
-                            src.fLeft, src.fTop, src.width(), src.height(),
-                            SkScalarToFloat(dst.fLeft), SkScalarToFloat(dst.fTop),
-                            SkScalarToFloat(dst.width()), SkScalarToFloat(dst.height()));
-                    if (2 == src.width() && SkIntToScalar(5) == dst.width()) {
-                        ALOGV("--- skip patch\n");
-                    }
-                }
-                drawStretchyPatch(canvas, src, dst, bitmap, *paint, initColor,
-                                  color, hasXfer);
-            }
-
-nextDiv:
-            src.fLeft = src.fRight;
-            dst.fLeft = dst.fRight;
-        }
-        src.fTop = src.fBottom;
-        dst.fTop = dst.fBottom;
-        dstRightsHaveBeenCached = true;
-    }
-}
-
-} // namespace android
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 2b3ed87..da0e515 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1465,7 +1465,7 @@
             mGpsNmeaListener = null;
             mNmeaBuffer = null;
             mOldGnssCallback = null;
-            mGnssCallback = new GnssStatus.Callback() {
+            mGnssCallback = mGpsListener != null ? new GnssStatus.Callback() {
                 @Override
                 public void onStarted() {
                     mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED);
@@ -1485,7 +1485,7 @@
                 public void onSatelliteStatusChanged(GnssStatus status) {
                     mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_SATELLITE_STATUS);
                 }
-            };
+            } : null;
             mOldGnssNmeaListener = null;
             mGnssNmeaListener = null;
         }
@@ -1502,12 +1502,12 @@
             mOldGnssCallback = null;
             mGnssCallback = null;
             mOldGnssNmeaListener = null;
-            mGnssNmeaListener = new OnNmeaMessageListener() {
+            mGnssNmeaListener = mGpsNmeaListener != null ? new OnNmeaMessageListener() {
                 @Override
                 public void onNmeaMessage(String nmea, long timestamp) {
                     mGpsNmeaListener.onNmeaReceived(timestamp, nmea);
                 }
-            };
+            } : null;
         }
 
         GnssStatusListenerTransport(GnssStatusCallback callback) {
@@ -1516,7 +1516,7 @@
 
         GnssStatusListenerTransport(GnssStatusCallback callback, Handler handler) {
             mOldGnssCallback = callback;
-            mGnssCallback = new GnssStatus.Callback() {
+            mGnssCallback = mOldGnssCallback != null ? new GnssStatus.Callback() {
                 @Override
                 public void onStarted() {
                     mOldGnssCallback.onStarted();
@@ -1536,7 +1536,7 @@
                 public void onSatelliteStatusChanged(GnssStatus status) {
                     mOldGnssCallback.onSatelliteStatusChanged(status);
                 }
-            };
+            } : null;
             mGnssHandler = new GnssHandler(handler);
             mOldGnssNmeaListener = null;
             mGnssNmeaListener = null;
@@ -1569,12 +1569,12 @@
             mOldGnssCallback = null;
             mGnssHandler = new GnssHandler(handler);
             mOldGnssNmeaListener = listener;
-            mGnssNmeaListener = new OnNmeaMessageListener() {
+            mGnssNmeaListener = mOldGnssNmeaListener != null ? new OnNmeaMessageListener() {
                 @Override
                 public void onNmeaMessage(String message, long timestamp) {
                     mOldGnssNmeaListener.onNmeaReceived(timestamp, message);
                 }
-            };
+            } : null;
             mGpsListener = null;
             mGpsNmeaListener = null;
             mNmeaBuffer = new ArrayList<Nmea>();
@@ -1597,7 +1597,7 @@
 
         @Override
         public void onGnssStarted() {
-            if (mGpsListener != null) {
+            if (mGnssCallback != null) {
                 Message msg = Message.obtain();
                 msg.what = GpsStatus.GPS_EVENT_STARTED;
                 mGnssHandler.sendMessage(msg);
@@ -1606,7 +1606,7 @@
 
         @Override
         public void onGnssStopped() {
-            if (mGpsListener != null) {
+            if (mGnssCallback != null) {
                 Message msg = Message.obtain();
                 msg.what = GpsStatus.GPS_EVENT_STOPPED;
                 mGnssHandler.sendMessage(msg);
@@ -1615,7 +1615,7 @@
 
         @Override
         public void onFirstFix(int ttff) {
-            if (mGpsListener != null) {
+            if (mGnssCallback != null) {
                 mTimeToFirstFix = ttff;
                 Message msg = Message.obtain();
                 msg.what = GpsStatus.GPS_EVENT_FIRST_FIX;
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 44f7e56..faefc9f 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -31,7 +31,6 @@
     libutils \
     libbinder \
     libmedia \
-    libmediadrm \
     libskia \
     libui \
     liblog \
@@ -41,7 +40,6 @@
     libstagefright_foundation \
     libcamera_client \
     libmtp \
-    libusbhost \
     libexif \
     libpiex
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index bbc249f..4f2fdff 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -257,6 +257,16 @@
 
         /*
          * (non-Javadoc)
+         * @see android.hardware.camera2.ICameraDeviceCallbacks#onRequestQueueEmpty()
+         */
+        @Override
+        public void onRequestQueueEmpty() throws RemoteException {
+            // TODO Auto-generated method stub
+
+        }
+
+        /*
+         * (non-Javadoc)
          * @see android.hardware.camera2.ICameraDeviceCallbacks#onRepeatingRequestError()
          */
         @Override
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 6c879b9..832363c 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -148,6 +148,16 @@
 
         /*
          * (non-Javadoc)
+         * @see android.hardware.camera2.ICameraDeviceCallbacks#onRequestQueueEmpty()
+         */
+        @Override
+        public void onRequestQueueEmpty() throws RemoteException {
+            // TODO Auto-generated method stub
+
+        }
+
+        /*
+         * (non-Javadoc)
          * @see android.hardware.camera2.ICameraDeviceCallbacks#onRepeatingRequestError()
          */
         @Override
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index 0b7b99f..bfc9ff3 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -272,7 +272,7 @@
     boolean deviceIsEncrypted() {
         try {
             return mMountService.getEncryptionState()
-                     != IMountService.ENCRYPTION_STATE_NONE
+                     != StorageManager.ENCRYPTION_STATE_NONE
                 && mMountService.getPasswordType()
                      != StorageManager.CRYPT_TYPE_DEFAULT;
         } catch (Exception e) {
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index b58c87a..bb8eb2c 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -115,6 +115,7 @@
         myWebView.clearCache(true);
         WebSettings webSettings = myWebView.getSettings();
         webSettings.setJavaScriptEnabled(true);
+        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
         mWebViewClient = new MyWebViewClient();
         myWebView.setWebViewClient(mWebViewClient);
         myWebView.setWebChromeClient(new MyWebChromeClient());
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 662a1cd..4e6f3d0 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -163,7 +163,8 @@
                     final VolumeInfo privateVol = mStorageManager.findPrivateForEmulated(volume);
                     title = mStorageManager.getBestVolumeDescription(privateVol);
                 }
-            } else if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
+            } else if (volume.getType() == VolumeInfo.TYPE_PUBLIC
+                    && volume.getMountUserId() == userId) {
                 rootId = volume.getFsUuid();
                 title = mStorageManager.getBestVolumeDescription(volume);
             } else {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
index caeb74c..d19821f 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -41,21 +41,12 @@
     private static final long ANNOUNCEMENT_DELAY = 250;
     private static final int DEFAULT_COLOR = -1;
 
-    private final KeyguardUpdateMonitor mUpdateMonitor;
     private final Handler mHandler;
     private final int mDefaultColor;
 
-    CharSequence mMessage;
+    private CharSequence mMessage;
     private int mNextMessageColor = DEFAULT_COLOR;
 
-    private final Runnable mClearMessageRunnable = new Runnable() {
-        @Override
-        public void run() {
-            mMessage = null;
-            update();
-        }
-    };
-
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
         public void onFinishedGoingToSleep(int why) {
             setSelected(false);
@@ -70,11 +61,14 @@
     }
 
     public KeyguardMessageArea(Context context, AttributeSet attrs) {
+        this(context, attrs, KeyguardUpdateMonitor.getInstance(context));
+    }
+
+    public KeyguardMessageArea(Context context, AttributeSet attrs, KeyguardUpdateMonitor monitor) {
         super(context, attrs);
         setLayerType(LAYER_TYPE_HARDWARE, null); // work around nested unclipped SaveLayer bug
 
-        mUpdateMonitor = KeyguardUpdateMonitor.getInstance(getContext());
-        mUpdateMonitor.registerCallback(mInfoCallback);
+        monitor.registerCallback(mInfoCallback);
         mHandler = new Handler(Looper.myLooper());
 
         mDefaultColor = getCurrentTextColor();
@@ -137,8 +131,8 @@
     }
 
     private void clearMessage() {
-        mHandler.removeCallbacks(mClearMessageRunnable);
-        mHandler.post(mClearMessageRunnable);
+        mMessage = null;
+        update();
     }
 
     private void update() {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java b/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java
index 366add0b..84745b2 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java
@@ -49,7 +49,6 @@
                 final Intent intent = new Intent(DocumentsContract.ACTION_BROWSE);
                 intent.setData(uri);
                 intent.addCategory(Intent.CATEGORY_DEFAULT);
-                intent.putExtra(DocumentsContract.EXTRA_FANCY_FEATURES, true);
                 this.startActivity(intent);
             } catch (IOException exception) {
                 Log.e(MtpDocumentsProvider.TAG, "Failed to open device", exception);
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 2da4d6a..4b9415e 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -71,6 +71,7 @@
             android:name=".ui.SelectPrinterActivity"
             android:label="@string/all_printers_label"
             android:theme="@style/Theme.SelectPrinterActivity"
+            android:parentActivityName=".ui.PrintActivity"
             android:exported="false">
         </activity>
 
@@ -78,6 +79,7 @@
             android:name=".ui.AddPrinterActivity"
             android:label="@string/print_add_printer"
             android:theme="@style/Theme.AddPrinterActivity"
+            android:parentActivityName=".ui.SelectPrinterActivity"
             android:exported="false">
         </activity>
 
diff --git a/packages/PrintSpooler/res/layout/print_activity.xml b/packages/PrintSpooler/res/layout/print_activity.xml
index 31a776c..94519d4 100644
--- a/packages/PrintSpooler/res/layout/print_activity.xml
+++ b/packages/PrintSpooler/res/layout/print_activity.xml
@@ -49,8 +49,10 @@
         android:id="@+id/summary_content"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
+        android:paddingTop="2dip"
         android:paddingStart="16dip"
         android:paddingEnd="16dip"
+        android:paddingBottom="8dip"
         android:orientation="horizontal"
         android:elevation="@dimen/preview_controls_elevation"
         android:background="?android:attr/colorPrimary">
diff --git a/packages/PrintSpooler/res/values-kn-rIN/strings.xml b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
index c6e36d2..64cb540 100644
--- a/packages/PrintSpooler/res/values-kn-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
@@ -81,7 +81,7 @@
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ರದ್ದು ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="failed_notification_title_template" msgid="2256217208186530973">"ಮುದ್ರಕ ದೋಷ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="blocked_notification_title_template" msgid="1175435827331588646">"ಮುದ್ರಕವು <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ನಿರ್ಬಂಧಿಸಿದೆ"</string>
-    <string name="cancel" msgid="4373674107267141885">"ರದ್ದುಮಾಡು"</string>
+    <string name="cancel" msgid="4373674107267141885">"ರದ್ದುಮಾಡಿ"</string>
     <string name="restart" msgid="2472034227037808749">"ಮರುಪ್ರಾರಂಭಿಸು"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ಮುದ್ರಕಕ್ಕೆ ಸಂಪರ್ಕವಿಲ್ಲ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ಅಪರಿಚಿತ"</string>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
index 293665a..74582f3 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
@@ -126,6 +126,8 @@
 
         setContentView(R.layout.select_printer_activity);
 
+        getActionBar().setDisplayHomeAsUpEnabled(true);
+
         mEnabledPrintServices = new ArrayMap<>();
 
         mPrinterRegistry = new PrinterRegistry(this, null, LOADER_ID_PRINT_REGISTRY,
@@ -268,6 +270,16 @@
     }
 
     @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (item.getItemId() == android.R.id.home) {
+            finish();
+            return true;
+        } else {
+            return super.onOptionsItemSelected(item);
+        }
+    }
+
+    @Override
     public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
         if (view == mListView) {
             final int position = ((AdapterContextMenuInfo) menuInfo).position;
diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml
index b89bad8..d7c8d03 100644
--- a/packages/SettingsLib/res/values-kn-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml
@@ -72,7 +72,7 @@
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ಇನ್‌ಪುಟ್‌ಗಾಗಿ ಬಳಸು"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ಜೋಡಿ"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ಜೋಡಿ ಮಾಡು"</string>
-    <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ರದ್ದುಮಾಡು"</string>
+    <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ರದ್ದುಮಾಡಿ"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"ಸಂಪರ್ಕಪಡಿಸಿದಾಗ, ಜೋಡಿಸುವಿಕೆಯು ನಿಮ್ಮ ಸಂಪರ್ಕಗಳು ಮತ್ತು ಕರೆ ಇತಿಹಾಸಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಜೋಡಣೆ ಮಾಡಲಾಗಲಿಲ್ಲ."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ತಪ್ಪಾಗಿರುವ ಪಿನ್‌ ಅಥವಾ ಪಾಸ್‌ಕೀ ಕಾರಣದಿಂದಾಗಿ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಜೋಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
diff --git a/packages/SettingsLib/res/values/config.xml b/packages/SettingsLib/res/values/config.xml
index e2e721c..0aa76a0 100755
--- a/packages/SettingsLib/res/values/config.xml
+++ b/packages/SettingsLib/res/values/config.xml
@@ -23,8 +23,8 @@
     <!-- Default data warning level in mb -->
     <integer name="default_data_warning_level_mb">2048</integer>
 
-    <!-- Whether to send a custom package name with the PSD. translatable="false"-->
-    <bool name="config_sendPackageName">true</bool>
+    <!-- Whether to send a custom package name with the PSD.-->
+    <bool name="config_sendPackageName">false</bool>
 
     <!-- Name for the set of keys associating package names -->
     <string name="config_helpPackageNameKey" translatable="false"></string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
index b04948b..ebb5d19 100644
--- a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
@@ -82,11 +82,10 @@
 
         final String PROC_VERSION_REGEX =
                 "Linux version (\\S+) " + /* group 1: "3.0.31-g6fb96c9" */
-                "\\((\\S+?)\\) " +        /* group 2: "x@y.com" (kernel builder) */
-                "(?:\\(gcc.+? \\)) " +    /* ignore: GCC version information */
-                "(#\\d+) " +              /* group 3: "#1" */
-                "(?:.*?)?" +              /* ignore: optional SMP, PREEMPT, and any CONFIG_FLAGS */
-                "((Sun|Mon|Tue|Wed|Thu|Fri|Sat).+)"; /* group 4: "Thu Jun 28 11:02:39 PDT 2012" */
+                "\\((\\S+)\\)" +          /* group 2: "x@y.com" (kernel builder) */
+                ".*(#\\d+)" +             /* group 3: "#1" */
+                /* group 4: "Thu Jun 28 11:02:39 PDT 2012" */
+                ".*((?:Sun|Mon|Tue|Wed|Thu|Fri|Sat).+)";
 
         Matcher m = Pattern.compile(PROC_VERSION_REGEX).matcher(rawKernelVersion);
         if (!m.matches()) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index 4ec4f4f..c1f5660 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -24,6 +24,8 @@
     public static final String CATEGORY_NETWORK = "com.android.settings.category.ia.wireless";
     public static final String CATEGORY_DEVICE = "com.android.settings.category.ia.device";
     public static final String CATEGORY_APPS = "com.android.settings.category.ia.apps";
+    public static final String CATEGORY_APPS_DEFAULT =
+            "com.android.settings.category.ia.apps.default";
     public static final String CATEGORY_BATTERY = "com.android.settings.category.ia.battery";
     public static final String CATEGORY_DISPLAY = "com.android.settings.category.ia.display";
     public static final String CATEGORY_SOUND = "com.android.settings.category.ia.sound";
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index b2ce13f..ac10ca8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -142,9 +142,9 @@
                 // Only add Settings for this user.
                 getTilesForAction(context, user, SETTINGS_ACTION, cache, null, tiles, true);
                 getTilesForAction(context, user, OPERATOR_SETTINGS, cache,
-                        OPERATOR_DEFAULT_CATEGORY, tiles, false);
+                        OPERATOR_DEFAULT_CATEGORY, tiles, false, true);
                 getTilesForAction(context, user, MANUFACTURER_SETTINGS, cache,
-                        MANUFACTURER_DEFAULT_CATEGORY, tiles, false);
+                        MANUFACTURER_DEFAULT_CATEGORY, tiles, false, true);
             }
             if (setup) {
                 getTilesForAction(context, user, EXTRA_SETTINGS_ACTION, cache, null, tiles, false);
@@ -211,12 +211,20 @@
     private static void getTilesForAction(Context context,
             UserHandle user, String action, Map<Pair<String, String>, Tile> addedCache,
             String defaultCategory, ArrayList<Tile> outTiles, boolean requireSettings) {
+        getTilesForAction(context, user, action, addedCache, defaultCategory, outTiles,
+                requireSettings, requireSettings);
+    }
+
+    private static void getTilesForAction(Context context,
+            UserHandle user, String action, Map<Pair<String, String>, Tile> addedCache,
+            String defaultCategory, ArrayList<Tile> outTiles, boolean requireSettings,
+            boolean usePriority) {
         Intent intent = new Intent(action);
         if (requireSettings) {
             intent.setPackage(SETTING_PKG);
         }
         getTilesForIntent(context, user, intent, addedCache, defaultCategory, outTiles,
-                requireSettings, true);
+                usePriority, true);
     }
 
     public static void getTilesForIntent(Context context, UserHandle user, Intent intent,
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index bfe8c07..77a45b3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -484,7 +484,8 @@
         mMainHandler.scheduleAPCopyingAndCloseWriteLock();
     }
 
-    private AccessPoint getCachedOrCreate(ScanResult result, List<AccessPoint> cache) {
+    @VisibleForTesting
+    AccessPoint getCachedOrCreate(ScanResult result, List<AccessPoint> cache) {
         final int N = cache.size();
         for (int i = 0; i < N; i++) {
             if (cache.get(i).matches(result)) {
@@ -493,10 +494,13 @@
                 return ret;
             }
         }
-        return new AccessPoint(mContext, result);
+        final AccessPoint accessPoint = new AccessPoint(mContext, result);
+        accessPoint.setListener(mAccessPointListenerAdapter);
+        return accessPoint;
     }
 
-    private AccessPoint getCachedOrCreate(WifiConfiguration config, List<AccessPoint> cache) {
+    @VisibleForTesting
+    AccessPoint getCachedOrCreate(WifiConfiguration config, List<AccessPoint> cache) {
         final int N = cache.size();
         for (int i = 0; i < N; i++) {
             if (cache.get(i).matches(config)) {
@@ -505,7 +509,7 @@
                 return ret;
             }
         }
-        AccessPoint accessPoint = new AccessPoint(mContext, config);
+        final AccessPoint accessPoint = new AccessPoint(mContext, config);
         accessPoint.setListener(mAccessPointListenerAdapter);
         return accessPoint;
     }
diff --git a/packages/SettingsLib/tests/AndroidManifest.xml b/packages/SettingsLib/tests/AndroidManifest.xml
index 9fd5a41..00b2164 100644
--- a/packages/SettingsLib/tests/AndroidManifest.xml
+++ b/packages/SettingsLib/tests/AndroidManifest.xml
@@ -21,6 +21,8 @@
     <uses-permission android:name="android.permission.MANAGE_USERS" />
     <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY"/>
     <uses-permission android:name="android.permission.SET_TIME_ZONE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/packages/SettingsLib/tests/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/src/com/android/settingslib/wifi/WifiTrackerTest.java
new file mode 100644
index 0000000..c650190
--- /dev/null
+++ b/packages/SettingsLib/tests/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 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.settingslib.wifi;
+
+
+import static org.junit.Assert.assertTrue;
+
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.List;
+
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WifiTrackerTest {
+
+    @Test
+    public void testAccessPointListenerSetWhenLookingUpUsingScanResults() {
+        ScanResult scanResult = new ScanResult();
+        scanResult.level = 123;
+        scanResult.BSSID = "bssid-" + 111;
+        scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
+        scanResult.capabilities = "";
+
+        WifiTracker tracker = new WifiTracker(
+                InstrumentationRegistry.getTargetContext(), null, true, true);
+
+        AccessPoint result = tracker.getCachedOrCreate(scanResult, new ArrayList<AccessPoint>());
+        assertTrue(result.mAccessPointListener != null);
+    }
+
+    @Test
+    public void testAccessPointListenerSetWhenLookingUpUsingWifiConfiguration() {
+        WifiConfiguration configuration = new WifiConfiguration();
+        configuration.SSID = "test123";
+        configuration.BSSID="bssid";
+        configuration.networkId = 123;
+        configuration.allowedKeyManagement = new BitSet();
+        configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+
+        WifiTracker tracker = new WifiTracker(
+                InstrumentationRegistry.getTargetContext(), null, true, true);
+
+        AccessPoint result = tracker.getCachedOrCreate(configuration, new ArrayList<AccessPoint>());
+        assertTrue(result.mAccessPointListener != null);
+    }
+}
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 977ac18..bb85de2 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -69,6 +69,7 @@
     <integer name="def_power_sounds_enabled">1</integer>
     <string name="def_low_battery_sound" translatable="false">/system/media/audio/ui/LowBattery.ogg</string>
     <integer name="def_dock_sounds_enabled">0</integer>
+    <integer name="def_dock_sounds_enabled_when_accessibility">0</integer>
     <string name="def_desk_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string>
     <string name="def_desk_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string>
     <string name="def_car_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index c1a1f84..d55bb4f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2662,6 +2662,8 @@
                     R.string.def_low_battery_sound);
             loadIntegerSetting(stmt, Settings.Global.DOCK_SOUNDS_ENABLED,
                     R.integer.def_dock_sounds_enabled);
+            loadIntegerSetting(stmt, Settings.Global.DOCK_SOUNDS_ENABLED_WHEN_ACCESSIBILITY,
+                    R.integer.def_dock_sounds_enabled_when_accessibility);
             loadStringSetting(stmt, Settings.Global.DESK_DOCK_SOUND,
                     R.string.def_desk_dock_sound);
             loadStringSetting(stmt, Settings.Global.DESK_UNDOCK_SOUND,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 3084b9b..e7f5f4f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2137,7 +2137,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 133;
+            private static final int SETTINGS_VERSION = 134;
 
             private final int mUserId;
 
@@ -2452,6 +2452,21 @@
                 }
 
                 if (currentVersion == 130) {
+                    // Split Ambient settings
+                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
+                    boolean dozeExplicitlyDisabled = "0".equals(secureSettings.
+                            getSettingLocked(Settings.Secure.DOZE_ENABLED).getValue());
+
+                    if (dozeExplicitlyDisabled) {
+                        secureSettings.insertSettingLocked(Settings.Secure.DOZE_PULSE_ON_PICK_UP,
+                                "0", SettingsState.SYSTEM_PACKAGE_NAME);
+                        secureSettings.insertSettingLocked(Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
+                                "0", SettingsState.SYSTEM_PACKAGE_NAME);
+                    }
+                    currentVersion = 131;
+                }
+
+                if (currentVersion == 131) {
                     // Initialize new multi-press timeout to default value
                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
                     final String oldValue = systemSecureSettings.getSettingLocked(
@@ -2464,11 +2479,11 @@
                                 SettingsState.SYSTEM_PACKAGE_NAME);
                     }
 
-                    currentVersion = 131;
+                    currentVersion = 132;
                 }
 
-                if (currentVersion == 131) {
-                    // Version 131: Allow managed profile to optionally use the parent's ringtones
+                if (currentVersion == 132) {
+                    // Version 132: Allow managed profile to optionally use the parent's ringtones
                     final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
                     String defaultSyncParentSounds = (getContext().getResources()
                             .getBoolean(R.bool.def_sync_parent_sounds) ? "1" : "0");
@@ -2476,11 +2491,11 @@
                             Settings.Secure.SYNC_PARENT_SOUNDS,
                             defaultSyncParentSounds,
                             SettingsState.SYSTEM_PACKAGE_NAME);
-                    currentVersion = 132;
+                    currentVersion = 133;
                 }
 
-                if (currentVersion == 132) {
-                    // Version 132: Add default end button behavior
+                if (currentVersion == 133) {
+                    // Version 133: Add default end button behavior
                     final SettingsState systemSettings = getSystemSettingsLocked(userId);
                     if (systemSettings.getSettingLocked(Settings.System.END_BUTTON_BEHAVIOR) ==
                             null) {
@@ -2489,7 +2504,7 @@
                         systemSettings.insertSettingLocked(Settings.System.END_BUTTON_BEHAVIOR,
                                 defaultEndButtonBehavior, SettingsState.SYSTEM_PACKAGE_NAME);
                     }
-                    currentVersion = 133;
+                    currentVersion = 134;
                 }
 
                 if (currentVersion != newVersion) {
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index ffddf02..d1e1060 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -54,6 +54,4 @@
 
 include $(BUILD_PACKAGE)
 
-ifeq ($(EXCLUDE_SYSTEMUI_TESTS),)
-    include $(call all-makefiles-under,$(LOCAL_PATH))
-endif
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 02518f2..4d59d57 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -389,7 +389,7 @@
 
         <!-- started from PipUI -->
         <activity
-            android:name="com.android.systemui.tv.pip.PipMenuActivity"
+            android:name=".pip.tv.PipMenuActivity"
             android:exported="true"
             android:theme="@style/PipTheme"
             android:launchMode="singleTop"
@@ -400,7 +400,7 @@
             androidprv:alwaysFocusable="true"
             android:excludeFromRecents="true" />
         <activity
-            android:name="com.android.systemui.tv.pip.PipOverlayActivity"
+            android:name=".pip.tv.PipOverlayActivity"
             android:exported="true"
             android:theme="@style/PipTheme"
             android:taskAffinity=""
@@ -409,7 +409,7 @@
             android:supportsPictureInPicture="true"
             android:excludeFromRecents="true" />
         <activity
-            android:name="com.android.systemui.tv.pip.PipOnboardingActivity"
+            android:name=".pip.tv.PipOnboardingActivity"
             android:exported="true"
             android:theme="@style/PipTheme"
             android:launchMode="singleTop"
diff --git a/packages/SystemUI/plugin/Android.mk b/packages/SystemUI/plugin/Android.mk
index 86527db..5e6dcc0 100644
--- a/packages/SystemUI/plugin/Android.mk
+++ b/packages/SystemUI/plugin/Android.mk
@@ -27,3 +27,7 @@
 LOCAL_JAR_EXCLUDE_FILES := none
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
+
+ifeq ($(EXCLUDE_SYSTEMUI_TESTS),)
+    include $(call all-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
index 75a5434..c64b188 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
@@ -131,6 +131,10 @@
                 new ComponentName(info.mPackage, info.mClass),
                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                 PackageManager.DONT_KILL_APP);
+        final String pkg = info.mPackage;
+        final Intent intent = new Intent(PluginManager.PLUGIN_CHANGED,
+                pkg != null ? Uri.fromParts("package", pkg, null) : null);
+        mContext.sendBroadcast(intent);
     }
 
     private class MainHandler extends Handler {
@@ -301,6 +305,11 @@
             }
             return getBaseContext().getSystemService(name);
         }
+
+        @Override
+        public Context getApplicationContext() {
+            return this;
+        }
     }
 
     private static class PluginInfo<T> {
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
index 686b4d4..85f2e2a 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
@@ -22,6 +22,7 @@
 import android.os.Build;
 import android.os.HandlerThread;
 import android.os.Looper;
+import android.os.SystemProperties;
 import android.util.ArrayMap;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -36,6 +37,8 @@
  */
 public class PluginManager extends BroadcastReceiver {
 
+    public static final String PLUGIN_CHANGED = "com.android.systemui.action.PLUGIN_CHANGED";
+
     private static PluginManager sInstance;
 
     private final HandlerThread mBackgroundThread;
@@ -105,6 +108,7 @@
         IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
         filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
         filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addAction(PLUGIN_CHANGED);
         filter.addDataScheme("package");
         mContext.registerReceiver(this, filter);
         filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
@@ -205,6 +209,10 @@
 
         @Override
         public void uncaughtException(Thread thread, Throwable throwable) {
+            if (SystemProperties.getBoolean("plugin.debugging", false)) {
+                mHandler.uncaughtException(thread, throwable);
+                return;
+            }
             // Search for and disable plugins that may have been involved in this crash.
             boolean disabledAny = checkStack(throwable);
             if (!disabledAny) {
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
new file mode 100644
index 0000000..0728482
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 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.systemui.plugins.statusbar.phone;
+
+import android.view.MotionEvent;
+
+import com.android.systemui.plugins.Plugin;
+
+public interface NavGesture extends Plugin {
+
+    public static final String ACTION = "com.android.systemui.action.PLUGIN_NAV_GESTURE";
+
+    public static final int VERSION = 1;
+
+    public GestureHelper getGestureHelper();
+
+    public interface GestureHelper {
+        public boolean onTouchEvent(MotionEvent event);
+
+        public boolean onInterceptTouchEvent(MotionEvent event);
+
+        public void setBarState(boolean vertical, boolean isRtl);
+    }
+
+}
diff --git a/packages/SystemUI/res/drawable/pip_dismiss.xml b/packages/SystemUI/res/drawable/pip_dismiss.xml
new file mode 100644
index 0000000..f656eeb
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pip_dismiss.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2016 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="42.0dp"
+        android:height="42.0dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M38.000000,12.800000l-2.799999,-2.800000 -11.200001,11.200001 -11.200000,-11.200001 -2.800000,2.800000 11.200001,11.200000 -11.200001,11.200001 2.800000,2.799999 11.200000,-11.200001 11.200001,11.200001 2.799999,-2.799999 -11.200001,-11.200001z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/pip_dismiss_background.xml b/packages/SystemUI/res/drawable/pip_dismiss_background.xml
new file mode 100644
index 0000000..3a75296
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pip_dismiss_background.xml
@@ -0,0 +1,22 @@
+<!--
+Copyright (C) 2016 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <corners
+        android:radius="100dp" />
+    <solid
+        android:color="#66000000" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/car_navigation_bar.xml b/packages/SystemUI/res/layout/car_navigation_bar.xml
index f7f673d..999dbac 100644
--- a/packages/SystemUI/res/layout/car_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_navigation_bar.xml
@@ -21,6 +21,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
+    android:gravity="center"
     android:background="@drawable/system_bar_background">
 
     <!-- phone.NavigationBarView has rot0 and rot90 but we expect the car head unit to have a fixed
@@ -28,7 +29,7 @@
     -->
     <LinearLayout
         android:layout_height="match_parent"
-        android:layout_width="match_parent"
+        android:layout_width="@dimen/car_navigation_bar_width"
         android:orientation="horizontal"
         android:clipChildren="false"
         android:clipToPadding="false"
diff --git a/packages/SystemUI/res/layout/pip_dismiss_view.xml b/packages/SystemUI/res/layout/pip_dismiss_view.xml
new file mode 100644
index 0000000..141e610
--- /dev/null
+++ b/packages/SystemUI/res/layout/pip_dismiss_view.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/pip_dismiss_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/pip_dismiss_background"
+    android:foreground="@drawable/pip_dismiss"
+    android:alpha="0"
+    android:forceHasOverlappingRendering="false" />
diff --git a/packages/SystemUI/res/layout/tv_pip_control_button.xml b/packages/SystemUI/res/layout/tv_pip_control_button.xml
index 096dda8..b9b0154 100644
--- a/packages/SystemUI/res/layout/tv_pip_control_button.xml
+++ b/packages/SystemUI/res/layout/tv_pip_control_button.xml
@@ -17,7 +17,7 @@
 */
 -->
 
-<!-- Layout for {@link com.android.systemui.tv.pip.PipControlButtonView}. -->
+<!-- Layout for {@link com.android.systemui.pip.tv.PipControlButtonView}. -->
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
     <ImageView android:id="@+id/button"
diff --git a/packages/SystemUI/res/layout/tv_pip_controls.xml b/packages/SystemUI/res/layout/tv_pip_controls.xml
index 49119fb..c6bcd32 100644
--- a/packages/SystemUI/res/layout/tv_pip_controls.xml
+++ b/packages/SystemUI/res/layout/tv_pip_controls.xml
@@ -17,17 +17,17 @@
 */
 -->
 
-<!-- Layout for {@link com.android.systemui.tv.pip.PipControlsView}. -->
+<!-- Layout for {@link com.android.systemui.pip.tv.PipControlsView}. -->
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <com.android.systemui.tv.pip.PipControlButtonView
+    <com.android.systemui.pip.tv.PipControlButtonView
         android:id="@+id/full_button"
         android:layout_width="100dp"
         android:layout_height="wrap_content"
         android:src="@drawable/ic_fullscreen_white_24dp"
         android:text="@string/pip_fullscreen" />
 
-    <com.android.systemui.tv.pip.PipControlButtonView
+    <com.android.systemui.pip.tv.PipControlButtonView
         android:id="@+id/close_button"
         android:layout_width="100dp"
         android:layout_height="wrap_content"
@@ -35,7 +35,7 @@
         android:src="@drawable/ic_close_white"
         android:text="@string/pip_close" />
 
-    <com.android.systemui.tv.pip.PipControlButtonView
+    <com.android.systemui.pip.tv.PipControlButtonView
         android:id="@+id/play_pause_button"
         android:layout_width="100dp"
         android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/tv_pip_menu.xml b/packages/SystemUI/res/layout/tv_pip_menu.xml
index 72a4929..35f2af4 100644
--- a/packages/SystemUI/res/layout/tv_pip_menu.xml
+++ b/packages/SystemUI/res/layout/tv_pip_menu.xml
@@ -26,7 +26,7 @@
     android:gravity="top|center_horizontal"
     android:clipChildren="false">
 
-    <com.android.systemui.tv.pip.PipControlsView
+    <com.android.systemui.pip.tv.PipControlsView
         android:id="@+id/pip_controls"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/tv_pip_recents_overlay.xml b/packages/SystemUI/res/layout/tv_pip_recents_overlay.xml
index f157fd5..949400c 100644
--- a/packages/SystemUI/res/layout/tv_pip_recents_overlay.xml
+++ b/packages/SystemUI/res/layout/tv_pip_recents_overlay.xml
@@ -20,7 +20,7 @@
     android:gravity="top|center_horizontal"
     android:orientation="vertical">
 
-    <com.android.systemui.tv.pip.PipRecentsControlsView
+    <com.android.systemui.pip.tv.PipRecentsControlsView
         android:id="@+id/pip_controls"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -35,13 +35,13 @@
             android:layout_gravity="top|center_horizontal"
             android:background="@drawable/tv_pip_recents_overlay_scrim"
             android:alpha="0" />
-        <com.android.systemui.tv.pip.PipControlsView
+        <com.android.systemui.pip.tv.PipControlsView
             android:id="@+id/pip_control_contents"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="10dp"
             android:layout_gravity="top|center_horizontal" />
-    </com.android.systemui.tv.pip.PipRecentsControlsView>
+    </com.android.systemui.pip.tv.PipRecentsControlsView>
 
     <!-- Placeholder view to handle focus change between Recents row and PIP controls
         in talkback mode -->
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index b8be190..1131b2a 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Blaaier"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakte"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-pos"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musiek"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index 2e1438c..87b4433 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Brauzer"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktlar"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-poçt"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musiqi"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Təqvim"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 28d0967..e173890 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Pregledač"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakti"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Imejl"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzika"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendar"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 4ea50cf..16c94d7 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Браузър"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Контакти"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Електронна поща"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музика"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Календар"</string>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 0d3e57a..feaa453 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ব্রাউজার"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"পরিচিতি"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ইমেল"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"সংগীত"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ক্যালেন্ডার"</string>
diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml
index 1c28298..f361b93 100644
--- a/packages/SystemUI/res/values-bs-rBA/strings.xml
+++ b/packages/SystemUI/res/values-bs-rBA/strings.xml
@@ -566,8 +566,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Preglednik"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakti"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-pošta"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzika"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendar"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index c4d82e4..8bedecd 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contactes"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Correu electrònic"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Música"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendari"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 9366b00..0ff0f93 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -568,8 +568,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Prohlížeč"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakty"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Hudba"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendář"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index a686306..b112405 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -476,7 +476,7 @@
     <string name="zen_alarm_warning" msgid="444533119582244293">"Du vil ikke kunne høre din næste alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template" msgid="3980063409350522735">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="4242179982586714810">"på <xliff:g id="WHEN">%1$s</xliff:g>"</string>
-    <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Hurtigindstillinger <xliff:g id="TITLE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Hurtige indstillinger <xliff:g id="TITLE">%s</xliff:g>."</string>
     <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string>
     <string name="accessibility_managed_profile" msgid="6613641363112584120">"Arbejdsprofil"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"Sjovt for nogle, men ikke for alle"</string>
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktpersoner"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"Sms"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musik"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 8d55230..9721362 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakte"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-Mail"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 3dc97e7..276b856 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Πρόγραμμα περιήγησης"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Επαφές"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Ηλεκτρονικό ταχυδρομείο"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Μουσική"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Ημερολόγιο"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 8a3f385f..ca2e5b3 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacts"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 8a3f385f..ca2e5b3 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacts"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 8a3f385f..ca2e5b3 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacts"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index e74d341..81696f6 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contactos"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Correo electrónico"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Música"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendario"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 0994575..aa9578a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contactos"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Correo electrónico"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Música"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendario"</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 06145d9..ab81af5 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Brauser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktid"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-post"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muusika"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 5c4f7c9..3617074 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Arakatzailea"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktuak"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Posta"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS mezuak"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musika"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 341e942..48f0b954 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"مرورگر"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"مخاطبین"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"رایانامه"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"پیامک"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"موسیقی"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"تقویم"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 13eb6aa..765e0aa 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navigateur"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacts"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Courriel"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"Message texte"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musique"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Agenda"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 0b64c62..e66d342 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navigateur"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacts"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Messagerie"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musique"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Agenda"</string>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index e20bb40..84f9105 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"બ્રાઉઝર"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"સંપર્કો"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ઇમેઇલ"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"સંગીત"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"કૅલેન્ડર"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index d4d0e85..89b5a6f 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ब्राउज़र"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"संपर्क"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ईमेल"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS करें"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"संगीत"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"कैलेंडर"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index ad77975..3c5812f 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Preglednik"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakti"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-pošta"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Glazba"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendar"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 5ddca19..f83ba28 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Böngésző"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Névjegyek"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS-üzenetek"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Zene"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Naptár"</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 1c267d0..4ce22e4 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Դիտարկիչ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Կոնտակտներ"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Էլփոստ"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Երաժշտություն"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Օրացույց"</string>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index b74341e..4875888 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Vafri"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Tengiliðir"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Tölvupóstur"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS-skilaboð"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Tónlist"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Dagatal"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 100df92..98a2424 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -344,7 +344,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Ricerca"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"A sinistra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="3070506961866919502">"Non verrai disturbato da suoni e vibrazioni, ad eccezione di sveglie, promemoria, eventi e chiamate da contatti da te specificati."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Non ti disturberanno: suoni e vibrazioni, ad eccezione di sveglie, promemoria, eventi e chiamate da contatti da te specificati."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizza"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Verranno bloccati TUTTI i suoni e le vibrazioni, anche di sveglie, musica, video e giochi. Potrai ancora telefonare."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Verranno bloccati TUTTI i suoni e le vibrazioni, anche di sveglie, musica, video e giochi."</string>
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contatti"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musica"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendario"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 93d633a..ce73705 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -566,8 +566,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"דפדפן"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"אנשי קשר"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"אימייל"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"מוזיקה"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"‏YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"יומן"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 92a35b1..c45fa4f 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -196,13 +196,13 @@
     <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"機内モードがONです。"</string>
     <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"機内モードをOFFにしました。"</string>
     <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"機内モードをONにしました。"</string>
-    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"[通知を非表示]はONで、優先する通知のみです。"</string>
-    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"[通知を非表示]はONで、サイレントです。"</string>
-    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"[通知を非表示]はONで、アラームのみです。"</string>
-    <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"通知を非表示"</string>
-    <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"[通知を非表示]はOFFです。"</string>
-    <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"[通知を非表示]をOFFにしました。"</string>
-    <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"[通知を非表示]をONにしました。"</string>
+    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"マナーモードは ON で、優先する通知のみ許可します。"</string>
+    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"マナーモードは ON で、サイレント モードです。"</string>
+    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"マナーモードは ON で、アラームのみ許可します。"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"マナーモード"</string>
+    <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"マナーモードは OFF です。"</string>
+    <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"マナーモードを OFF にしました。"</string>
+    <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"マナーモードを ON にしました。"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"BluetoothがOFFです。"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"BluetoothがONです。"</string>
@@ -263,7 +263,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"デザートケース"</string>
     <string name="start_dreams" msgid="5640361424498338327">"スクリーン セーバー"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"イーサネット"</string>
-    <string name="quick_settings_dnd_label" msgid="8735855737575028208">"通知を非表示"</string>
+    <string name="quick_settings_dnd_label" msgid="8735855737575028208">"マナーモード"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"優先する通知のみ"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"アラームのみ"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"サイレント"</string>
@@ -564,15 +564,14 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ブラウザ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"連絡先"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"メール"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"音楽"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"カレンダー"</string>
     <string name="tuner_full_zen_title" msgid="4540823317772234308">"音量調節を表示"</string>
-    <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"通知の非表示"</string>
+    <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"マナーモード"</string>
     <string name="volume_dnd_silent" msgid="4363882330723050727">"音量ボタンのショートカット"</string>
-    <string name="volume_up_silent" msgid="7141255269783588286">"音量上げボタンで [通知を非表示] を OFF にする"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"音量上げボタンでマナーモードを OFF にする"</string>
     <string name="battery" msgid="7498329822413202973">"電池"</string>
     <string name="clock" msgid="7416090374234785905">"時計"</string>
     <string name="headset" msgid="4534219457597457353">"ヘッドセット"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index efc3940..a151b8f 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ბრაუზერი"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"კონტაქტები"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ელფოსტა"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"მუსიკა"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"კალენდარი"</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index 271035f..6c0c967 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Браузер"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Контактілер"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Электрондық пошта"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"Мәтіндік хабар"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Mузыка"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Күнтізбе"</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 874993f..d3e97cc 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"កម្មវិធីរុករក"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"ទំនាក់ទំនង"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"អ៊ីមែល"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"សារ SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"តន្ត្រី"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ប្រតិទិន"</string>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index c71d67e..cbd71f9 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -96,7 +96,7 @@
     <string name="voice_assist_label" msgid="3956854378310019854">"ಧ್ವನಿ ಸಹಾಯಕವನ್ನು ತೆರೆ"</string>
     <string name="camera_label" msgid="7261107956054836961">"ಕ್ಯಾಮರಾ ತೆರೆಯಿರಿ"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ಹೊಸ ಕಾರ್ಯ ವಿನ್ಯಾಸವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
-    <string name="cancel" msgid="6442560571259935130">"ರದ್ದುಮಾಡು"</string>
+    <string name="cancel" msgid="6442560571259935130">"ರದ್ದುಮಾಡಿ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ಹೊಂದಾಣಿಕೆಯ ಝೂಮ್ ಬಟನ್."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ಚಿಕ್ಕ ಪರದೆಯಿಂದ ದೊಡ್ಡ ಪರದೆಗೆ ಝೂಮ್ ಮಾಡು."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ಬ್ಲೂಟೂತ್‌‌ ಸಂಪರ್ಕಗೊಂಡಿದೆ."</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 0a98831..3827dba 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -464,7 +464,7 @@
     <string name="show_battery_percentage_summary" msgid="3215025775576786037">"충전 중이 아닌 경우 상태 표시줄 아이콘 내에 배터리 잔량 비율 표시"</string>
     <string name="quick_settings" msgid="10042998191725428">"빠른 설정"</string>
     <string name="status_bar" msgid="4877645476959324760">"상태 표시줄"</string>
-    <string name="overview" msgid="4018602013895926956">"개요"</string>
+    <string name="overview" msgid="4018602013895926956">"최근 사용"</string>
     <string name="demo_mode" msgid="2389163018533514619">"데모 모드"</string>
     <string name="enable_demo_mode" msgid="4844205668718636518">"데모 모드 사용"</string>
     <string name="show_demo_mode" msgid="2018336697782464029">"데모 모드 표시"</string>
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"브라우저"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"주소록"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"이메일"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"음악"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"캘린더"</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 47abacd..56c8360 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Серепчи"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Байланыштар"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Электрондук почта"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музыка"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Жылнаама"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 6514008..c4676fa 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -566,8 +566,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Naršyklė"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktai"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"El. paštas"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzika"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendorius"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index fb736a0..a8266dd 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Pārlūkprogramma"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktpersonas"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-pasts"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"Īsziņas"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Mūzika"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendārs"</string>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index b4d085e..a1a3b31 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ബ്രൗസർ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"കോൺടാക്റ്റുകൾ"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ഇമെയിൽ"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS:"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"സംഗീതം"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"കലണ്ടർ"</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 8f762fb..9b83058 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Хөтөч"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Харилцагчид"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Имэйл"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Хөгжим"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Хуанли"</string>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index b4d8b1a..8003890 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ब्राउझर"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"संपर्क"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ईमेल"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"संगीत"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"कॅलेंडर"</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index ca54993..1a16967 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Penyemak imbas"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kenalan"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mel"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzik"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendar"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index d07de09..43c577d 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacten"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"Sms"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muziek"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Agenda"</string>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index 32397f6..6ef8674 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ਬ੍ਰਾਊਜ਼ਰ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"ਸੰਪਰਕ"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ਈਮੇਲ"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"ਸੰਗੀਤ"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ਕੈਲੰਡਰ"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 7264b95..41ec367 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -568,8 +568,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Браузер"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Контакты"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Эл. почта"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музыка"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Календарь"</string>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 0dc2f9f..8f65531 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"බ්‍රවුසරය"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"සම්බන්ධතා"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ඊ-තැපෑල"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"සංගීතය"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"දින දර්ශනය"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 4cdb97e..276c266 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -568,8 +568,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Prehliadač"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakty"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Hudba"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendár"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 6df7acc..cda2ac9 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -568,8 +568,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Brskalnik"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Stiki"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-pošta"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"Sporočila SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Glasba"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Koledar"</string>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index ba4cea0..33b2d5b 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Shfletuesi"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktet"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Mail-i"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzikë"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendari"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 4fdbb98..11d05b7 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Прегледач"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Контакти"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Имејл"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музика"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Календар"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 7ccf197..46e3f05 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Webbläsare"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakter"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-post"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"Sms"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musik"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 7df7ac5..364173e 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"உலாவி"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"தொடர்புகள்"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"மின்னஞ்சல்"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"மியூசிக்"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"கேலெண்டர்"</string>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index eff3a03..c1e55c8 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"బ్రౌజర్"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"పరిచయాలు"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ఇమెయిల్"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"సంగీతం"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"క్యాలెండర్"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 440d02f..f2b1772 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"เบราว์เซอร์"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"รายชื่อติดต่อ"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"อีเมล"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"เพลง"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ปฏิทิน"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 30dc7f5..f58ed17 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Mga Contact"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendaryo"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 740fdc6..e7b1abb 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Tarayıcı"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kişiler"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-posta"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Müzik"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Takvim"</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index b8781f5..31d90e2 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"براؤزر"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"رابطے"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ای میل"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"موسیقی"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"کیلنڈر"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 04e1f89..ba49055 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Trình duyệt"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Danh bạ"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Âm nhạc"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Lịch"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 1982b57..7a7991f 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"浏览器"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"通讯录"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"电子邮件"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"短信"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"音乐"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"日历"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 31a92ee..4f7ffe5 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -564,8 +564,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"瀏覽器"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"通訊錄"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"電郵"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"短訊"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"音樂"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"日曆"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 6aec964..2de07e3 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -562,8 +562,7 @@
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"瀏覽器"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"聯絡人"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"電子郵件"</string>
-    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
-    <skip />
+    <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"簡訊"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"音樂"</string>
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"日曆"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 549d50e..12f7881 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -694,4 +694,7 @@
 
     <!-- The alpha to apply to the recents row when it doesn't have focus -->
     <item name="recents_recents_row_dim_alpha" format="float" type="dimen">0.5</item>
+
+    <!-- The size of the PIP dismiss target. -->
+    <dimen name="pip_dismiss_target_size">48dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/SystemUI/res/values/dimens_car.xml
index 04402b7..988caf5 100644
--- a/packages/SystemUI/res/values/dimens_car.xml
+++ b/packages/SystemUI/res/values/dimens_car.xml
@@ -29,4 +29,5 @@
     <dimen name="car_fullscreen_user_pod_image_avatar_height">128dp</dimen>
     <dimen name="car_fullscreen_user_pod_text_size">24sp</dimen>
     <dimen name="car_navigation_button_width">64dp</dimen>
+    <dimen name="car_navigation_bar_width">760dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 92e10d2..d8c8b82 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1667,4 +1667,32 @@
          not appear on production builds ever. -->
     <string name="plugins" translatable="false">Plugins</string>
 
+    <!-- Ambient display section of the tuner. Non-translatable since it should
+        not appear on production builds ever. -->
+    <string name="tuner_doze" translatable="false">Ambient Display</string>
+
+    <!-- Ambient display always-on of the tuner. Non-translatable since it should
+        not appear on production builds ever. -->
+    <string name="tuner_doze_always_on" translatable="false">Always on</string>
+
+    <!-- PIP section of the tuner. Non-translatable since it should
+        not appear on production builds ever. -->
+    <string name="picture_in_picture" translatable="false">Picture-in-Picture</string>
+
+    <!-- PIP swipe to dismiss title. Non-translatable since it should
+        not appear on production builds ever. -->
+    <string name="pip_swipe_to_dismiss_title" translatable="false">Swipe to dismiss</string>
+
+    <!-- PIP swipe to dismiss description. Non-translatable since it should
+        not appear on production builds ever. -->
+    <string name="pip_swipe_to_dismiss_summary" translatable="false">Swipe left or right off screen to close the PIP</string>
+
+    <!-- PIP drag to dismiss title. Non-translatable since it should
+        not appear on production builds ever. -->
+    <string name="pip_drag_to_dismiss_title" translatable="false">Drag to dismiss</string>
+
+    <!-- PIP drag to dismiss description. Non-translatable since it should
+        not appear on production builds ever. -->
+    <string name="pip_drag_to_dismiss_summary" translatable="false">Drag to the dismiss target at the bottom of the screen to close the PIP</string>
+
 </resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 211f8e8..942f847 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -121,6 +121,35 @@
 
     </PreferenceScreen>
 
+    <PreferenceScreen
+      android:key="picture_in_picture"
+      android:title="@string/picture_in_picture">
+
+        <com.android.systemui.tuner.TunerSwitch
+          android:key="pip_swipe_to_dismiss"
+          android:title="@string/pip_swipe_to_dismiss_title"
+          android:summary="@string/pip_swipe_to_dismiss_summary"
+          sysui:defValue="true" />
+
+        <com.android.systemui.tuner.TunerSwitch
+          android:key="pip_drag_to_dismiss"
+          android:title="@string/pip_drag_to_dismiss_title"
+          android:summary="@string/pip_drag_to_dismiss_summary"
+          sysui:defValue="true" />
+
+    </PreferenceScreen>
+
+    <PreferenceScreen
+      android:key="doze"
+      android:title="@string/tuner_doze">
+
+        <com.android.systemui.tuner.TunerSwitch
+          android:key="doze_always_on"
+          android:title="@string/tuner_doze_always_on"
+          sysui:defValue="false" />
+
+    </PreferenceScreen>
+
     <!--
     <Preference
         android:key="nav_bar"
diff --git a/packages/SystemUI/src/com/android/systemui/DejankUtils.java b/packages/SystemUI/src/com/android/systemui/DejankUtils.java
index f8ce1d3..eba1d0f 100644
--- a/packages/SystemUI/src/com/android/systemui/DejankUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/DejankUtils.java
@@ -16,8 +16,9 @@
 
 package com.android.systemui;
 
+import com.android.systemui.util.Assert;
+
 import android.os.Handler;
-import android.os.Looper;
 import android.view.Choreographer;
 
 import java.util.ArrayList;
@@ -50,7 +51,7 @@
      * <p>Needs to be called from the main thread.
      */
     public static void postAfterTraversal(Runnable r) {
-        throwIfNotCalledOnMainThread();
+        Assert.isMainThread();
         sPendingRunnables.add(r);
         postAnimationCallback();
     }
@@ -61,7 +62,7 @@
      * <p>Needs to be called from the main thread.
      */
     public static void removeCallbacks(Runnable r) {
-        throwIfNotCalledOnMainThread();
+        Assert.isMainThread();
         sPendingRunnables.remove(r);
         sHandler.removeCallbacks(r);
     }
@@ -70,10 +71,4 @@
         sChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, sAnimationCallbackRunnable,
                 null);
     }
-
-    private static void throwIfNotCalledOnMainThread() {
-        if (!Looper.getMainLooper().isCurrentThread()) {
-            throw new IllegalStateException("should be called from the main thread.");
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index bfc8642..99e7876 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -42,7 +42,7 @@
 import com.android.systemui.statusbar.SystemBars;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
 import com.android.systemui.tuner.TunerService;
-import com.android.systemui.tv.pip.PipUI;
+import com.android.systemui.pip.PipUI;
 import com.android.systemui.usb.StorageNotification;
 import com.android.systemui.volume.VolumeUI;
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 82a1bfe..02a98b0 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -27,6 +27,7 @@
     void startDozing(@NonNull Runnable ready);
     void pulseWhileDozing(@NonNull PulseCallback callback, int reason);
     void stopDozing();
+    void dozeTimeTick();
     boolean isPowerSaveActive();
     boolean isNotificationLightOn();
     boolean isPulsingBlocked();
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
new file mode 100644
index 0000000..fd1ac8e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2016 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.systemui.doze;
+
+import com.android.internal.hardware.AmbientDisplayConfiguration;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto;
+import com.android.systemui.statusbar.phone.DozeParameters;
+
+import android.annotation.AnyThread;
+import android.app.ActivityManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.TriggerEvent;
+import android.hardware.TriggerEventListener;
+import android.media.AudioAttributes;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.List;
+
+public class DozeSensors {
+
+    private static final boolean DEBUG = DozeService.DEBUG;
+
+    private static final String TAG = "DozeSensors";
+
+    private final Context mContext;
+    private final SensorManager mSensorManager;
+    private final TriggerSensor[] mSensors;
+    private final ContentResolver mResolver;
+    private final TriggerSensor mPickupSensor;
+    private final DozeParameters mDozeParameters;
+    private final AmbientDisplayConfiguration mConfig;
+    private final PowerManager.WakeLock mWakeLock;
+    private final Callback mCallback;
+
+    private final Handler mHandler = new Handler();
+
+
+    public DozeSensors(Context context, SensorManager sensorManager, DozeParameters dozeParameters,
+            AmbientDisplayConfiguration config, PowerManager.WakeLock wakeLock, Callback callback) {
+        mContext = context;
+        mSensorManager = sensorManager;
+        mDozeParameters = dozeParameters;
+        mConfig = config;
+        mWakeLock = wakeLock;
+        mResolver = mContext.getContentResolver();
+
+        mSensors = new TriggerSensor[] {
+                new TriggerSensor(
+                        mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
+                        null /* setting */,
+                        dozeParameters.getPulseOnSigMotion(),
+                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION),
+                mPickupSensor = new TriggerSensor(
+                        mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
+                        Settings.Secure.DOZE_PULSE_ON_PICK_UP,
+                        config.pulseOnPickupAvailable(),
+                        DozeLog.PULSE_REASON_SENSOR_PICKUP),
+                new TriggerSensor(
+                        findSensorWithType(config.doubleTapSensorType()),
+                        Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
+                        true /* configured */,
+                        DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP)
+        };
+        mCallback = callback;
+    }
+
+    private Sensor findSensorWithType(String type) {
+        if (TextUtils.isEmpty(type)) {
+            return null;
+        }
+        List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+        for (Sensor s : sensorList) {
+            if (type.equals(s.getStringType())) {
+                return s;
+            }
+        }
+        return null;
+    }
+
+    public void setListen(boolean listen) {
+        for (TriggerSensor s : mSensors) {
+            s.setListening(listen);
+            if (listen) {
+                s.registerSettingsObserver(mSettingsObserver);
+            }
+        }
+        if (!listen) {
+            mResolver.unregisterContentObserver(mSettingsObserver);
+        }
+    }
+
+    public void reregisterAllSensors() {
+        for (TriggerSensor s : mSensors) {
+            s.setListening(false);
+        }
+        for (TriggerSensor s : mSensors) {
+            s.setListening(true);
+        }
+    }
+
+    public void onUserSwitched() {
+        for (TriggerSensor s : mSensors) {
+            s.updateListener();
+        }
+    }
+
+    private final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
+        @Override
+        public void onChange(boolean selfChange, Uri uri, int userId) {
+            if (userId != ActivityManager.getCurrentUser()) {
+                return;
+            }
+            for (TriggerSensor s : mSensors) {
+                s.updateListener();
+            }
+        }
+    };
+
+    public void setDisableSensorsInterferingWithProximity(boolean disable) {
+        mPickupSensor.setDisabled(disable);
+    }
+
+    private class TriggerSensor extends TriggerEventListener {
+        final Sensor mSensor;
+        final boolean mConfigured;
+        final int mPulseReason;
+        final String mSetting;
+
+        private boolean mRequested;
+        private boolean mRegistered;
+        private boolean mDisabled;
+
+        public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason) {
+            mSensor = sensor;
+            mSetting = setting;
+            mConfigured = configured;
+            mPulseReason = pulseReason;
+        }
+
+        public void setListening(boolean listen) {
+            if (mRequested == listen) return;
+            mRequested = listen;
+            updateListener();
+        }
+
+        public void setDisabled(boolean disabled) {
+            if (mDisabled == disabled) return;
+            mDisabled = disabled;
+            updateListener();
+        }
+
+        public void updateListener() {
+            if (!mConfigured || mSensor == null) return;
+            if (mRequested && !mDisabled && enabledBySetting() && !mRegistered) {
+                mRegistered = mSensorManager.requestTriggerSensor(this, mSensor);
+                if (DEBUG) Log.d(TAG, "requestTriggerSensor " + mRegistered);
+            } else if (mRegistered) {
+                final boolean rt = mSensorManager.cancelTriggerSensor(this, mSensor);
+                if (DEBUG) Log.d(TAG, "cancelTriggerSensor " + rt);
+                mRegistered = false;
+            }
+        }
+
+        private boolean enabledBySetting() {
+            if (TextUtils.isEmpty(mSetting)) {
+                return true;
+            }
+            return Settings.Secure.getIntForUser(mResolver, mSetting, 1,
+                    UserHandle.USER_CURRENT) != 0;
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder("{mRegistered=").append(mRegistered)
+                    .append(", mRequested=").append(mRequested)
+                    .append(", mDisabled=").append(mDisabled)
+                    .append(", mConfigured=").append(mConfigured)
+                    .append(", mSensor=").append(mSensor).append("}").toString();
+        }
+
+        @Override
+        @AnyThread
+        public void onTrigger(TriggerEvent event) {
+            mHandler.post(mWakeLock.wrap(() -> {
+                if (DEBUG)
+                    Log.d(TAG, "onTrigger: " + triggerEventToString(event));
+                boolean sensorPerformsProxCheck = false;
+                if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
+                    int subType = (int) event.values[0];
+                    MetricsLogger.action(
+                            mContext, MetricsProto.MetricsEvent.ACTION_AMBIENT_GESTURE,
+                            subType);
+                    sensorPerformsProxCheck =
+                            mDozeParameters.getPickupSubtypePerformsProxCheck(subType);
+                }
+
+                mRegistered = false;
+                mCallback.onSensorPulse(mPulseReason, sensorPerformsProxCheck);
+                updateListener();  // reregister, this sensor only fires once
+            }));
+        }
+
+        public void registerSettingsObserver(ContentObserver settingsObserver) {
+            if (mConfigured && !TextUtils.isEmpty(mSetting)) {
+                mResolver.registerContentObserver(
+                        Settings.Secure.getUriFor(mSetting), false /* descendants */,
+                        mSettingsObserver, UserHandle.USER_ALL);
+            }
+        }
+
+        private String triggerEventToString(TriggerEvent event) {
+            if (event == null) return null;
+            final StringBuilder sb = new StringBuilder("TriggerEvent[")
+                    .append(event.timestamp).append(',')
+                    .append(event.sensor.getName());
+            if (event.values != null) {
+                for (int i = 0; i < event.values.length; i++) {
+                    sb.append(',').append(event.values[i]);
+                }
+            }
+            return sb.append(']').toString();
+        }
+    }
+
+    public interface Callback {
+        void onSensorPulse(int pulseReason, boolean sensorPerformedProxCheck);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 6c35243..cbaf232 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -16,47 +16,41 @@
 
 package com.android.systemui.doze;
 
-import android.app.ActivityManager;
+import android.app.AlarmManager;
 import android.app.UiModeManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Configuration;
-import android.database.ContentObserver;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
-import android.hardware.TriggerEvent;
-import android.hardware.TriggerEventListener;
-import android.media.AudioAttributes;
-import android.net.Uri;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
-import android.os.Vibrator;
-import android.provider.Settings;
 import android.service.dreams.DreamService;
-import android.text.TextUtils;
 import android.util.Log;
 import android.view.Display;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.MetricsProto.MetricsEvent;
+import com.android.internal.util.Preconditions;
+import com.android.systemui.DejankUtils;
 import com.android.systemui.SystemUIApplication;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.util.Assert;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.Calendar;
 import java.util.Date;
-import java.util.List;
+import java.util.GregorianCalendar;
 
-public class DozeService extends DreamService {
+public class DozeService extends DreamService implements DozeSensors.Callback {
     private static final String TAG = "DozeService";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private static final String ACTION_BASE = "com.android.systemui.doze";
     private static final String PULSE_ACTION = ACTION_BASE + ".pulse";
@@ -72,9 +66,8 @@
     private final Handler mHandler = new Handler();
 
     private DozeHost mHost;
+    private DozeSensors mDozeSensors;
     private SensorManager mSensorManager;
-    private TriggerSensor[] mSensors;
-    private TriggerSensor mPickupSensor;
     private PowerManager mPowerManager;
     private PowerManager.WakeLock mWakeLock;
     private UiModeManager mUiModeManager;
@@ -87,6 +80,7 @@
     private long mNotificationPulseTime;
 
     private AmbientDisplayConfiguration mConfig;
+    private AlarmManager mAlarmManager;
 
     public DozeService() {
         if (DEBUG) Log.d(mTag, "new DozeService()");
@@ -101,10 +95,6 @@
         pw.print("  mWakeLock: held="); pw.println(mWakeLock.isHeld());
         pw.print("  mHost: "); pw.println(mHost);
         pw.print("  mBroadcastReceiverRegistered: "); pw.println(mBroadcastReceiverRegistered);
-        for (TriggerSensor s : mSensors) {
-            pw.print("  sensor: ");
-            pw.println(s);
-        }
         pw.print("  mDisplayStateSupported: "); pw.println(mDisplayStateSupported);
         pw.print("  mPowerSaveActive: "); pw.println(mPowerSaveActive);
         pw.print("  mCarMode: "); pw.println(mCarMode);
@@ -128,31 +118,16 @@
         setWindowless(true);
 
         mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
+        mAlarmManager = (AlarmManager) mContext.getSystemService(AlarmManager.class);
         mConfig = new AmbientDisplayConfiguration(mContext);
-        mSensors = new TriggerSensor[] {
-                new TriggerSensor(
-                        mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
-                        null /* setting */,
-                        mDozeParameters.getPulseOnSigMotion(),
-                        mDozeParameters.getVibrateOnSigMotion(),
-                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION),
-                mPickupSensor = new TriggerSensor(
-                        mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
-                        Settings.Secure.DOZE_PULSE_ON_PICK_UP,
-                        mConfig.pulseOnPickupAvailable(), mDozeParameters.getVibrateOnPickup(),
-                        DozeLog.PULSE_REASON_SENSOR_PICKUP),
-                new TriggerSensor(
-                        findSensorWithType(mConfig.doubleTapSensorType()),
-                        Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, true,
-                        mDozeParameters.getVibrateOnPickup(),
-                        DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP)
-        };
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
         mWakeLock.setReferenceCounted(true);
         mDisplayStateSupported = mDozeParameters.getDisplayStateSupported();
         mUiModeManager = (UiModeManager) mContext.getSystemService(Context.UI_MODE_SERVICE);
         turnDisplayOff();
+        mDozeSensors = new DozeSensors(mContext, mSensorManager, mDozeParameters,
+                mConfig, mWakeLock, this);
     }
 
     @Override
@@ -198,6 +173,10 @@
                 // stopDozing because can we just keep dozing until the bitter end.
             }
         }));
+
+        if (mDozeParameters.getAlwaysOn()) {
+            mTimeTick.onAlarm();
+        }
     }
 
     @Override
@@ -214,6 +193,7 @@
 
         // Tell the host that it's over.
         mHost.stopDozing();
+        mAlarmManager.cancel(mTimeTick);
     }
 
     private void requestPulse(final int reason) {
@@ -221,6 +201,7 @@
     }
 
     private void requestPulse(final int reason, boolean performedProxCheck) {
+        Assert.isMainThread();
         if (mHost != null && mDreaming && !mPulsing) {
             // Let the host know we want to pulse.  Wait for it to be ready, then
             // turn the screen on.  When finished, turn the screen off again.
@@ -282,7 +263,7 @@
                 if (mPulsing && mDreaming) {
                     mPulsing = false;
                     if (REREGISTER_ALL_SENSORS_ON_SCREEN_OFF) {
-                        reregisterAllSensors();
+                        mDozeSensors.reregisterAllSensors();
                     }
                     turnDisplayOff();
                 }
@@ -293,7 +274,11 @@
 
     private void turnDisplayOff() {
         if (DEBUG) Log.d(mTag, "Display off");
-        setDozeScreenState(Display.STATE_OFF);
+        if (mDozeParameters.getAlwaysOn()) {
+            turnDisplayOn();
+        } else {
+            setDozeScreenState(Display.STATE_OFF);
+        }
     }
 
     private void turnDisplayOn() {
@@ -313,22 +298,11 @@
 
     private void listenForPulseSignals(boolean listen) {
         if (DEBUG) Log.d(mTag, "listenForPulseSignals: " + listen);
-        for (TriggerSensor s : mSensors) {
-            s.setListening(listen);
-        }
+        mDozeSensors.setListen(listen);
         listenForBroadcasts(listen);
         listenForNotifications(listen);
     }
 
-    private void reregisterAllSensors() {
-        for (TriggerSensor s : mSensors) {
-            s.setListening(false);
-        }
-        for (TriggerSensor s : mSensors) {
-            s.setListening(true);
-        }
-    }
-
     private void listenForBroadcasts(boolean listen) {
         if (listen) {
             final IntentFilter filter = new IntentFilter(PULSE_ACTION);
@@ -336,18 +310,10 @@
             filter.addAction(Intent.ACTION_USER_SWITCHED);
             mContext.registerReceiver(mBroadcastReceiver, filter);
 
-            for (TriggerSensor s : mSensors) {
-                if (s.mConfigured && !TextUtils.isEmpty(s.mSetting)) {
-                    mContext.getContentResolver().registerContentObserver(
-                            Settings.Secure.getUriFor(s.mSetting), false /* descendants */,
-                            mSettingsObserver, UserHandle.USER_ALL);
-                }
-            }
             mBroadcastReceiverRegistered = true;
         } else {
             if (mBroadcastReceiverRegistered) {
                 mContext.unregisterReceiver(mBroadcastReceiver);
-                mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
             }
             mBroadcastReceiverRegistered = false;
         }
@@ -368,17 +334,18 @@
         requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
     }
 
-    private static String triggerEventToString(TriggerEvent event) {
-        if (event == null) return null;
-        final StringBuilder sb = new StringBuilder("TriggerEvent[")
-                .append(event.timestamp).append(',')
-                .append(event.sensor.getName());
-        if (event.values != null) {
-            for (int i = 0; i < event.values.length; i++) {
-                sb.append(',').append(event.values[i]);
-            }
+    @Override
+    public void onSensorPulse(int pulseReason, boolean sensorPerformedProxCheck) {
+        requestPulse(pulseReason, sensorPerformedProxCheck);
+
+        if (pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP) {
+            final long timeSinceNotification =
+                    SystemClock.elapsedRealtime() - mNotificationPulseTime;
+            final boolean withinVibrationThreshold =
+                    timeSinceNotification < mDozeParameters.getPickupVibrationThreshold();
+            DozeLog.tracePickupPulse(mContext, withinVibrationThreshold);
         }
-        return sb.append(']').toString();
+
     }
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -395,22 +362,28 @@
                 }
             }
             if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
-                for (TriggerSensor s : mSensors) {
-                    s.updateListener();
-                }
+                mDozeSensors.onUserSwitched();
             }
         }
     };
 
-    private final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
+    private AlarmManager.OnAlarmListener mTimeTick = new AlarmManager.OnAlarmListener() {
         @Override
-        public void onChange(boolean selfChange, Uri uri, int userId) {
-            if (userId != ActivityManager.getCurrentUser()) {
-                return;
-            }
-            for (TriggerSensor s : mSensors) {
-                s.updateListener();
-            }
+        public void onAlarm() {
+            mHost.dozeTimeTick();
+
+            // Keep wakelock until a frame has been pushed.
+            mHandler.post(mWakeLock.wrap(()->{}));
+
+            Calendar calendar = GregorianCalendar.getInstance();
+            calendar.setTimeInMillis(System.currentTimeMillis());
+            calendar.set(Calendar.MILLISECOND, 0);
+            calendar.set(Calendar.SECOND, 0);
+            calendar.add(Calendar.MINUTE, 1);
+
+            long delta = calendar.getTimeInMillis() - System.currentTimeMillis();
+            mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                    SystemClock.elapsedRealtime() + delta, "doze_time_tick", mTimeTick, mHandler);
         }
     };
 
@@ -442,122 +415,6 @@
         }
     };
 
-    private Sensor findSensorWithType(String type) {
-        if (TextUtils.isEmpty(type)) {
-            return null;
-        }
-        List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
-        for (Sensor s : sensorList) {
-            if (type.equals(s.getStringType())) {
-                return s;
-            }
-        }
-        return null;
-    }
-
-    private class TriggerSensor extends TriggerEventListener {
-        final Sensor mSensor;
-        final boolean mConfigured;
-        final boolean mDebugVibrate;
-        final int mPulseReason;
-        final String mSetting;
-
-        private boolean mRequested;
-        private boolean mRegistered;
-        private boolean mDisabled;
-
-        public TriggerSensor(Sensor sensor, String setting, boolean configured,
-                boolean debugVibrate, int pulseReason) {
-            mSensor = sensor;
-            mSetting = setting;
-            mConfigured = configured;
-            mDebugVibrate = debugVibrate;
-            mPulseReason = pulseReason;
-        }
-
-        public void setListening(boolean listen) {
-            if (mRequested == listen) return;
-            mRequested = listen;
-            updateListener();
-        }
-
-        public void setDisabled(boolean disabled) {
-            if (mDisabled == disabled) return;
-            mDisabled = disabled;
-            updateListener();
-        }
-
-        public void updateListener() {
-            if (!mConfigured || mSensor == null) return;
-            if (mRequested && !mDisabled && enabledBySetting() && !mRegistered) {
-                mRegistered = mSensorManager.requestTriggerSensor(this, mSensor);
-                if (DEBUG) Log.d(mTag, "requestTriggerSensor " + mRegistered);
-            } else if (mRegistered) {
-                final boolean rt = mSensorManager.cancelTriggerSensor(this, mSensor);
-                if (DEBUG) Log.d(mTag, "cancelTriggerSensor " + rt);
-                mRegistered = false;
-            }
-        }
-
-        private boolean enabledBySetting() {
-            if (TextUtils.isEmpty(mSetting)) {
-                return true;
-            }
-            return Settings.Secure.getIntForUser(mContext.getContentResolver(), mSetting, 1,
-                    UserHandle.USER_CURRENT) != 0;
-        }
-
-        @Override
-        public String toString() {
-            return new StringBuilder("{mRegistered=").append(mRegistered)
-                    .append(", mRequested=").append(mRequested)
-                    .append(", mDisabled=").append(mDisabled)
-                    .append(", mConfigured=").append(mConfigured)
-                    .append(", mDebugVibrate=").append(mDebugVibrate)
-                    .append(", mSensor=").append(mSensor).append("}").toString();
-        }
-
-        @Override
-        public void onTrigger(TriggerEvent event) {
-            mWakeLock.acquire();
-            try {
-                if (DEBUG) Log.d(mTag, "onTrigger: " + triggerEventToString(event));
-                boolean sensorPerformsProxCheck = false;
-                if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
-                    int subType = (int) event.values[0];
-                    MetricsLogger.action(mContext, MetricsEvent.ACTION_AMBIENT_GESTURE, subType);
-                    sensorPerformsProxCheck = mDozeParameters.getPickupSubtypePerformsProxCheck(
-                            subType);
-                }
-                if (mDebugVibrate) {
-                    final Vibrator v = (Vibrator) mContext.getSystemService(
-                            Context.VIBRATOR_SERVICE);
-                    if (v != null) {
-                        v.vibrate(1000, new AudioAttributes.Builder()
-                                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
-                                .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build());
-                    }
-                }
-
-                mRegistered = false;
-                requestPulse(mPulseReason, sensorPerformsProxCheck);
-                updateListener();  // reregister, this sensor only fires once
-
-                // record pickup gesture, also keep track of whether we might have been triggered
-                // by recent vibration.
-                final long timeSinceNotification = SystemClock.elapsedRealtime()
-                        - mNotificationPulseTime;
-                final boolean withinVibrationThreshold =
-                        timeSinceNotification < mDozeParameters.getPickupVibrationThreshold();
-                if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
-                    DozeLog.tracePickupPulse(mContext, withinVibrationThreshold);
-                }
-            } finally {
-                mWakeLock.release();
-            }
-        }
-    }
-
     private abstract class ProximityCheck implements SensorEventListener, Runnable {
         private static final int TIMEOUT_DELAY_MS = 500;
 
@@ -581,8 +438,7 @@
                 finishWithResult(RESULT_UNKNOWN);
                 return;
             }
-            // the pickup sensor interferes with the prox event, disable it until we have a result
-            mPickupSensor.setDisabled(true);
+            mDozeSensors.setDisableSensorsInterferingWithProximity(true);
 
             mMaxRange = sensor.getMaximumRange();
             mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL, 0,
@@ -614,8 +470,7 @@
             if (mRegistered) {
                 mHandler.removeCallbacks(this);
                 mSensorManager.unregisterListener(this);
-                // we're done - reenable the pickup sensor
-                mPickupSensor.setDisabled(false);
+                mDozeSensors.setDisableSensorsInterferingWithProximity(false);
                 mRegistered = false;
             }
             onProximityResult(result);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
new file mode 100644
index 0000000..617d8ad
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 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.systemui.pip;
+
+import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
+import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
+
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+
+import com.android.systemui.SystemUI;
+
+/**
+ * Controls the picture-in-picture window.
+ */
+public class PipUI extends SystemUI {
+
+    private boolean mSupportsPip;
+    private boolean mIsLeanBackOnly;
+
+    @Override
+    public void start() {
+        PackageManager pm = mContext.getPackageManager();
+        mSupportsPip = pm.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
+        mIsLeanBackOnly = pm.hasSystemFeature(FEATURE_LEANBACK_ONLY);
+        if (!mSupportsPip) {
+            return;
+        }
+        if (mIsLeanBackOnly) {
+            com.android.systemui.pip.tv.PipManager.getInstance().initialize(mContext);
+        } else {
+            com.android.systemui.pip.phone.PipManager.getInstance().initialize(mContext);
+        }
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        if (!mSupportsPip) {
+            return;
+        }
+        if (mIsLeanBackOnly) {
+            com.android.systemui.pip.tv.PipManager.getInstance().onConfigurationChanged();
+        } else {
+            com.android.systemui.pip.phone.PipManager.getInstance().onConfigurationChanged();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
new file mode 100644
index 0000000..a7ac719
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2016 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.systemui.pip.phone;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnLayoutChangeListener;
+import android.view.WindowManager;
+
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
+
+public class PipDismissViewController {
+
+    // This delay controls how long to wait before we show the target when the user first moves
+    // the PIP, to prevent the target from animating if the user just wants to fling the PIP
+    private static final int SHOW_TARGET_DELAY = 100;
+    private static final int SHOW_TARGET_DURATION = 200;
+
+    private Context mContext;
+    private WindowManager mWindowManager;
+
+    private View mDismissView;
+    private Rect mDismissTargetScreenBounds = new Rect();
+
+    public PipDismissViewController(Context context) {
+        mContext = context;
+        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+    }
+
+    /**
+     * Creates the dismiss target for showing via {@link #showDismissTarget()}.
+     */
+    public void createDismissTarget() {
+        if (mDismissView == null) {
+            // Create a new view for the dismiss target
+            int dismissTargetSize = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.pip_dismiss_target_size);
+            LayoutInflater inflater = LayoutInflater.from(mContext);
+            mDismissView = inflater.inflate(R.layout.pip_dismiss_view, null);
+            mDismissView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+                @Override
+                public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                        int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                    if (mDismissView != null) {
+                        mDismissView.getBoundsOnScreen(mDismissTargetScreenBounds);
+                    }
+                }
+            });
+
+            // Add the target to the window
+            WindowManager.LayoutParams lp =  new WindowManager.LayoutParams(
+                    dismissTargetSize,
+                    dismissTargetSize,
+                    WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG,
+                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                            | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                            | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                    PixelFormat.TRANSLUCENT);
+            lp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+            mWindowManager.addView(mDismissView, lp);
+        }
+        mDismissView.animate().cancel();
+    }
+
+    /**
+     * Shows the dismiss target.
+     */
+    public void showDismissTarget() {
+        mDismissView.animate()
+                .alpha(1f)
+                .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
+                .setStartDelay(SHOW_TARGET_DELAY)
+                .setDuration(SHOW_TARGET_DURATION)
+                .start();
+    }
+
+    /**
+     * Hides and destroys the dismiss target.
+     */
+    public void destroyDismissTarget() {
+        if (mDismissView != null) {
+            mDismissView.animate()
+                    .alpha(0f)
+                    .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
+                    .setStartDelay(0)
+                    .setDuration(SHOW_TARGET_DURATION)
+                    .withEndAction(new Runnable() {
+                        @Override
+                        public void run() {
+                            mWindowManager.removeView(mDismissView);
+                            mDismissView = null;
+                        }
+                    })
+                    .start();
+        }
+    }
+
+    /**
+     * @return the dismiss target screen bounds.
+     */
+    public Rect getDismissBounds() {
+        return mDismissTargetScreenBounds;
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
new file mode 100644
index 0000000..f9a4f7c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 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.systemui.pip.phone;
+
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.content.Context;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
+
+/**
+ * Manages the picture-in-picture (PIP) UI and states for Phones.
+ */
+public class PipManager {
+    private static final String TAG = "PipManager";
+
+    private static PipManager sPipController;
+
+    private Context mContext;
+    private IActivityManager mActivityManager;
+    private IWindowManager mWindowManager;
+
+    private PipTouchHandler mTouchHandler;
+
+    private PipManager() {}
+
+    /**
+     * Initializes {@link PipManager}.
+     */
+    public void initialize(Context context) {
+        mContext = context;
+        mActivityManager = ActivityManagerNative.getDefault();
+        mWindowManager = WindowManagerGlobal.getWindowManagerService();
+
+        mTouchHandler = new PipTouchHandler(context, mActivityManager, mWindowManager);
+    }
+
+    /**
+     * Updates the PIP per configuration changed.
+     */
+    public void onConfigurationChanged() {
+        mTouchHandler.onConfigurationChanged();
+    }
+
+    /**
+     * Gets an instance of {@link PipManager}.
+     */
+    public static PipManager getInstance() {
+        if (sPipController == null) {
+            sPipController = new PipManager();
+        }
+        return sPipController;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
new file mode 100644
index 0000000..7f2d415
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -0,0 +1,485 @@
+/*
+ * Copyright (C) 2016 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.systemui.pip.phone;
+
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.INPUT_CONSUMER_PIP;
+
+import static com.android.systemui.Interpolators.FAST_OUT_LINEAR_IN;
+import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.app.ActivityManager.StackInfo;
+import android.app.IActivityManager;
+import android.content.Context;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.IPinnedStackController;
+import android.view.IPinnedStackListener;
+import android.view.IWindowManager;
+import android.view.InputChannel;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.ViewConfiguration;
+
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.policy.PipMotionHelper;
+import com.android.internal.policy.PipSnapAlgorithm;
+import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.tuner.TunerService;
+
+/**
+ * Manages all the touch handling for PIP on the Phone, including moving, dismissing and expanding
+ * the PIP.
+ */
+public class PipTouchHandler implements TunerService.Tunable {
+    private static final String TAG = "PipTouchHandler";
+    private static final boolean DEBUG_ALLOW_OUT_OF_BOUNDS_STACK = false;
+
+    private static final String TUNER_KEY_SWIPE_TO_DISMISS = "pip_swipe_to_dismiss";
+    private static final String TUNER_KEY_DRAG_TO_DISMISS = "pip_drag_to_dismiss";
+
+    private static final int SNAP_STACK_DURATION = 225;
+    private static final int DISMISS_STACK_DURATION = 375;
+    private static final int EXPAND_STACK_DURATION = 225;
+
+    private final Context mContext;
+    private final IActivityManager mActivityManager;
+    private final IWindowManager mWindowManager;
+    private final ViewConfiguration mViewConfig;
+    private final InputChannel mInputChannel = new InputChannel();
+    private final PinnedStackListener mPinnedStackListener = new PinnedStackListener();
+    private IPinnedStackController mPinnedStackController;
+
+    private final PipInputEventReceiver mInputEventReceiver;
+    private PipDismissViewController mDismissViewController;
+    private PipSnapAlgorithm mSnapAlgorithm;
+    private PipMotionHelper mMotionHelper;
+
+    private boolean mEnableSwipeToDismiss = true;
+    private boolean mEnableDragToDismiss = true;
+
+    private final Rect mPinnedStackBounds = new Rect();
+    private final Rect mBoundedPinnedStackBounds = new Rect();
+    private ValueAnimator mPinnedStackBoundsAnimator = null;
+    private ValueAnimator.AnimatorUpdateListener mUpdatePinnedStackBoundsListener =
+            new AnimatorUpdateListener() {
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            mPinnedStackBounds.set((Rect) animation.getAnimatedValue());
+        }
+    };
+
+    private final PointF mDownTouch = new PointF();
+    private final PointF mLastTouch = new PointF();
+    private boolean mIsDragging;
+    private boolean mIsSwipingToDismiss;
+    private int mActivePointerId;
+
+    private final FlingAnimationUtils mFlingAnimationUtils;
+    private VelocityTracker mVelocityTracker;
+
+    private final Rect mTmpBounds = new Rect();
+
+    /**
+     * Input handler used for Pip windows.
+     */
+    private final class PipInputEventReceiver extends InputEventReceiver {
+
+        public PipInputEventReceiver(InputChannel inputChannel, Looper looper) {
+            super(inputChannel, looper);
+        }
+
+        @Override
+        public void onInputEvent(InputEvent event) {
+            boolean handled = true;
+            try {
+                // To be implemented for input handling over Pip windows
+                if (event instanceof MotionEvent) {
+                    MotionEvent ev = (MotionEvent) event;
+                    handleTouchEvent(ev);
+                }
+            } finally {
+                finishInputEvent(event, handled);
+            }
+        }
+    }
+
+    /**
+     * Handler for messages from the PIP controller.
+     */
+    private class PinnedStackListener extends IPinnedStackListener.Stub {
+
+        @Override
+        public void onListenerRegistered(IPinnedStackController controller) {
+            mPinnedStackController = controller;
+        }
+
+        @Override
+        public void onBoundsChanged(boolean adjustedForIme) {
+            // Do nothing
+        }
+    }
+
+    public PipTouchHandler(Context context, IActivityManager activityManager,
+            IWindowManager windowManager) {
+
+        // Initialize the Pip input consumer
+        try {
+            windowManager.destroyInputConsumer(INPUT_CONSUMER_PIP);
+            windowManager.createInputConsumer(INPUT_CONSUMER_PIP, mInputChannel);
+            windowManager.registerPinnedStackListener(DEFAULT_DISPLAY, mPinnedStackListener);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to create PIP input consumer", e);
+        }
+        mContext = context;
+        mActivityManager = activityManager;
+        mWindowManager = windowManager;
+        mViewConfig = ViewConfiguration.get(context);
+        mInputEventReceiver = new PipInputEventReceiver(mInputChannel, Looper.myLooper());
+        if (mEnableDragToDismiss) {
+            mDismissViewController = new PipDismissViewController(context);
+        }
+        mFlingAnimationUtils = new FlingAnimationUtils(context, 2f);
+        mMotionHelper = new PipMotionHelper(BackgroundThread.getHandler());
+
+        // Register any tuner settings changes
+        TunerService.get(context).addTunable(this, TUNER_KEY_SWIPE_TO_DISMISS,
+            TUNER_KEY_DRAG_TO_DISMISS);
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (newValue == null) {
+            return;
+        }
+        switch (key) {
+            case TUNER_KEY_SWIPE_TO_DISMISS:
+                mEnableSwipeToDismiss = Integer.parseInt(newValue) != 0;
+                break;
+            case TUNER_KEY_DRAG_TO_DISMISS:
+                mEnableDragToDismiss = Integer.parseInt(newValue) != 0;
+                break;
+        }
+    }
+
+    public void onConfigurationChanged() {
+        updateBoundedPinnedStackBounds();
+    }
+
+    private void handleTouchEvent(MotionEvent ev) {
+        // Skip touch handling until we are bound to the controller
+        if (mPinnedStackController == null) {
+            return;
+        }
+
+        switch (ev.getAction()) {
+            case MotionEvent.ACTION_DOWN: {
+                // Cancel any existing animations on the pinned stack
+                if (mPinnedStackBoundsAnimator != null) {
+                    mPinnedStackBoundsAnimator.cancel();
+                }
+
+                updateBoundedPinnedStackBounds();
+                initOrResetVelocityTracker();
+                mVelocityTracker.addMovement(ev);
+                mActivePointerId = ev.getPointerId(0);
+                mLastTouch.set(ev.getX(), ev.getY());
+                mDownTouch.set(mLastTouch);
+                mIsDragging = false;
+                try {
+                    mPinnedStackController.setInInteractiveMode(true);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Could not set dragging state", e);
+                }
+                if (mEnableDragToDismiss) {
+                    // TODO: Consider setting a timer such at after X time, we show the dismiss
+                    //       target if the user hasn't already dragged some distance
+                    mDismissViewController.createDismissTarget();
+                }
+                break;
+            }
+            case MotionEvent.ACTION_MOVE: {
+                // Update the velocity tracker
+                mVelocityTracker.addMovement(ev);
+
+                int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+                float x = ev.getX(activePointerIndex);
+                float y = ev.getY(activePointerIndex);
+                float left = mPinnedStackBounds.left + (x - mLastTouch.x);
+                float top = mPinnedStackBounds.top + (y - mLastTouch.y);
+
+                if (!mIsDragging) {
+                    // Check if the pointer has moved far enough
+                    float movement = PointF.length(mDownTouch.x - x, mDownTouch.y - y);
+                    if (movement > mViewConfig.getScaledTouchSlop()) {
+                        mIsDragging = true;
+                        if (mEnableSwipeToDismiss) {
+                            // TODO: this check can have some buffer so that we only start swiping
+                            //       after a significant move out of bounds
+                            mIsSwipingToDismiss = !(mBoundedPinnedStackBounds.left <= left &&
+                                    left <= mBoundedPinnedStackBounds.right) &&
+                                    Math.abs(mDownTouch.x - x) > Math.abs(y - mLastTouch.y);
+                        }
+                        if (mEnableDragToDismiss) {
+                            mDismissViewController.showDismissTarget();
+                        }
+                    }
+                }
+
+                if (mIsSwipingToDismiss) {
+                    // Ignore the vertical movement
+                    mTmpBounds.set(mPinnedStackBounds);
+                    mTmpBounds.offsetTo((int) left, mPinnedStackBounds.top);
+                    if (!mTmpBounds.equals(mPinnedStackBounds)) {
+                        mPinnedStackBounds.set(mTmpBounds);
+                        mMotionHelper.resizeToBounds(mPinnedStackBounds);
+                    }
+                } else if (mIsDragging) {
+                    // Move the pinned stack
+                    if (!DEBUG_ALLOW_OUT_OF_BOUNDS_STACK) {
+                        left = Math.max(mBoundedPinnedStackBounds.left, Math.min(
+                                mBoundedPinnedStackBounds.right, left));
+                        top = Math.max(mBoundedPinnedStackBounds.top, Math.min(
+                                mBoundedPinnedStackBounds.bottom, top));
+                    }
+                    mTmpBounds.set(mPinnedStackBounds);
+                    mTmpBounds.offsetTo((int) left, (int) top);
+                    if (!mTmpBounds.equals(mPinnedStackBounds)) {
+                        mPinnedStackBounds.set(mTmpBounds);
+                        mMotionHelper.resizeToBounds(mPinnedStackBounds);
+                    }
+                }
+                mLastTouch.set(ev.getX(), ev.getY());
+                break;
+            }
+            case MotionEvent.ACTION_POINTER_UP: {
+                // Update the velocity tracker
+                mVelocityTracker.addMovement(ev);
+
+                int pointerIndex = ev.getActionIndex();
+                int pointerId = ev.getPointerId(pointerIndex);
+                if (pointerId == mActivePointerId) {
+                    // Select a new active pointer id and reset the movement state
+                    final int newPointerIndex = (pointerIndex == 0) ? 1 : 0;
+                    mActivePointerId = ev.getPointerId(newPointerIndex);
+                    mLastTouch.set(ev.getX(newPointerIndex), ev.getY(newPointerIndex));
+                }
+                break;
+            }
+            case MotionEvent.ACTION_UP: {
+                // Update the velocity tracker
+                mVelocityTracker.addMovement(ev);
+                mVelocityTracker.computeCurrentVelocity(1000,
+                    ViewConfiguration.get(mContext).getScaledMaximumFlingVelocity());
+                float velocityX = mVelocityTracker.getXVelocity();
+                float velocityY = mVelocityTracker.getYVelocity();
+                float velocity = PointF.length(velocityX, velocityY);
+
+                if (mIsSwipingToDismiss) {
+                    if (Math.abs(velocityX) > mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
+                        flingToDismiss(velocityX);
+                    } else {
+                        animateToClosestSnapTarget();
+                    }
+                } else if (mIsDragging) {
+                    if (velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
+                        flingToSnapTarget(velocity, velocityX, velocityY);
+                    } else {
+                        int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+                        int x = (int) ev.getX(activePointerIndex);
+                        int y = (int) ev.getY(activePointerIndex);
+                        Rect dismissBounds = mEnableDragToDismiss
+                                ? mDismissViewController.getDismissBounds()
+                                : null;
+                        if (dismissBounds != null && dismissBounds.contains(x, y)) {
+                            animateDismissPinnedStack(dismissBounds);
+                        } else {
+                            animateToClosestSnapTarget();
+                        }
+                    }
+                } else {
+                    expandPinnedStackToFullscreen();
+                }
+                if (mEnableDragToDismiss) {
+                    mDismissViewController.destroyDismissTarget();
+                }
+
+                // Fall through to clean up
+            }
+            case MotionEvent.ACTION_CANCEL: {
+                mIsDragging = false;
+                mIsSwipingToDismiss = false;
+                try {
+                    mPinnedStackController.setInInteractiveMode(false);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Could not set dragging state", e);
+                }
+                recycleVelocityTracker();
+                break;
+            }
+        }
+    }
+
+    private void initOrResetVelocityTracker() {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        } else {
+            mVelocityTracker.clear();
+        }
+    }
+
+    private void recycleVelocityTracker() {
+        if (mVelocityTracker != null) {
+            mVelocityTracker.recycle();
+            mVelocityTracker = null;
+        }
+    }
+
+    /**
+     * Flings the PIP to the closest snap target.
+     */
+    private void flingToSnapTarget(float velocity, float velocityX, float velocityY) {
+        Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(mBoundedPinnedStackBounds,
+                mPinnedStackBounds, velocityX, velocityY);
+        if (!mPinnedStackBounds.equals(toBounds)) {
+            mPinnedStackBoundsAnimator = mMotionHelper.createAnimationToBounds(mPinnedStackBounds,
+                toBounds, 0, FAST_OUT_SLOW_IN, mUpdatePinnedStackBoundsListener);
+            mFlingAnimationUtils.apply(mPinnedStackBoundsAnimator, 0,
+                distanceBetweenRectOffsets(mPinnedStackBounds, toBounds),
+                velocity);
+            mPinnedStackBoundsAnimator.start();
+        }
+    }
+
+    /**
+     * Animates the PIP to the closest snap target.
+     */
+    private void animateToClosestSnapTarget() {
+        Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(mBoundedPinnedStackBounds,
+                mPinnedStackBounds);
+        if (!mPinnedStackBounds.equals(toBounds)) {
+            mPinnedStackBoundsAnimator = mMotionHelper.createAnimationToBounds(mPinnedStackBounds,
+                toBounds, SNAP_STACK_DURATION, FAST_OUT_SLOW_IN, mUpdatePinnedStackBoundsListener);
+            mPinnedStackBoundsAnimator.start();
+        }
+    }
+
+    /**
+     * Flings the PIP to dismiss it offscreen.
+     */
+    private void flingToDismiss(float velocityX) {
+        float offsetX = velocityX > 0
+            ? mBoundedPinnedStackBounds.right + 2 * mPinnedStackBounds.width()
+            : mBoundedPinnedStackBounds.left - 2 * mPinnedStackBounds.width();
+        Rect toBounds = new Rect(mPinnedStackBounds);
+        toBounds.offsetTo((int) offsetX, toBounds.top);
+        if (!mPinnedStackBounds.equals(toBounds)) {
+            mPinnedStackBoundsAnimator = mMotionHelper.createAnimationToBounds(mPinnedStackBounds,
+                toBounds, 0, FAST_OUT_SLOW_IN, mUpdatePinnedStackBoundsListener);
+            mFlingAnimationUtils.apply(mPinnedStackBoundsAnimator, 0,
+                distanceBetweenRectOffsets(mPinnedStackBounds, toBounds),
+                velocityX);
+            mPinnedStackBoundsAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    BackgroundThread.getHandler().post(() -> {
+                        try {
+                            mActivityManager.removeStack(PINNED_STACK_ID);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Failed to remove PIP", e);
+                        }
+                    });
+                }
+            });
+            mPinnedStackBoundsAnimator.start();
+        }
+    }
+
+    /**
+     * Animates the dismissal of the PIP over the dismiss target bounds.
+     */
+    private void animateDismissPinnedStack(Rect dismissBounds) {
+        Rect toBounds = new Rect(dismissBounds.centerX(),
+            dismissBounds.centerY(),
+            dismissBounds.centerX() + 1,
+            dismissBounds.centerY() + 1);
+        mPinnedStackBoundsAnimator = mMotionHelper.createAnimationToBounds(mPinnedStackBounds,
+            toBounds, DISMISS_STACK_DURATION, FAST_OUT_LINEAR_IN, mUpdatePinnedStackBoundsListener);
+        mPinnedStackBoundsAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                BackgroundThread.getHandler().post(() -> {
+                    try {
+                        mActivityManager.removeStack(PINNED_STACK_ID);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Failed to remove PIP", e);
+                    }
+                });
+            }
+        });
+        mPinnedStackBoundsAnimator.start();
+    }
+
+    /**
+     * Resizes the pinned stack back to fullscreen.
+     */
+    private void expandPinnedStackToFullscreen() {
+        BackgroundThread.getHandler().post(() -> {
+            try {
+                mActivityManager.resizeStack(PINNED_STACK_ID, null /* bounds */,
+                        true /* allowResizeInDockedMode */, true /* preserveWindows */,
+                        true /* animate */, EXPAND_STACK_DURATION);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error showing PIP menu activity", e);
+            }
+        });
+    }
+
+    /**
+     * Updates the movement bounds of the pinned stack.
+     */
+    private void updateBoundedPinnedStackBounds() {
+        try {
+            StackInfo info = mActivityManager.getStackInfo(PINNED_STACK_ID);
+            if (info != null) {
+                mPinnedStackBounds.set(info.bounds);
+                mBoundedPinnedStackBounds.set(mWindowManager.getPictureInPictureMovementBounds(
+                        info.displayId));
+                mSnapAlgorithm = new PipSnapAlgorithm(mContext);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Could not fetch PIP movement bounds.", e);
+        }
+    }
+
+    /**
+     * @return the distance between points {@param p1} and {@param p2}.
+     */
+    private float distanceBetweenRectOffsets(Rect r1, Rect r2) {
+        return PointF.length(r1.left - r2.left, r1.top - r2.top);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlButtonView.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlButtonView.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/tv/pip/PipControlButtonView.java
rename to packages/SystemUI/src/com/android/systemui/pip/tv/PipControlButtonView.java
index 80c593c..59cb086 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlButtonView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.tv.pip;
+package com.android.systemui.pip.tv;
 
 import android.animation.Animator;
 import android.animation.AnimatorInflater;
@@ -22,7 +22,6 @@
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
-import android.view.View.OnFocusChangeListener;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlsView.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/tv/pip/PipControlsView.java
rename to packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java
index 71740ce..a2aff2d 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlsView.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.tv.pip;
+package com.android.systemui.pip.tv;
 
 import android.content.Context;
 import android.media.session.MediaController;
@@ -22,9 +22,6 @@
 import android.view.View;
 import android.view.Gravity;
 import android.view.LayoutInflater;
-import android.view.View.OnFocusChangeListener;
-import android.widget.ImageView;
-import android.widget.TextView;
 import android.widget.LinearLayout;
 import android.util.AttributeSet;
 
@@ -33,10 +30,6 @@
 import static android.media.session.PlaybackState.ACTION_PAUSE;
 import static android.media.session.PlaybackState.ACTION_PLAY;
 
-import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_PLAYING;
-import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_PAUSED;
-import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_UNAVAILABLE;
-
 
 /**
  * A view containing PIP controls including fullscreen, close, and media controls.
@@ -145,9 +138,9 @@
                 }
                 long actions = mMediaController.getPlaybackState().getActions();
                 int state = mMediaController.getPlaybackState().getState();
-                if (mPipManager.getPlaybackState() == PLAYBACK_STATE_PAUSED) {
+                if (mPipManager.getPlaybackState() == PipManager.PLAYBACK_STATE_PAUSED) {
                     mMediaController.getTransportControls().play();
-                } else if (mPipManager.getPlaybackState() == PLAYBACK_STATE_PLAYING) {
+                } else if (mPipManager.getPlaybackState() == PipManager.PLAYBACK_STATE_PLAYING) {
                     mMediaController.getTransportControls().pause();
                 }
                 // View will be updated later in {@link mMediaControllerCallback}
@@ -188,11 +181,11 @@
 
     private void updatePlayPauseView() {
         int state = mPipManager.getPlaybackState();
-        if (state == PLAYBACK_STATE_UNAVAILABLE) {
+        if (state == PipManager.PLAYBACK_STATE_UNAVAILABLE) {
             mPlayPauseButtonView.setVisibility(View.GONE);
         } else {
             mPlayPauseButtonView.setVisibility(View.VISIBLE);
-            if (state == PLAYBACK_STATE_PLAYING) {
+            if (state == PipManager.PLAYBACK_STATE_PLAYING) {
                 mPlayPauseButtonView.setImageResource(R.drawable.ic_pause_white_24dp);
                 mPlayPauseButtonView.setText(R.string.pip_pause);
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
rename to packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 75c2bcd..c272ae6 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.tv.pip;
+package com.android.systemui.pip.tv;
 
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManager.StackInfo;
@@ -25,7 +25,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.media.session.MediaController;
@@ -33,17 +32,15 @@
 import android.media.session.PlaybackState;
 import android.os.Debug;
 import android.os.Handler;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
+import android.view.Display;
 import android.view.IWindowManager;
-import android.view.InputChannel;
-import android.view.InputEvent;
-import android.view.InputEventReceiver;
 import android.view.WindowManagerGlobal;
+
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -53,7 +50,6 @@
 import java.util.List;
 
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.view.WindowManager.INPUT_CONSUMER_PIP;
 import static com.android.systemui.Prefs.Key.TV_PICTURE_IN_PICTURE_ONBOARDING_SHOWN;
 
 /**
@@ -67,8 +63,6 @@
 
     private static PipManager sPipManager;
 
-    private static final int MAX_RUNNING_TASKS_COUNT = 10;
-
     /**
      * List of package and class name which are considered as Settings,
      * so PIP location should be adjusted to the left of the side panel.
@@ -143,6 +137,7 @@
     private Context mContext;
     private PipRecentsOverlayManager mPipRecentsOverlayManager;
     private IActivityManager mActivityManager;
+    private IWindowManager mWindowManager;
     private MediaSessionManager mMediaSessionManager;
     private int mState = STATE_NO_PIP;
     private final Handler mHandler = new Handler();
@@ -163,9 +158,6 @@
     private boolean mOnboardingShown;
     private String[] mLastPackagesResourceGranted;
 
-    private InputChannel mInputChannel;
-    private PipInputEventReceiver mInputEventReceiver;
-
     private final Runnable mResizePinnedStackRunnable = new Runnable() {
         @Override
         public void run() {
@@ -203,25 +195,6 @@
                 }
             };
 
-    /**
-     * Input handler used for Pip windows.  Currently eats all the input events.
-     */
-    private final class PipInputEventReceiver extends InputEventReceiver {
-        public PipInputEventReceiver(InputChannel inputChannel, Looper looper) {
-            super(inputChannel, looper);
-        }
-
-        @Override
-        public void onInputEvent(InputEvent event) {
-            boolean handled = true;
-            try {
-                // To be implemented for input handling over Pip windows
-            } finally {
-                finishInputEvent(event, handled);
-            }
-        }
-    }
-
     private PipManager() { }
 
     /**
@@ -235,6 +208,7 @@
         mContext = context;
 
         mActivityManager = ActivityManagerNative.getDefault();
+        mWindowManager = WindowManagerGlobal.getWindowManagerService();
         SystemServicesProxy.getInstance(context).registerTaskStackListener(mTaskStackListener);
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
@@ -246,26 +220,16 @@
         mPipRecentsOverlayManager = new PipRecentsOverlayManager(context);
         mMediaSessionManager =
                 (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
-
-        PackageManager pm = mContext.getPackageManager();
-        if (!pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)) {
-            // Initialize the Pip input consumer
-            mInputChannel = new InputChannel();
-            try {
-                IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
-                wm.destroyInputConsumer(INPUT_CONSUMER_PIP);
-                wm.createInputConsumer(INPUT_CONSUMER_PIP, mInputChannel);
-                mInputEventReceiver = new PipInputEventReceiver(mInputChannel, Looper.myLooper());
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to create Pip input consumer", e);
-            }
-        }
     }
 
     private void loadConfigurationsAndApply() {
         Resources res = mContext.getResources();
-        mDefaultPipBounds = Rect.unflattenFromString(res.getString(
-                com.android.internal.R.string.config_defaultPictureInPictureBounds));
+        try {
+            mDefaultPipBounds = mWindowManager.getPictureInPictureDefaultBounds(
+                    Display.DEFAULT_DISPLAY);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to get default PIP bounds", e);
+        }
         mSettingsPipBounds = Rect.unflattenFromString(res.getString(
                 R.string.pip_settings_bounds));
         mMenuModePipBounds = Rect.unflattenFromString(res.getString(
@@ -287,7 +251,7 @@
     /**
      * Updates the PIP per configuration changed.
      */
-    void onConfigurationChanged() {
+    public void onConfigurationChanged() {
         loadConfigurationsAndApply();
         mPipRecentsOverlayManager.onConfigurationChanged(mContext);
     }
@@ -347,11 +311,7 @@
      */
     private void showPipOverlay() {
         if (DEBUG) Log.d(TAG, "showPipOverlay()");
-        // Temporary workaround to prevent the overlay on phones
-        PackageManager pm = mContext.getPackageManager();
-        if (pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)) {
-            PipOverlayActivity.showPipOverlay(mContext);
-        }
+        PipOverlayActivity.showPipOverlay(mContext);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
rename to packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
index 542a935..01d86b6 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.tv.pip;
+package com.android.systemui.pip.tv;
 
 import android.animation.Animator;
 import android.animation.AnimatorInflater;
@@ -23,7 +23,6 @@
 import android.view.View;
 
 import com.android.systemui.R;
-import com.android.systemui.Interpolators;
 
 /**
  * Activity to show the PIP menu to control PIP.
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipOnboardingActivity.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java
rename to packages/SystemUI/src/com/android/systemui/pip/tv/PipOnboardingActivity.java
index 9a87cfc..57952f4 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipOnboardingActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.tv.pip;
+package com.android.systemui.pip.tv;
 
 import android.animation.Animator;
 import android.animation.AnimatorInflater;
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipOverlayActivity.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
rename to packages/SystemUI/src/com/android/systemui/pip/tv/PipOverlayActivity.java
index 011e159..f52121f 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipOverlayActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.tv.pip;
+package com.android.systemui.pip.tv;
 
 import android.animation.Animator;
 import android.animation.AnimatorInflater;
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsControlsView.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipRecentsControlsView.java
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsControlsView.java
rename to packages/SystemUI/src/com/android/systemui/pip/tv/PipRecentsControlsView.java
index ffe96af..a891d12 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsControlsView.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipRecentsControlsView.java
@@ -14,26 +14,20 @@
  * limitations under the License.
  */
 
-package com.android.systemui.tv.pip;
+package com.android.systemui.pip.tv;
 
 import android.animation.Animator;
 import android.animation.AnimatorInflater;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.View;
-import android.view.View.OnFocusChangeListener;
 import android.widget.FrameLayout;
 
 import com.android.systemui.R;
 
-import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_PLAYING;
-import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_PAUSED;
-import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_UNAVAILABLE;
-
 /**
  * An FrameLayout that contains {@link PipControlsView} with its scrim.
  */
@@ -49,7 +43,6 @@
     }
 
     private final PipManager mPipManager = PipManager.getInstance();
-    private Listener mListener;
     private PipControlsView mPipControlsView;
     private View mScrim;
     private Animator mFocusGainAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipRecentsOverlayManager.java
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java
rename to packages/SystemUI/src/com/android/systemui/pip/tv/PipRecentsOverlayManager.java
index 895b8a2..835bcbc 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipRecentsOverlayManager.java
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.tv.pip;
+package com.android.systemui.pip.tv;
 
 import android.content.Context;
 import android.graphics.PixelFormat;
-import android.graphics.Rect;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -32,9 +31,6 @@
 import static android.view.Gravity.CENTER_HORIZONTAL;
 import static android.view.Gravity.TOP;
 import static android.view.View.MeasureSpec.UNSPECIFIED;
-import static com.android.systemui.tv.pip.PipManager.STATE_PIP_OVERLAY;
-import static com.android.systemui.tv.pip.PipManager.STATE_PIP_RECENTS;
-import static com.android.systemui.tv.pip.PipManager.STATE_PIP_RECENTS_FOCUSED;
 
 public class PipRecentsOverlayManager {
     private static final String TAG = "PipRecentsOverlayManager";
@@ -158,7 +154,7 @@
         mIsPipFocusedInRecent = true;
         mPipControlsView.startFocusGainAnimation();
         mWindowManager.updateViewLayout(mOverlayView, mPipRecentsControlsViewFocusedLayoutParams);
-        mPipManager.resizePinnedStack(STATE_PIP_RECENTS_FOCUSED);
+        mPipManager.resizePinnedStack(PipManager.STATE_PIP_RECENTS_FOCUSED);
         if (mTalkBackEnabled) {
             mPipControlsView.requestFocus();
             mPipControlsView.sendAccessibilityEvent(
@@ -177,7 +173,7 @@
         mIsPipFocusedInRecent = false;
         mPipControlsView.startFocusLossAnimation();
         mWindowManager.updateViewLayout(mOverlayView, mPipRecentsControlsViewLayoutParams);
-        mPipManager.resizePinnedStack(STATE_PIP_RECENTS);
+        mPipManager.resizePinnedStack(PipManager.STATE_PIP_RECENTS);
         if (mCallback != null) {
             mCallback.onRecentsFocused();
         }
@@ -198,7 +194,7 @@
         }
         mIsRecentsShown = true;
         mIsPipFocusedInRecent = true;
-        mPipManager.resizePinnedStack(STATE_PIP_RECENTS_FOCUSED);
+        mPipManager.resizePinnedStack(PipManager.STATE_PIP_RECENTS_FOCUSED);
         // Overlay view will be added after the resize animation ends, if any.
     }
 
@@ -212,7 +208,7 @@
         removePipRecentsOverlayView();
 
         if (mPipManager.isPipShown()) {
-            mPipManager.resizePinnedStack(STATE_PIP_OVERLAY);
+            mPipManager.resizePinnedStack(PipManager.STATE_PIP_OVERLAY);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 4ac629d..ccb28e9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -188,7 +188,8 @@
                         profileOwner, profileVpn, primaryVpn);
             } else {
                 if (isBranded) {
-                    return mContext.getString(R.string.branded_monitoring_description_app_personal);
+                    return mContext.getString(R.string.branded_monitoring_description_app_personal,
+                            primaryVpn);
                 } else {
                     return mContext.getString(R.string.monitoring_description_app_personal,
                             primaryVpn);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index e0cdb1a..c91b060 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -79,6 +79,8 @@
 import com.android.internal.app.AssistUtils;
 import com.android.internal.os.BackgroundThread;
 import com.android.systemui.R;
+import com.android.systemui.pip.tv.PipMenuActivity;
+import com.android.systemui.pip.tv.PipOnboardingActivity;
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.RecentsImpl;
 import com.android.systemui.recents.model.Task;
@@ -109,8 +111,8 @@
     final static List<String> sRecentsBlacklist;
     static {
         sRecentsBlacklist = new ArrayList<>();
-        sRecentsBlacklist.add("com.android.systemui.tv.pip.PipOnboardingActivity");
-        sRecentsBlacklist.add("com.android.systemui.tv.pip.PipMenuActivity");
+        sRecentsBlacklist.add(PipOnboardingActivity.class.getName());
+        sRecentsBlacklist.add(PipMenuActivity.class.getName());
     }
 
     private static SystemServicesProxy sSystemServicesProxy;
@@ -158,7 +160,7 @@
      * ActivityManagerNative.
      * This simply passes callbacks to listeners through {@link H}.
      * */
-    private ITaskStackListener.Stub mTaskStackListener = new ITaskStackListener.Stub() {
+    private android.app.TaskStackListener mTaskStackListener = new android.app.TaskStackListener() {
         @Override
         public void onTaskStackChanged() throws RemoteException {
             mHandler.removeMessages(H.ON_TASK_STACK_CHANGED);
@@ -1082,7 +1084,8 @@
         if (mWm == null) return;
 
         try {
-            WindowManagerGlobal.getWindowManagerService().getStableInsets(outStableInsets);
+            WindowManagerGlobal.getWindowManagerService().getStableInsets(Display.DEFAULT_DISPLAY,
+                    outStableInsets);
         } catch (Exception e) {
             e.printStackTrace();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index ecb12d3..a2a8199 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -58,8 +58,8 @@
 import com.android.systemui.recents.tv.views.TaskStackHorizontalGridView;
 import com.android.systemui.recents.tv.views.TaskStackHorizontalViewAdapter;
 import com.android.systemui.statusbar.BaseStatusBar;
-import com.android.systemui.tv.pip.PipManager;
-import com.android.systemui.tv.pip.PipRecentsOverlayManager;
+import com.android.systemui.pip.tv.PipManager;
+import com.android.systemui.pip.tv.PipRecentsOverlayManager;
 
 import java.util.ArrayList;
 import java.util.Collections;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
index ef9de53..ac9a217 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
@@ -25,7 +25,6 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 
-import com.android.systemui.SystemUIApplication;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsActivityLaunchState;
 import com.android.systemui.recents.RecentsConfiguration;
@@ -37,8 +36,7 @@
 import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.model.ThumbnailData;
 import com.android.systemui.recents.tv.views.TaskCardView;
-import com.android.systemui.statusbar.tv.TvStatusBar;
-import com.android.systemui.tv.pip.PipManager;
+import com.android.systemui.pip.tv.PipManager;
 
 public class RecentsTvImpl extends RecentsImpl{
     public final static String RECENTS_TV_ACTIVITY =
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 24ef433..febeacb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -95,7 +95,6 @@
     private static final int SHOW_STACK_ACTION_BUTTON_DURATION = 134;
     private static final int HIDE_STACK_ACTION_BUTTON_DURATION = 100;
 
-    private TaskStack mStack;
     private TaskStackView mTaskStackView;
     private TextView mStackActionButton;
     private TextView mEmptyView;
@@ -195,7 +194,6 @@
      * Called from RecentsActivity when the task stack is updated.
      */
     public void updateStack(TaskStack stack, boolean setStackViewTasks) {
-        mStack = stack;
         if (setStackViewTasks) {
             mTaskStackView.setTasks(stack, true /* allowNotifyStackChanges */);
         }
@@ -212,7 +210,7 @@
      * Returns the current TaskStack.
      */
     public TaskStack getStack() {
-        return mStack;
+        return mTaskStackView.getStack();
     }
 
     /*
@@ -251,8 +249,7 @@
     /** Launches the task that recents was launched from if possible */
     public boolean launchPreviousTask() {
         if (mTaskStackView != null) {
-            TaskStack stack = mTaskStackView.getStack();
-            Task task = stack.getLaunchTarget();
+            Task task = getStack().getLaunchTarget();
             if (task != null) {
                 TaskView taskView = mTaskStackView.getChildViewForTask(task);
                 EventBus.getDefault().send(new LaunchTaskEvent(taskView, task, null,
@@ -437,8 +434,9 @@
 
     public final void onBusEvent(LaunchTaskEvent event) {
         mLastTaskLaunchedWasFreeform = event.task.isFreeformTask();
-        mTransitionHelper.launchTaskFromRecents(mStack, event.task, mTaskStackView, event.taskView,
-                event.screenPinningRequested, event.targetTaskBounds, event.targetTaskStack);
+        mTransitionHelper.launchTaskFromRecents(getStack(), event.task, mTaskStackView,
+                event.taskView, event.screenPinningRequested, event.targetTaskBounds,
+                event.targetTaskStack);
     }
 
     public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
@@ -514,8 +512,7 @@
                         EventBus.getDefault().send(new DockedFirstAnimationFrameEvent());
                         // Remove the task and don't bother relaying out, as all the tasks will be
                         // relaid out when the stack changes on the multiwindow change event
-                        mTaskStackView.getStack().removeTask(event.task, null,
-                                true /* fromDockGesture */);
+                        getStack().removeTask(event.task, null, true /* fromDockGesture */);
                     }
                 };
 
@@ -536,7 +533,7 @@
                 MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP,
                         event.task.getTopComponent().flattenToShortString());
             } else {
-                EventBus.getDefault().send(new DragEndCancelledEvent(mStack, event.task,
+                EventBus.getDefault().send(new DragEndCancelledEvent(getStack(), event.task,
                         event.taskView));
             }
         } else {
@@ -598,7 +595,7 @@
     public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
         RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
         if (!launchState.launchedViaDockGesture && !launchState.launchedFromApp
-                && mStack.getTaskCount() > 0) {
+                && getStack().getTaskCount() > 0) {
             animateBackgroundScrim(1f,
                     TaskStackAnimationHelper.ENTER_FROM_HOME_TRANSLATION_DURATION);
         }
@@ -797,8 +794,8 @@
         writer.print(" [0x"); writer.print(id); writer.print("]");
         writer.println();
 
-        if (mStack != null) {
-            mStack.dump(innerPrefix, writer);
+        if (getStack() != null) {
+            getStack().dump(innerPrefix, writer);
         }
         if (mTaskStackView != null) {
             mTaskStackView.dump(innerPrefix, writer);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 265f319..d3ec984 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -31,6 +31,7 @@
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
+import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.ui.HideIncompatibleAppOverlayEvent;
 import com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
@@ -139,7 +140,10 @@
     /** Handles touch events once we have intercepted them */
     public boolean onTouchEvent(MotionEvent ev) {
         handleTouchEvent(ev);
-        return mDragRequested;
+        if (ev.getAction() == MotionEvent.ACTION_UP && mRv.getStack().getStackTaskCount() == 0) {
+            EventBus.getDefault().send(new HideRecentsEvent(false, true));
+        }
+        return true;
     }
 
     /**** Events ****/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index a7331d8..8a5a8a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -248,6 +248,11 @@
         }
     }
 
+    @Override
+    public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
+        // Do nothing, we don't want to display media art in the lock screen for a car.
+    }
+
     private int startActivityWithOptions(Intent intent, Bundle options) {
         int result = ActivityManager.START_CANCELED;
         try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 9e9bdd7..0e074c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -17,20 +17,17 @@
 package com.android.systemui.statusbar.phone;
 
 import android.content.Context;
+import android.os.Build;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.text.TextUtils;
-import android.util.Log;
 import android.util.MathUtils;
 import android.util.SparseBooleanArray;
 
-import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.systemui.R;
 
 import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 public class DozeParameters {
     private static final int MAX_DURATION = 60 * 1000;
@@ -115,6 +112,12 @@
         return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
     }
 
+    public boolean getAlwaysOn() {
+        return Build.IS_DEBUGGABLE
+                && Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.DOZE_ALWAYS_ON, 0, UserHandle.USER_CURRENT) != 0;
+    }
+
     private boolean getBoolean(String propName, int resId) {
         return SystemProperties.getBoolean(propName, mContext.getResources().getBoolean(resId));
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index b44f5f7..b141454 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.os.Handler;
 import android.util.Log;
+import android.view.View;
 import android.view.animation.Interpolator;
 
 import com.android.systemui.Interpolators;
@@ -40,6 +41,8 @@
     private final Handler mHandler = new Handler();
     private final ScrimController mScrimController;
 
+    private final View mStackScroller;
+
     private boolean mDozing;
     private DozeHost.PulseCallback mPulseCallback;
     private int mPulseReason;
@@ -48,7 +51,9 @@
     private float mInFrontTarget;
     private float mBehindTarget;
 
-    public DozeScrimController(ScrimController scrimController, Context context) {
+    public DozeScrimController(ScrimController scrimController, Context context,
+            View stackScroller) {
+        mStackScroller = stackScroller;
         mScrimController = scrimController;
         mDozeParameters = new DozeParameters(context);
     }
@@ -59,7 +64,11 @@
         if (mDozing) {
             abortAnimations();
             mScrimController.setDozeBehindAlpha(1f);
-            mScrimController.setDozeInFrontAlpha(1f);
+            mScrimController.setDozeInFrontAlpha(mDozeParameters.getAlwaysOn() ? 0f : 1f);
+            if (mDozeParameters.getAlwaysOn()) {
+                mStackScroller.setAlpha(0f);
+                mHandler.postDelayed(() -> mStackScroller.setAlpha(0f), 30);
+            }
         } else {
             cancelPulsing();
             if (animate) {
@@ -74,6 +83,9 @@
                 mScrimController.setDozeBehindAlpha(0f);
                 mScrimController.setDozeInFrontAlpha(0f);
             }
+            if (mDozeParameters.getAlwaysOn()) {
+                mStackScroller.setAlpha(1f);
+            }
         }
     }
 
@@ -93,7 +105,9 @@
         // be invoked when we're done so that the caller can drop the pulse wakelock.
         mPulseCallback = callback;
         mPulseReason = reason;
-        mHandler.post(mPulseIn);
+        if (mDozeParameters.getAlwaysOn()) {
+            mHandler.post(mPulseIn);
+        }
     }
 
     /**
@@ -111,6 +125,9 @@
         if (isPulsing()) {
             final boolean pickupOrDoubleTap = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP
                     || mPulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
+            if (mDozeParameters.getAlwaysOn()) {
+                mStackScroller.setAlpha(1f);
+            }
             startScrimAnimation(true /* inFront */, 0f,
                     mDozeParameters.getPulseInDuration(pickupOrDoubleTap),
                     pickupOrDoubleTap ? Interpolators.LINEAR_OUT_SLOW_IN : Interpolators.ALPHA_OUT,
@@ -245,6 +262,10 @@
 
             // Signal that the pulse is ready to turn the screen on and draw.
             pulseStarted();
+
+            if (mDozeParameters.getAlwaysOn()) {
+                mHandler.post(DozeScrimController.this::onScreenTurnedOn);
+            }
         }
     };
 
@@ -262,7 +283,8 @@
         public void run() {
             if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
             if (!mDozing) return;
-            startScrimAnimation(true /* inFront */, 1f, mDozeParameters.getPulseOutDuration(),
+            startScrimAnimation(true /* inFront */, mDozeParameters.getAlwaysOn() ? 0 : 1,
+                    mDozeParameters.getPulseOutDuration(),
                     Interpolators.ALPHA_IN, mPulseOutFinished);
         }
     };
@@ -271,6 +293,9 @@
         @Override
         public void run() {
             if (DEBUG) Log.d(TAG, "Pulse out finished");
+            if (mDozeParameters.getAlwaysOn()) {
+                mStackScroller.setAlpha(0f);
+            }
             DozeLog.tracePulseFinish();
 
             // Signal that the pulse is all finished so we can turn the screen off now.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
index 583a63e..0f800bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -31,6 +31,7 @@
 import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
+import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.tuner.TunerService;
 
@@ -42,7 +43,7 @@
  * Class to detect gestures on the navigation bar.
  */
 public class NavigationBarGestureHelper extends GestureDetector.SimpleOnGestureListener
-        implements TunerService.Tunable {
+        implements TunerService.Tunable, GestureHelper {
 
     private static final String KEY_DOCK_WINDOW_GESTURE = "overview_nav_bar_gesture";
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 3a0eb94..798d9df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -44,16 +44,20 @@
 import android.view.WindowManagerGlobal;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.FrameLayout;
-import android.widget.LinearLayout;
+
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.plugins.statusbar.phone.NavGesture;
+import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.policy.DeadZone;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
-public class NavigationBarView extends FrameLayout {
+public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> {
     final static boolean DEBUG = false;
     final static String TAG = "StatusBar/NavBarView";
 
@@ -83,7 +87,7 @@
     private Drawable mImeIcon;
     private Drawable mMenuIcon;
 
-    private NavigationBarGestureHelper mGestureHelper;
+    private GestureHelper mGestureHelper;
     private DeadZone mDeadZone;
     private final NavigationBarTransitions mBarTransitions;
 
@@ -105,6 +109,8 @@
     private Configuration mConfiguration;
 
     private NavigationBarInflaterView mNavigationInflaterView;
+    private RecentsComponent mRecentsComponent;
+    private Divider mDivider;
 
     private class NavTransitionListener implements TransitionListener {
         private boolean mBackTransitioning;
@@ -212,7 +218,12 @@
     }
 
     public void setComponents(RecentsComponent recentsComponent, Divider divider) {
-        mGestureHelper.setComponents(recentsComponent, divider, this);
+        mRecentsComponent = recentsComponent;
+        mDivider = divider;
+        if (mGestureHelper instanceof NavigationBarGestureHelper) {
+            ((NavigationBarGestureHelper) mGestureHelper).setComponents(
+                    recentsComponent, divider, this);
+        }
     }
 
     public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) {
@@ -700,6 +711,33 @@
         }
     }
 
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        PluginManager.getInstance(getContext()).addPluginListener(NavGesture.ACTION, this,
+                NavGesture.VERSION, false /* Only one */);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        PluginManager.getInstance(getContext()).removePluginListener(this);
+    }
+
+    @Override
+    public void onPluginConnected(NavGesture plugin) {
+        mGestureHelper = plugin.getGestureHelper();
+        updateTaskSwitchHelper();
+    }
+
+    @Override
+    public void onPluginDisconnected(NavGesture plugin) {
+        NavigationBarGestureHelper defaultHelper = new NavigationBarGestureHelper(getContext());
+        defaultHelper.setComponents(mRecentsComponent, mDivider, this);
+        mGestureHelper = defaultHelper;
+        updateTaskSwitchHelper();
+    }
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("NavigationBarView {");
         final Rect r = new Rect();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 28e5f7e..0ef2687 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -123,6 +123,7 @@
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.keyguard.KeyguardHostView.OnDismissAction;
+import com.android.keyguard.KeyguardStatusView;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.ViewMediatorCallback;
@@ -367,7 +368,7 @@
     // top bar
     BaseStatusBarHeader mHeader;
     protected KeyguardStatusBarView mKeyguardStatusBar;
-    View mKeyguardStatusView;
+    KeyguardStatusView mKeyguardStatusView;
     KeyguardBottomAreaView mKeyguardBottomArea;
     boolean mLeaveOpenOnKeyguardHide;
     KeyguardIndicationController mKeyguardIndicationController;
@@ -846,10 +847,11 @@
         mHeadsUpManager.addListener(mScrimController);
         mStackScroller.setScrimController(mScrimController);
         mStatusBarView.setScrimController(mScrimController);
-        mDozeScrimController = new DozeScrimController(mScrimController, context);
+        mDozeScrimController = new DozeScrimController(mScrimController, context, mStackScroller);
 
         mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
-        mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
+        mKeyguardStatusView =
+                (KeyguardStatusView) mStatusBarWindow.findViewById(R.id.keyguard_status_view);
         mKeyguardBottomArea =
                 (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
         mKeyguardBottomArea.setActivityStarter(this);
@@ -2695,6 +2697,10 @@
         mFalsingManager.onScreenOff();
     }
 
+    public boolean isPulsing() {
+        return mDozeScrimController.isPulsing();
+    }
+
     /**
      * All changes to the status bar and notifications funnel through here and are batched.
      */
@@ -5135,6 +5141,11 @@
         }
 
         @Override
+        public void dozeTimeTick() {
+            mKeyguardStatusView.refreshTime();
+        }
+
+        @Override
         public boolean isPowerSaveActive() {
             return mBatteryController != null && mBatteryController.isPowerSave();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 4425c5e..5696123 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -248,6 +248,10 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (mService.isDozing() && !mService.isPulsing()) {
+            // Discard all touch events in always-on.
+            return true;
+        }
         boolean intercept = false;
         if (mNotificationPanel.isFullyExpanded()
                 && mStackScrollLayout.getVisibility() == View.VISIBLE
@@ -274,6 +278,11 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
+        if (mService.isDozing() && !mService.isPulsing()) {
+            // Discard all touch events in always-on.
+            return true;
+        }
+
         boolean handled = false;
         if (mService.getBarState() == StatusBarState.KEYGUARD) {
             handled = mDragDownHelper.onTouchEvent(ev);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 3c83921..f5c60a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -27,7 +27,7 @@
 import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.NotificationData;
-import com.android.systemui.tv.pip.PipManager;
+import com.android.systemui.pip.tv.PipManager;
 
 /**
  * Status bar implementation for "large screen" products that mostly present no on-screen nav
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
index 132a6dd..f6b8891 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
@@ -14,11 +14,14 @@
 
 package com.android.systemui.tuner;
 
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.net.Uri;
 import android.os.Bundle;
 import android.support.v14.preference.PreferenceFragment;
 import android.support.v14.preference.SwitchPreference;
@@ -27,6 +30,7 @@
 import android.support.v7.preference.PreferenceViewHolder;
 import android.view.View;
 
+import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.PluginPrefs;
 import com.android.systemui.R;
 
@@ -41,7 +45,30 @@
     private PluginPrefs mPluginPrefs;
 
     @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addAction(PluginManager.PLUGIN_CHANGED);
+        filter.addDataScheme("package");
+        getContext().registerReceiver(mReceiver, filter);
+        filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
+        getContext().registerReceiver(mReceiver, filter);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        getContext().unregisterReceiver(mReceiver);
+    }
+
+    @Override
     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+        loadPrefs();
+    }
+
+    private void loadPrefs() {
         PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(getContext());
         screen.setOrderingAsAdded(false);
         Context prefContext = getPreferenceManager().getContext();
@@ -64,6 +91,13 @@
         setPreferenceScreen(screen);
     }
 
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            loadPrefs();
+        }
+    };
+
     private static class PluginPreference extends SwitchPreference {
         private final ComponentName mComponent;
         private final boolean mHasSettings;
@@ -82,10 +116,17 @@
 
         @Override
         protected boolean persistBoolean(boolean value) {
-            getContext().getPackageManager().setComponentEnabledSetting(mComponent,
-                    value ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
-                            : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+            PackageManager pm = getContext().getPackageManager();
+            final int desiredState = value ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+                    : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+            if (pm.getComponentEnabledSetting(mComponent) == desiredState) return true;
+            pm.setComponentEnabledSetting(mComponent,
+                    desiredState,
                     PackageManager.DONT_KILL_APP);
+            final String pkg = mComponent.getPackageName();
+            final Intent intent = new Intent(PluginManager.PLUGIN_CHANGED,
+                    pkg != null ? Uri.fromParts("package", pkg, null) : null);
+            getContext().sendBroadcast(intent);
             return true;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipUI.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipUI.java
deleted file mode 100644
index 3306cb3..0000000
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipUI.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.tv.pip;
-
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-
-import com.android.systemui.SystemUI;
-
-import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
-
-/**
- * Controls the picture-in-picture window.
- */
-public class PipUI extends SystemUI {
-    private boolean mSupportPip;
-
-    @Override
-    public void start() {
-        PackageManager pm = mContext.getPackageManager();
-        mSupportPip = pm.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
-        if (!mSupportPip) {
-            return;
-        }
-        PipManager pipManager = PipManager.getInstance();
-        pipManager.initialize(mContext);
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        if (!mSupportPip) {
-            return;
-        }
-        PipManager.getInstance().onConfigurationChanged();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/util/Assert.java b/packages/SystemUI/src/com/android/systemui/util/Assert.java
new file mode 100644
index 0000000..af447f3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/Assert.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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.systemui.util;
+
+import android.os.Looper;
+
+/**
+ * Helper providing common assertions.
+ */
+public class Assert {
+
+    public static void isMainThread() {
+        if (!Looper.getMainLooper().isCurrentThread()) {
+            throw new IllegalStateException("should be called from the main thread.");
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 6038171..ecf174f 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -87,7 +87,9 @@
 
 include frameworks/base/packages/SettingsLib/common.mk
 
-include $(BUILD_PACKAGE)
+ifeq ($(EXCLUDE_SYSTEMUI_TESTS),)
+    include $(BUILD_PACKAGE)
+endif
 
 # Reset variables
 local_java_files :=
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaTest.java
new file mode 100644
index 0000000..fccb2a2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 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.keyguard;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import static junit.framework.Assert.*;
+import static org.mockito.Mockito.mock;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class KeyguardMessageAreaTest extends SysuiTestCase {
+    private Context mContext = InstrumentationRegistry.getTargetContext();
+    private Handler mHandler = new Handler(Looper.getMainLooper());
+    private KeyguardMessageArea mMessageArea;
+
+    @Before
+    public void setUp() throws Exception {
+        KeyguardUpdateMonitor monitor = mock(KeyguardUpdateMonitor.class);
+        mHandler.post(()-> mMessageArea = new KeyguardMessageArea(mContext, null, monitor));
+        waitForIdleSync();
+    }
+
+    @Test
+    public void clearFollowedByMessage_keepsMessage() {
+        mHandler.post(()-> {
+            mMessageArea.setMessage("");
+            mMessageArea.setMessage("test");
+        });
+
+        waitForIdleSync();
+
+        CharSequence[] messageText = new CharSequence[1];
+        mHandler.post(()-> {
+            messageText[0] = mMessageArea.getText();
+        });
+
+        waitForIdleSync();
+
+        assertEquals("test", messageText[0]);
+    }
+
+}
diff --git a/preloaded-classes b/preloaded-classes
index 5ddd08b..45734b6 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -365,7 +365,6 @@
 android.app.ApplicationLoaders
 android.app.ApplicationPackageManager
 android.app.ApplicationPackageManager$ResourceName
-android.app.ApplicationThreadNative
 android.app.BackStackRecord
 android.app.BackStackRecord$Op
 android.app.BackStackRecord$TransitionState
@@ -393,6 +392,8 @@
 android.app.IAlarmManager$Stub
 android.app.IAlarmManager$Stub$Proxy
 android.app.IApplicationThread
+android.app.IApplicationThread$Stub
+android.app.IApplicationThread$Stub$Proxy
 android.app.IInstrumentationWatcher
 android.app.IInstrumentationWatcher$Stub
 android.app.INotificationManager
diff --git a/services/core/proto/ipconnectivity.proto b/proto/src/ipconnectivity.proto
similarity index 94%
rename from services/core/proto/ipconnectivity.proto
rename to proto/src/ipconnectivity.proto
index e0d7f09..29b318f 100644
--- a/services/core/proto/ipconnectivity.proto
+++ b/proto/src/ipconnectivity.proto
@@ -53,6 +53,7 @@
 
   // The event type code of the probe, represented by constants defined in
   // android.net.metrics.IpReachabilityEvent.
+  // NUD_FAILED_ORGANIC and PROVISIONING_LOST_ORGANIC recorded since version 1.
   optional int32 event_type = 2;
 };
 
@@ -126,11 +127,12 @@
 
   // Lifetime duration in milliseconds of a DhcpClient state, or transition
   // time in milliseconds between specific pairs of DhcpClient's states.
-  // Only populated when state_transition is populated.
+  // Only populated since version 1, when state_transition is populated.
   optional int32 duration_ms = 4;
 }
 
 // Represents the generation of an Android Packet Filter program.
+// Since version 1.
 message ApfProgramEvent {
   // Lifetime of the program in seconds.
   optional int64 lifetime = 1;
@@ -154,6 +156,7 @@
 
 // Represents Router Advertisement listening statistics for an interface with
 // Android Packet Filter enabled.
+// Since version 1.
 message ApfStatistics {
   // The time interval in milliseconds these stastistics cover.
   optional int64 duration_ms = 1;
@@ -183,6 +186,7 @@
 
 // Represents the reception of a Router Advertisement packet for an interface
 // with Android Packet Filter enabled.
+// Since version 1.
 message RaEvent {
   // All lifetime values are expressed in seconds. The default value for an
   // option lifetime that was not present in the RA option list is -1.
@@ -271,4 +275,11 @@
 
   // The number of events that had to be dropped due to a full buffer.
   optional int32 dropped_events = 2;
+
+  // The version number of the metrics events being collected.
+  //  nyc-dev: not populated, implicitly 0
+  //  nyc-dr1: not populated, implicitly 1 (sailfish and marlin only)
+  //  nyc-mr1: not populated, implicitly 1
+  //  nyc-mr2: 2
+  optional int32 version = 3;
 };
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index cebde98..ba0725e 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2593,6 +2593,38 @@
     // ACTION: Logs provisioning started by trusted source.
     PROVISIONING_ENTRY_POINT_TRUSTED_SOURCE = 618;
 
+    // ACTION: Logged when copy account task finishes.
+    // TIME: Indicates time taken by copy account task to finish in MS.
+    PROVISIONING_COPY_ACCOUNT_TASK_MS = 619;
+
+    // ACTION: Logged when create profile task finishes.
+    // TIME: Indicates time taken by create profile task to finish in MS.
+    PROVISIONING_CREATE_PROFILE_TASK_MS = 620;
+
+    // ACTION: Logged when start profile task finishes.
+    // TIME: Indicates time taken by start profile task to finish in MS.
+    PROVISIONING_START_PROFILE_TASK_MS = 621;
+
+    // ACTION: Logged when download package task finishes.
+    // TIME: Indicates time taken by download package task to finish in MS.
+    PROVISIONING_DOWNLOAD_PACKAGE_TASK_MS = 622;
+
+    // ACTION: Logged when install package task finishes.
+    // TIME: Indicates time taken by install package task to finish in MS.
+    PROVISIONING_INSTALL_PACKAGE_TASK_MS = 623;
+
+    // ACTION: User cancelled provisioning.
+    PROVISIONING_CANCELLED = 624;
+
+    // ACTION: Logged when provisioning throws an error.
+    PROVISIONING_ERROR = 625;
+
+    // ACTION: Logs the status of copying user account during provisioning.
+    PROVISIONING_COPY_ACCOUNT_STATUS = 626;
+
+    // ACTION: Logs the end to end time taken by all provisioning tasks.
+    PROVISIONING_TOTAL_TASK_TIME_MS = 627;
+
     // ---- End O Constants, all O constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
new file mode 100644
index 0000000..9416ac1
--- /dev/null
+++ b/proto/src/wifi.proto
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+syntax = "proto2";
+
+package clearcut.connectivity;
+
+option java_package = "com.android.server.wifi";
+option java_outer_classname = "WifiMetricsProto";
+
+// The information about the Wifi events.
+message WifiLog {
+
+  // Session information that gets logged for every Wifi connection.
+  repeated ConnectionEvent connection_event = 1;
+
+  // Number of saved networks in the user profile.
+  optional int32 num_saved_networks = 2;
+
+  // Number of open networks in the saved networks.
+  optional int32 num_open_networks = 3;
+
+  // Number of personal networks.
+  optional int32 num_personal_networks = 4;
+
+  // Number of enterprise networks.
+  optional int32 num_enterprise_networks = 5;
+
+  // Does the user have location setting enabled.
+  optional bool is_location_enabled = 6;
+
+  // Does the user have scanning enabled.
+  optional bool is_scanning_always_enabled = 7;
+
+  // Number of times user toggled wifi using the settings menu.
+  optional int32 num_wifi_toggled_via_settings = 8;
+
+  // Number of times user toggled wifi using the airplane menu.
+  optional int32 num_wifi_toggled_via_airplane = 9;
+
+  // Number of networks added by the user.
+  optional int32 num_networks_added_by_user = 10;
+
+  // Number of networks added by applications.
+  optional int32 num_networks_added_by_apps = 11;
+
+  // Number scans that returned empty results.
+  optional int32 num_empty_scan_results = 12;
+
+  // Number scans that returned at least one result.
+  optional int32 num_non_empty_scan_results = 13;
+
+  // Number of scans that were one time.
+  optional int32 num_oneshot_scans = 14;
+
+  // Number of repeated background scans that were scheduled to the chip.
+  optional int32 num_background_scans = 15;
+
+  // Error codes that a scan can result in.
+  enum ScanReturnCode {
+
+    // Return Code is unknown.
+    SCAN_UNKNOWN = 0;
+
+    // Scan was successful.
+    SCAN_SUCCESS = 1;
+
+    // Scan was successfully started, but was interrupted.
+    SCAN_FAILURE_INTERRUPTED = 2;
+
+    //  Scan failed to start because of invalid configuration
+    //  (bad channel, etc).
+    SCAN_FAILURE_INVALID_CONFIGURATION = 3;
+
+    // Could not start a scan because wifi is disabled.
+    FAILURE_WIFI_DISABLED = 4;
+
+  }
+
+  // Mapping of error codes to the number of times that scans resulted
+  // in that error.
+  repeated ScanReturnEntry scan_return_entries = 16;
+
+  message ScanReturnEntry {
+
+     // Return code of the scan.
+     optional ScanReturnCode scan_return_code = 1;
+
+     // Number of entries that were found in the scan.
+     optional int32 scan_results_count = 2;
+  }
+
+  // State of the Wifi.
+  enum WifiState {
+
+    // State is unknown.
+    WIFI_UNKNOWN = 0;
+
+    // Wifi is disabled.
+    WIFI_DISABLED = 1;
+
+    // Wifi is enabled.
+    WIFI_DISCONNECTED = 2;
+
+    // Wifi is enabled and associated with an AP.
+    WIFI_ASSOCIATED = 3;
+  }
+
+  // Mapping of system state to the number of times that scans were requested in
+  // that state
+  repeated WifiSystemStateEntry wifi_system_state_entries = 17;
+
+  message WifiSystemStateEntry {
+
+     // Current WiFi state.
+     optional WifiState wifi_state = 1;
+
+     // Count of scans in state.
+     optional int32 wifi_state_count = 2;
+
+     // Is screen on.
+     optional bool is_screen_on = 3;
+  }
+
+  // Mapping of Error/Success codes to the number of background scans that resulted in it
+  repeated ScanReturnEntry background_scan_return_entries = 18;
+
+  // Mapping of system state to the number of times that Background scans were requested in that
+  // state
+  repeated WifiSystemStateEntry background_scan_request_state = 19;
+
+  // Total number of times the Watchdog of Last Resort triggered, resetting the wifi stack
+  optional int32 num_last_resort_watchdog_triggers = 20;
+
+  // Total number of networks over bad association threshold when watchdog triggered
+  optional int32 num_last_resort_watchdog_bad_association_networks_total = 21;
+
+  // Total number of networks over bad authentication threshold when watchdog triggered
+  optional int32 num_last_resort_watchdog_bad_authentication_networks_total = 22;
+
+  // Total number of networks over bad dhcp threshold when watchdog triggered
+  optional int32 num_last_resort_watchdog_bad_dhcp_networks_total = 23;
+
+  // Total number of networks over bad other threshold when watchdog triggered
+  optional int32 num_last_resort_watchdog_bad_other_networks_total = 24;
+
+  // Total count of networks seen when watchdog triggered
+  optional int32 num_last_resort_watchdog_available_networks_total = 25;
+
+  // Total count of triggers with atleast one bad association network
+  optional int32 num_last_resort_watchdog_triggers_with_bad_association = 26;
+
+  // Total count of triggers with atleast one bad authentication network
+  optional int32 num_last_resort_watchdog_triggers_with_bad_authentication = 27;
+
+  // Total count of triggers with atleast one bad dhcp network
+  optional int32 num_last_resort_watchdog_triggers_with_bad_dhcp = 28;
+
+  // Total count of triggers with atleast one bad other network
+  optional int32 num_last_resort_watchdog_triggers_with_bad_other = 29;
+
+  // Count of times connectivity watchdog confirmed pno is working
+  optional int32 num_connectivity_watchdog_pno_good = 30;
+
+  // Count of times connectivity watchdog found pno not working
+  optional int32 num_connectivity_watchdog_pno_bad = 31;
+
+  // Count of times connectivity watchdog confirmed background scan is working
+  optional int32 num_connectivity_watchdog_background_good = 32;
+
+  // Count of times connectivity watchdog found background scan not working
+  optional int32 num_connectivity_watchdog_background_bad = 33;
+
+  // The time duration represented by this wifi log, from start to end of capture
+  optional int32 record_duration_sec = 34;
+
+  // Counts the occurrences of each individual RSSI poll level
+  repeated RssiPollCount rssi_poll_rssi_count = 35;
+
+  // Total number of times WiFi connected immediately after a Last Resort Watchdog trigger,
+  // without new networks becoming available.
+  optional int32 num_last_resort_watchdog_successes = 36;
+
+  // Total number of saved hidden networks
+  optional int32 num_hidden_networks = 37;
+
+  // Total number of saved passpoint / hotspot 2.0 networks
+  optional int32 num_passpoint_networks = 38;
+
+  // Total number of scan results
+  optional int32 num_total_scan_results = 39;
+
+  // Total number of scan results for open networks
+  optional int32 num_open_network_scan_results = 40;
+
+  // Total number of scan results for personal networks
+  optional int32 num_personal_network_scan_results = 41;
+
+  // Total number of scan results for enterprise networks
+  optional int32 num_enterprise_network_scan_results = 42;
+
+  // Total number of scan results for hidden networks
+  optional int32 num_hidden_network_scan_results = 43;
+
+  // Total number of scan results for hotspot 2.0 r1 networks
+  optional int32 num_hotspot2_r1_network_scan_results = 44;
+
+  // Total number of scan results for hotspot 2.0 r2 networks
+  optional int32 num_hotspot2_r2_network_scan_results = 45;
+
+  // Total number of scans handled by framework (oneshot or otherwise)
+  optional int32 num_scans = 46;
+
+  // Counts the occurrences of each alert reason.
+  repeated AlertReasonCount alert_reason_count = 47;
+
+  // Counts the occurrences of each Wifi score
+  repeated WifiScoreCount wifi_score_count = 48;
+
+  // Histogram of Soft AP Durations
+  repeated SoftApDurationBucket soft_ap_duration = 49;
+
+  // Histogram of Soft AP ReturnCode
+  repeated SoftApReturnCodeCount soft_ap_return_code = 50;
+
+  // Histogram of the delta between scan result RSSI and RSSI polls
+  repeated RssiPollCount rssi_poll_delta_count = 51;
+}
+
+// Information that gets logged for every WiFi connection.
+message RouterFingerPrint {
+
+  enum RoamType {
+
+    // Type is unknown.
+    ROAM_TYPE_UNKNOWN = 0;
+
+    // No roaming - usually happens on a single band (2.4 GHz) router.
+    ROAM_TYPE_NONE = 1;
+
+    // Enterprise router.
+    ROAM_TYPE_ENTERPRISE = 2;
+
+    // DBDC => Dual Band Dual Concurrent essentially a router that
+    // supports both 2.4 GHz and 5 GHz bands.
+    ROAM_TYPE_DBDC = 3;
+  }
+
+  enum Auth {
+
+    // Auth is unknown.
+    AUTH_UNKNOWN = 0;
+
+    // No authentication.
+    AUTH_OPEN = 1;
+
+    // If the router uses a personal authentication.
+    AUTH_PERSONAL = 2;
+
+    // If the router is setup for enterprise authentication.
+    AUTH_ENTERPRISE = 3;
+  }
+
+  enum RouterTechnology {
+
+    // Router is unknown.
+    ROUTER_TECH_UNKNOWN = 0;
+
+    // Router Channel A.
+    ROUTER_TECH_A = 1;
+
+    // Router Channel B.
+    ROUTER_TECH_B = 2;
+
+    // Router Channel G.
+    ROUTER_TECH_G = 3;
+
+    // Router Channel N.
+    ROUTER_TECH_N = 4;
+
+    // Router Channel AC.
+    ROUTER_TECH_AC = 5;
+
+    // When the channel is not one of the above.
+    ROUTER_TECH_OTHER = 6;
+  }
+
+  optional RoamType roam_type = 1;
+
+  // Channel on which the connection takes place.
+  optional int32 channel_info = 2;
+
+  // DTIM setting of the router.
+  optional int32 dtim = 3;
+
+  // Authentication scheme of the router.
+  optional Auth authentication = 4;
+
+  // If the router is hidden.
+  optional bool hidden = 5;
+
+  // Channel information.
+  optional RouterTechnology router_technology = 6;
+
+  // whether ipv6 is supported.
+  optional bool supports_ipv6 = 7;
+
+  // If the router is a passpoint / hotspot 2.0 network
+  optional bool passpoint = 8;
+}
+
+message ConnectionEvent {
+
+  // Roam Type.
+  enum RoamType {
+
+    // Type is unknown.
+    ROAM_UNKNOWN = 0;
+
+    // No roaming.
+    ROAM_NONE  = 1;
+
+    // DBDC roaming.
+    ROAM_DBDC = 2;
+
+    // Enterprise roaming.
+    ROAM_ENTERPRISE = 3;
+
+    // User selected roaming.
+    ROAM_USER_SELECTED = 4;
+
+    // Unrelated.
+    ROAM_UNRELATED = 5;
+  }
+
+  // Connectivity Level Failure.
+  enum ConnectivityLevelFailure {
+
+    // Failure is unknown.
+    HLF_UNKNOWN = 0;
+
+    // No failure.
+    HLF_NONE = 1;
+
+    // DHCP failure.
+    HLF_DHCP = 2;
+
+    // No internet connection.
+    HLF_NO_INTERNET = 3;
+
+    // No internet connection.
+    HLF_UNWANTED = 4;
+  }
+
+  // Start time of the connection.
+  optional int64 start_time_millis = 1;// [(datapol.semantic_type) = ST_TIMESTAMP];
+
+  // Duration to connect.
+  optional int32 duration_taken_to_connect_millis = 2;
+
+  // Router information.
+  optional RouterFingerPrint router_fingerprint = 3;
+
+  // RSSI at the start of the connection.
+  optional int32 signal_strength = 4;
+
+  // Roam Type.
+  optional RoamType roam_type = 5;
+
+  // Result of the connection.
+  optional int32 connection_result = 6;
+
+  // Reasons for level 2 failure (needs to be coordinated with wpa-supplicant).
+  optional int32 level_2_failure_code = 7;
+
+  // Failures that happen at the connectivity layer.
+  optional ConnectivityLevelFailure connectivity_level_failure_code = 8;
+
+  // Has bug report been taken.
+  optional bool automatic_bug_report_taken = 9;
+}
+
+// Number of occurrences of a specific RSSI poll rssi value
+message RssiPollCount {
+  // RSSI
+  optional int32 rssi = 1;
+
+  // Number of RSSI polls with 'rssi'
+  optional int32 count = 2;
+}
+
+// Number of occurrences of a specific alert reason value
+message AlertReasonCount {
+  // Alert reason
+  optional int32 reason = 1;
+
+  // Number of alerts with |reason|.
+  optional int32 count = 2;
+}
+
+// Counts the number of instances of a specific Wifi Score calculated by WifiScoreReport
+message WifiScoreCount {
+  // Wifi Score
+  optional int32 score = 1;
+
+  // Number of Wifi score reports with this score
+  optional int32 count = 2;
+}
+
+// Number of occurrences of Soft AP session durations
+message SoftApDurationBucket {
+  // Bucket covers duration : [duration_sec, duration_sec + bucket_size_sec)
+  // The (inclusive) lower bound of Soft AP session duration represented by this bucket
+  optional int32 duration_sec = 1;
+
+  // The size of this bucket
+  optional int32 bucket_size_sec = 2;
+
+  // Number of soft AP session durations that fit into this bucket
+  optional int32 count = 3;
+}
+
+// Number of occurrences of a soft AP session return code
+message SoftApReturnCodeCount {
+  // Return code of the soft AP session
+  optional int32 return_code = 1;
+
+  // Occurrences of this soft AP return code
+  optional int32 count = 2;
+}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 9d3035a..6375e9a 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -3983,7 +3983,7 @@
     boolean deviceIsEncrypted() {
         try {
             return mMountService.getEncryptionState()
-                     != IMountService.ENCRYPTION_STATE_NONE
+                     != StorageManager.ENCRYPTION_STATE_NONE
                 && mMountService.getPasswordType()
                      != StorageManager.CRYPT_TYPE_DEFAULT;
         } catch (Exception e) {
diff --git a/services/core/Android.mk b/services/core/Android.mk
index 9efafb7..11586ee 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -8,7 +8,6 @@
 
 LOCAL_SRC_FILES += \
     $(call all-java-files-under,java) \
-    $(call all-proto-files-under, proto) \
     java/com/android/server/EventLogTags.logtags \
     java/com/android/server/am/EventLogTags.logtags \
     ../../../../system/netd/server/binder/android/net/INetd.aidl \
@@ -24,7 +23,6 @@
     android.hardware.light@2.0-java
 
 LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
 
 ifneq ($(INCREMENTAL_BUILDS),)
     LOCAL_PROGUARD_ENABLED := disabled
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 067f932..6456048 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -222,6 +222,7 @@
                                 mBluetoothLock.readLock().lock();
                                 if (mBluetooth != null) {
                                     mBluetooth.onBrEdrDown();
+                                    mEnable = false;
                                     mEnableExternal = false;
                                 }
                             } catch (RemoteException e) {
@@ -458,14 +459,16 @@
 
     class ClientDeathRecipient implements IBinder.DeathRecipient {
         public void binderDied() {
-            if (DBG) Slog.d(TAG, "Binder is dead -  unregister Ble App");
+            if (DBG) Slog.d(TAG, "Binder is dead - unregister Ble App");
             if (mBleAppCount > 0) --mBleAppCount;
 
             if (mBleAppCount == 0) {
                 if (DBG) Slog.d(TAG, "Disabling LE only mode after application crash");
                 try {
                     mBluetoothLock.readLock().lock();
-                    if (mBluetooth != null) {
+                    if (mBluetooth != null &&
+                        mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) {
+                        mEnable = false;
                         mBluetooth.onBrEdrDown();
                     }
                 } catch (RemoteException e) {
@@ -482,6 +485,9 @@
 
     @Override
     public boolean isBleScanAlwaysAvailable() {
+        if (isAirplaneModeOn() && !mEnable) {
+            return false;
+        }
         try {
             return (Settings.Global.getInt(mContentResolver,
                     Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE)) != 0;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 8883c4b..de70026 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -132,6 +132,7 @@
 import com.android.server.am.BatteryStatsService;
 import com.android.server.connectivity.DataConnectionStats;
 import com.android.server.connectivity.KeepaliveTracker;
+import com.android.server.connectivity.MockableSystemProperties;
 import com.android.server.connectivity.Nat464Xlat;
 import com.android.server.connectivity.LingerMonitor;
 import com.android.server.connectivity.NetworkAgentInfo;
@@ -815,7 +816,8 @@
         mTestMode = SystemProperties.get("cm.test.mode").equals("true")
                 && SystemProperties.get("ro.build.type").equals("eng");
 
-        mTethering = new Tethering(mContext, mNetd, statsService, mPolicyManager);
+        mTethering = new Tethering(mContext, mNetd, statsService, mPolicyManager,
+                                   IoThread.get().getLooper(), new MockableSystemProperties());
 
         mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
 
diff --git a/services/core/java/com/android/server/DockObserver.java b/services/core/java/com/android/server/DockObserver.java
index 07aa5656..122074b 100644
--- a/services/core/java/com/android/server/DockObserver.java
+++ b/services/core/java/com/android/server/DockObserver.java
@@ -167,10 +167,17 @@
             intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
             intent.putExtra(Intent.EXTRA_DOCK_STATE, mReportedDockState);
 
+            boolean dockSoundsEnabled = Settings.Global.getInt(cr,
+                    Settings.Global.DOCK_SOUNDS_ENABLED, 1) == 1;
+            boolean dockSoundsEnabledWhenAccessibility = Settings.Global.getInt(cr,
+                    Settings.Global.DOCK_SOUNDS_ENABLED_WHEN_ACCESSIBILITY, 1) == 1;
+            boolean accessibilityEnabled = Settings.Secure.getInt(cr,
+                    Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
+
             // Play a sound to provide feedback to confirm dock connection.
             // Particularly useful for flaky contact pins...
-            if (Settings.Global.getInt(cr,
-                    Settings.Global.DOCK_SOUNDS_ENABLED, 1) == 1) {
+            if ((dockSoundsEnabled) ||
+                   (accessibilityEnabled && dockSoundsEnabledWhenAccessibility)) {
                 String whichSound = null;
                 if (mReportedDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
                     if ((previousDockState == Intent.EXTRA_DOCK_STATE_DESK) ||
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index b9a4831..8bb9326 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -46,6 +46,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.content.res.ObbInfo;
+import android.net.TrafficStats;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.DropBoxManager;
@@ -86,6 +87,7 @@
 import android.util.ArrayMap;
 import android.util.AtomicFile;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.util.Xml;
@@ -2535,11 +2537,11 @@
         } catch (NumberFormatException e) {
             // Bad result - unexpected.
             Slog.w(TAG, "Unable to parse result from cryptfs cryptocomplete");
-            return ENCRYPTION_STATE_ERROR_UNKNOWN;
+            return StorageManager.ENCRYPTION_STATE_ERROR_UNKNOWN;
         } catch (NativeDaemonConnectorException e) {
             // Something bad happened.
             Slog.w(TAG, "Error in communicating with cryptfs in validating");
-            return ENCRYPTION_STATE_ERROR_UNKNOWN;
+            return StorageManager.ENCRYPTION_STATE_ERROR_UNKNOWN;
         }
     }
 
@@ -3738,6 +3740,18 @@
 
             pw.println();
             pw.println("Primary storage UUID: " + mPrimaryStorageUuid);
+            final Pair<String, Long> pair = StorageManager.getPrimaryStoragePathAndSize();
+            if (pair == null) {
+                pw.println("Internal storage total size: N/A");
+            } else {
+                pw.print("Internal storage (");
+                pw.print(pair.first);
+                pw.print(") total size: ");
+                pw.print(pair.second);
+                pw.print(" (");
+                pw.print((float) pair.second / TrafficStats.GB_IN_BYTES);
+                pw.println(" GB)");
+            }
             pw.println("Force adoptable: " + mForceAdoptable);
             pw.println();
             pw.println("Local unlocked users: " + Arrays.toString(mLocalUnlockedUsers));
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index bb5f62b..2825cf9 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -466,9 +466,8 @@
         if (mCarModeEnabled) {
             if (mLastBroadcastState != Intent.EXTRA_DOCK_STATE_CAR) {
                 adjustStatusBarCarModeLocked();
-
                 if (oldAction != null) {
-                    getContext().sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL);
+                    sendForegroundBroadcastToAllUsers(oldAction);
                 }
                 mLastBroadcastState = Intent.EXTRA_DOCK_STATE_CAR;
                 action = UiModeManager.ACTION_ENTER_CAR_MODE;
@@ -476,7 +475,7 @@
         } else if (isDeskDockState(mDockState)) {
             if (!isDeskDockState(mLastBroadcastState)) {
                 if (oldAction != null) {
-                    getContext().sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL);
+                    sendForegroundBroadcastToAllUsers(oldAction);
                 }
                 mLastBroadcastState = mDockState;
                 action = UiModeManager.ACTION_ENTER_DESK_MODE;
@@ -502,6 +501,7 @@
             Intent intent = new Intent(action);
             intent.putExtra("enableFlags", enableFlags);
             intent.putExtra("disableFlags", disableFlags);
+            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
             getContext().sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
                     mResultReceiver, null, Activity.RESULT_OK, null, null);
 
@@ -550,6 +550,11 @@
         }
     }
 
+    private void sendForegroundBroadcastToAllUsers(String action) {
+        getContext().sendBroadcastAsUser(new Intent(action)
+                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND), UserHandle.ALL);
+    }
+
     private void updateAfterBroadcastLocked(String action, int enableFlags, int disableFlags) {
         // Launch a dock activity
         String category = null;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1490c91..40f0aae 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18,6 +18,9 @@
 
 import android.app.ApplicationThreadConstants;
 import android.os.IDeviceIdentifiersPolicyService;
+import android.util.Size;
+import android.util.TypedValue;
+import android.view.DisplayInfo;
 import com.android.internal.telephony.TelephonyIntents;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
@@ -73,6 +76,7 @@
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManager.StackId;
 import android.app.ActivityManager.StackInfo;
+import android.app.ActivityManager.TaskDescription;
 import android.app.ActivityManager.TaskThumbnailInfo;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerInternal.SleepToken;
@@ -216,7 +220,6 @@
 import android.util.SparseArray;
 import android.util.TimeUtils;
 import android.util.Xml;
-import android.view.Display;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -253,6 +256,7 @@
 import libcore.io.IoUtils;
 import libcore.util.EmptyArray;
 
+import static android.Manifest.permission.CHANGE_CONFIGURATION;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
@@ -276,6 +280,7 @@
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
+import static android.os.Build.VERSION_CODES.N;
 import static android.os.Process.PROC_CHAR;
 import static android.os.Process.PROC_OUT_LONG;
 import static android.os.Process.PROC_PARENS;
@@ -288,6 +293,9 @@
 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
 import static android.provider.Settings.System.FONT_SCALE;
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+import static android.view.Display.DEFAULT_DISPLAY;
+
 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
 import static com.android.internal.util.XmlUtils.readIntAttribute;
 import static com.android.internal.util.XmlUtils.readLongAttribute;
@@ -517,9 +525,6 @@
     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
     static final int ALLOW_FULL_ONLY = 2;
 
-    // Delay in notifying task stack change listeners (in millis)
-    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
-
     // Necessary ApplicationInfo flags to mark an app as persistent
     private static final int PERSISTENT_MASK =
             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
@@ -547,9 +552,7 @@
 
     final ActivityStarter mActivityStarter;
 
-    /** Task stack change listeners. */
-    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
-            new RemoteCallbackList<ITaskStackListener>();
+    final TaskChangeNotificationController mTaskChangeNotificationController;
 
     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
 
@@ -1125,10 +1128,11 @@
     private int mConfigurationSeq;
 
     /**
-     * Temp object used when global configuration is updated. It is also sent to outer world
-     * instead of {@link #getGlobalConfiguration} because we don't trust anyone...
+     * Temp object used when global and/or display override configuration is updated. It is also
+     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
+     * anyone...
      */
-    private Configuration mTempGlobalConfig = new Configuration();
+    private Configuration mTempConfig = new Configuration();
 
     private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
             new UpdateConfigurationResult();
@@ -1369,7 +1373,6 @@
     boolean mSupportsFreeformWindowManagement;
     boolean mSupportsPictureInPicture;
     boolean mSupportsLeanbackOnly;
-    Rect mDefaultPinnedStackBounds;
     IActivityController mController = null;
     boolean mControllerIsAMonkey = false;
     String mProfileApp = null;
@@ -1513,29 +1516,23 @@
     static final int START_USER_SWITCH_UI_MSG = 46;
     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
     static final int DISMISS_DIALOG_UI_MSG = 48;
-    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
-    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
-    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
-    static final int DELETE_DUMPHEAP_MSG = 52;
-    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
-    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
-    static final int REPORT_TIME_TRACKER_MSG = 55;
-    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
-    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
-    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
-    static final int IDLE_UIDS_MSG = 60;
-    static final int SYSTEM_USER_UNLOCK_MSG = 61;
-    static final int LOG_STACK_STATE = 62;
-    static final int VR_MODE_CHANGE_MSG = 63;
-    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
-    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
-    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
-    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
-    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
-    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
-    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
-    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 71;
-    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 72;
+    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
+    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
+    static final int DELETE_DUMPHEAP_MSG = 51;
+    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
+    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
+    static final int REPORT_TIME_TRACKER_MSG = 54;
+    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
+    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
+    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
+    static final int IDLE_UIDS_MSG = 58;
+    static final int SYSTEM_USER_UNLOCK_MSG = 59;
+    static final int LOG_STACK_STATE = 60;
+    static final int VR_MODE_CHANGE_MSG = 61;
+    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 62;
+    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 63;
+    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 64;
+    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 65;
     static final int START_USER_SWITCH_FG_MSG = 712;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
@@ -2092,92 +2089,6 @@
                 }
                 break;
             }
-            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
-                synchronized (ActivityManagerService.this) {
-                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
-                        try {
-                            // Make a one-way callback to the listener
-                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
-                        } catch (RemoteException e){
-                            // Handled by the RemoteCallbackList
-                        }
-                    }
-                    mTaskStackListeners.finishBroadcast();
-                }
-                break;
-            }
-            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
-                synchronized (ActivityManagerService.this) {
-                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
-                        try {
-                            // Make a one-way callback to the listener
-                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
-                        } catch (RemoteException e){
-                            // Handled by the RemoteCallbackList
-                        }
-                    }
-                    mTaskStackListeners.finishBroadcast();
-                }
-                break;
-            }
-            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
-                synchronized (ActivityManagerService.this) {
-                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
-                        try {
-                            // Make a one-way callback to the listener
-                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
-                        } catch (RemoteException e){
-                            // Handled by the RemoteCallbackList
-                        }
-                    }
-                    mTaskStackListeners.finishBroadcast();
-                }
-                break;
-            }
-            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
-                synchronized (ActivityManagerService.this) {
-                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
-                        try {
-                            // Make a one-way callback to the listener
-                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
-                        } catch (RemoteException e){
-                            // Handled by the RemoteCallbackList
-                        }
-                    }
-                    mTaskStackListeners.finishBroadcast();
-                }
-                break;
-            }
-            case NOTIFY_FORCED_RESIZABLE_MSG: {
-                synchronized (ActivityManagerService.this) {
-                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
-                        try {
-                            // Make a one-way callback to the listener
-                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
-                                    (String) msg.obj, msg.arg1);
-                        } catch (RemoteException e){
-                            // Handled by the RemoteCallbackList
-                        }
-                    }
-                    mTaskStackListeners.finishBroadcast();
-                }
-                break;
-            }
-                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
-                    synchronized (ActivityManagerService.this) {
-                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
-                            try {
-                                // Make a one-way callback to the listener
-                                mTaskStackListeners.getBroadcastItem(i)
-                                        .onActivityDismissingDockedStack();
-                            } catch (RemoteException e){
-                                // Handled by the RemoteCallbackList
-                            }
-                        }
-                        mTaskStackListeners.finishBroadcast();
-                    }
-                    break;
-                }
             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
                 final int uid = msg.arg1;
                 final byte[] firstPacket = (byte[]) msg.obj;
@@ -2309,11 +2220,6 @@
             case IDLE_UIDS_MSG: {
                 idleUids();
             } break;
-            case LOG_STACK_STATE: {
-                synchronized (ActivityManagerService.this) {
-                    mStackSupervisor.logStackState();
-                }
-            } break;
             case VR_MODE_CHANGE_MSG: {
                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
                 if (vrService == null) {
@@ -2707,16 +2613,18 @@
 
         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
 
-        mTempGlobalConfig.setToDefaults();
-        mTempGlobalConfig.setLocales(LocaleList.getDefault());
-        mConfigurationSeq = mTempGlobalConfig.seq = 1;
+        mTempConfig.setToDefaults();
+        mTempConfig.setLocales(LocaleList.getDefault());
+        mConfigurationSeq = mTempConfig.seq = 1;
 
         mProcessCpuTracker.init();
 
         mStackSupervisor = new ActivityStackSupervisor(this);
-        mStackSupervisor.onConfigurationChanged(mTempGlobalConfig);
+        mStackSupervisor.onConfigurationChanged(mTempConfig);
         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
+        mTaskChangeNotificationController =
+                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
         mRecentTasks = new RecentTasks(this, mStackSupervisor);
 
@@ -3091,13 +2999,18 @@
     @Override
     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
-        synchronized (this) {
-            if (listener != null) {
-                mTaskStackListeners.register(listener);
-            }
-        }
+        mTaskChangeNotificationController.registerTaskStackListener(listener);
     }
 
+    /**
+     * Unregister a task stack listener so that it stops receiving callbacks.
+     */
+    @Override
+    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
+         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
+         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
+     }
+
     @Override
     public void notifyActivityDrawn(IBinder token) {
         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
@@ -4059,7 +3972,7 @@
     @Override
     public int getPackageProcessState(String packageName, String callingPackage) {
         if (!hasUsageStatsPermission(callingPackage)) {
-            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
+            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
                     "getPackageProcessState");
         }
 
@@ -4069,20 +3982,12 @@
                 final ProcessRecord proc = mLruProcesses.get(i);
                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
                         || procState > proc.setProcState) {
-                    boolean found = false;
-                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
-                        if (proc.pkgList.keyAt(j).equals(packageName)) {
-                            procState = proc.setProcState;
-                            found = true;
-                        }
+                    if (proc.pkgList.containsKey(packageName)) {
+                        procState = proc.setProcState;
+                        break;
                     }
-                    if (proc.pkgDeps != null && !found) {
-                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
-                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
-                                procState = proc.setProcState;
-                                break;
-                            }
-                        }
+                    if (proc.pkgDeps != null && proc.pkgDeps.contains(packageName)) {
+                        procState = proc.setProcState;
                     }
                 }
             }
@@ -4199,18 +4104,6 @@
                     "*** Delivering " + N + " uid changes");
         }
 
-        if (mLocalPowerManager != null) {
-            for (int j=0; j<N; j++) {
-                UidRecord.ChangeItem item = mActiveUidChanges[j];
-                if (item.change == UidRecord.CHANGE_GONE
-                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
-                    mLocalPowerManager.uidGone(item.uid);
-                } else {
-                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
-                }
-            }
-        }
-
         int i = mUidObservers.beginBroadcast();
         while (i > 0) {
             i--;
@@ -4752,23 +4645,12 @@
             if (r == null) {
                 return;
             }
-            TaskRecord task = r.task;
-            if (task != null && (!task.mFullscreen || !task.getStack().mFullscreen)) {
-                // Fixed screen orientation isn't supported when activities aren't in full screen
-                // mode.
-                return;
-            }
             final long origId = Binder.clearCallingIdentity();
-            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
-            Configuration config = mWindowManager.updateOrientationFromAppTokens(
-                    getGlobalConfiguration(), r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
-            if (config != null) {
-                r.frozenBeforeDestroy = true;
-                if (!updateConfigurationLocked(config, r, false)) {
-                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
-                }
+            try {
+                r.setRequestedOrientation(requestedOrientation);
+            } finally {
+                Binder.restoreCallingIdentity(origId);
             }
-            Binder.restoreCallingIdentity(origId);
         }
     }
 
@@ -7595,7 +7477,8 @@
                 // current bounds.
                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
                 final Rect bounds = (pinnedStack != null)
-                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
+                        ? pinnedStack.mBounds
+                        : mWindowManager.getPictureInPictureDefaultBounds(DEFAULT_DISPLAY);
 
                 mStackSupervisor.moveActivityToPinnedStackLocked(
                         r, "enterPictureInPictureMode", bounds);
@@ -7692,7 +7575,8 @@
             try {
                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
                         .getPermissionInfo(permission, 0);
-                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
+                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
+                        == PermissionInfo.PROTECTION_DANGEROUS;
             } catch (NameNotFoundException nnfe) {
                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
             }
@@ -9350,7 +9234,6 @@
 
                 task.setLastThumbnailLocked(thumbnail);
                 task.freeLastThumbnail();
-
                 return task.taskId;
             }
         } finally {
@@ -9372,6 +9255,7 @@
             if (r != null) {
                 r.setTaskDescription(td);
                 r.task.updateTaskDescription();
+                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
             }
         }
     }
@@ -9783,14 +9667,6 @@
     }
 
     @Override
-    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
-        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
-        synchronized (this) {
-            mStackSupervisor.deleteActivityContainer(container);
-        }
-    }
-
-    @Override
     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
         synchronized (this) {
@@ -9811,7 +9687,7 @@
             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
                 return stack.mActivityContainer.getDisplayId();
             }
-            return Display.DEFAULT_DISPLAY;
+            return DEFAULT_DISPLAY;
         }
     }
 
@@ -11661,38 +11537,10 @@
         mRecentTasks.notifyTaskPersisterLocked(task, flush);
     }
 
-    /** Notifies all listeners when the task stack has changed. */
-    void notifyTaskStackChangedLocked() {
-        mHandler.sendEmptyMessage(LOG_STACK_STATE);
-        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
-        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
-        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
-    }
-
-    /** Notifies all listeners when an Activity is pinned. */
-    void notifyActivityPinnedLocked() {
-        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
-        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
-    }
-
-    /**
-     * Notifies all listeners when an attempt was made to start an an activity that is already
-     * running in the pinned stack and the activity was not actually started, but the task is
-     * either brought to the front or a new Intent is delivered to it.
-     */
-    void notifyPinnedActivityRestartAttemptLocked() {
-        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
-        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
-    }
-
     /** Notifies all listeners when the pinned stack animation ends. */
     @Override
     public void notifyPinnedStackAnimationEnded() {
-        synchronized (this) {
-            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
-            mHandler.obtainMessage(
-                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
-        }
+        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
     }
 
     @Override
@@ -13151,7 +12999,6 @@
             mLenientBackgroundCheck = lenientBackgroundCheck;
             mSupportsLeanbackOnly = supportsLeanbackOnly;
             mForceResizableActivities = forceResizable;
-            mWindowManager.setForceResizableTasks(mForceResizableActivities);
             if (supportsMultiWindow || forceResizable) {
                 mSupportsMultiWindow = true;
                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
@@ -13161,6 +13008,8 @@
                 mSupportsFreeformWindowManagement = false;
                 mSupportsPictureInPicture = false;
             }
+            mWindowManager.setForceResizableTasks(mForceResizableActivities);
+            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
             // This happens before any activities are started, so we can change global configuration
             // in-place.
             updateConfigurationLocked(configuration, null, true);
@@ -13174,8 +13023,6 @@
                     com.android.internal.R.dimen.thumbnail_width);
             mThumbnailHeight = res.getDimensionPixelSize(
                     com.android.internal.R.dimen.thumbnail_height);
-            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
-                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
                     com.android.internal.R.string.config_appsNotReportingCrashes));
             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
@@ -14779,6 +14626,7 @@
         }
         if (dumpPackage == null) {
             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
+            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
         }
         if (dumpAll) {
             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
@@ -18841,8 +18689,7 @@
 
     @Override
     public void updatePersistentConfiguration(Configuration values) {
-        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
-                "updatePersistentConfiguration()");
+        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
         enforceWriteSettingsPermission("updatePersistentConfiguration()");
         if (values == null) {
             throw new NullPointerException("Configuration must not be null");
@@ -18867,12 +18714,16 @@
     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
                 FONT_SCALE, 1.0f, userId);
-        if (getGlobalConfiguration().fontScale != scaleFactor) {
-            final Configuration configuration = mWindowManager.computeNewConfiguration();
-            configuration.fontScale = scaleFactor;
-            synchronized (this) {
-                updatePersistentConfigurationLocked(configuration, userId);
+
+        synchronized (this) {
+            if (getGlobalConfiguration().fontScale == scaleFactor) {
+                return;
             }
+
+            final Configuration configuration
+                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
+            configuration.fontScale = scaleFactor;
+            updatePersistentConfigurationLocked(configuration, userId);
         }
     }
 
@@ -18897,21 +18748,20 @@
 
     @Override
     public boolean updateConfiguration(Configuration values) {
-        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
-                "updateConfiguration()");
+        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
 
         synchronized(this) {
             if (values == null && mWindowManager != null) {
                 // sentinel: fetch the current configuration from the window manager
-                values = mWindowManager.computeNewConfiguration();
+                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
             }
 
             if (mWindowManager != null) {
+                // Update OOM levels based on display size.
                 mProcessList.applyDisplaySize(mWindowManager);
             }
 
             final long origId = Binder.clearCallingIdentity();
-
             try {
                 if (values != null) {
                     Settings.System.clearConfiguration(values);
@@ -18998,8 +18848,8 @@
     /** Update default (global) configuration and notify listeners about changes. */
     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
             boolean persistent, int userId, boolean deferResume) {
-        mTempGlobalConfig.setTo(getGlobalConfiguration());
-        final int changes = mTempGlobalConfig.updateFrom(values);
+        mTempConfig.setTo(getGlobalConfiguration());
+        final int changes = mTempConfig.updateFrom(values);
         if (changes == 0) {
             return 0;
         }
@@ -19026,33 +18876,33 @@
         }
 
         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
-        mTempGlobalConfig.seq = mConfigurationSeq;
+        mTempConfig.seq = mConfigurationSeq;
 
         // Update stored global config and notify everyone about the change.
-        mStackSupervisor.onConfigurationChanged(mTempGlobalConfig);
+        mStackSupervisor.onConfigurationChanged(mTempConfig);
 
-        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempGlobalConfig);
+        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
         // TODO(multi-display): Update UsageEvents#Event to include displayId.
-        mUsageStatsService.reportConfigurationChange(mTempGlobalConfig,
+        mUsageStatsService.reportConfigurationChange(mTempConfig,
                 mUserController.getCurrentUserIdLocked());
 
         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
-        mShowDialogs = shouldShowDialogs(mTempGlobalConfig, mInVrMode);
+        mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode);
 
         AttributeCache ac = AttributeCache.instance();
         if (ac != null) {
-            ac.updateConfiguration(mTempGlobalConfig);
+            ac.updateConfiguration(mTempConfig);
         }
 
         // Make sure all resources in our process are updated right now, so that anyone who is going
         // to retrieve resource values after we return will be sure to get the new ones. This is
         // especially important during boot, where the first config change needs to guarantee all
         // resources have that config before following boot code is executed.
-        mSystemThread.applyConfigurationToResources(mTempGlobalConfig);
+        mSystemThread.applyConfigurationToResources(mTempConfig);
 
         // We need another copy of global config because we're scheduling some calls instead of
         // running them in place. We need to be sure that object we send will be handled unchanged.
-        final Configuration configCopy = new Configuration(mTempGlobalConfig);
+        final Configuration configCopy = new Configuration(mTempConfig);
         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
             msg.obj = configCopy;
@@ -19060,16 +18910,6 @@
             mHandler.sendMessage(msg);
         }
 
-        // TODO(multi-display): Clear also on secondary display density change?
-        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
-        if (isDensityChange) {
-            // Reset the unsupported display size dialog.
-            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
-
-            killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
-                    ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
-        }
-
         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
             ProcessRecord app = mLruProcesses.get(i);
             try {
@@ -19099,13 +18939,116 @@
                     UserHandle.USER_ALL);
         }
 
+        // Override configuration of the default display duplicates global config, so we need to
+        // update it also. This will also notify WindowManager about changes.
+        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
+                DEFAULT_DISPLAY);
+
+        return changes;
+    }
+
+    @Override
+    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
+        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
+
+        synchronized (this) {
+            if (values == null && mWindowManager != null) {
+                // sentinel: fetch the current configuration from the window manager
+                values = mWindowManager.computeNewConfiguration(displayId);
+            }
+
+            if (mWindowManager != null) {
+                // Update OOM levels based on display size.
+                mProcessList.applyDisplaySize(mWindowManager);
+            }
+
+            final long origId = Binder.clearCallingIdentity();
+            try {
+                if (values != null) {
+                    Settings.System.clearConfiguration(values);
+                }
+                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
+                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
+                return mTmpUpdateConfigurationResult.changes != 0;
+            } finally {
+                Binder.restoreCallingIdentity(origId);
+            }
+        }
+    }
+
+    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
+            boolean deferResume, int displayId) {
+        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
+                displayId, null /* result */);
+    }
+
+    /**
+     * Updates override configuration specific for the selected display. If no config is provided,
+     * new one will be computed in WM based on current display info.
+     */
+    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
+            ActivityRecord starting, boolean deferResume, int displayId,
+            UpdateConfigurationResult result) {
+        int changes = 0;
+        boolean kept = true;
+
+        if (mWindowManager != null) {
+            mWindowManager.deferSurfaceLayout();
+        }
+        try {
+            if (values != null) {
+                if (displayId == DEFAULT_DISPLAY) {
+                    // Override configuration of the default display duplicates global config, so
+                    // we're calling global config update instead for default display. It will also
+                    // apply the correct override config.
+                    changes = updateGlobalConfiguration(values, false /* initLocale */,
+                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
+                } else {
+                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
+                }
+            }
+
+            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
+        } finally {
+            if (mWindowManager != null) {
+                mWindowManager.continueSurfaceLayout();
+            }
+        }
+
+        if (result != null) {
+            result.changes = changes;
+            result.activityRelaunched = !kept;
+        }
+        return kept;
+    }
+
+    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
+            int displayId) {
+        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
+        final int changes = mTempConfig.updateFrom(values);
+        if (changes == 0) {
+            return 0;
+        }
+
+        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
+                + " for displayId=" + displayId);
+        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
+
+        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
+        if (isDensityChange) {
+            // Reset the unsupported display size dialog.
+            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
+
+            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+        }
+
         // Update the configuration with WM first and check if any of the stacks need to be resized
         // due to the configuration change. If so, resize the stacks now and do any relaunches if
         // necessary. This way we don't need to relaunch again afterwards in
         // ensureActivityConfigurationLocked().
         if (mWindowManager != null) {
             final int[] resizedStacks =
-                    mWindowManager.setNewConfiguration(mTempGlobalConfig);
+                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
             if (resizedStacks != null) {
                 for (int stackId : resizedStacks) {
                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
@@ -20721,6 +20664,27 @@
         pendingChange.change = change;
         pendingChange.processState = uidRec != null
                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
+
+        // Directly update the power manager, since we sit on top of it and it is critical
+        // it be kept in sync (so wake locks will be held as soon as appropriate).
+        if (mLocalPowerManager != null) {
+            switch (change) {
+                case UidRecord.CHANGE_GONE:
+                case UidRecord.CHANGE_GONE_IDLE:
+                    mLocalPowerManager.uidGone(pendingChange.uid);
+                    break;
+                case UidRecord.CHANGE_IDLE:
+                    mLocalPowerManager.uidIdle(pendingChange.uid);
+                    break;
+                case UidRecord.CHANGE_ACTIVE:
+                    mLocalPowerManager.uidActive(pendingChange.uid);
+                    break;
+                default:
+                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
+                            pendingChange.processState);
+                    break;
+            }
+        }
     }
 
     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
@@ -21269,6 +21233,9 @@
         }
 
         // Update from any uid changes.
+        if (mLocalPowerManager != null) {
+            mLocalPowerManager.startUidChanges();
+        }
         for (int i=mActiveUids.size()-1; i>=0; i--) {
             final UidRecord uidRec = mActiveUids.valueAt(i);
             int uidChange = UidRecord.CHANGE_PROCSTATE;
@@ -21299,6 +21266,9 @@
                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
             }
         }
+        if (mLocalPowerManager != null) {
+            mLocalPowerManager.finishUidChanges();
+        }
 
         if (mProcessStats.shouldWriteNowLocked(now)) {
             mHandler.post(new Runnable() {
@@ -21323,10 +21293,17 @@
 
     final void idleUids() {
         synchronized (this) {
+            final int N = mActiveUids.size();
+            if (N <= 0) {
+                return;
+            }
             final long nowElapsed = SystemClock.elapsedRealtime();
             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
             long nextTime = 0;
-            for (int i=mActiveUids.size()-1; i>=0; i--) {
+            if (mLocalPowerManager != null) {
+                mLocalPowerManager.startUidChanges();
+            }
+            for (int i=N-1; i>=0; i--) {
                 final UidRecord uidRec = mActiveUids.valueAt(i);
                 final long bgTime = uidRec.lastBackgroundTime;
                 if (bgTime > 0 && !uidRec.idle) {
@@ -21340,6 +21317,9 @@
                     }
                 }
             }
+            if (mLocalPowerManager != null) {
+                mLocalPowerManager.finishUidChanges();
+            }
             if (nextTime > 0) {
                 mHandler.removeMessages(IDLE_UIDS_MSG);
                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
@@ -22305,4 +22285,29 @@
         // before the profile user is unlocked.
         return rInfo != null && rInfo.activityInfo != null;
     }
+
+    /**
+     * Attach an agent to the specified process (proces name or PID)
+     */
+    public void attachAgent(String process, String path) {
+        try {
+            synchronized (this) {
+                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
+                if (proc == null || proc.thread == null) {
+                    throw new IllegalArgumentException("Unknown process: " + process);
+                }
+
+                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
+                if (!isDebuggable) {
+                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
+                        throw new SecurityException("Process not debuggable: " + proc);
+                    }
+                }
+
+                proc.thread.attachAgent(path);
+            }
+        } catch (RemoteException e) {
+            throw new IllegalStateException("Process disappeared");
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 7d9a706..1484420 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -220,6 +220,8 @@
                     return runTask(pw);
                 case "write":
                     return runWrite(pw);
+                case "attach-agent":
+                    return runAttachAgent(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -2462,6 +2464,21 @@
         return 0;
     }
 
+    int runAttachAgent(PrintWriter pw) {
+        // TODO: revisit the permissions required for attaching agents
+        mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
+                "attach-agent");
+        String process = getNextArgRequired();
+        String agent = getNextArgRequired();
+        String opt;
+        if ((opt = getNextArg()) != null) {
+            pw.println("Error: Unknown option: " + opt);
+            return -1;
+        }
+        mInternal.attachAgent(process, agent);
+        return 0;
+    }
+
     @Override
     public void onHelp() {
         PrintWriter pw = getOutPrintWriter();
@@ -2618,6 +2635,8 @@
             pw.println("      Optionally controls lenient background check mode, returns current mode.");
             pw.println("  get-uid-state <UID>");
             pw.println("      Gets the process state of an app given its <UID>.");
+            pw.println("  attach-agent <PROCESS> <FILE>");
+            pw.println("    Attach an agent to the specified <PROCESS>, which may be either a process name or a PID.");
             pw.println("  get-config");
             pw.println("      Rtrieve the configuration and any recent configurations of the device.");
             pw.println("  suppress-resize-config-changes <true|false>");
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index b7618a1..df03af2 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -664,10 +664,18 @@
         hasBeenLaunched = false;
         mStackSupervisor = supervisor;
         mInitialActivityContainer = container;
+
+        mRotationAnimationHint = aInfo.rotationAnimation;
+
         if (options != null) {
             pendingOptions = options;
             mLaunchTaskBehind = pendingOptions.getLaunchTaskBehind();
-            mRotationAnimationHint = pendingOptions.getRotationAnimationHint();
+
+            final int rotationAnimation = pendingOptions.getRotationAnimationHint();
+            // Only override manifest supplied option if set.
+            if (rotationAnimation >= 0) {
+                mRotationAnimationHint = rotationAnimation;
+            }
             PendingIntent usageReport = pendingOptions.getUsageTimeReport();
             if (usageReport != null) {
                 appTimeTracker = new AppTimeTracker(usageReport);
@@ -932,6 +940,10 @@
             if (stopped) {
                 clearOptionsLocked();
             }
+
+            if (service != null) {
+                service.mTaskChangeNotificationController.notifyTaskStackChanged();
+            }
         }
     }
 
@@ -1646,6 +1658,17 @@
         return null;
     }
 
+    /**
+     * @return display id to which this record is attached, -1 if not attached.
+     */
+    int getDisplayId() {
+        final ActivityStack stack = getStack();
+        if (stack == null) {
+            return -1;
+        }
+        return stack.mDisplayId;
+    }
+
     final boolean isDestroyable() {
         if (finishing || app == null || state == ActivityState.DESTROYING
                 || state == ActivityState.DESTROYED) {
@@ -1704,6 +1727,28 @@
         }
     }
 
+    void setRequestedOrientation(int requestedOrientation) {
+        if (task != null && (!task.mFullscreen || !task.getStack().mFullscreen)) {
+            // Fixed screen orientation isn't supported when activities aren't in full screen mode.
+            return;
+        }
+
+        service.mWindowManager.setAppOrientation(appToken, requestedOrientation);
+        final int displayId = getDisplayId();
+        final Configuration config = service.mWindowManager.updateOrientationFromAppTokens(
+                mStackSupervisor.getDisplayOverrideConfiguration(displayId),
+                mayFreezeScreenLocked(app) ? appToken : null, displayId);
+        if (config != null) {
+            frozenBeforeDestroy = true;
+            if (!service.updateDisplayOverrideConfigurationLocked(config, this,
+                    false /* deferResume */, displayId)) {
+                mStackSupervisor.resumeFocusedStackTopActivityLocked();
+            }
+        }
+        service.mTaskChangeNotificationController.notifyActivityRequestedOrientationChanged(
+                task.taskId, requestedOrientation);
+    }
+
     // TODO: now used only in one place to address race-condition. Remove when that will be fixed.
     void setLastReportedConfiguration(@NonNull Configuration config) {
         mLastReportedConfiguration.setTo(config);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 55066fd..fc41fd3 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -467,20 +467,21 @@
         }
     }
 
-    void detachDisplay() {
+    void remove() {
         mDisplayId = Display.INVALID_DISPLAY;
         mStacks = null;
         if (mTaskPositioner != null) {
             mTaskPositioner.reset();
         }
-        mWindowManager.detachStack(mStackId);
-        onParentChanged();
         if (mStackId == DOCKED_STACK_ID) {
             // If we removed a docked stack we want to resize it so it resizes all other stacks
             // in the system to fullscreen.
             mStackSupervisor.resizeDockedStackLocked(
                     null, null, null, null, null, PRESERVE_WINDOWS);
         }
+        mStackSupervisor.deleteActivityContainerRecord(mStackId);
+        mWindowManager.removeStack(mStackId);
+        onParentChanged();
     }
 
     void getDisplaySize(Point out) {
@@ -1278,7 +1279,7 @@
         // task stack changes, because its positioning may depend on it.
         if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
                 || mService.mStackSupervisor.getStack(PINNED_STACK_ID) != null) {
-            mService.notifyTaskStackChangedLocked();
+            mService.mTaskChangeNotificationController.notifyTaskStackChanged();
             mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
         }
 
@@ -2285,13 +2286,14 @@
             // the screen based on the new activity order.
             boolean notUpdated = true;
             if (mStackSupervisor.isFocusedStack(this)) {
-                Configuration config = mWindowManager.updateOrientationFromAppTokens(
-                        mService.getGlobalConfiguration(),
-                        next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
+                final Configuration config = mWindowManager.updateOrientationFromAppTokens(
+                        mStackSupervisor.getDisplayOverrideConfiguration(mDisplayId),
+                        next.mayFreezeScreenLocked(next.app) ? next.appToken : null, mDisplayId);
                 if (config != null) {
                     next.frozenBeforeDestroy = true;
                 }
-                notUpdated = !mService.updateConfigurationLocked(config, next, false);
+                notUpdated = !mService.updateDisplayOverrideConfigurationLocked(config, next,
+                        false /* deferResume */, mDisplayId);
             }
 
             if (notUpdated) {
@@ -3312,9 +3314,11 @@
         final boolean endTask = index <= 0;
         final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
         if (mResumedActivity == r) {
-
             if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                     "Prepare close transition: finishing " + r);
+            if (endTask) {
+                mService.mTaskChangeNotificationController.notifyTaskRemovalStarted(task.taskId);
+            }
             mWindowManager.prepareAppTransition(transit, false);
 
             // Tell window manager to prepare for this one to be removed.
@@ -4136,6 +4140,8 @@
 
         mStackSupervisor.resumeFocusedStackTopActivityLocked();
         EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
+
+        mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId);
     }
 
     /**
@@ -4688,6 +4694,7 @@
                 // default configuration the next time it launches.
                 task.updateOverrideConfiguration(null);
             }
+            mService.mTaskChangeNotificationController.notifyTaskRemoved(task.taskId);
         }
 
         final ActivityRecord r = mResumedActivity;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 63a4e86..f0427e4 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -45,6 +45,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
@@ -76,6 +77,7 @@
 import android.service.voice.IVoiceInteractionSession;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -155,8 +157,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.ActivityManagerService.ANIMATE;
 import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
-import static com.android.server.am.ActivityManagerService.NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG;
-import static com.android.server.am.ActivityManagerService.NOTIFY_FORCED_RESIZABLE_MSG;
 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
@@ -419,7 +419,7 @@
     }
 
     @Override
-    protected ConfigurationContainer getChildAt(int index) {
+    protected ActivityDisplay getChildAt(int index) {
         return mActivityDisplays.valueAt(index);
     }
 
@@ -428,6 +428,24 @@
         return null;
     }
 
+    Configuration getDisplayOverrideConfiguration(int displayId) {
+        final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
+        if (activityDisplay == null) {
+            throw new IllegalArgumentException("No display found with id: " + displayId);
+        }
+
+        return activityDisplay.getOverrideConfiguration();
+    }
+
+    void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) {
+        final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
+        if (activityDisplay == null) {
+            throw new IllegalArgumentException("No display found with id: " + displayId);
+        }
+
+        activityDisplay.onOverrideConfigurationChanged(overrideConfiguration);
+    }
+
     static class FindTaskResult {
         ActivityRecord r;
         boolean matchedByRootAffinity;
@@ -1190,20 +1208,20 @@
             r.startLaunchTickingLocked();
         }
 
-        // Have the window manager re-evaluate the orientation of
-        // the screen based on the new activity order.  Note that
-        // as a result of this, it can call back into the activity
-        // manager with a new orientation.  We don't care about that,
-        // because the activity is not currently running so we are
-        // just restarting it anyway.
+        // Have the window manager re-evaluate the orientation of the screen based on the new
+        // activity order.  Note that as a result of this, it can call back into the activity
+        // manager with a new orientation.  We don't care about that, because the activity is not
+        // currently running so we are just restarting it anyway.
         if (checkConfig) {
-            Configuration config = mWindowManager.updateOrientationFromAppTokens(
-                    mService.getGlobalConfiguration(),
-                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
+            final int displayId = r.getDisplayId();
+            final Configuration config = mWindowManager.updateOrientationFromAppTokens(
+                    getDisplayOverrideConfiguration(displayId),
+                    r.mayFreezeScreenLocked(app) ? r.appToken : null, displayId);
             // Deferring resume here because we're going to launch new activity shortly.
             // We don't want to perform a redundant launch of the same record while ensuring
             // configurations and trying to resume top activity of focused stack.
-            mService.updateConfigurationLocked(config, r, false, true /* deferResume */);
+            mService.updateDisplayOverrideConfigurationLocked(config, r, true /* deferResume */,
+                    displayId);
         }
 
         r.app = app;
@@ -1989,15 +2007,10 @@
         }
     }
 
-    void deleteActivityContainer(IActivityContainer container) {
-        ActivityContainer activityContainer = (ActivityContainer)container;
-        if (activityContainer != null) {
-            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
-                    "deleteActivityContainer: callers=" + Debug.getCallers(4));
-            final int stackId = activityContainer.mStackId;
-            mActivityContainers.remove(stackId);
-            mWindowManager.removeStack(stackId);
-        }
+    void deleteActivityContainerRecord(int stackId) {
+        if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
+                "deleteActivityContainerRecord: callers=" + Debug.getCallers(4));
+        mActivityContainers.remove(stackId);
     }
 
     void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds,
@@ -2567,7 +2580,7 @@
         resumeFocusedStackTopActivityLocked();
 
         mWindowManager.animateResizePinnedStack(bounds, -1);
-        mService.notifyActivityPinnedLocked();
+        mService.mTaskChangeNotificationController.notifyActivityPinned();
     }
 
     boolean moveFocusableActivityStackToFrontLocked(ActivityRecord r, String reason) {
@@ -2889,7 +2902,7 @@
         r.mLaunchTaskBehind = false;
         task.setLastThumbnailLocked(r.screenshotActivityLocked());
         mRecentTasks.addLocked(task);
-        mService.notifyTaskStackChangedLocked();
+        mService.mTaskChangeNotificationController.notifyTaskStackChanged();
         mWindowManager.setAppVisibility(r.appToken, false);
 
         // When launching tasks behind, update the last active time of the top task after the new
@@ -3156,6 +3169,20 @@
     }
 
     /**
+     * Dump all connected displays' configurations.
+     * @param prefix Prefix to apply to each line of the dump.
+     */
+    void dumpDisplayConfigs(PrintWriter pw, String prefix) {
+        pw.print(prefix); pw.println("Display override configurations:");
+        final int displayCount = mActivityDisplays.size();
+        for (int i = 0; i < displayCount; i++) {
+            final ActivityDisplay activityDisplay = mActivityDisplays.valueAt(i);
+            pw.print(prefix); pw.print("  "); pw.print(activityDisplay.mDisplayId); pw.print(": ");
+                    pw.println(activityDisplay.getOverrideConfiguration());
+        }
+    }
+
+    /**
      * Dumps the activities matching the given {@param name} in the either the focused stack
      * or all visible stacks if {@param dumpVisibleStacks} is true.
      */
@@ -3424,7 +3451,7 @@
             if (activityDisplay != null) {
                 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
                 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                    stacks.get(stackNdx).mActivityContainer.detachLocked();
+                    stacks.get(stackNdx).mActivityContainer.removeLocked();
                 }
                 mActivityDisplays.remove(displayId);
             }
@@ -3547,7 +3574,7 @@
         final ActivityRecord topActivity = task.getTopActivity();
         if (!task.canGoInDockedStack() || forceNonResizable) {
             // Display a warning toast that we tried to put a non-dockable task in the docked stack.
-            mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
+            mService.mTaskChangeNotificationController.notifyActivityDismissingDockedStack();
 
             // Dismiss docked stack. If task appeared to be in docked stack but is not resizable -
             // we need to move it to top of fullscreen stack, otherwise it will be covered.
@@ -3555,8 +3582,8 @@
         } else if (topActivity != null && topActivity.isNonResizableOrForced()
                 && !topActivity.noDisplay) {
             String packageName = topActivity.appInfo.packageName;
-            mService.mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, task.taskId, 0,
-                    packageName).sendToTarget();
+            mService.mTaskChangeNotificationController.notifyActivityForcedResizable(
+                    task.taskId, packageName);
         }
     }
 
@@ -4064,14 +4091,14 @@
             }
         }
 
-        protected void detachLocked() {
-            if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display="
+        void removeLocked() {
+            if (DEBUG_STACK) Slog.d(TAG_STACK, "removeLocked: " + this + " from display="
                     + mActivityDisplay + " Callers=" + Debug.getCallers(2));
             if (mActivityDisplay != null) {
                 mActivityDisplay.detachActivitiesLocked(mStack);
                 mActivityDisplay = null;
-                mStack.detachDisplay();
             }
+            mStack.remove();
         }
 
         @Override
@@ -4146,8 +4173,7 @@
         }
 
         void onTaskListEmptyLocked() {
-            detachLocked();
-            deleteActivityContainer(this);
+            removeLocked();
             mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
         }
 
@@ -4253,7 +4279,8 @@
         /** Actual Display this object tracks. */
         int mDisplayId;
         Display mDisplay;
-        DisplayInfo mDisplayInfo = new DisplayInfo();
+        private final DisplayMetrics mRealMetrics = new DisplayMetrics();
+        private final Point mRealSize = new Point();
 
         /** All of the stacks on this display. Order matters, topmost stack is in front of all other
          * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
@@ -4277,7 +4304,6 @@
         void init(Display display) {
             mDisplay = display;
             mDisplayId = display.getDisplayId();
-            mDisplay.getDisplayInfo(mDisplayInfo);
         }
 
         void attachActivities(ActivityStack stack, boolean onTop) {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index a834af7..006c13d 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -631,7 +631,7 @@
             // The activity was already running in the pinned stack so it wasn't started, but either
             // brought to the front or the new intent was delivered to it since it was already in
             // front. Notify anyone interested in this piece of information.
-            mService.notifyPinnedActivityRestartAttemptLocked();
+            mService.mTaskChangeNotificationController.notifyPinnedActivityRestartAttempt();
             return;
         }
     }
@@ -1592,9 +1592,9 @@
                 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
             // The caller has requested to completely replace any existing task with its new
             // activity. Well that should not be too hard...
+            intentActivity.task.performClearTaskLocked();
+            intentActivity.task.setIntent(mStartActivity);
             mReuseTask = intentActivity.task;
-            mReuseTask.performClearTaskLocked();
-            mReuseTask.setIntent(mStartActivity);
             // When we clear the task - focus will be adjusted, which will bring another task
             // to top before we launch the activity we need. This will temporary swap their
             // mTaskToReturnTo values and we don't want to overwrite them accidentally.
diff --git a/services/core/java/com/android/server/am/ConfigurationContainer.java b/services/core/java/com/android/server/am/ConfigurationContainer.java
index 30f5309..a3e95b8 100644
--- a/services/core/java/com/android/server/am/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/am/ConfigurationContainer.java
@@ -114,10 +114,14 @@
      */
     void onParentChanged() {
         final ConfigurationContainer parent = getParent();
-        // Update full configuration of this container and all its children.
-        onConfigurationChanged(parent != null ? parent.mFullConfiguration : Configuration.EMPTY);
-        // Update merged override configuration of this container and all its children.
-        onMergedOverrideConfigurationChanged();
+        // Removing parent usually means that we've detached this entity to destroy it or to attach
+        // to another parent. In both cases we don't need to update the configuration now.
+        if (parent != null) {
+            // Update full configuration of this container and all its children.
+            onConfigurationChanged(parent.mFullConfiguration);
+            // Update merged override configuration of this container and all its children.
+            onMergedOverrideConfigurationChanged();
+        }
     }
 
     abstract protected int getChildCount();
diff --git a/services/core/java/com/android/server/am/TaskChangeNotificationController.java b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
new file mode 100644
index 0000000..b6e35d2
--- /dev/null
+++ b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2016 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.server.am;
+
+import android.app.ITaskStackListener;
+import android.app.ActivityManager.TaskDescription;
+import android.content.ComponentName;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+
+class TaskChangeNotificationController {
+    static final int LOG_STACK_STATE_MSG = 1;
+    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 2;
+    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 3;
+    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 4;
+    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 5;
+    static final int NOTIFY_FORCED_RESIZABLE_MSG = 6;
+    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 7;
+    static final int NOTIFY_TASK_ADDED_LISTENERS_MSG = 8;
+    static final int NOTIFY_TASK_REMOVED_LISTENERS_MSG = 9;
+    static final int NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG = 10;
+    static final int NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG = 11;
+    static final int NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS = 12;
+    static final int NOTIFY_TASK_REMOVAL_STARTED_LISTENERS = 13;
+
+    // Delay in notifying task stack change listeners (in millis)
+    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
+
+    private final ActivityManagerService mService;
+    private final ActivityStackSupervisor mStackSupervisor;
+    private final Handler mHandler;
+
+    /** Task stack change listeners. */
+    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
+            new RemoteCallbackList<ITaskStackListener>();
+
+    @FunctionalInterface
+    public interface ConsumerWithRemoteException<T> {
+        void accept(T t) throws RemoteException;
+    }
+
+    private class MainHandler extends Handler {
+        public MainHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case LOG_STACK_STATE_MSG: {
+                    synchronized (mService) {
+                        mStackSupervisor.logStackState();
+                    }
+                    break;
+                }
+                case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG:
+                    forAllListeners((listener) -> listener.onTaskStackChanged());
+                    break;
+                case NOTIFY_TASK_ADDED_LISTENERS_MSG:
+                    forAllListeners((listener) -> listener.onTaskCreated(msg.arg1,
+                            (ComponentName) msg.obj));
+                    break;
+                case NOTIFY_TASK_REMOVED_LISTENERS_MSG:
+                    forAllListeners((listener) -> listener.onTaskRemoved(msg.arg1));
+                    break;
+                case NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG:
+                    forAllListeners((listener) -> listener.onTaskMovedToFront(msg.arg1));
+                    break;
+                case NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG:
+                    forAllListeners((listener) -> listener.onTaskDescriptionChanged(msg.arg1,
+                            (TaskDescription) msg.obj));
+                    break;
+                case NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS:
+                    forAllListeners((listener) -> listener.onActivityRequestedOrientationChanged(
+                            msg.arg1, msg.arg2));
+                case NOTIFY_TASK_REMOVAL_STARTED_LISTENERS:
+                    forAllListeners((listener) -> listener.onTaskRemovalStarted(msg.arg1));
+                    break;
+                case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG:
+                    forAllListeners((listener) -> listener.onActivityPinned());
+                    break;
+                case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG:
+                    forAllListeners((listener) -> listener.onPinnedActivityRestartAttempt());
+                    break;
+                case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG:
+                    forAllListeners((listener) -> listener.onPinnedStackAnimationEnded());
+                    break;
+                case NOTIFY_FORCED_RESIZABLE_MSG:
+                    forAllListeners((listener) -> listener.onActivityForcedResizable(
+                            (String) msg.obj, msg.arg1));
+                    break;
+                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG:
+                    forAllListeners((listener) -> listener.onActivityDismissingDockedStack());
+                    break;
+            }
+        }
+    }
+
+    public TaskChangeNotificationController(ActivityManagerService service,
+            ActivityStackSupervisor stackSupervisor, Handler handler) {
+        mService = service;
+        mStackSupervisor = stackSupervisor;
+        mHandler = new MainHandler(handler.getLooper());
+    }
+
+    public void registerTaskStackListener(ITaskStackListener listener) {
+        synchronized (mService) {
+            if (listener != null) {
+                mTaskStackListeners.register(listener);
+            }
+        }
+    }
+
+    public void unregisterTaskStackListener(ITaskStackListener listener) {
+        synchronized (mService) {
+            if (listener != null) {
+                mTaskStackListeners.unregister(listener);
+            }
+        }
+    }
+
+    void forAllListeners(ConsumerWithRemoteException<ITaskStackListener> callback) {
+        synchronized (mService) {
+            for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
+                try {
+                    // Make a one-way callback to the listener
+                    callback.accept(mTaskStackListeners.getBroadcastItem(i));
+                } catch (RemoteException e) {
+                    // Handled by the RemoteCallbackList.
+                }
+            }
+            mTaskStackListeners.finishBroadcast();
+         }
+      }
+
+    /** Notifies all listeners when the task stack has changed. */
+    void notifyTaskStackChanged() {
+        mHandler.sendEmptyMessage(LOG_STACK_STATE_MSG);
+        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
+        Message msg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
+        // Only the main task stack change notification requires a delay.
+        mHandler.sendMessageDelayed(msg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
+    }
+
+    /** Notifies all listeners when an Activity is pinned. */
+    void notifyActivityPinned() {
+        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
+        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
+    }
+
+    /**
+     * Notifies all listeners when an attempt was made to start an an activity that is already
+     * running in the pinned stack and the activity was not actually started, but the task is
+     * either brought to the front or a new Intent is delivered to it.
+     */
+    void notifyPinnedActivityRestartAttempt() {
+        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
+        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
+    }
+
+    /** Notifies all listeners when the pinned stack animation ends. */
+    void notifyPinnedStackAnimationEnded() {
+        mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
+        mHandler.obtainMessage(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG)
+                .sendToTarget();
+    }
+
+    void notifyActivityDismissingDockedStack() {
+        mHandler.removeMessages(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
+        mHandler.obtainMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG).sendToTarget();
+    }
+
+    void notifyActivityForcedResizable(int taskId, String packageName) {
+        mHandler.removeMessages(NOTIFY_FORCED_RESIZABLE_MSG);
+        mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, taskId, 0 /* unused */, packageName)
+                .sendToTarget();
+    }
+
+    void notifyTaskCreated(int taskId, ComponentName componentName) {
+        mHandler.obtainMessage(NOTIFY_TASK_ADDED_LISTENERS_MSG, taskId, 0 /* unused */,
+                componentName).sendToTarget();
+    }
+
+    void notifyTaskRemoved(int taskId) {
+        mHandler.obtainMessage(NOTIFY_TASK_REMOVED_LISTENERS_MSG, taskId, 0 /* unused */)
+                .sendToTarget();
+    }
+
+    void notifyTaskMovedToFront(int taskId) {
+        mHandler.obtainMessage(NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG, taskId, 0 /* unused */)
+                .sendToTarget();
+    }
+
+    void notifyTaskDescriptionChanged(int taskId, TaskDescription taskDescription) {
+        mHandler.obtainMessage(NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG, taskId,
+                0 /* unused */, taskDescription).sendToTarget();
+    }
+
+    void notifyActivityRequestedOrientationChanged(int taskId, int orientation) {
+        mHandler.obtainMessage(NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS, taskId,
+                orientation).sendToTarget();
+    }
+
+    /**
+     * Notify listeners that the task is about to be finished before its surfaces are removed from
+     * the window manager. This allows interested parties to perform relevant animations before
+     * the window disappears.
+     */
+    void notifyTaskRemovalStarted(int taskId) {
+        mHandler.obtainMessage(NOTIFY_TASK_REMOVAL_STARTED_LISTENERS, taskId, 0 /* unused */)
+                .sendToTarget();
+    }
+}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 9d97dd3..b37b3f0 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -298,6 +298,7 @@
         setIntent(_intent, info);
         setMinDimensions(info);
         touchActiveTime();
+        mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
     }
 
     TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
@@ -329,6 +330,7 @@
         mTaskToReturnTo = HOME_ACTIVITY_TYPE;
         lastTaskDescription = _taskDescription;
         touchActiveTime();
+        mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
     }
 
     private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
@@ -383,6 +385,7 @@
         mPrivileged = privileged;
         mMinWidth = minWidth;
         mMinHeight = minHeight;
+        mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
     }
 
     void touchActiveTime() {
@@ -861,7 +864,7 @@
             // We normally notify listeners of task stack changes on pause, however pinned stack
             // activities are normally in the paused state so no notification will be sent there
             // before the activity is removed. We send it here so instead.
-            mService.notifyTaskStackChangedLocked();
+            mService.mTaskChangeNotificationController.notifyTaskStackChanged();
         }
 
         if (mActivities.isEmpty()) {
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
index f1ef947..f1d01e0 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
@@ -48,6 +48,10 @@
         final IpConnectivityLog log = new IpConnectivityLog();
         log.events = toProto(events);
         log.droppedEvents = dropped;
+        if ((log.events.length > 0) || (dropped > 0)) {
+            // Only write version number if log has some information at all.
+            log.version = IpConnectivityMetrics.VERSION;
+        }
         return IpConnectivityLog.toByteArray(log);
     }
 
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
index 2e3359f..be68173 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
@@ -19,19 +19,25 @@
 import android.content.Context;
 import android.net.ConnectivityMetricsEvent;
 import android.net.IIpConnectivityMetrics;
+import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.IpConnectivityLog;
 import android.os.IBinder;
 import android.os.Parcelable;
+import android.provider.Settings;
 import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.util.ArrayMap;
 import android.util.Base64;
 import android.util.Log;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.TokenBucket;
 import com.android.server.SystemService;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.function.ToIntFunction;
 
 import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityEvent;
 
@@ -40,10 +46,21 @@
     private static final String TAG = IpConnectivityMetrics.class.getSimpleName();
     private static final boolean DBG = false;
 
+    // The logical version numbers of ipconnectivity.proto, corresponding to the
+    // "version" field of IpConnectivityLog.
+    private static final int NYC      = 0;
+    private static final int NYC_MR1  = 1;
+    private static final int NYC_MR2  = 2;
+    public static final int VERSION   = NYC_MR2;
+
     private static final String SERVICE_NAME = IpConnectivityLog.SERVICE_NAME;
 
     // Default size of the event buffer. Once the buffer is full, incoming events are dropped.
     private static final int DEFAULT_BUFFER_SIZE = 2000;
+    // Maximum size of the event buffer.
+    private static final int MAXIMUM_BUFFER_SIZE = DEFAULT_BUFFER_SIZE * 10;
+
+    private static final int ERROR_RATE_LIMITED = -1;
 
     // Lock ensuring that concurrent manipulations of the event buffer are correct.
     // There are three concurrent operations to synchronize:
@@ -62,10 +79,19 @@
     private int mDropped;
     @GuardedBy("mLock")
     private int mCapacity;
+    @GuardedBy("mLock")
+    private final ArrayMap<Class<?>, TokenBucket> mBuckets = makeRateLimitingBuckets();
+
+    private final ToIntFunction<Context> mCapacityGetter;
+
+    public IpConnectivityMetrics(Context ctx, ToIntFunction<Context> capacityGetter) {
+        super(ctx);
+        mCapacityGetter = capacityGetter;
+        initBuffer();
+    }
 
     public IpConnectivityMetrics(Context ctx) {
-        super(ctx);
-        initBuffer();
+        this(ctx, READ_BUFFER_SIZE);
     }
 
     @Override
@@ -86,7 +112,7 @@
 
     @VisibleForTesting
     public int bufferCapacity() {
-        return DEFAULT_BUFFER_SIZE; // TODO: read from config
+        return mCapacityGetter.applyAsInt(getContext());
     }
 
     private void initBuffer() {
@@ -104,6 +130,10 @@
             if (event == null) {
                 return left;
             }
+            if (isRateLimited(event)) {
+                // Do not count as a dropped event. TODO: consider adding separate counter
+                return ERROR_RATE_LIMITED;
+            }
             if (left == 0) {
                 mDropped++;
                 return 0;
@@ -113,6 +143,11 @@
         }
     }
 
+    private boolean isRateLimited(ConnectivityMetricsEvent event) {
+        TokenBucket tb = mBuckets.get(event.data.getClass());
+        return (tb != null) && !tb.get();
+    }
+
     private String flushEncodedOutput() {
         final ArrayList<ConnectivityMetricsEvent> events;
         final int dropped;
@@ -229,4 +264,20 @@
             getContext().enforceCallingOrSelfPermission(what, "IpConnectivityMetrics");
         }
     };
+
+    private static final ToIntFunction<Context> READ_BUFFER_SIZE = (ctx) -> {
+        int size = Settings.Global.getInt(ctx.getContentResolver(),
+                Settings.Global.CONNECTIVITY_METRICS_BUFFER_SIZE, DEFAULT_BUFFER_SIZE);
+        if (size <= 0) {
+            return DEFAULT_BUFFER_SIZE;
+        }
+        return Math.min(size, MAXIMUM_BUFFER_SIZE);
+    };
+
+    private static ArrayMap<Class<?>, TokenBucket> makeRateLimitingBuckets() {
+        ArrayMap<Class<?>, TokenBucket> map = new ArrayMap<>();
+        // one token every minute, 50 tokens max: burst of ~50 events every hour.
+        map.put(ApfProgramEvent.class, new TokenBucket((int)DateUtils.MINUTE_IN_MILLIS, 50));
+        return map;
+    }
 }
diff --git a/services/core/java/com/android/server/connectivity/MockableSystemProperties.java b/services/core/java/com/android/server/connectivity/MockableSystemProperties.java
new file mode 100644
index 0000000..4f68652
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/MockableSystemProperties.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 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.server.connectivity;
+
+import android.os.SystemProperties;
+
+public class MockableSystemProperties {
+    public boolean getBoolean(String key, boolean def) {
+        return SystemProperties.getBoolean(key, def);
+    }
+}
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 921fd23..0beb227 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -52,7 +52,6 @@
 import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
@@ -62,6 +61,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.IndentingPrintWriter;
@@ -69,7 +69,6 @@
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
-import com.android.server.IoThread;
 import com.android.server.connectivity.tethering.IControlsTethering;
 import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
 import com.android.server.connectivity.tethering.TetherInterfaceStateMachine;
@@ -100,6 +99,8 @@
     private final static boolean DBG = false;
     private final static boolean VDBG = false;
 
+    protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
+
     private static final Class[] messageClasses = {
             Tethering.class, TetherMasterSM.class, TetherInterfaceStateMachine.class
     };
@@ -127,6 +128,7 @@
     private final INetworkStatsService mStatsService;
     private final INetworkPolicyManager mPolicyManager;
     private final Looper mLooper;
+    private final MockableSystemProperties mSystemProperties;
 
     private static class TetherState {
         public final TetherInterfaceStateMachine mStateMachine;
@@ -180,18 +182,19 @@
     private boolean mWifiTetherRequested;
 
     public Tethering(Context context, INetworkManagementService nmService,
-            INetworkStatsService statsService, INetworkPolicyManager policyManager) {
+            INetworkStatsService statsService, INetworkPolicyManager policyManager,
+            Looper looper, MockableSystemProperties systemProperties) {
         mContext = context;
         mNMService = nmService;
         mStatsService = statsService;
         mPolicyManager = policyManager;
+        mLooper = looper;
+        mSystemProperties = systemProperties;
 
         mPublicSync = new Object();
 
         mTetherStates = new ArrayMap<>();
 
-        // make our own thread so we don't anr the system
-        mLooper = IoThread.get().getLooper();
         mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper);
         mTetherMasterSM.start();
 
@@ -394,10 +397,11 @@
      *
      * @return a boolean - {@code true} indicating tether provisioning is required by the carrier.
      */
-    private boolean isTetherProvisioningRequired() {
+    @VisibleForTesting
+    protected boolean isTetherProvisioningRequired() {
         String[] provisionApp = mContext.getResources().getStringArray(
                 com.android.internal.R.array.config_mobile_hotspot_provision_app);
-        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)
+        if (mSystemProperties.getBoolean(DISABLE_PROVISIONING_SYSPROP_KEY, false)
                 || provisionApp == null) {
             return false;
         }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index df5def9..3b2dc34 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -284,7 +284,7 @@
                     + mScreenBrightnessDarkConfig + ") to be less than or equal to "
                     + "config_screenBrightnessDim (" + mScreenBrightnessDimConfig + ").");
         }
-        if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
+        if (mScreenBrightnessDarkConfig > screenBrightnessSettingMinimum) {
             Slog.w(TAG, "Expected config_screenBrightnessDark ("
                     + mScreenBrightnessDarkConfig + ") to be less than or equal to "
                     + "config_screenBrightnessSettingMinimum ("
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index ae98077..9ae496f 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -58,6 +58,7 @@
 import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.PersistableBundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -75,6 +76,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyManager;
+import android.telephony.CarrierConfigManager;
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
 import android.util.Log;
@@ -396,10 +398,6 @@
     // Persist property for LPP_PROFILE
     private final static String LPP_PROFILE = "persist.sys.gps.lpp";
 
-    // VZW PLMN info
-    private static final String[] VzwMccMncList = {"311480", "310004", "20404"};
-    // corresponding GID1 value, empty string means ignore gid1 match.
-    private static final String[] VzwGid1List = {"", "", "BAE0000000000000"};
 
 
     private final PowerManager mPowerManager;
@@ -520,42 +518,30 @@
         }
     };
 
-    private final boolean isVerizon(String mccMnc, String imsi, String groupId) {
-        if (DEBUG) Log.d(TAG, "simOperator: " + mccMnc);
-        if (!TextUtils.isEmpty(mccMnc) || !TextUtils.isEmpty(imsi)) {
-            for (int i = 0; i < VzwMccMncList.length; i++) {
-                if ((!TextUtils.isEmpty(mccMnc) && mccMnc.equals(VzwMccMncList[i])) ||
-                        (!TextUtils.isEmpty(imsi) && imsi.startsWith(VzwMccMncList[i]))) {
-                    // check gid too if needed
-                    if (TextUtils.isEmpty(VzwGid1List[i]) || VzwGid1List[i].equals(groupId)) {
-                        if (DEBUG) Log.d(TAG, "Verizon UICC");
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
     private void subscriptionOrSimChanged(Context context) {
         if (DEBUG) Log.d(TAG, "received SIM related action: ");
         TelephonyManager phone = (TelephonyManager)
                 mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        CarrierConfigManager configManager = (CarrierConfigManager)
+                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
         String mccMnc = phone.getSimOperator();
-        String imsi = phone.getSubscriberId();
-        String groupId = phone.getGroupIdLevel1();
+        boolean isKeepLppProfile = false;
         if (!TextUtils.isEmpty(mccMnc)) {
             if (DEBUG) Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
             synchronized (mLock) {
-                if (isVerizon(mccMnc, imsi, groupId)) {
-                        // load current properties for carrier VZW
-                        loadPropertiesFromResource(context, mProperties);
-                        String lpp_profile = mProperties.getProperty("LPP_PROFILE");
-                        // set the persist property LPP_PROFILE for VZW
-                        SystemProperties.set(LPP_PROFILE, lpp_profile);
+                if (configManager != null) {
+                    PersistableBundle b = configManager.getConfig();
+                    isKeepLppProfile = b.getBoolean(CarrierConfigManager.KEY_PERSIST_LPP_MODE_BOOL);
+                }
+                if (isKeepLppProfile) {
+                    // load current properties for the carrier
+                    loadPropertiesFromResource(context, mProperties);
+                    String lpp_profile = mProperties.getProperty("LPP_PROFILE");
+                    // set the persist property LPP_PROFILE for the value
+                    SystemProperties.set(LPP_PROFILE, lpp_profile);
                 } else {
-                        // reset the persist property for Non VZW
-                        SystemProperties.set(LPP_PROFILE, "");
+                    // reset the persist property
+                    SystemProperties.set(LPP_PROFILE, "");
                 }
                 reloadGpsProperties(context, mProperties);
                 mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
diff --git a/services/core/java/com/android/server/pm/BasePermission.java b/services/core/java/com/android/server/pm/BasePermission.java
index 52d0928..8948fa3 100644
--- a/services/core/java/com/android/server/pm/BasePermission.java
+++ b/services/core/java/com/android/server/pm/BasePermission.java
@@ -94,4 +94,8 @@
                 == PermissionInfo.PROTECTION_SIGNATURE
                 && (protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0;
     }
+
+    public boolean isEphemeral() {
+        return (protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0;
+    }
 }
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 68b465a..a6a3774 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -56,6 +56,7 @@
     /** Intent used to bind to the service */
     private final Intent mIntent;
 
+    private volatile boolean mBindRequested;
     private IEphemeralResolver mRemoteInstance;
 
     public EphemeralResolverConnection(Context context, ComponentName componentName) {
@@ -111,8 +112,11 @@
             return;
         }
 
-        mContext.bindServiceAsUser(mIntent, mServiceConnection,
-                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, UserHandle.SYSTEM);
+        if (!mBindRequested) {
+            mBindRequested = true;
+            mContext.bindServiceAsUser(mIntent, mServiceConnection,
+                    Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, UserHandle.SYSTEM);
+        }
 
         final long startMillis = SystemClock.uptimeMillis();
         while (true) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e48d6fb..59c4fb9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -466,11 +466,11 @@
 
     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
     /**
-     * If VENDOR_OVERLAY_SKU_PROPERTY is set, search for runtime resource overlay APKs also in
-     * VENDOR_OVERLAY_DIR/<value of VENDOR_OVERLAY_SKU_PROPERTY> in addition to
+     * If VENDOR_OVERLAY_THEME_PROPERTY is set, search for runtime resource overlay APKs also in
+     * VENDOR_OVERLAY_DIR/<value of VENDOR_OVERLAY_THEME_PROPERTY> in addition to
      * VENDOR_OVERLAY_DIR.
      */
-    private static final String VENDOR_OVERLAY_SKU_PROPERTY = "ro.boot.vendor.overlay.sku";
+    private static final String VENDOR_OVERLAY_THEME_PROPERTY = "ro.boot.vendor.overlay.theme";
 
     private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000;
     private static int DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT = 5;
@@ -2288,9 +2288,9 @@
             // Collect vendor overlay packages. (Do this before scanning any apps.)
             // For security and version matching reason, only consider
             // overlay packages if they reside in the right directory.
-            String overlaySkuDir = SystemProperties.get(VENDOR_OVERLAY_SKU_PROPERTY);
-            if (!overlaySkuDir.isEmpty()) {
-                scanDirTracedLI(new File(VENDOR_OVERLAY_DIR, overlaySkuDir), mDefParseFlags
+            String overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PROPERTY);
+            if (!overlayThemeDir.isEmpty()) {
+                scanDirTracedLI(new File(VENDOR_OVERLAY_DIR, overlayThemeDir), mDefParseFlags
                         | PackageParser.PARSE_IS_SYSTEM
                         | PackageParser.PARSE_IS_SYSTEM_DIR
                         | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
@@ -4083,6 +4083,11 @@
                 return;
             }
 
+            if (pkg.applicationInfo.isEphemeralApp() && !bp.isEphemeral()) {
+                throw new SecurityException("Cannot grant non-ephemeral permission"
+                        + name + " for package " + packageName);
+            }
+
             if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
                 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
                 return;
@@ -10109,6 +10114,14 @@
                 continue;
             }
 
+
+            // Limit ephemeral apps to ephemeral allowed permissions.
+            if (pkg.applicationInfo.isEphemeralApp() && !bp.isEphemeral()) {
+                Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
+                        + pkg.packageName);
+                continue;
+            }
+
             final String perm = bp.name;
             boolean allowedSig = false;
             int grant = GRANT_DENIED;
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index efd6f46..a15af3c 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -2483,13 +2483,17 @@
      */
     @Override
     public boolean removeUser(int userHandle) {
+        Slog.i(LOG_TAG, "removeUser u" + userHandle);
         checkManageOrCreateUsersPermission("Only the system can remove users");
         if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
                 UserManager.DISALLOW_REMOVE_USER, false)) {
             Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
             return false;
         }
+        return removeUserUnchecked(userHandle);
+    }
 
+    private boolean removeUserUnchecked(int userHandle) {
         long ident = Binder.clearCallingIdentity();
         try {
             final UserData userData;
@@ -3567,6 +3571,11 @@
         }
 
         @Override
+        public boolean removeUserEvenWhenDisallowed(int userId) {
+            return removeUserUnchecked(userId);
+        }
+
+        @Override
         public boolean isUserRunning(int userId) {
             synchronized (mUserStates) {
                 return mUserStates.get(userId, -1) >= 0;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index b8b16d5..40dfcda 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5408,18 +5408,15 @@
                 }
             } else if (mDismissKeyguard != DISMISS_KEYGUARD_NONE) {
                 mKeyguardHidden = false;
-                boolean willDismiss = false;
+                boolean dismissKeyguard = false;
+                final boolean trusted = mKeyguardDelegate.isTrusted();
                 if (mDismissKeyguard == DISMISS_KEYGUARD_START) {
-                    final boolean trusted = mKeyguardDelegate.isTrusted();
-                    willDismiss = trusted && mKeyguardOccluded && mKeyguardDelegate != null
-                            && mKeyguardDelegate.isShowing();
+                    final boolean willDismiss = trusted && mKeyguardOccluded
+                            && mKeyguardDelegate != null && mKeyguardDelegate.isShowing();
                     if (willDismiss) {
                         mCurrentlyDismissingKeyguard = true;
                     }
-
-                    // Only launch the next keyguard unlock window once per window.
-                    mHandler.post(() -> mKeyguardDelegate.dismiss(
-                            trusted /* allowWhileOccluded */));
+                    dismissKeyguard = true;
                 }
 
                 // If we are currently dismissing Keyguard, there is no need to unocclude it.
@@ -5430,6 +5427,12 @@
                                 | FINISH_LAYOUT_REDO_WALLPAPER;
                     }
                 }
+
+                if (dismissKeyguard) {
+                    // Only launch the next keyguard unlock window once per window.
+                    mHandler.post(() -> mKeyguardDelegate.dismiss(
+                            trusted /* allowWhileOccluded */));
+                }
             } else {
                 mWinDismissingKeyguard = null;
                 mSecureDismissingKeyguard = false;
@@ -7919,6 +7922,12 @@
         if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) {
             return false;
         }
+        // If the navigation bar can't change sides, then it will
+        // jump when we change orientations and we don't rotate
+        // seamlessly.
+        if (!mNavigationBarCanMove) {
+            return false;
+        }
         int delta = newRotation - oldRotation;
         if (delta < 0) delta += 4;
         // Likewise we don't rotate seamlessly for 180 degree rotations
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 706828b..6b967a2 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -59,7 +59,7 @@
 import android.util.EventLog;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
-import android.util.SparseIntArray;
+import android.util.SparseArray;
 import android.util.TimeUtils;
 import android.view.Display;
 import android.view.WindowManagerPolicy;
@@ -483,7 +483,13 @@
     // Set of app ids that are temporarily allowed to acquire wakelocks due to high-pri message
     int[] mDeviceIdleTempWhitelist = new int[0];
 
-    private final SparseIntArray mUidState = new SparseIntArray();
+    private final SparseArray<UidState> mUidState = new SparseArray<>();
+
+    // We are currently in the middle of a batch change of uids.
+    private boolean mUidsChanging;
+
+    // Some uids have actually changed while mUidsChanging was true.
+    private boolean mUidsChanged;
 
     // True if theater mode is enabled
     private boolean mTheaterModeEnabled;
@@ -878,7 +884,15 @@
                 }
                 notifyAcquire = false;
             } else {
-                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);
+                UidState state = mUidState.get(uid);
+                if (state == null) {
+                    state = new UidState(uid);
+                    state.mProcState = ActivityManager.PROCESS_STATE_NONEXISTENT;
+                    mUidState.put(uid, state);
+                }
+                state.mNumWakeLocks++;
+                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid,
+                        state);
                 try {
                     lock.linkToDeath(wakeLock, 0);
                 } catch (RemoteException ex) {
@@ -976,6 +990,12 @@
 
     private void removeWakeLockLocked(WakeLock wakeLock, int index) {
         mWakeLocks.remove(index);
+        UidState state = wakeLock.mUidState;
+        state.mNumWakeLocks--;
+        if (state.mNumWakeLocks <= 0 &&
+                state.mProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
+            mUidState.remove(state.mUid);
+        }
         notifyWakeLockReleasedLocked(wakeLock);
 
         applyWakeLockFlagsOnReleaseLocked(wakeLock);
@@ -2580,20 +2600,82 @@
         }
     }
 
+    void startUidChangesInternal() {
+        synchronized (mLock) {
+            mUidsChanging = true;
+        }
+    }
+
+    void finishUidChangesInternal() {
+        synchronized (mLock) {
+            mUidsChanging = false;
+            if (mUidsChanged) {
+                updateWakeLockDisabledStatesLocked();
+                mUidsChanged = false;
+            }
+        }
+    }
+
+    private void handleUidStateChangeLocked() {
+        if (mUidsChanging) {
+            mUidsChanged = true;
+        } else {
+            updateWakeLockDisabledStatesLocked();
+        }
+    }
+
     void updateUidProcStateInternal(int uid, int procState) {
         synchronized (mLock) {
-            mUidState.put(uid, procState);
-            if (mDeviceIdleMode) {
-                updateWakeLockDisabledStatesLocked();
+            UidState state = mUidState.get(uid);
+            if (state == null) {
+                state = new UidState(uid);
+                mUidState.put(uid, state);
+            }
+            state.mProcState = procState;
+            if (mDeviceIdleMode && state.mNumWakeLocks > 0) {
+                handleUidStateChangeLocked();
             }
         }
     }
 
     void uidGoneInternal(int uid) {
         synchronized (mLock) {
-            mUidState.delete(uid);
-            if (mDeviceIdleMode) {
-                updateWakeLockDisabledStatesLocked();
+            final int index = mUidState.indexOfKey(uid);
+            if (index >= 0) {
+                UidState state = mUidState.valueAt(index);
+                state.mProcState = ActivityManager.PROCESS_STATE_NONEXISTENT;
+                state.mActive = false;
+                mUidState.removeAt(index);
+                if (mDeviceIdleMode && state.mNumWakeLocks > 0) {
+                    handleUidStateChangeLocked();
+                }
+            }
+        }
+    }
+
+    void uidActiveInternal(int uid) {
+        synchronized (mLock) {
+            UidState state = mUidState.get(uid);
+            if (state == null) {
+                state = new UidState(uid);
+                state.mProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+                mUidState.put(uid, state);
+            }
+            state.mActive = true;
+            if (state.mNumWakeLocks > 0) {
+                handleUidStateChangeLocked();
+            }
+        }
+    }
+
+    void uidIdleInternal(int uid) {
+        synchronized (mLock) {
+            UidState state = mUidState.get(uid);
+            if (state != null) {
+                state.mActive = false;
+                if (state.mNumWakeLocks > 0) {
+                    handleUidStateChangeLocked();
+                }
             }
         }
     }
@@ -2626,17 +2708,20 @@
         if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
                 == PowerManager.PARTIAL_WAKE_LOCK) {
             boolean disabled = false;
-            if (mDeviceIdleMode) {
-                final int appid = UserHandle.getAppId(wakeLock.mOwnerUid);
-                // If we are in idle mode, we will ignore all partial wake locks that are
-                // for application uids that are not whitelisted.
-                if (appid >= Process.FIRST_APPLICATION_UID &&
-                        Arrays.binarySearch(mDeviceIdleWhitelist, appid) < 0 &&
-                        Arrays.binarySearch(mDeviceIdleTempWhitelist, appid) < 0 &&
-                        mUidState.get(wakeLock.mOwnerUid,
-                                ActivityManager.PROCESS_STATE_CACHED_EMPTY)
-                                > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
-                    disabled = true;
+            final int appid = UserHandle.getAppId(wakeLock.mOwnerUid);
+            if (appid >= Process.FIRST_APPLICATION_UID) {
+                if (mDeviceIdleMode) {
+                    // If we are in idle mode, we will ignore all partial wake locks that are
+                    // for application uids that are not whitelisted.
+                    final UidState state = wakeLock.mUidState;
+                    if (Arrays.binarySearch(mDeviceIdleWhitelist, appid) < 0 &&
+                            Arrays.binarySearch(mDeviceIdleTempWhitelist, appid) < 0 &&
+                            state.mProcState != ActivityManager.PROCESS_STATE_NONEXISTENT &&
+                            state.mProcState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
+                        disabled = true;
+                    }
+                } else {
+                    disabled = !wakeLock.mUidState.mActive;
                 }
             }
             if (wakeLock.mDisabled != disabled) {
@@ -2964,10 +3049,21 @@
             pw.println("Screen dim duration: " + screenDimDuration + " ms");
 
             pw.println();
-            pw.println("UID states:");
+            pw.print("UID states (changing=");
+            pw.print(mUidsChanging);
+            pw.print(" changed=");
+            pw.print(mUidsChanged);
+            pw.println("):");
             for (int i=0; i<mUidState.size(); i++) {
+                final UidState state = mUidState.valueAt(i);
                 pw.print("  UID "); UserHandle.formatUid(pw, mUidState.keyAt(i));
-                pw.print(": "); pw.println(mUidState.valueAt(i));
+                pw.print(": ");
+                if (state.mActive) pw.print("  ACTIVE ");
+                else pw.print("INACTIVE ");
+                pw.print(" count=");
+                pw.print(state.mNumWakeLocks);
+                pw.print(" state=");
+                pw.println(state.mProcState);
             }
 
             pw.println();
@@ -3122,13 +3218,15 @@
         public String mHistoryTag;
         public final int mOwnerUid;
         public final int mOwnerPid;
+        public final UidState mUidState;
         public long mAcquireTime;
         public boolean mNotifiedAcquired;
         public boolean mNotifiedLong;
         public boolean mDisabled;
 
         public WakeLock(IBinder lock, int flags, String tag, String packageName,
-                WorkSource workSource, String historyTag, int ownerUid, int ownerPid) {
+                WorkSource workSource, String historyTag, int ownerUid, int ownerPid,
+                UidState uidState) {
             mLock = lock;
             mFlags = flags;
             mTag = tag;
@@ -3137,6 +3235,7 @@
             mHistoryTag = historyTag;
             mOwnerUid = ownerUid;
             mOwnerPid = ownerPid;
+            mUidState = uidState;
         }
 
         @Override
@@ -3312,6 +3411,17 @@
         }
     }
 
+    static final class UidState {
+        final int mUid;
+        int mNumWakeLocks;
+        int mProcState;
+        boolean mActive;
+
+        UidState(int uid) {
+            mUid = uid;
+        }
+    }
+
     private final class BinderService extends IPowerManager.Stub {
         @Override // Binder call
         public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,
@@ -3880,6 +3990,16 @@
         }
 
         @Override
+        public void startUidChanges() {
+            startUidChangesInternal();
+        }
+
+        @Override
+        public void finishUidChanges() {
+            finishUidChangesInternal();
+        }
+
+        @Override
         public void updateUidProcState(int uid, int procState) {
             updateUidProcStateInternal(uid, procState);
         }
@@ -3890,6 +4010,16 @@
         }
 
         @Override
+        public void uidActive(int uid) {
+            uidActiveInternal(uid);
+        }
+
+        @Override
+        public void uidIdle(int uid) {
+            uidIdleInternal(uid);
+        }
+
+        @Override
         public void powerHint(int hintId, int data) {
             powerHintInternal(hintId, data);
         }
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index bb76449..9f0f11a 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -36,6 +36,7 @@
 import android.util.Log;
 import android.webkit.WebViewFactory;
 import android.webkit.WebViewProviderInfo;
+import android.webkit.WebViewZygote;
 
 import com.android.internal.util.XmlUtils;
 
@@ -268,6 +269,11 @@
         return pm.getPackageInfo(configInfo.packageName, PACKAGE_FLAGS);
     }
 
+    @Override
+    public void setMultiprocessEnabled(boolean enabled) {
+        WebViewZygote.setMultiprocessEnabled(enabled);
+    }
+
     // flags declaring we want extra info from the package manager for webview providers
     private final static int PACKAGE_FLAGS = PackageManager.GET_META_DATA
             | PackageManager.GET_SIGNATURES | PackageManager.MATCH_DEBUG_TRIAGED_MISSING
diff --git a/services/core/java/com/android/server/webkit/SystemInterface.java b/services/core/java/com/android/server/webkit/SystemInterface.java
index 7bde37a..7c934fc 100644
--- a/services/core/java/com/android/server/webkit/SystemInterface.java
+++ b/services/core/java/com/android/server/webkit/SystemInterface.java
@@ -48,4 +48,6 @@
     public boolean systemIsDebuggable();
     public PackageInfo getPackageInfoForProvider(WebViewProviderInfo configInfo)
             throws NameNotFoundException;
+
+    public void setMultiprocessEnabled(boolean enabled);
 }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index b69a8c1..57cd768 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -20,7 +20,12 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.Signature;
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.Base64;
 import android.util.Slog;
 import android.webkit.WebViewFactory;
@@ -73,6 +78,7 @@
 
     private SystemInterface mSystemInterface;
     private WebViewUpdater mWebViewUpdater;
+    private SettingsObserver mSettingsObserver;
     private Context mContext;
 
     public WebViewUpdateServiceImpl(Context context, SystemInterface systemInterface) {
@@ -92,6 +98,10 @@
     void prepareWebViewInSystemServer() {
         updateFallbackStateOnBoot();
         mWebViewUpdater.prepareWebViewInSystemServer();
+
+        // Register for changes in the multiprocess developer option. This has to be done
+        // here, since the update service gets created before the ContentResolver service.
+        mSettingsObserver = new SettingsObserver();
     }
 
     private boolean existsValidNonFallbackProvider(WebViewProviderInfo[] providers) {
@@ -709,4 +719,41 @@
                         & ApplicationInfo.PRIVATE_FLAG_HIDDEN) == 0));
     }
 
+    /**
+     * Watches for changes in the WEBVIEW_MULTIPROCESS setting and lets
+     * the WebViewZygote know, so it can start or stop the zygote process
+     * appropriately.
+     */
+    private class SettingsObserver extends ContentObserver {
+        private final ContentResolver mResolver;
+
+        SettingsObserver() {
+            super(new Handler());
+
+            mResolver = mContext.getContentResolver();
+            mResolver.registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.WEBVIEW_MULTIPROCESS),
+                    false, this);
+
+            // Push the current value of the setting immediately.
+            notifyZygote();
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            notifyZygote();
+        }
+
+        private void notifyZygote() {
+            boolean enableMultiprocess = false;
+
+            try {
+                enableMultiprocess = Settings.Global.getInt(mResolver,
+                        Settings.Global.WEBVIEW_MULTIPROCESS) == 1;
+            } catch (Settings.SettingNotFoundException ex) {
+            }
+
+            mSystemInterface.setMultiprocessEnabled(enableMultiprocess);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 893749e..bde65ed 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -648,12 +648,11 @@
             }
 
             private void populateWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
-                DisplayContent displayContent = mWindowManagerService
-                        .getDefaultDisplayContentLocked();
-                WindowList windowList = displayContent.getWindowList();
+                final DisplayContent dc = mWindowManagerService.getDefaultDisplayContentLocked();
+                final ReadOnlyWindowList windowList = dc.getReadOnlyWindowList();
                 final int windowCount = windowList.size();
                 for (int i = 0; i < windowCount; i++) {
-                    WindowState windowState = windowList.get(i);
+                    final WindowState windowState = windowList.get(i);
                     if (windowState.isOnScreen() && windowState.isVisibleLw() &&
                             !windowState.mWinAnimator.mEnterAnimationPending) {
                         outWindows.put(windowState.mLayer, windowState);
@@ -1027,9 +1026,8 @@
                 Region unaccountedSpace = mTempRegion;
                 unaccountedSpace.set(0, 0, screenWidth, screenHeight);
 
-                SparseArray<WindowState> visibleWindows = mTempWindowStates;
+                final SparseArray<WindowState> visibleWindows = mTempWindowStates;
                 populateVisibleWindowsOnScreenLocked(visibleWindows);
-
                 Set<IBinder> addedWindows = mTempBinderSet;
                 addedWindows.clear();
 
@@ -1299,12 +1297,11 @@
         }
 
         private void populateVisibleWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
-            DisplayContent displayContent = mWindowManagerService
-                    .getDefaultDisplayContentLocked();
-            WindowList windowList = displayContent.getWindowList();
+            final DisplayContent dc = mWindowManagerService.getDefaultDisplayContentLocked();
+            final ReadOnlyWindowList windowList = dc.getReadOnlyWindowList();
             final int windowCount = windowList.size();
             for (int i = 0; i < windowCount; i++) {
-                WindowState windowState = windowList.get(i);
+                final WindowState windowState = windowList.get(i);
                 if (windowState.isVisibleLw()) {
                     outWindows.put(windowState.mLayer, windowState);
                 }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 56eaa83..e3588ff 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -676,6 +676,34 @@
         mPendingRelaunchCount = 0;
     }
 
+    /**
+     * Returns true if the new child window we are adding to this token is considered greater than
+     * the existing child window in this token in terms of z-order.
+     */
+    @Override
+    protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
+            WindowState existingWindow) {
+        final int type1 = newWindow.mAttrs.type;
+        final int type2 = existingWindow.mAttrs.type;
+
+        // Base application windows should be z-ordered BELOW all other windows in the app token.
+        if (type1 == TYPE_BASE_APPLICATION && type2 != TYPE_BASE_APPLICATION) {
+            return false;
+        } else if (type1 != TYPE_BASE_APPLICATION && type2 == TYPE_BASE_APPLICATION) {
+            return true;
+        }
+
+        // Starting windows should be z-ordered ABOVE all other windows in the app token.
+        if (type1 == TYPE_APPLICATION_STARTING && type2 != TYPE_APPLICATION_STARTING) {
+            return true;
+        } else if (type1 != TYPE_APPLICATION_STARTING && type2 == TYPE_APPLICATION_STARTING) {
+            return false;
+        }
+
+        // Otherwise the new window is greater than the existing window.
+        return true;
+    }
+
     @Override
     void addWindow(WindowState w) {
         super.addWindow(w);
@@ -918,8 +946,7 @@
 
             if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
                     "Removing starting window: " + tStartingWindow);
-            getDisplayContent().getWindowList().remove(tStartingWindow);
-            mService.mWindowsChanged = true;
+            getDisplayContent().removeFromWindowList(tStartingWindow);
             if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                     "Removing starting " + tStartingWindow + " from " + fromToken);
             fromToken.removeChild(tStartingWindow);
@@ -949,7 +976,7 @@
 
             mService.updateFocusedWindowLocked(
                     UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
-            mService.getDefaultDisplayContentLocked().setLayoutNeeded();
+            getDisplayContent().setLayoutNeeded();
             mService.mWindowPlacerLocked.performSurfacePlacement();
             Binder.restoreCallingIdentity(origId);
             return true;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e6f281d..793d2fe 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -29,40 +29,90 @@
 import static android.view.Surface.ROTATION_180;
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
+import static android.view.View.GONE;
 import static android.view.WindowManager.DOCKED_BOTTOM;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.DOCKED_TOP;
+import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
+import static android.view.WindowManager.INPUT_CONSUMER_PIP;
+import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
 import static android.view.WindowManager.LayoutParams.NEEDS_MENU_UNSET;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
+import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
+import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
+import static com.android.server.wm.WindowAnimator.KEYGUARD_ANIMATING_OUT;
+import static com.android.server.wm.WindowAnimator.KEYGUARD_ANIM_TIMEOUT_MS;
+import static com.android.server.wm.WindowAnimator.KEYGUARD_NOT_SHOWN;
+import static com.android.server.wm.WindowAnimator.KEYGUARD_SHOWN;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
+import static com.android.server.wm.WindowManagerService.H.UPDATE_DOCKED_STACK_DIVIDER;
 import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
+import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
+import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
+import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
+import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
 import static com.android.server.wm.WindowManagerService.dipToPixel;
 import static com.android.server.wm.WindowManagerService.localLOGV;
+import static com.android.server.wm.WindowManagerService.logSurface;
 import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
+import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
+import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
+import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
+import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
 
 import android.annotation.NonNull;
 import android.app.ActivityManager.StackId;
 import android.content.res.Configuration;
+import android.graphics.Bitmap;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -72,15 +122,23 @@
 import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SystemClock;
 import android.util.DisplayMetrics;
 import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.IWindow;
-import android.view.WindowManager;
+import android.view.InputChannel;
+import android.view.Surface;
+import android.view.SurfaceControl;
 import android.view.WindowManagerPolicy;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
 
 import com.android.internal.util.FastPrintWriter;
+import com.android.internal.view.IInputMethodClient;
+import com.android.server.input.InputWindowHandle;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -90,7 +148,11 @@
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /**
  * Utility class for keeping track of the WindowStates and other pertinent contents of a
@@ -100,6 +162,7 @@
  * WindowManagerService.mWindowMap.
  */
 class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer> {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
 
     /** Unique identifier of this stack. */
     private final int mDisplayId;
@@ -162,6 +225,7 @@
     private boolean mDeferredRemoval;
 
     final DockedStackDividerController mDividerControllerLocked;
+    final PinnedStackController mPinnedStackControllerLocked;
 
     final DimLayerController mDimLayerController;
 
@@ -170,6 +234,14 @@
     /** Used when rebuilding window list to keep track of windows that have been removed. */
     private WindowState[] mRebuildTmp = new WindowState[20];
 
+    /**
+     * Temporary list for comparison. Always clear this after use so we don't end up with
+     * orphaned windows references
+     */
+    private final ArrayList<WindowState> mTmpWindows = new ArrayList<>();
+
+    private final LinkedList<AppWindowToken> mTmpUpdateAllDrawn = new LinkedList();
+
     private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult =
             new TaskForResizePointSearchResult();
     private final GetWindowOnDisplaySearchResult mTmpGetWindowOnDisplaySearchResult =
@@ -180,6 +252,7 @@
     private boolean mRemovingDisplay = false;
 
     private final WindowLayersController mLayersController;
+    final WallpaperController mWallpaperController;
     int mInputMethodAnimLayerAdjustment;
 
     /**
@@ -187,18 +260,22 @@
      * @param service You know.
      * @param layersController window layer controller used to assign layer to the windows on this
      *                         display.
+     * @param wallpaperController wallpaper windows controller used to adjust the positioning of the
+     *                            wallpaper windows in the window list.
      */
     DisplayContent(Display display, WindowManagerService service,
-            WindowLayersController layersController) {
+            WindowLayersController layersController, WallpaperController wallpaperController) {
         mDisplay = display;
         mDisplayId = display.getDisplayId();
         mLayersController = layersController;
+        mWallpaperController = wallpaperController;
         display.getDisplayInfo(mDisplayInfo);
         display.getMetrics(mDisplayMetrics);
         isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
         mService = service;
         initializeDisplayBaseInfo();
         mDividerControllerLocked = new DockedStackDividerController(service, this);
+        mPinnedStackControllerLocked = new PinnedStackController(service, this);
         mDimLayerController = new DimLayerController(this);
 
         // These are the only direct children we should ever have and they are permanent.
@@ -210,10 +287,6 @@
         return mDisplayId;
     }
 
-    WindowList getWindowList() {
-        return mWindows;
-    }
-
     WindowToken getWindowToken(IBinder binder) {
         return mTokenMap.get(binder);
     }
@@ -269,6 +342,10 @@
         return mDividerControllerLocked;
     }
 
+    PinnedStackController getPinnedStackController() {
+        return mPinnedStackControllerLocked;
+    }
+
     /**
      * Returns true if the specified UID has access to this display.
      */
@@ -307,6 +384,7 @@
         mService.reconfigureDisplayLocked(this);
 
         getDockedDividerController().onConfigurationChanged();
+        getPinnedStackController().onConfigurationChanged();
     }
 
     /**
@@ -340,33 +418,79 @@
 
     @Override
     int getOrientation() {
-        if (mService.isStackVisibleLocked(DOCKED_STACK_ID)
-                || mService.isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
-            // Apps and their containers are not allowed to specify an orientation while the docked
-            // or freeform stack is visible...except for the home stack/task if the docked stack is
-            // minimized and it actually set something.
-            if (mHomeStack != null && mHomeStack.isVisible()
-                    && mDividerControllerLocked.isMinimizedDock()) {
-                final int orientation = mHomeStack.getOrientation();
-                if (orientation != SCREEN_ORIENTATION_UNSET) {
-                    return orientation;
-                }
+        final WindowManagerPolicy policy = mService.mPolicy;
+
+        // TODO: All the logic before the last return statement in this method should really go in
+        // #NonAppWindowContainer.getOrientation() since it is trying to decide orientation based
+        // on non-app windows. But, we can not do that until the window list is always correct in
+        // terms of z-ordering based on layers.
+        if (mService.mDisplayFrozen) {
+            if (mService.mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
+                        "Display is frozen, return " + mService.mLastWindowForcedOrientation);
+                // If the display is frozen, some activities may be in the middle of restarting, and
+                // thus have removed their old window. If the window has the flag to hide the lock
+                // screen, then the lock screen can re-appear and inflict its own orientation on us.
+                // Keep the orientation stable until this all settles down.
+                return mService.mLastWindowForcedOrientation;
+            } else if (policy.isKeyguardLocked()) {
+                // Use the last orientation the while the display is frozen with the keyguard
+                // locked. This could be the keyguard forced orientation or from a SHOW_WHEN_LOCKED
+                // window. We don't want to check the show when locked window directly though as
+                // things aren't stable while the display is frozen, for example the window could be
+                // momentarily unavailable due to activity relaunch.
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display is frozen while keyguard locked, "
+                        + "return " + mService.mLastOrientation);
+                return mService.mLastOrientation;
             }
-            return SCREEN_ORIENTATION_UNSPECIFIED;
+        } else {
+            for (int pos = mWindows.size() - 1; pos >= 0; --pos) {
+                final WindowState win = mWindows.get(pos);
+                if (win.mAppToken != null) {
+                    // We hit an application window. so the orientation will be determined by the
+                    // app window. No point in continuing further.
+                    break;
+                }
+                if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
+                    continue;
+                }
+                int req = win.mAttrs.screenOrientation;
+                if(req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND) {
+                    continue;
+                }
+
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
+                if (policy.isKeyguardHostWindow(win.mAttrs)) {
+                    mService.mLastKeyguardForcedOrientation = req;
+                }
+                return (mService.mLastWindowForcedOrientation = req);
+            }
+            mService.mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+
+            if (policy.isKeyguardLocked()) {
+                // The screen is locked and no top system window is requesting an orientation.
+                // Return either the orientation of the show-when-locked app (if there is any) or
+                // the orientation of the keyguard. No point in searching from the rest of apps.
+                WindowState winShowWhenLocked = (WindowState) policy.getWinShowWhenLockedLw();
+                AppWindowToken appShowWhenLocked = winShowWhenLocked == null
+                        ? null : winShowWhenLocked.mAppToken;
+                if (appShowWhenLocked != null) {
+                    int req = appShowWhenLocked.getOrientation();
+                    if (req == SCREEN_ORIENTATION_BEHIND) {
+                        req = mService.mLastKeyguardForcedOrientation;
+                    }
+                    if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Done at " + appShowWhenLocked
+                            + " -- show when locked, return " + req);
+                    return req;
+                }
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
+                        "No one is requesting an orientation when the screen is locked");
+                return mService.mLastKeyguardForcedOrientation;
+            }
         }
 
-        final int orientation = super.getOrientation();
-        if (orientation != SCREEN_ORIENTATION_UNSET && orientation != SCREEN_ORIENTATION_BEHIND) {
-            if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
-                    "App is requesting an orientation, return " + orientation);
-            return orientation;
-        }
-
-        if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
-                "No app is requesting an orientation, return " + mService.mLastOrientation);
-        // The next app has not been requested to be visible, so we keep the current orientation
-        // to prevent freezing/unfreezing the display too early.
-        return mService.mLastOrientation;
+        // Top system windows are not requesting an orientation. Start searching from apps.
+        return mTaskStackContainers.getOrientation();
     }
 
     void updateDisplayInfo() {
@@ -455,14 +579,6 @@
         throw new UnsupportedOperationException("See DisplayChildWindowContainer");
     }
 
-    /**
-     * Propagate the new bounds to all child stacks.
-     * @param contentRect The bounds to apply at the top level.
-     */
-    void resize(Rect contentRect) {
-        mContentRect.set(contentRect);
-    }
-
     int taskIdFromPoint(int x, int y) {
         for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
             final TaskStack stack = mTaskStackContainers.get(stackNdx);
@@ -534,9 +650,9 @@
     }
 
     void switchUser() {
-        final WindowList windows = getWindowList();
-        for (int i = 0; i < windows.size(); i++) {
-            final WindowState win = windows.get(i);
+        final int count = mWindows.size();
+        for (int i = 0; i < count; i++) {
+            final WindowState win = mWindows.get(i);
             if (win.isHiddenFromUserLocked()) {
                 if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + win
                         + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid);
@@ -561,7 +677,7 @@
         return mDimLayerController.animateDimLayers();
     }
 
-    void resetDimming() {
+    private void resetDimming() {
         mDimLayerController.resetDimming();
     }
 
@@ -569,7 +685,7 @@
         return mDimLayerController.isDimming();
     }
 
-    void stopDimmingIfNeeded() {
+    private void stopDimmingIfNeeded() {
         mDimLayerController.stopDimmingIfNeeded();
     }
 
@@ -704,6 +820,7 @@
             mDividerControllerLocked.setAdjustedForIme(
                     false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
         }
+        mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);
     }
 
     void setInputMethodAnimLayerAdjustment(int adj) {
@@ -846,6 +963,8 @@
         mDimLayerController.dump(prefix + "  ", pw);
         pw.println();
         mDividerControllerLocked.dump(prefix + "  ", pw);
+        pw.println();
+        mPinnedStackControllerLocked.dump(prefix + "  ", pw);
 
         if (mInputMethodAnimLayerAdjustment != 0) {
             pw.println(subPrefix
@@ -914,10 +1033,9 @@
 
     boolean canAddToastWindowForUid(int uid) {
         // We allow one toast window per UID being shown at a time.
-        WindowList windows = getWindowList();
-        final int windowCount = windows.size();
+        final int windowCount = mWindows.size();
         for (int i = 0; i < windowCount; i++) {
-            WindowState window = windows.get(i);
+            final WindowState window = mWindows.get(i);
             if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == uid
                     && !window.mPermanentlyHidden && !window.mAnimatingExit
                     && !window.mRemoveOnExit) {
@@ -932,11 +1050,10 @@
             return;
         }
         final int lostFocusUid = oldFocus.mOwnerUid;
-        final WindowList windows = getWindowList();
-        final int windowCount = windows.size();
+        final int windowCount = mWindows.size();
         final Handler handler = mService.mH;
         for (int i = 0; i < windowCount; i++) {
-            final WindowState window = windows.get(i);
+            final WindowState window = mWindows.get(i);
             if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == lostFocusUid) {
                 if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, window)) {
                     handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, window),
@@ -1001,12 +1118,13 @@
         return null;
     }
 
-    int addAppWindowToWindowList(final WindowState win) {
+    void addAppWindowToWindowList(final WindowState win) {
         final IWindow client = win.mClient;
 
         WindowList tokenWindowList = getTokenWindowsOnDisplay(win.mToken);
         if (!tokenWindowList.isEmpty()) {
-            return addAppWindowExisting(win, tokenWindowList);
+            addAppWindowExisting(win, tokenWindowList);
+            return;
         }
 
         // No windows from this token on this display
@@ -1044,7 +1162,7 @@
                 }
             }
             addWindowToListBefore(win, pos);
-            return 0;
+            return;
         }
 
         // Continue looking down until we find the first token that has windows on this display.
@@ -1070,7 +1188,7 @@
                 }
             }
             addWindowToListAfter(win, pos);
-            return 0;
+            return;
         }
 
         // Just search for the start of this layer.
@@ -1091,7 +1209,6 @@
                 + mWindows.size());
         mWindows.add(i + 1, win);
         mService.mWindowsChanged = true;
-        return 0;
     }
 
     /** Adds this non-app window to the window list. */
@@ -1121,34 +1238,35 @@
     }
 
     void addToWindowList(WindowState win, int index) {
+        mService.mWindowsChanged = true;
         mWindows.add(index, win);
     }
 
     boolean removeFromWindowList(WindowState win) {
+        mService.mWindowsChanged = true;
         return mWindows.remove(win);
     }
 
     private int removeWindowAndChildrenFromWindowList(WindowState win, int interestingPos) {
-        final WindowList windows = getWindowList();
-        int wpos = windows.indexOf(win);
+        int wpos = mWindows.indexOf(win);
         if (wpos < 0) {
             return interestingPos;
         }
 
         if (wpos < interestingPos) interestingPos--;
         if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this);
-        windows.remove(wpos);
+        mWindows.remove(wpos);
         mService.mWindowsChanged = true;
         int childWinCount = win.mChildren.size();
         while (childWinCount > 0) {
             childWinCount--;
             final WindowState cw = win.mChildren.get(childWinCount);
-            int cpos = windows.indexOf(cw);
+            int cpos = mWindows.indexOf(cw);
             if (cpos >= 0) {
                 if (cpos < interestingPos) interestingPos--;
                 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
                         "Temp removing child at " + cpos + ": " + cw);
-                windows.remove(cpos);
+                mWindows.remove(cpos);
             }
         }
         return interestingPos;
@@ -1198,12 +1316,18 @@
 
     /** Updates the layer assignment of windows on this display. */
     void assignWindowLayers(boolean setLayoutNeeded) {
-        mLayersController.assignWindowLayers(mWindows);
+        mLayersController.assignWindowLayers(mWindows.getReadOnly());
         if (setLayoutNeeded) {
             setLayoutNeeded();
         }
     }
 
+    void adjustWallpaperWindows() {
+        if (mWallpaperController.adjustWallpaperWindows(mWindows.getReadOnly())) {
+            assignWindowLayers(true /*setLayoutNeeded*/);
+        }
+    }
+
     /**
      * Z-orders the display window list so that:
      * <ul>
@@ -1296,6 +1420,160 @@
         Arrays.fill(mRebuildTmp, null);
     }
 
+    /** Rebuilds the display's window list and does a relayout if something changed. */
+    void rebuildAppWindowsAndLayoutIfNeeded() {
+        mTmpWindows.clear();
+        mTmpWindows.addAll(mWindows);
+
+        rebuildAppWindowList();
+
+        // Set displayContent.mLayoutNeeded if window order changed.
+        final int tmpSize = mTmpWindows.size();
+        final int winSize = mWindows.size();
+        int tmpNdx = 0, winNdx = 0;
+        while (tmpNdx < tmpSize && winNdx < winSize) {
+            // Skip over all exiting windows, they've been moved out of order.
+            WindowState tmp;
+            do {
+                tmp = mTmpWindows.get(tmpNdx++);
+            } while (tmpNdx < tmpSize && tmp.mAppToken != null && tmp.mAppToken.mIsExiting);
+
+            WindowState win;
+            do {
+                win = mWindows.get(winNdx++);
+            } while (winNdx < winSize && win.mAppToken != null && win.mAppToken.mIsExiting);
+
+            if (tmp != win) {
+                // Window order changed.
+                setLayoutNeeded();
+                break;
+            }
+        }
+        if (tmpNdx != winNdx) {
+            // One list was different from the other.
+            setLayoutNeeded();
+        }
+        mTmpWindows.clear();
+
+        if (!mService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
+                false /*updateInputWindows*/)) {
+            assignWindowLayers(false /* setLayoutNeeded */);
+        }
+
+        mService.mInputMonitor.setUpdateInputWindowsNeededLw();
+        mService.mWindowPlacerLocked.performSurfacePlacement();
+        mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
+    }
+
+    void updateInputWindows(InputMonitor inputMonitor, WindowState inputFocus, boolean inDrag) {
+        final InputConsumerImpl navInputConsumer =
+                mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_NAVIGATION, mDisplayId);
+        final InputConsumerImpl pipInputConsumer =
+                mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_PIP, mDisplayId);
+        final InputConsumerImpl wallpaperInputConsumer =
+                mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_WALLPAPER, mDisplayId);
+        boolean addInputConsumerHandle = navInputConsumer != null;
+        boolean addPipInputConsumerHandle = pipInputConsumer != null;
+        boolean addWallpaperInputConsumerHandle = wallpaperInputConsumer != null;
+        final Rect pipTouchableBounds = addPipInputConsumerHandle ? new Rect() : null;
+        boolean disableWallpaperTouchEvents = false;
+
+        for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) {
+            final WindowState child = mWindows.get(winNdx);
+            final InputChannel inputChannel = child.mInputChannel;
+            final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
+            if (inputChannel == null || inputWindowHandle == null || child.mRemoved
+                    || child.isAdjustedForMinimizedDock()) {
+                // Skip this window because it cannot possibly receive input.
+                continue;
+            }
+
+            if (addPipInputConsumerHandle
+                    && child.getStackId() == PINNED_STACK_ID
+                    && inputWindowHandle.layer <= pipInputConsumer.mWindowHandle.layer) {
+                // Update the bounds of the Pip input consumer to match the Pinned stack
+                child.getStack().getBounds(pipTouchableBounds);
+                pipInputConsumer.mWindowHandle.touchableRegion.set(pipTouchableBounds);
+                inputMonitor.addInputWindowHandle(pipInputConsumer.mWindowHandle);
+                addPipInputConsumerHandle = false;
+            }
+
+            if (addInputConsumerHandle
+                    && inputWindowHandle.layer <= navInputConsumer.mWindowHandle.layer) {
+                inputMonitor.addInputWindowHandle(navInputConsumer.mWindowHandle);
+                addInputConsumerHandle = false;
+            }
+
+            if (addWallpaperInputConsumerHandle) {
+                if (child.mAttrs.type == TYPE_WALLPAPER && child.isVisibleLw()) {
+                    // Add the wallpaper input consumer above the first visible wallpaper.
+                    inputMonitor.addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
+                    addWallpaperInputConsumerHandle = false;
+                }
+            }
+
+            final int flags = child.mAttrs.flags;
+            final int privateFlags = child.mAttrs.privateFlags;
+            final int type = child.mAttrs.type;
+
+            final boolean hasFocus = child == inputFocus;
+            final boolean isVisible = child.isVisibleLw();
+            if ((privateFlags & PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS) != 0) {
+                disableWallpaperTouchEvents = true;
+            }
+            final boolean hasWallpaper = mWallpaperController.isWallpaperTarget(child)
+                    && (privateFlags & PRIVATE_FLAG_KEYGUARD) == 0
+                    && !disableWallpaperTouchEvents;
+
+            // If there's a drag in progress and 'child' is a potential drop target,
+            // make sure it's been told about the drag
+            if (inDrag && isVisible && isDefaultDisplay) {
+                mService.mDragState.sendDragStartedIfNeededLw(child);
+            }
+
+            inputMonitor.addInputWindowHandle(
+                    inputWindowHandle, child, flags, type, isVisible, hasFocus, hasWallpaper);
+        }
+
+        if (addWallpaperInputConsumerHandle) {
+            // No visible wallpaper found, add the wallpaper input consumer at the end.
+            inputMonitor.addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
+        }
+    }
+
+    /** Returns true if a leaked surface was destroyed */
+    boolean destroyLeakedSurfaces() {
+        boolean leakedSurface = false;
+        final int numWindows = mWindows.size();
+        for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
+            final WindowState ws = mWindows.get(winNdx);
+            final WindowStateAnimator wsa = ws.mWinAnimator;
+            if (wsa.mSurfaceController == null) {
+                continue;
+            }
+            if (!mService.mSessions.contains(wsa.mSession)) {
+                Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
+                        + ws + " surface=" + wsa.mSurfaceController
+                        + " token=" + ws.mToken
+                        + " pid=" + ws.mSession.mPid
+                        + " uid=" + ws.mSession.mUid);
+                wsa.destroySurface();
+                mService.mForceRemoves.add(ws);
+                leakedSurface = true;
+            } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
+                Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
+                        + ws + " surface=" + wsa.mSurfaceController
+                        + " token=" + ws.mAppToken
+                        + " saved=" + ws.hasSavedSurface());
+                if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
+                wsa.destroySurface();
+                leakedSurface = true;
+            }
+        }
+
+        return leakedSurface;
+    }
+
     /** Return the list of Windows on this display associated with the input token. */
     WindowList getTokenWindowsOnDisplay(WindowToken token) {
         final WindowList windowList = new WindowList();
@@ -1377,8 +1655,6 @@
         }
 
         // TODO(multidisplay): IMEs are only supported on the default display.
-        WindowList windows = mWindows;
-
         int imPos = findDesiredInputMethodWindowIndex(true);
         if (imPos >= 0) {
             // In this case, the input method windows are to be placed
@@ -1386,8 +1662,8 @@
 
             // First check to see if the input method windows are already
             // located here, and contiguous.
-            final int N = windows.size();
-            final WindowState firstImWin = imPos < N ? windows.get(imPos) : null;
+            final int N = mWindows.size();
+            final WindowState firstImWin = imPos < N ? mWindows.get(imPos) : null;
 
             // Figure out the actual input method window that should be
             // at the bottom of their stack.
@@ -1402,7 +1678,7 @@
                 // First find the top IM window.
                 int pos = imPos+1;
                 while (pos < N) {
-                    if (!(windows.get(pos)).mIsImWindow) {
+                    if (!(mWindows.get(pos)).mIsImWindow) {
                         break;
                     }
                     pos++;
@@ -1410,7 +1686,7 @@
                 pos++;
                 // Now there should be no more input method windows above.
                 while (pos < N) {
-                    if ((windows.get(pos)).mIsImWindow) {
+                    if ((mWindows.get(pos)).mIsImWindow) {
                         break;
                     }
                     pos++;
@@ -1423,17 +1699,17 @@
             if (imWin != null) {
                 if (DEBUG_INPUT_METHOD) {
                     Slog.v(TAG_WM, "Moving IM from " + imPos);
-                    logWindowList(windows, "  ");
+                    logWindowList(mWindows, "  ");
                 }
                 imPos = removeWindowAndChildrenFromWindowList(imWin, imPos);
                 if (DEBUG_INPUT_METHOD) {
                     Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":");
-                    logWindowList(windows, "  ");
+                    logWindowList(mWindows, "  ");
                 }
                 imWin.reAddWindow(imPos);
                 if (DEBUG_INPUT_METHOD) {
                     Slog.v(TAG_WM, "List after moving IM to " + imPos + ":");
-                    logWindowList(windows, "  ");
+                    logWindowList(mWindows, "  ");
                 }
                 if (DN > 0) moveInputMethodDialogs(imPos+1);
             } else {
@@ -1450,7 +1726,7 @@
                 reAddToWindowList(imWin);
                 if (DEBUG_INPUT_METHOD) {
                     Slog.v(TAG_WM, "List with no IM target:");
-                    logWindowList(windows, "  ");
+                    logWindowList(mWindows, "  ");
                 }
                 if (DN > 0) moveInputMethodDialogs(-1);
             } else {
@@ -1475,11 +1751,10 @@
         // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
         // same display. Or even when the current IME/target are not on the same screen as the next
         // IME/target. For now only look for input windows on the main screen.
-        final WindowList windows = getWindowList();
         WindowState w = null;
         int i;
-        for (i = windows.size() - 1; i >= 0; --i) {
-            WindowState win = windows.get(i);
+        for (i = mWindows.size() - 1; i >= 0; --i) {
+            final WindowState win = mWindows.get(i);
 
             if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG_WM, "Checking window @" + i
                     + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
@@ -1492,7 +1767,7 @@
                 // is not actually looking to move the IME, look down below for a real window to
                 // target...
                 if (!willMove && w.mAttrs.type == TYPE_APPLICATION_STARTING && i > 0) {
-                    WindowState wb = windows.get(i-1);
+                    final WindowState wb = mWindows.get(i-1);
                     if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
                         i--;
                         w = wb;
@@ -1517,7 +1792,7 @@
                 && curTarget.isClosing()
                 && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
             if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
-            return windows.indexOf(curTarget) + 1;
+            return mWindows.indexOf(curTarget) + 1;
         }
 
         if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target="
@@ -1533,7 +1808,7 @@
                 WindowState highestTarget = null;
                 int highestPos = 0;
                 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
-                    WindowList curWindows = token.getDisplayContent().getWindowList();
+                    WindowList curWindows = token.getDisplayContent().mWindows;
                     int pos = curWindows.indexOf(curTarget);
                     while (pos >= 0) {
                         WindowState win = curWindows.get(pos);
@@ -1598,7 +1873,7 @@
             // docked divider. Unless it is already above the divider.
             final WindowState dockedDivider = mDividerControllerLocked.getWindow();
             if (dockedDivider != null && dockedDivider.isVisibleLw()) {
-                int dividerIndex = windows.indexOf(dockedDivider);
+                int dividerIndex = mWindows.indexOf(dockedDivider);
                 if (dividerIndex > 0 && dividerIndex > i) {
                     return dividerIndex + 1;
                 }
@@ -1651,7 +1926,6 @@
 
     boolean getNeedsMenu(WindowState win, WindowManagerPolicy.WindowState bottom) {
         int index = -1;
-        WindowList windows = getWindowList();
         while (true) {
             if (win.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) {
                 return win.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE;
@@ -1664,13 +1938,13 @@
             // The current window hasn't specified whether menu key is needed; look behind it.
             // First, we may need to determine the starting position.
             if (index < 0) {
-                index = windows.indexOf(win);
+                index = mWindows.indexOf(win);
             }
             index--;
             if (index < 0) {
                 return false;
             }
-            win = windows.get(index);
+            win = mWindows.get(index);
         }
     }
 
@@ -1679,7 +1953,7 @@
         mLayoutNeeded = true;
     }
 
-    void clearLayoutNeeded() {
+    private void clearLayoutNeeded() {
         if (DEBUG_LAYOUT) Slog.w(TAG_WM, "clearLayoutNeeded: callers=" + Debug.getCallers(3));
         mLayoutNeeded = false;
     }
@@ -1688,23 +1962,20 @@
         return mLayoutNeeded;
     }
 
-    private int addAppWindowExisting(WindowState win, WindowList tokenWindowList) {
+    private void addAppWindowExisting(WindowState win, WindowList tokenWindowList) {
 
-        int tokenWindowsPos;
         // If this application has existing windows, we simply place the new window on top of
         // them... but keep the starting window on top.
         if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
             // Base windows go behind everything else.
             final WindowState lowestWindow = tokenWindowList.get(0);
             addWindowToListBefore(win, lowestWindow);
-            tokenWindowsPos = win.mToken.getWindowIndex(lowestWindow);
         } else {
             final AppWindowToken atoken = win.mAppToken;
             final int windowListPos = tokenWindowList.size();
             final WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
             if (atoken != null && lastWindow == atoken.startingWindow) {
                 addWindowToListBefore(win, lastWindow);
-                tokenWindowsPos = win.mToken.getWindowIndex(lastWindow);
             } else {
                 int newIdx = findIdxBasedOnAppTokens(win);
                 // There is a window above this one associated with the same apptoken note that the
@@ -1714,16 +1985,9 @@
                         "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
                                 + mWindows.size());
                 mWindows.add(newIdx + 1, win);
-                if (newIdx < 0) {
-                    // No window from token found on win's display.
-                    tokenWindowsPos = 0;
-                } else {
-                    tokenWindowsPos = win.mToken.getWindowIndex(mWindows.get(newIdx)) + 1;
-                }
                 mService.mWindowsChanged = true;
             }
         }
-        return tokenWindowsPos;
     }
 
     /** Places the first input window after the second input window in the window list. */
@@ -1772,9 +2036,8 @@
 
     private void dumpWindows() {
         Slog.v(TAG_WM, " Display #" + mDisplayId);
-        final WindowList windows = getWindowList();
-        for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-            Slog.v(TAG_WM, "  #" + winNdx + ": " + windows.get(winNdx));
+        for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) {
+            Slog.v(TAG_WM, "  #" + winNdx + ": " + mWindows.get(winNdx));
         }
     }
 
@@ -1797,6 +2060,14 @@
         }
     }
 
+    void dumpWindowAnimators(PrintWriter pw, String subPrefix) {
+        final int count = mWindows.size();
+        for (int j = 0; j < count; j++) {
+            final WindowStateAnimator wAnim = mWindows.get(j).mWinAnimator;
+            pw.println(subPrefix + "Window #" + j + ": " + wAnim);
+        }
+    }
+
     void enableSurfaceTrace(FileDescriptor fd) {
         for (int i = mWindows.size() - 1; i >= 0; i--) {
             final WindowState win = mWindows.get(i);
@@ -1811,6 +2082,1198 @@
         }
     }
 
+    boolean checkWaitingForWindows() {
+
+        boolean haveBootMsg = false;
+        boolean haveApp = false;
+        // if the wallpaper service is disabled on the device, we're never going to have
+        // wallpaper, don't bother waiting for it
+        boolean haveWallpaper = false;
+        boolean wallpaperEnabled = mService.mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_enableWallpaperService)
+                && !mService.mOnlyCore;
+        boolean haveKeyguard = true;
+        final int count = mWindows.size();
+        for (int i = 0; i < count; i++) {
+            final WindowState w = mWindows.get(i);
+            if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
+                return true;
+            }
+            if (w.isDrawnLw()) {
+                if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
+                    haveBootMsg = true;
+                } else if (w.mAttrs.type == TYPE_APPLICATION
+                        || w.mAttrs.type == TYPE_DRAWN_APPLICATION) {
+                    haveApp = true;
+                } else if (w.mAttrs.type == TYPE_WALLPAPER) {
+                    haveWallpaper = true;
+                } else if (w.mAttrs.type == TYPE_STATUS_BAR) {
+                    haveKeyguard = mService.mPolicy.isKeyguardDrawnLw();
+                }
+            }
+        }
+
+        if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM,
+                "******** booted=" + mService.mSystemBooted
+                + " msg=" + mService.mShowingBootMessages
+                + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
+                + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
+                + " haveKeyguard=" + haveKeyguard);
+
+        // If we are turning on the screen to show the boot message, don't do it until the boot
+        // message is actually displayed.
+        if (!mService.mSystemBooted && !haveBootMsg) {
+            return true;
+        }
+
+        // If we are turning on the screen after the boot is completed normally, don't do so until
+        // we have the application and wallpaper.
+        if (mService.mSystemBooted && ((!haveApp && !haveKeyguard) ||
+                (wallpaperEnabled && !haveWallpaper))) {
+            return true;
+        }
+
+        return false;
+    }
+
+    void updateWindowsForAnimator(WindowAnimator animator) {
+        final WindowManagerPolicy policy = animator.mPolicy;
+        final int keyguardGoingAwayFlags = animator.mKeyguardGoingAwayFlags;
+        final boolean keyguardGoingAwayToShade =
+                (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0;
+        final boolean keyguardGoingAwayNoAnimation =
+                (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0;
+        final boolean keyguardGoingAwayWithWallpaper =
+                (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0;
+
+        if (animator.mKeyguardGoingAway) {
+            for (int i = mWindows.size() - 1; i >= 0; i--) {
+                WindowState win = mWindows.get(i);
+                if (!policy.isKeyguardHostWindow(win.mAttrs)) {
+                    continue;
+                }
+                final WindowStateAnimator winAnimator = win.mWinAnimator;
+                if (policy.isKeyguardShowingAndNotOccluded()) {
+                    if (!winAnimator.mAnimating) {
+                        if (DEBUG_KEYGUARD) Slog.d(TAG,
+                                "updateWindowsForAnimator: creating delay animation");
+
+                        // Create a new animation to delay until keyguard is gone on its own.
+                        winAnimator.mAnimation = new AlphaAnimation(1.0f, 1.0f);
+                        winAnimator.mAnimation.setDuration(KEYGUARD_ANIM_TIMEOUT_MS);
+                        winAnimator.mAnimationIsEntrance = false;
+                        winAnimator.mAnimationStartTime = -1;
+                        winAnimator.mKeyguardGoingAwayAnimation = true;
+                        winAnimator.mKeyguardGoingAwayWithWallpaper
+                                = keyguardGoingAwayWithWallpaper;
+                    }
+                } else {
+                    if (DEBUG_KEYGUARD) Slog.d(TAG,
+                            "updateWindowsForAnimator: StatusBar is no longer keyguard");
+                    animator.mKeyguardGoingAway = false;
+                    winAnimator.clearAnimation();
+                }
+                break;
+            }
+        }
+
+        animator.mForceHiding = KEYGUARD_NOT_SHOWN;
+
+        boolean wallpaperInUnForceHiding = false;
+        boolean startingInUnForceHiding = false;
+        ArrayList<WindowStateAnimator> unForceHiding = null;
+        WindowState wallpaper = null;
+        final WallpaperController wallpaperController = mWallpaperController;
+        for (int i = mWindows.size() - 1; i >= 0; i--) {
+            WindowState win = mWindows.get(i);
+            WindowStateAnimator winAnimator = win.mWinAnimator;
+            final int flags = win.mAttrs.flags;
+            boolean canBeForceHidden = policy.canBeForceHidden(win, win.mAttrs);
+            boolean shouldBeForceHidden = animator.shouldForceHide(win);
+            if (winAnimator.hasSurface()) {
+                final boolean wasAnimating = winAnimator.mWasAnimating;
+                final boolean nowAnimating = winAnimator.stepAnimationLocked(animator.mCurrentTime);
+                winAnimator.mWasAnimating = nowAnimating;
+                animator.orAnimating(nowAnimating);
+
+                if (DEBUG_WALLPAPER) Slog.v(TAG,
+                        win + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating);
+
+                if (wasAnimating && !winAnimator.mAnimating
+                        && wallpaperController.isWallpaperTarget(win)) {
+                    animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
+                    pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+                    if (DEBUG_LAYOUT_REPEATS) {
+                        mService.mWindowPlacerLocked.debugLayoutRepeats(
+                                "updateWindowsAndWallpaperLocked 2", pendingLayoutChanges);
+                    }
+                }
+
+                if (policy.isForceHiding(win.mAttrs)) {
+                    if (!wasAnimating && nowAnimating) {
+                        if (DEBUG_KEYGUARD || DEBUG_ANIM || DEBUG_VISIBILITY) Slog.v(TAG,
+                                "Animation started that could impact force hide: " + win);
+                        animator.mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
+                        pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+                        if (DEBUG_LAYOUT_REPEATS) {
+                            mService.mWindowPlacerLocked.debugLayoutRepeats(
+                                    "updateWindowsAndWallpaperLocked 3", pendingLayoutChanges);
+                        }
+                        mService.mFocusMayChange = true;
+                    } else if (animator.mKeyguardGoingAway && !nowAnimating) {
+                        // Timeout!!
+                        Slog.e(TAG, "Timeout waiting for animation to startup");
+                        policy.startKeyguardExitAnimation(0, 0);
+                        animator.mKeyguardGoingAway = false;
+                    }
+                    if (win.isReadyForDisplay()) {
+                        if (nowAnimating && win.mWinAnimator.mKeyguardGoingAwayAnimation) {
+                            animator.mForceHiding = KEYGUARD_ANIMATING_OUT;
+                        } else {
+                            animator.mForceHiding = win.isDrawnLw()
+                                    ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN;
+                        }
+                    }
+                    if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
+                            "Force hide " + animator.forceHidingToString()
+                                    + " hasSurface=" + win.mHasSurface
+                                    + " policyVis=" + win.mPolicyVisibility
+                                    + " destroying=" + win.mDestroying
+                                    + " parentHidden=" + win.isParentWindowHidden()
+                                    + " vis=" + win.mViewVisibility
+                                    + " hidden=" + win.mToken.hidden
+                                    + " anim=" + win.mWinAnimator.mAnimation);
+                } else if (canBeForceHidden) {
+                    if (shouldBeForceHidden) {
+                        if (!win.hideLw(false, false)) {
+                            // Was already hidden
+                            continue;
+                        }
+                        if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
+                                "Now policy hidden: " + win);
+                    } else {
+                        final Animation postKeyguardExitAnimation =
+                                animator.mPostKeyguardExitAnimation;
+                        boolean applyExistingExitAnimation = postKeyguardExitAnimation != null
+                                && !postKeyguardExitAnimation.hasEnded()
+                                && !winAnimator.mKeyguardGoingAwayAnimation
+                                && win.hasDrawnLw()
+                                && !win.isChildWindow()
+                                && !win.mIsImWindow
+                                && isDefaultDisplay;
+
+                        // If the window is already showing and we don't need to apply an existing
+                        // Keyguard exit animation, skip.
+                        if (!win.showLw(false, false) && !applyExistingExitAnimation) {
+                            continue;
+                        }
+                        final boolean visibleNow = win.isVisibleNow();
+                        if (!visibleNow) {
+                            // Couldn't really show, must showLw() again when win becomes visible.
+                            win.hideLw(false, false);
+                            continue;
+                        }
+                        if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
+                                "Now policy shown: " + win);
+                        if ((animator.mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0
+                                && !win.isChildWindow()) {
+                            if (unForceHiding == null) {
+                                unForceHiding = new ArrayList<>();
+                            }
+                            unForceHiding.add(winAnimator);
+                            if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
+                                wallpaperInUnForceHiding = true;
+                            }
+                            if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
+                                startingInUnForceHiding = true;
+                            }
+                        } else if (applyExistingExitAnimation) {
+                            // We're already in the middle of an animation. Use the existing
+                            // animation to bring in this window.
+                            if (DEBUG_KEYGUARD) Slog.v(TAG,
+                                    "Applying existing Keyguard exit animation to new window: win="
+                                            + win);
+
+                            final Animation a = policy.createForceHideEnterAnimation(false,
+                                    keyguardGoingAwayToShade);
+                            winAnimator.setAnimation(a, postKeyguardExitAnimation.getStartTime(),
+                                    STACK_CLIP_BEFORE_ANIM);
+                            winAnimator.mKeyguardGoingAwayAnimation = true;
+                            winAnimator.mKeyguardGoingAwayWithWallpaper
+                                    = keyguardGoingAwayWithWallpaper;
+                        }
+                        final WindowState currentFocus = mService.mCurrentFocus;
+                        if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
+                            // We are showing on top of the current
+                            // focus, so re-evaluate focus to make
+                            // sure it is correct.
+                            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG,
+                                    "updateWindowsForAnimator: setting mFocusMayChange true");
+                            mService.mFocusMayChange = true;
+                        }
+                    }
+                    if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
+                        animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
+                        pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+                        if (DEBUG_LAYOUT_REPEATS) {
+                            mService.mWindowPlacerLocked.debugLayoutRepeats(
+                                    "updateWindowsAndWallpaperLocked 4", pendingLayoutChanges);
+                        }
+                    }
+                }
+            }
+
+            // If the window doesn't have a surface, the only thing we care about is the correct
+            // policy visibility.
+            else if (canBeForceHidden) {
+                if (shouldBeForceHidden) {
+                    win.hideLw(false, false);
+                } else {
+                    win.showLw(false, false);
+                }
+            }
+
+            final AppWindowToken atoken = win.mAppToken;
+            if (winAnimator.mDrawState == READY_TO_SHOW) {
+                if (atoken == null || atoken.allDrawn) {
+                    if (win.performShowLocked()) {
+                        pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
+                        if (DEBUG_LAYOUT_REPEATS) {
+                            mService.mWindowPlacerLocked.debugLayoutRepeats(
+                                    "updateWindowsAndWallpaperLocked 5", pendingLayoutChanges);
+                        }
+                    }
+                }
+            }
+            final AppWindowAnimator appAnimator = winAnimator.mAppAnimator;
+            if (appAnimator != null && appAnimator.thumbnail != null) {
+                if (appAnimator.thumbnailTransactionSeq != animator.mAnimTransactionSequence) {
+                    appAnimator.thumbnailTransactionSeq = animator.mAnimTransactionSequence;
+                    appAnimator.thumbnailLayer = 0;
+                }
+                if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) {
+                    appAnimator.thumbnailLayer = winAnimator.mAnimLayer;
+                }
+            }
+            if (win.mIsWallpaper) {
+                wallpaper = win;
+            }
+        } // end forall windows
+
+        // If we have windows that are being shown due to them no longer being force-hidden, apply
+        // the appropriate animation to them if animations are not disabled.
+        if (unForceHiding != null) {
+            if (!keyguardGoingAwayNoAnimation) {
+                boolean first = true;
+                for (int i=unForceHiding.size()-1; i>=0; i--) {
+                    final WindowStateAnimator winAnimator = unForceHiding.get(i);
+                    final Animation a = policy.createForceHideEnterAnimation(
+                            wallpaperInUnForceHiding && !startingInUnForceHiding,
+                            keyguardGoingAwayToShade);
+                    if (a != null) {
+                        if (DEBUG_KEYGUARD) Slog.v(TAG,
+                                "Starting keyguard exit animation on window " + winAnimator.mWin);
+                        winAnimator.setAnimation(a, STACK_CLIP_BEFORE_ANIM);
+                        winAnimator.mKeyguardGoingAwayAnimation = true;
+                        winAnimator.mKeyguardGoingAwayWithWallpaper
+                                = keyguardGoingAwayWithWallpaper;
+                        if (first) {
+                            animator.mPostKeyguardExitAnimation = a;
+                            animator.mPostKeyguardExitAnimation.setStartTime(animator.mCurrentTime);
+                            first = false;
+                        }
+                    }
+                }
+            } else if (animator.mKeyguardGoingAway) {
+                policy.startKeyguardExitAnimation(animator.mCurrentTime, 0 /* duration */);
+                animator.mKeyguardGoingAway = false;
+            }
+
+
+            // Wallpaper is going away in un-force-hide motion, animate it as well.
+            if (!wallpaperInUnForceHiding && wallpaper != null && !keyguardGoingAwayNoAnimation) {
+                if (DEBUG_KEYGUARD) Slog.d(TAG,
+                        "updateWindowsForAnimator: wallpaper animating away");
+                final Animation a = policy.createForceHideWallpaperExitAnimation(
+                        keyguardGoingAwayToShade);
+                if (a != null) {
+                    wallpaper.mWinAnimator.setAnimation(a);
+                }
+            }
+        }
+
+        if (animator.mPostKeyguardExitAnimation != null) {
+            // We're in the midst of a keyguard exit animation.
+            if (animator.mKeyguardGoingAway) {
+                policy.startKeyguardExitAnimation(animator.mCurrentTime +
+                                animator.mPostKeyguardExitAnimation.getStartOffset(),
+                        animator.mPostKeyguardExitAnimation.getDuration());
+                animator.mKeyguardGoingAway = false;
+            }
+            // mPostKeyguardExitAnimation might either be ended normally, cancelled, or "orphaned",
+            // meaning that the window it was running on was removed. We check for hasEnded() for
+            // ended normally and cancelled case, and check the time for the "orphaned" case.
+            else if (animator.mPostKeyguardExitAnimation.hasEnded()
+                    || animator.mCurrentTime - animator.mPostKeyguardExitAnimation.getStartTime()
+                    > animator.mPostKeyguardExitAnimation.getDuration()) {
+                // Done with the animation, reset.
+                if (DEBUG_KEYGUARD) Slog.v(TAG, "Done with Keyguard exit animations.");
+                animator.mPostKeyguardExitAnimation = null;
+            }
+        }
+
+        final WindowState winShowWhenLocked = (WindowState) policy.getWinShowWhenLockedLw();
+        if (winShowWhenLocked != null) {
+            animator.mLastShowWinWhenLocked = winShowWhenLocked;
+        }
+    }
+
+    void updateWallpaperForAnimator(WindowAnimator animator) {
+        resetAnimationBackgroundAnimator();
+
+        final WindowList windows = mWindows;
+        WindowState detachedWallpaper = null;
+
+        for (int i = windows.size() - 1; i >= 0; i--) {
+            final WindowState win = windows.get(i);
+            final WindowStateAnimator winAnimator = win.mWinAnimator;
+            if (winAnimator.mSurfaceController == null || !winAnimator.hasSurface()) {
+                continue;
+            }
+
+            final int flags = win.mAttrs.flags;
+
+            // If this window is animating, make a note that we have an animating window and take
+            // care of a request to run a detached wallpaper animation.
+            if (winAnimator.mAnimating) {
+                if (winAnimator.mAnimation != null) {
+                    if ((flags & FLAG_SHOW_WALLPAPER) != 0
+                            && winAnimator.mAnimation.getDetachWallpaper()) {
+                        detachedWallpaper = win;
+                    }
+                    final int color = winAnimator.mAnimation.getBackgroundColor();
+                    if (color != 0) {
+                        final TaskStack stack = win.getStack();
+                        if (stack != null) {
+                            stack.setAnimationBackground(winAnimator, color);
+                        }
+                    }
+                }
+                animator.setAnimating(true);
+            }
+
+            // If this window's app token is running a detached wallpaper animation, make a note so
+            // we can ensure the wallpaper is displayed behind it.
+            final AppWindowAnimator appAnimator = winAnimator.mAppAnimator;
+            if (appAnimator != null && appAnimator.animation != null
+                    && appAnimator.animating) {
+                if ((flags & FLAG_SHOW_WALLPAPER) != 0
+                        && appAnimator.animation.getDetachWallpaper()) {
+                    detachedWallpaper = win;
+                }
+
+                final int color = appAnimator.animation.getBackgroundColor();
+                if (color != 0) {
+                    final TaskStack stack = win.getStack();
+                    if (stack != null) {
+                        stack.setAnimationBackground(winAnimator, color);
+                    }
+                }
+            }
+        } // end forall windows
+
+        if (animator.mWindowDetachedWallpaper != detachedWallpaper) {
+            if (DEBUG_WALLPAPER) Slog.v(TAG, "Detached wallpaper changed from "
+                    + animator.mWindowDetachedWallpaper + " to " + detachedWallpaper);
+            animator.mWindowDetachedWallpaper = detachedWallpaper;
+            animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
+        }
+    }
+
+    void prepareWindowSurfaces() {
+        final int count = mWindows.size();
+        for (int j = 0; j < count; j++) {
+            mWindows.get(j).mWinAnimator.prepareSurfaceLocked(true);
+        }
+    }
+
+    boolean inputMethodClientHasFocus(IInputMethodClient client) {
+        // The focus for the client is the window immediately below where we would place the input
+        // method window.
+        int idx = findDesiredInputMethodWindowIndex(false);
+        if (idx <= 0) {
+            return false;
+        }
+
+        WindowState imFocus = mWindows.get(idx - 1);
+        if (DEBUG_INPUT_METHOD) {
+            Slog.i(TAG_WM, "Desired input method target: " + imFocus);
+            Slog.i(TAG_WM, "Current focus: " + mService.mCurrentFocus);
+            Slog.i(TAG_WM, "Last focus: " + mService.mLastFocus);
+        }
+
+        if (imFocus == null) {
+            return false;
+        }
+
+        // This may be a starting window, in which case we still want to count it as okay.
+        if (imFocus.mAttrs.type == TYPE_APPLICATION_STARTING && imFocus.mAppToken != null) {
+            // The client has definitely started, so it really should have a window in this app
+            // token. Let's look for it.
+            final WindowState w = imFocus.mAppToken.getFirstNonStartingWindow();
+            if (w != null) {
+                if (DEBUG_INPUT_METHOD) Slog.i(TAG_WM, "Switching to real app window: " + w);
+                imFocus = w;
+            }
+        }
+
+        final IInputMethodClient imeClient = imFocus.mSession.mClient;
+
+        if (DEBUG_INPUT_METHOD) {
+            Slog.i(TAG_WM, "IM target client: " + imeClient);
+            if (imeClient != null) {
+                Slog.i(TAG_WM, "IM target client binder: " + imeClient.asBinder());
+                Slog.i(TAG_WM, "Requesting client binder: " + client.asBinder());
+            }
+        }
+
+        return imeClient != null && imeClient.asBinder() == client.asBinder();
+    }
+
+    boolean hasSecureWindowOnScreen() {
+        for (int i = mWindows.size() - 1; i >= 0; --i) {
+            final WindowState ws = mWindows.get(i);
+            if (ws.isOnScreen() && (ws.mAttrs.flags & FLAG_SECURE) != 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void updateSystemUiVisibility(int visibility, int globalDiff) {
+        for (int i = mWindows.size() - 1; i >= 0; --i) {
+            final WindowState ws = mWindows.get(i);
+            try {
+                int curValue = ws.mSystemUiVisibility;
+                int diff = (curValue ^ visibility) & globalDiff;
+                int newValue = (curValue & ~diff) | (visibility & diff);
+                if (newValue != curValue) {
+                    ws.mSeq++;
+                    ws.mSystemUiVisibility = newValue;
+                }
+                if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
+                    ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
+                            visibility, newValue, diff);
+                }
+            } catch (RemoteException e) {
+                // so sorry
+            }
+        }
+    }
+
+    void onWindowFreezeTimeout() {
+        Slog.w(TAG_WM, "Window freeze timeout expired.");
+        mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
+        for (int i = mWindows.size() - 1; i >= 0; --i) {
+            final WindowState w = mWindows.get(i);
+            if (!w.mOrientationChanging) {
+                continue;
+            }
+            w.mOrientationChanging = false;
+            w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
+                    - mService.mDisplayFreezeTime);
+            Slog.w(TAG_WM, "Force clearing orientation change: " + w);
+        }
+        mService.mWindowPlacerLocked.performSurfacePlacement();
+    }
+
+    void waitForAllWindowsDrawn() {
+        final WindowManagerPolicy policy = mService.mPolicy;
+        for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) {
+            final WindowState win = mWindows.get(winNdx);
+            final boolean isForceHiding = policy.isForceHiding(win.mAttrs);
+            final boolean keyguard = policy.isKeyguardHostWindow(win.mAttrs);
+            if (win.isVisibleLw() && (win.mAppToken != null || isForceHiding || keyguard)) {
+                win.mWinAnimator.mDrawState = DRAW_PENDING;
+                // Force add to mResizingWindows.
+                win.mLastContentInsets.set(-1, -1, -1, -1);
+                mService.mWaitingForDrawn.add(win);
+
+                // No need to wait for the windows below Keyguard.
+                if (isForceHiding) {
+                    return;
+                }
+            }
+        }
+    }
+
+    ReadOnlyWindowList getReadOnlyWindowList() {
+        return mWindows.getReadOnly();
+    }
+
+    void getWindows(WindowList output) {
+        output.addAll(mWindows);
+    }
+
+    // TODO: Super crazy long method that should be broken down...
+    boolean applySurfaceChangesTransaction(boolean recoveringMemory) {
+
+        boolean focusDisplayed = false;
+        boolean displayHasContent = false;
+        float preferredRefreshRate = 0;
+        int preferredModeId = 0;
+
+
+        final int dw = mDisplayInfo.logicalWidth;
+        final int dh = mDisplayInfo.logicalHeight;
+        final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
+
+        mTmpUpdateAllDrawn.clear();
+
+        int repeats = 0;
+        do {
+            repeats++;
+            if (repeats > 6) {
+                Slog.w(TAG, "Animation repeat aborted after too many iterations");
+                clearLayoutNeeded();
+                break;
+            }
+
+            if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("On entry to LockedInner",
+                    pendingLayoutChanges);
+
+            if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
+                adjustWallpaperWindows();
+            }
+
+            if (isDefaultDisplay && (pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
+                if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
+                if (mService.updateOrientationFromAppTokensLocked(true, mDisplayId)) {
+                    setLayoutNeeded();
+                    mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
+                }
+            }
+
+            if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
+                setLayoutNeeded();
+            }
+
+            // FIRST LOOP: Perform a layout, if needed.
+            if (repeats < LAYOUT_REPEAT_THRESHOLD) {
+                performLayout(repeats == 1, false /* updateInputWindows */);
+            } else {
+                Slog.w(TAG, "Layout repeat skipped after too many iterations");
+            }
+
+            // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think it is animating.
+            pendingLayoutChanges = 0;
+
+            if (isDefaultDisplay) {
+                mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
+                for (int i = mWindows.size() - 1; i >= 0; i--) {
+                    final WindowState w = mWindows.get(i);
+                    if (w.mHasSurface) {
+                        mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow());
+                    }
+                }
+                pendingLayoutChanges |= mService.mPolicy.finishPostLayoutPolicyLw();
+                if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
+                        "after finishPostLayoutPolicyLw", pendingLayoutChanges);
+            }
+        } while (pendingLayoutChanges != 0);
+
+        RootWindowContainer root = mService.mRoot;
+        boolean obscured = false;
+        boolean syswin = false;
+        resetDimming();
+
+        // Only used if default window
+        final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
+
+        for (int i = mWindows.size() - 1; i >= 0; i--) {
+            final WindowState w = mWindows.get(i);
+            final Task task = w.getTask();
+            final boolean obscuredChanged = w.mObscured != obscured;
+
+            // Update effect.
+            w.mObscured = obscured;
+            if (!obscured) {
+                final boolean isDisplayed = w.isDisplayedLw();
+
+                if (isDisplayed && w.isObscuringFullscreen(mDisplayInfo)) {
+                    // This window completely covers everything behind it, so we want to leave all
+                    // of them as undimmed (for performance reasons).
+                    root.mObscuringWindow = w;
+                    obscured = true;
+                }
+
+                displayHasContent |= root.handleNotObscuredLocked(w, obscured, syswin);
+
+                if (w.mHasSurface && isDisplayed) {
+                    final int type = w.mAttrs.type;
+                    if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR
+                            || (w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
+                        syswin = true;
+                    }
+                    if (preferredRefreshRate == 0 && w.mAttrs.preferredRefreshRate != 0) {
+                        preferredRefreshRate = w.mAttrs.preferredRefreshRate;
+                    }
+                    if (preferredModeId == 0 && w.mAttrs.preferredDisplayModeId != 0) {
+                        preferredModeId = w.mAttrs.preferredDisplayModeId;
+                    }
+                }
+            }
+
+            w.applyDimLayerIfNeeded();
+
+            if (isDefaultDisplay && obscuredChanged && w.isVisibleLw()
+                    && mWallpaperController.isWallpaperTarget(w)) {
+                // This is the wallpaper target and its obscured state changed... make sure the
+                // current wallpaper's visibility has been updated accordingly.
+                mWallpaperController.updateWallpaperVisibility();
+            }
+
+            w.handleWindowMovedIfNeeded();
+
+            final WindowStateAnimator winAnimator = w.mWinAnimator;
+
+            //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
+            w.mContentChanged = false;
+
+            // Moved from updateWindowsAndWallpaperLocked().
+            if (w.mHasSurface) {
+                // Take care of the window being ready to display.
+                final boolean committed = winAnimator.commitFinishDrawingLocked();
+                if (isDefaultDisplay && committed) {
+                    if (w.mAttrs.type == TYPE_DREAM) {
+                        // HACK: When a dream is shown, it may at that point hide the lock screen.
+                        // So we need to redo the layout to let the phone window manager make this
+                        // happen.
+                        pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
+                        if (DEBUG_LAYOUT_REPEATS) {
+                            surfacePlacer.debugLayoutRepeats(
+                                    "dream and commitFinishDrawingLocked true",
+                                    pendingLayoutChanges);
+                        }
+                    }
+                    if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
+                        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                                "First draw done in potential wallpaper target " + w);
+                        root.mWallpaperMayChange = true;
+                        pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+                        if (DEBUG_LAYOUT_REPEATS) {
+                            surfacePlacer.debugLayoutRepeats(
+                                    "wallpaper and commitFinishDrawingLocked true",
+                                    pendingLayoutChanges);
+                        }
+                    }
+                }
+                if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) {
+                    // Updates the shown frame before we set up the surface. This is needed
+                    // because the resizing could change the top-left position (in addition to
+                    // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
+                    // position the surface.
+                    //
+                    // If an animation is being started, we can't call this method because the
+                    // animation hasn't processed its initial transformation yet, but in general
+                    // we do want to update the position if the window is animating.
+                    winAnimator.computeShownFrameLocked();
+                }
+                winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
+            }
+
+            final AppWindowToken atoken = w.mAppToken;
+            if (atoken != null) {
+                final boolean updateAllDrawn = atoken.updateDrawnWindowStates(w);
+                if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(atoken)) {
+                    mTmpUpdateAllDrawn.add(atoken);
+                }
+            }
+
+            if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
+                    && w.isDisplayedLw()) {
+                focusDisplayed = true;
+            }
+
+            w.updateResizingWindowIfNeeded();
+        }
+
+        mService.mDisplayManagerInternal.setDisplayProperties(mDisplayId,
+                displayHasContent,
+                preferredRefreshRate,
+                preferredModeId,
+                true /* inTraversal, must call performTraversalInTrans... below */);
+
+        stopDimmingIfNeeded();
+
+        while (!mTmpUpdateAllDrawn.isEmpty()) {
+            final AppWindowToken atoken = mTmpUpdateAllDrawn.removeLast();
+            // See if any windows have been drawn, so they (and others associated with them)
+            // can now be shown.
+            atoken.updateAllDrawn(this);
+        }
+
+        return focusDisplayed;
+    }
+
+    void performLayout(boolean initial, boolean updateInputWindows) {
+        if (!isLayoutNeeded()) {
+            return;
+        }
+        clearLayoutNeeded();
+
+        final int dw = mDisplayInfo.logicalWidth;
+        final int dh = mDisplayInfo.logicalHeight;
+
+        int i;
+
+        if (DEBUG_LAYOUT) {
+            Slog.v(TAG, "-------------------------------------");
+            Slog.v(TAG, "performLayout: needed=" + isLayoutNeeded() + " dw=" + dw + " dh=" + dh);
+        }
+
+        mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation,
+                getConfiguration().uiMode);
+        if (isDefaultDisplay) {
+            // Not needed on non-default displays.
+            mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
+            mService.mScreenRect.set(0, 0, dw, dh);
+        }
+
+        mService.mPolicy.getContentRectLw(mContentRect);
+
+        int seq = mService.mLayoutSeq + 1;
+        if (seq < 0) seq = 0;
+        mService.mLayoutSeq = seq;
+
+        boolean behindDream = false;
+
+        // First perform layout of any root windows (not attached to another window).
+        int topAttached = -1;
+        for (i = mWindows.size() - 1; i >= 0; i--) {
+            final WindowState win = mWindows.get(i);
+
+            // Don't do layout of a window if it is not visible, or soon won't be visible, to avoid
+            // wasting time and funky changes while a window is animating away.
+            final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
+                    || win.isGoneForLayoutLw();
+
+            if (DEBUG_LAYOUT && !win.mLayoutAttached) {
+                Slog.v(TAG, "1ST PASS " + win + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
+                        + " mLayoutAttached=" + win.mLayoutAttached
+                        + " screen changed=" + win.isConfigChanged());
+                final AppWindowToken atoken = win.mAppToken;
+                if (gone) Slog.v(TAG, "  GONE: mViewVisibility=" + win.mViewVisibility
+                        + " mRelayoutCalled=" + win.mRelayoutCalled + " hidden=" + win.mToken.hidden
+                        + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested)
+                        + " parentHidden=" + win.isParentWindowHidden());
+                else Slog.v(TAG, "  VIS: mViewVisibility=" + win.mViewVisibility
+                        + " mRelayoutCalled=" + win.mRelayoutCalled + " hidden=" + win.mToken.hidden
+                        + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested)
+                        + " parentHidden=" + win.isParentWindowHidden());
+            }
+
+            // If this view is GONE, then skip it -- keep the current frame, and let the caller know
+            // so they can ignore it if they want.  (We do the normal layout for INVISIBLE windows,
+            // since that means "perform layout as normal, just don't display").
+            if (!gone || !win.mHaveFrame || win.mLayoutNeeded
+                    || ((win.isConfigChanged() || win.setReportResizeHints())
+                    && !win.isGoneForLayoutLw() &&
+                    ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
+                            (win.mHasSurface && win.mAppToken != null &&
+                                    win.mAppToken.layoutConfigChanges)))) {
+                if (!win.mLayoutAttached) {
+                    if (initial) {
+                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
+                        win.mContentChanged = false;
+                    }
+                    if (win.mAttrs.type == TYPE_DREAM) {
+                        // Don't layout windows behind a dream, so that if it does stuff like hide
+                        // the status bar we won't get a bad transition when it goes away.
+                        behindDream = true;
+                    }
+                    win.mLayoutNeeded = false;
+                    win.prelayout();
+                    mService.mPolicy.layoutWindowLw(win, null);
+                    win.mLayoutSeq = seq;
+
+                    // Window frames may have changed. Update dim layer with the new bounds.
+                    final Task task = win.getTask();
+                    if (task != null) {
+                        mDimLayerController.updateDimLayer(task);
+                    }
+
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame=" + win.mFrame
+                            + " mContainingFrame=" + win.mContainingFrame
+                            + " mDisplayFrame=" + win.mDisplayFrame);
+                } else {
+                    if (topAttached < 0) topAttached = i;
+                }
+            }
+        }
+
+        boolean attachedBehindDream = false;
+
+        // Now perform layout of attached windows, which usually depend on the position of the
+        // window they are attached to. XXX does not deal with windows that are attached to windows
+        // that are themselves attached.
+        for (i = topAttached; i >= 0; i--) {
+            final WindowState win = mWindows.get(i);
+
+            if (win.mLayoutAttached) {
+                if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame
+                        + " mViewVisibility=" + win.mViewVisibility
+                        + " mRelayoutCalled=" + win.mRelayoutCalled);
+                // If this view is GONE, then skip it -- keep the current frame, and let the caller
+                // know so they can ignore it if they want.  (We do the normal layout for INVISIBLE
+                // windows, since that means "perform layout as normal, just don't display").
+                if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
+                    continue;
+                }
+                if ((win.mViewVisibility != GONE && win.mRelayoutCalled) || !win.mHaveFrame
+                        || win.mLayoutNeeded) {
+                    if (initial) {
+                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
+                        win.mContentChanged = false;
+                    }
+                    win.mLayoutNeeded = false;
+                    win.prelayout();
+                    mService.mPolicy.layoutWindowLw(win, win.getParentWindow());
+                    win.mLayoutSeq = seq;
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame=" + win.mFrame
+                            + " mContainingFrame=" + win.mContainingFrame
+                            + " mDisplayFrame=" + win.mDisplayFrame);
+                }
+            } else if (win.mAttrs.type == TYPE_DREAM) {
+                // Don't layout windows behind a dream, so that if it does stuff like hide the
+                // status bar we won't get a bad transition when it goes away.
+                attachedBehindDream = behindDream;
+            }
+        }
+
+        // Window frames may have changed. Tell the input dispatcher about it.
+        mService.mInputMonitor.layoutInputConsumers(dw, dh);
+        mService.mInputMonitor.setUpdateInputWindowsNeededLw();
+        if (updateInputWindows) {
+            mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
+        }
+
+        mService.mPolicy.finishLayoutLw();
+        mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
+    }
+
+    /**
+     * Takes a snapshot of the display.  In landscape mode this grabs the whole screen.
+     * In portrait mode, it grabs the full screenshot.
+     *
+     * @param width the width of the target bitmap
+     * @param height the height of the target bitmap
+     * @param includeFullDisplay true if the screen should not be cropped before capture
+     * @param frameScale the scale to apply to the frame, only used when width = -1 and height = -1
+     * @param config of the output bitmap
+     * @param wallpaperOnly true if only the wallpaper layer should be included in the screenshot
+     */
+    Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height,
+            boolean includeFullDisplay, float frameScale, Bitmap.Config config,
+            boolean wallpaperOnly) {
+        int dw = mDisplayInfo.logicalWidth;
+        int dh = mDisplayInfo.logicalHeight;
+        if (dw == 0 || dh == 0) {
+            if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot of " + appToken
+                    + ": returning null. logical widthxheight=" + dw + "x" + dh);
+            return null;
+        }
+
+        Bitmap bm = null;
+
+        int maxLayer = 0;
+        final Rect frame = new Rect();
+        final Rect stackBounds = new Rect();
+
+        boolean screenshotReady;
+        int minLayer;
+        if (appToken == null && !wallpaperOnly) {
+            screenshotReady = true;
+            minLayer = 0;
+        } else {
+            screenshotReady = false;
+            minLayer = Integer.MAX_VALUE;
+        }
+
+        WindowState appWin = null;
+
+        boolean includeImeInScreenshot;
+        synchronized(mService.mWindowMap) {
+            final AppWindowToken imeTargetAppToken = mService.mInputMethodTarget != null
+                    ? mService.mInputMethodTarget.mAppToken : null;
+            // We only include the Ime in the screenshot if the app we are screenshoting is the IME
+            // target and isn't in multi-window mode. We don't screenshot the IME in multi-window
+            // mode because the frame of the IME might not overlap with that of the app.
+            // E.g. IME target app at the top in split-screen mode and the IME at the bottom
+            // overlapping with the bottom app.
+            includeImeInScreenshot = imeTargetAppToken != null
+                    && imeTargetAppToken.appToken != null
+                    && imeTargetAppToken.appToken.asBinder() == appToken
+                    && !mService.mInputMethodTarget.isInMultiWindowMode();
+        }
+
+        final int aboveAppLayer = (mService.mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) + 1)
+                * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
+
+        synchronized(mService.mWindowMap) {
+            // Figure out the part of the screen that is actually the app.
+            appWin = null;
+            for (int i = mWindows.size() - 1; i >= 0; i--) {
+                final WindowState ws = mWindows.get(i);
+                if (!ws.mHasSurface) {
+                    continue;
+                }
+                if (ws.mLayer >= aboveAppLayer) {
+                    continue;
+                }
+                if (wallpaperOnly && !ws.mIsWallpaper) {
+                    continue;
+                }
+                if (ws.mIsImWindow) {
+                    if (!includeImeInScreenshot) {
+                        continue;
+                    }
+                } else if (ws.mIsWallpaper) {
+                    // If this is the wallpaper layer and we're only looking for the wallpaper layer
+                    // then the target window state is this one.
+                    if (wallpaperOnly) {
+                        appWin = ws;
+                    }
+
+                    if (appWin == null) {
+                        // We have not ran across the target window yet, so it is probably behind
+                        // the wallpaper. This can happen when the keyguard is up and all windows
+                        // are moved behind the wallpaper. We don't want to include the wallpaper
+                        // layer in the screenshot as it will cover-up the layer of the target
+                        // window.
+                        continue;
+                    }
+                    // Fall through. The target window is in front of the wallpaper. For this
+                    // case we want to include the wallpaper layer in the screenshot because
+                    // the target window might have some transparent areas.
+                } else if (appToken != null) {
+                    if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
+                        // This app window is of no interest if it is not associated with the
+                        // screenshot app.
+                        continue;
+                    }
+                    appWin = ws;
+                }
+
+                // Include this window.
+
+                final WindowStateAnimator winAnim = ws.mWinAnimator;
+                int layer = winAnim.mSurfaceController.getLayer();
+                if (maxLayer < layer) {
+                    maxLayer = layer;
+                }
+                if (minLayer > layer) {
+                    minLayer = layer;
+                }
+
+                // Don't include wallpaper in bounds calculation
+                if (!includeFullDisplay && !ws.mIsWallpaper) {
+                    final Rect wf = ws.mFrame;
+                    final Rect cr = ws.mContentInsets;
+                    int left = wf.left + cr.left;
+                    int top = wf.top + cr.top;
+                    int right = wf.right - cr.right;
+                    int bottom = wf.bottom - cr.bottom;
+                    frame.union(left, top, right, bottom);
+                    ws.getVisibleBounds(stackBounds);
+                    if (!Rect.intersects(frame, stackBounds)) {
+                        // Set frame empty if there's no intersection.
+                        frame.setEmpty();
+                    }
+                }
+
+                final boolean foundTargetWs =
+                        (ws.mAppToken != null && ws.mAppToken.token == appToken)
+                                || (appWin != null && wallpaperOnly);
+                if (foundTargetWs && ws.isDisplayedLw() && winAnim.getShown()) {
+                    screenshotReady = true;
+                }
+
+                if (ws.isObscuringFullscreen(mDisplayInfo)){
+                    break;
+                }
+            }
+
+            if (appToken != null && appWin == null) {
+                // Can't find a window to snapshot.
+                if (DEBUG_SCREENSHOT) Slog.i(TAG_WM,
+                        "Screenshot: Couldn't find a surface matching " + appToken);
+                return null;
+            }
+
+            if (!screenshotReady) {
+                Slog.i(TAG_WM, "Failed to capture screenshot of " + appToken +
+                        " appWin=" + (appWin == null ? "null" : (appWin + " drawState=" +
+                        appWin.mWinAnimator.mDrawState)));
+                return null;
+            }
+
+            // Screenshot is ready to be taken. Everything from here below will continue
+            // through the bottom of the loop and return a value. We only stay in the loop
+            // because we don't want to release the mWindowMap lock until the screenshot is
+            // taken.
+
+            if (maxLayer == 0) {
+                if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot of " + appToken
+                        + ": returning null maxLayer=" + maxLayer);
+                return null;
+            }
+
+            if (!includeFullDisplay) {
+                // Constrain frame to the screen size.
+                if (!frame.intersect(0, 0, dw, dh)) {
+                    frame.setEmpty();
+                }
+            } else {
+                // Caller just wants entire display.
+                frame.set(0, 0, dw, dh);
+            }
+            if (frame.isEmpty()) {
+                return null;
+            }
+
+            if (width < 0) {
+                width = (int) (frame.width() * frameScale);
+            }
+            if (height < 0) {
+                height = (int) (frame.height() * frameScale);
+            }
+
+            // Tell surface flinger what part of the image to crop. Take the top
+            // right part of the application, and crop the larger dimension to fit.
+            Rect crop = new Rect(frame);
+            if (width / (float) frame.width() < height / (float) frame.height()) {
+                int cropWidth = (int)((float)width / (float)height * frame.height());
+                crop.right = crop.left + cropWidth;
+            } else {
+                int cropHeight = (int)((float)height / (float)width * frame.width());
+                crop.bottom = crop.top + cropHeight;
+            }
+
+            // The screenshot API does not apply the current screen rotation.
+            int rot = mDisplay.getRotation();
+
+            if (rot == ROTATION_90 || rot == ROTATION_270) {
+                rot = (rot == ROTATION_90) ? ROTATION_270 : ROTATION_90;
+            }
+
+            // Surfaceflinger is not aware of orientation, so convert our logical
+            // crop to surfaceflinger's portrait orientation.
+            convertCropForSurfaceFlinger(crop, rot, dw, dh);
+
+            if (DEBUG_SCREENSHOT) {
+                Slog.i(TAG_WM, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
+                        + maxLayer + " appToken=" + appToken);
+                for (int i = 0; i < mWindows.size(); i++) {
+                    final WindowState win = mWindows.get(i);
+                    final WindowSurfaceController controller = win.mWinAnimator.mSurfaceController;
+                    Slog.i(TAG_WM, win + ": " + win.mLayer
+                            + " animLayer=" + win.mWinAnimator.mAnimLayer
+                            + " surfaceLayer=" + ((controller == null)
+                            ? "null" : controller.getLayer()));
+                }
+            }
+
+            final ScreenRotationAnimation screenRotationAnimation =
+                    mService.mAnimator.getScreenRotationAnimationLocked(DEFAULT_DISPLAY);
+            final boolean inRotation = screenRotationAnimation != null &&
+                    screenRotationAnimation.isAnimating();
+            if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG_WM,
+                    "Taking screenshot while rotating");
+
+            // We force pending transactions to flush before taking
+            // the screenshot by pushing an empty synchronous transaction.
+            SurfaceControl.openTransaction();
+            SurfaceControl.closeTransactionSync();
+
+            bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
+                    inRotation, rot);
+            if (bm == null) {
+                Slog.w(TAG_WM, "Screenshot failure taking screenshot for (" + dw + "x" + dh
+                        + ") to layer " + maxLayer);
+                return null;
+            }
+        }
+
+        if (DEBUG_SCREENSHOT) {
+            // TEST IF IT's ALL BLACK
+            int[] buffer = new int[bm.getWidth() * bm.getHeight()];
+            bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
+            boolean allBlack = true;
+            final int firstColor = buffer[0];
+            for (int i = 0; i < buffer.length; i++) {
+                if (buffer[i] != firstColor) {
+                    allBlack = false;
+                    break;
+                }
+            }
+            if (allBlack) {
+                Slog.i(TAG_WM, "Screenshot " + appWin + " was monochrome(" +
+                        Integer.toHexString(firstColor) + ")! mSurfaceLayer=" +
+                        (appWin != null ?
+                                appWin.mWinAnimator.mSurfaceController.getLayer() : "null") +
+                        " minLayer=" + minLayer + " maxLayer=" + maxLayer);
+            }
+        }
+
+        // Create a copy of the screenshot that is immutable and backed in ashmem.
+        // This greatly reduces the overhead of passing the bitmap between processes.
+        Bitmap ret = bm.createAshmemBitmap(config);
+        bm.recycle();
+        return ret;
+    }
+
+    // TODO: Can this use createRotationMatrix()?
+    private static void convertCropForSurfaceFlinger(Rect crop, int rot, int dw, int dh) {
+        if (rot == Surface.ROTATION_90) {
+            final int tmp = crop.top;
+            crop.top = dw - crop.right;
+            crop.right = crop.bottom;
+            crop.bottom = dw - crop.left;
+            crop.left = tmp;
+        } else if (rot == Surface.ROTATION_180) {
+            int tmp = crop.top;
+            crop.top = dh - crop.bottom;
+            crop.bottom = dh - tmp;
+            tmp = crop.right;
+            crop.right = dw - crop.left;
+            crop.left = dw - tmp;
+        } else if (rot == Surface.ROTATION_270) {
+            final int tmp = crop.top;
+            crop.top = crop.left;
+            crop.left = dh - crop.bottom;
+            crop.bottom = crop.right;
+            crop.right = dh - tmp;
+        }
+    }
+
+    void onSeamlessRotationTimeout() {
+        boolean layoutNeeded = false;
+        for (int i = mWindows.size() - 1; i >= 0; i--) {
+            final WindowState w = mWindows.get(i);
+            if (!w.mSeamlesslyRotated) {
+                continue;
+            }
+            layoutNeeded = true;
+            w.setDisplayLayoutNeeded();
+            mService.markForSeamlessRotation(w, false);
+        }
+
+        if (layoutNeeded) {
+            mService.mWindowPlacerLocked.performSurfacePlacement();
+        }
+    }
+
     static final class GetWindowOnDisplaySearchResult {
         boolean reachedToken;
         WindowState foundWindow;
@@ -1907,6 +3370,37 @@
             setLayoutNeeded();
         }
 
+        @Override
+        int getOrientation() {
+            if (mService.isStackVisibleLocked(DOCKED_STACK_ID)
+                    || mService.isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
+                // Apps and their containers are not allowed to specify an orientation while the
+                // docked or freeform stack is visible...except for the home stack/task if the
+                // docked stack is minimized and it actually set something.
+                if (mHomeStack != null && mHomeStack.isVisible()
+                        && mDividerControllerLocked.isMinimizedDock()) {
+                    final int orientation = mHomeStack.getOrientation();
+                    if (orientation != SCREEN_ORIENTATION_UNSET) {
+                        return orientation;
+                    }
+                }
+                return SCREEN_ORIENTATION_UNSPECIFIED;
+            }
+
+            final int orientation = super.getOrientation();
+            if (orientation != SCREEN_ORIENTATION_UNSET
+                    && orientation != SCREEN_ORIENTATION_BEHIND) {
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
+                        "App is requesting an orientation, return " + orientation);
+                return orientation;
+            }
+
+            if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
+                    "No app is requesting an orientation, return " + mService.mLastOrientation);
+            // The next app has not been requested to be visible, so we keep the current orientation
+            // to prevent freezing/unfreezing the display too early.
+            return mService.mLastOrientation;
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 8b5f62e..530fb1b 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -268,7 +268,7 @@
     }
 
     private void resetDragResizingChangeReported() {
-        final WindowList windowList = mDisplayContent.getWindowList();
+        final ReadOnlyWindowList windowList = mDisplayContent.getReadOnlyWindowList();
         for (int i = windowList.size() - 1; i >= 0; i--) {
             windowList.get(i).resetDragResizingChangeReported();
         }
@@ -371,6 +371,7 @@
     }
 
     void notifyDockedStackExistsChanged(boolean exists) {
+        // TODO(multi-display): Perform all actions only for current display.
         final int size = mDockedStackListeners.beginBroadcast();
         for (int i = 0; i < size; ++i) {
             final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 588bb76..d52168c 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -271,7 +271,7 @@
             Slog.d(TAG_WM, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
         }
 
-        final WindowList windows = mDisplayContent.getWindowList();
+        final ReadOnlyWindowList windows = mDisplayContent.getReadOnlyWindowList();
         final int N = windows.size();
         for (int i = 0; i < N; i++) {
             sendDragStartedLw(windows.get(i), touchX, touchY, mDataDescription);
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 065a3dc..a8eb75c 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,8 +16,10 @@
 
 package com.android.server.wm;
 
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.INPUT_CONSUMER_PIP;
 import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
@@ -108,7 +110,7 @@
         mService = service;
     }
 
-    void addInputConsumer(String name, InputConsumerImpl consumer) {
+    private void addInputConsumer(String name, InputConsumerImpl consumer) {
         mInputConsumers.put(name, consumer);
         updateInputWindowsLw(true /* force */);
     }
@@ -129,8 +131,9 @@
         return false;
     }
 
-    InputConsumerImpl getInputConsumer(String name) {
-        return mInputConsumers.get(name);
+    InputConsumerImpl getInputConsumer(String name, int displayId) {
+        // TODO(multi-display): Allow input consumers on non-default displays?
+        return (displayId == DEFAULT_DISPLAY) ? mInputConsumers.get(name) : null;
     }
 
     void layoutInputConsumers(int dw, int dh) {
@@ -164,8 +167,7 @@
             case INPUT_CONSUMER_PIP:
                 // The touchable region of the Pip input window is cropped to the bounds of the
                 // stack, and we need FLAG_NOT_TOUCH_MODAL to ensure other events fall through
-                consumer.mWindowHandle.layoutParamsFlags |=
-                        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+                consumer.mWindowHandle.layoutParamsFlags |= FLAG_NOT_TOUCH_MODAL;
                 break;
         }
         addInputConsumer(name, consumer);
@@ -384,7 +386,8 @@
     /* Notifies that the input device configuration has changed. */
     @Override
     public void notifyConfigurationChanged() {
-        mService.sendNewConfiguration();
+        // TODO(multi-display): Notify proper displays that are associated with this input device.
+        mService.sendNewConfiguration(DEFAULT_DISPLAY);
 
         synchronized (mInputDevicesReadyMonitor) {
             if (!mInputDevicesReady) {
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
new file mode 100644
index 0000000..a488d52
--- /dev/null
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2016 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.server.wm;
+
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import android.animation.ValueAnimator;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.Size;
+import android.util.Slog;
+import android.util.TypedValue;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.IPinnedStackController;
+import android.view.IPinnedStackListener;
+
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.policy.PipMotionHelper;
+import com.android.internal.policy.PipSnapAlgorithm;
+
+import java.io.PrintWriter;
+
+/**
+ * Holds the common state of the pinned stack between the system and SystemUI.
+ */
+class PinnedStackController {
+
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "PinnedStackController" : TAG_WM;
+
+    private final WindowManagerService mService;
+    private final DisplayContent mDisplayContent;
+    private final Handler mHandler = new Handler();
+
+    private IPinnedStackListener mPinnedStackListener;
+    private final PinnedStackListenerDeathHandler mPinnedStackListenerDeathHandler =
+            new PinnedStackListenerDeathHandler();
+
+    private final PinnedStackControllerCallback mCallbacks = new PinnedStackControllerCallback();
+    private final PipSnapAlgorithm mSnapAlgorithm;
+    private final PipMotionHelper mMotionHelper;
+
+    // States that affect how the PIP can be manipulated
+    private boolean mInInteractiveMode;
+    private boolean mIsImeShowing;
+    private int mImeHeight;
+    private final Rect mPreImeShowingBounds = new Rect();
+    private ValueAnimator mBoundsAnimator = null;
+
+    // The size and position information that describes where the pinned stack will go by default.
+    private int mDefaultStackGravity;
+    private Size mDefaultStackSize;
+    private Point mScreenEdgeInsets;
+
+    // Temp vars for calculation
+    private final DisplayMetrics mTmpMetrics = new DisplayMetrics();
+    private final Rect mTmpInsets = new Rect();
+
+    /**
+     * The callback object passed to listeners for them to notify the controller of state changes.
+     */
+    private class PinnedStackControllerCallback extends IPinnedStackController.Stub {
+
+        @Override
+        public void setInInteractiveMode(final boolean inInteractiveMode) {
+            mHandler.post(() -> {
+                // Cancel any existing animations on the PIP once the user starts dragging it
+                if (mBoundsAnimator != null && inInteractiveMode) {
+                    mBoundsAnimator.cancel();
+                }
+                mInInteractiveMode = inInteractiveMode;
+                mPreImeShowingBounds.setEmpty();
+            });
+        }
+    }
+
+    /**
+     * Handler for the case where the listener dies.
+     */
+    private class PinnedStackListenerDeathHandler implements IBinder.DeathRecipient {
+
+        @Override
+        public void binderDied() {
+            // Clean up the state if the listener dies
+            mInInteractiveMode = false;
+            mPinnedStackListener = null;
+        }
+    }
+
+    PinnedStackController(WindowManagerService service, DisplayContent displayContent) {
+        mService = service;
+        mDisplayContent = displayContent;
+        mSnapAlgorithm = new PipSnapAlgorithm(service.mContext);
+        mMotionHelper = new PipMotionHelper(BackgroundThread.getHandler());
+        reloadResources();
+    }
+
+    void onConfigurationChanged() {
+        reloadResources();
+    }
+
+    /**
+     * Reloads all the resources for the current configuration.
+     */
+    void reloadResources() {
+        final Resources res = mService.mContext.getResources();
+        final Size defaultSizeDp = Size.parseSize(res.getString(
+                com.android.internal.R.string.config_defaultPictureInPictureSize));
+        final Size screenEdgeInsetsDp = Size.parseSize(res.getString(
+                com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets));
+        mDefaultStackGravity = res.getInteger(
+                com.android.internal.R.integer.config_defaultPictureInPictureGravity);
+        mDisplayContent.getDisplay().getRealMetrics(mTmpMetrics);
+        mDefaultStackSize = new Size(dpToPx(defaultSizeDp.getWidth(), mTmpMetrics),
+                dpToPx(defaultSizeDp.getHeight(), mTmpMetrics));
+        mScreenEdgeInsets = new Point(dpToPx(screenEdgeInsetsDp.getWidth(), mTmpMetrics),
+                dpToPx(screenEdgeInsetsDp.getHeight(), mTmpMetrics));
+    }
+
+    /**
+     * Registers a pinned stack listener.
+     */
+    void registerPinnedStackListener(IPinnedStackListener listener) {
+        try {
+            listener.asBinder().linkToDeath(mPinnedStackListenerDeathHandler, 0);
+            listener.onListenerRegistered(mCallbacks);
+            mPinnedStackListener = listener;
+            notifyBoundsChanged(mIsImeShowing);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to register pinned stack listener", e);
+        }
+    }
+
+    /**
+     * @return the default bounds to show the PIP when there is no active PIP.
+     */
+    Rect getDefaultBounds() {
+        final Display display = mDisplayContent.getDisplay();
+        final Rect insetBounds = new Rect();
+        final Point displaySize = new Point();
+        display.getRealSize(displaySize);
+        mService.getStableInsetsLocked(mDisplayContent.getDisplayId(), mTmpInsets);
+        getInsetBounds(displaySize, mTmpInsets, insetBounds);
+
+        final Rect defaultBounds = new Rect();
+        Gravity.apply(mDefaultStackGravity, mDefaultStackSize.getWidth(),
+                mDefaultStackSize.getHeight(), insetBounds, 0, 0, defaultBounds);
+        return defaultBounds;
+    }
+
+    /**
+     * @return the movement bounds for the given {@param stackBounds} and the current state of the
+     *         controller.
+     */
+    Rect getMovementBounds(Rect stackBounds) {
+        final Display display = mDisplayContent.getDisplay();
+        final Rect movementBounds = new Rect();
+        final Point displaySize = new Point();
+        display.getRealSize(displaySize);
+        mService.getStableInsetsLocked(mDisplayContent.getDisplayId(), mTmpInsets);
+        getInsetBounds(displaySize, mTmpInsets, movementBounds);
+
+        // Adjust the right/bottom to ensure the stack bounds never goes offscreen
+        movementBounds.right = Math.max(movementBounds.left, movementBounds.right -
+                stackBounds.width());
+        movementBounds.bottom = Math.max(movementBounds.top, movementBounds.bottom -
+                stackBounds.height());
+
+        // Adjust the top if the ime is open
+        if (mIsImeShowing) {
+            movementBounds.bottom -= mImeHeight;
+        }
+
+        return movementBounds;
+    }
+
+    /**
+     * @return the PIP bounds given it's bounds pre-rotation, and post-rotation (with as applied
+     * by the display content, which currently transposes the dimensions but keeps each stack in
+     * the same physical space on the device).
+     */
+    Rect getPostRotationBounds(Rect preRotationStackBounds, Rect postRotationStackBounds) {
+        // Keep the pinned stack in the same aspect ratio as in the old orientation, but
+        // move it into the position in the rotated space, and snap to the closest space
+        // in the new orientation.
+        final Rect movementBounds = getMovementBounds(preRotationStackBounds);
+        final int stackWidth = preRotationStackBounds.width();
+        final int stackHeight = preRotationStackBounds.height();
+        final int left = postRotationStackBounds.centerX() - (stackWidth / 2);
+        final int top = postRotationStackBounds.centerY() - (stackHeight / 2);
+        final Rect postRotBounds = new Rect(left, top, left + stackWidth, top + stackHeight);
+        return mSnapAlgorithm.findClosestSnapBounds(movementBounds, postRotBounds);
+    }
+
+    /**
+     * Sets the Ime state and height.
+     */
+    void setAdjustedForIme(boolean adjustedForIme, int imeHeight) {
+        // Return early if there is no state change
+        if (mIsImeShowing == adjustedForIme && mImeHeight == imeHeight) {
+            return;
+        }
+
+        final Rect stackBounds = new Rect();
+        mService.getStackBounds(PINNED_STACK_ID, stackBounds);
+        final Rect prevMovementBounds = getMovementBounds(stackBounds);
+        final boolean wasAdjustedForIme = mIsImeShowing;
+        mIsImeShowing = adjustedForIme;
+        mImeHeight = imeHeight;
+        if (mInInteractiveMode) {
+            // If the user is currently interacting with the PIP and the ime state changes, then
+            // don't adjust the bounds and defer that to after the interaction
+            notifyBoundsChanged(adjustedForIme /* adjustedForIme */);
+        } else {
+            // Otherwise, we can move the PIP to a sane location to ensure that it does not block
+            // the user from interacting with the IME
+            Rect toBounds;
+            if (!wasAdjustedForIme && adjustedForIme) {
+                // If we are showing the IME, then store the previous bounds
+                mPreImeShowingBounds.set(stackBounds);
+                toBounds = adjustBoundsInMovementBounds(stackBounds);
+            } else if (wasAdjustedForIme && !adjustedForIme) {
+                if (!mPreImeShowingBounds.isEmpty()) {
+                    // If we are hiding the IME and the user is not interacting with the PIP, restore
+                    // the previous bounds
+                    toBounds = mPreImeShowingBounds;
+                } else {
+                    if (stackBounds.top == prevMovementBounds.bottom) {
+                        // If the PIP is resting on top of the IME, then adjust it with the hiding
+                        // of the IME
+                        final Rect movementBounds = getMovementBounds(stackBounds);
+                        toBounds = new Rect(stackBounds);
+                        toBounds.offsetTo(toBounds.left, movementBounds.bottom);
+                    } else {
+                        // Otherwise, leave the PIP in place
+                        toBounds = stackBounds;
+                    }
+                }
+            } else {
+                // Otherwise, the IME bounds have changed so we need to adjust the PIP bounds also
+                toBounds = adjustBoundsInMovementBounds(stackBounds);
+            }
+            if (!toBounds.equals(stackBounds)) {
+                if (mBoundsAnimator != null) {
+                    mBoundsAnimator.cancel();
+                }
+                mBoundsAnimator = mMotionHelper.createAnimationToBounds(stackBounds, toBounds);
+                mBoundsAnimator.start();
+            }
+        }
+    }
+
+    /**
+     * @return the adjusted {@param stackBounds} such that they are in the movement bounds.
+     */
+    private Rect adjustBoundsInMovementBounds(Rect stackBounds) {
+        final Rect movementBounds = getMovementBounds(stackBounds);
+        final Rect adjustedBounds = new Rect(stackBounds);
+        adjustedBounds.offset(0, Math.min(0, movementBounds.bottom - stackBounds.top));
+        return adjustedBounds;
+    }
+
+    /**
+     * Sends a broadcast that the PIP movement bounds have changed.
+     */
+    private void notifyBoundsChanged(boolean adjustedForIme) {
+        if (mPinnedStackListener != null) {
+            try {
+                mPinnedStackListener.onBoundsChanged(adjustedForIme);
+            } catch (RemoteException e) {
+                Slog.e(TAG_WM, "Error delivering bounds changed event.", e);
+            }
+        }
+    }
+
+    /**
+     * @return the bounds on the screen that the PIP can be visible in.
+     */
+    private void getInsetBounds(Point displaySize, Rect insets, Rect outRect) {
+        outRect.set(insets.left + mScreenEdgeInsets.x, insets.top + mScreenEdgeInsets.y,
+                displaySize.x - insets.right - mScreenEdgeInsets.x,
+                displaySize.y - insets.bottom - mScreenEdgeInsets.y);
+    }
+
+    /**
+     * @return the pixels for a given dp value.
+     */
+    private int dpToPx(float dpValue, DisplayMetrics dm) {
+        return (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, dpValue, dm);
+    }
+
+    void dump(String prefix, PrintWriter pw) {
+        pw.println(prefix + "PinnedStackController");
+        pw.println(prefix + "  mIsImeShowing=" + mIsImeShowing);
+        pw.println(prefix + "  mInInteractiveMode=" + mInInteractiveMode);
+    }
+}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index bddf6e2..a28dc10 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import android.app.AppOpsManager;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.hardware.power.V1_0.PowerHint;
@@ -34,35 +33,26 @@
 import android.util.SparseIntArray;
 import android.view.Display;
 import android.view.DisplayInfo;
-import android.view.InputChannel;
 import android.view.WindowManager;
 import com.android.internal.util.ArrayUtils;
 import com.android.server.EventLogTags;
-import com.android.server.input.InputWindowHandle;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.LinkedList;
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_DEFAULT;
+import static android.app.AppOpsManager.OP_NONE;
 import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
-import static android.view.WindowManager.INPUT_CONSUMER_PIP;
-import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
-import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -72,7 +62,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
@@ -89,7 +78,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
 import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
-import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
@@ -104,8 +92,6 @@
 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
 
 /** Root {@link WindowContainer} for the device. */
-// TODO: Several methods in here are accessing children of this container's children through various
-// references (WindowList I am looking at you :/). See if we can delegate instead.
 class RootWindowContainer extends WindowContainer<DisplayContent> {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
 
@@ -118,13 +104,6 @@
     private float mButtonBrightness = -1;
     private long mUserActivityTimeout = -1;
     private boolean mUpdateRotation = false;
-    private boolean mObscured = false;
-    private boolean mSyswin = false;
-    // Set to true when the display contains content to show the user.
-    // When false, the display manager may choose to mirror or blank the display.
-    private boolean mDisplayHasContent = false;
-    private float mPreferredRefreshRate = 0;
-    private int mPreferredModeId = 0;
     // Following variables are for debugging screen wakelock only.
     // Last window that requires screen wakelock
     WindowState mHoldScreenWindow = null;
@@ -147,8 +126,6 @@
 
     private final ArrayList<Integer> mChangedStackList = new ArrayList();
 
-    private final LinkedList<AppWindowToken> mTmpUpdateAllDrawn = new LinkedList();
-
     private final ArrayList<WindowToken> mTmpTokensList = new ArrayList();
 
     // Collection of binder tokens mapped to their window type we are allowed to create window
@@ -166,10 +143,12 @@
     RemoteEventTrace mRemoteEventTrace;
 
     private final WindowLayersController mLayersController;
+    final WallpaperController mWallpaperController;
 
     RootWindowContainer(WindowManagerService service) {
         mService = service;
         mLayersController = new WindowLayersController(mService);
+        mWallpaperController = new WallpaperController(mService);
     }
 
     WindowState computeFocusedWindow() {
@@ -214,7 +193,8 @@
     }
 
     private DisplayContent createDisplayContent(final Display display) {
-        final DisplayContent dc = new DisplayContent(display, mService, mLayersController);
+        final DisplayContent dc = new DisplayContent(display, mService, mLayersController,
+                mWallpaperController);
         final int displayId = display.getDisplayId();
 
         if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
@@ -233,7 +213,7 @@
             mService.configureDisplayPolicyLocked(dc);
 
             // TODO(multi-display): Create an input channel for each display with touch capability.
-            if (displayId == Display.DEFAULT_DISPLAY) {
+            if (displayId == DEFAULT_DISPLAY) {
                 dc.mTapDetector = new TaskTapPointerEventListener(
                         mService, dc);
                 mService.registerPointerEventListener(dc.mTapDetector);
@@ -271,8 +251,7 @@
 
             mService.mStackIdToStack.put(stackId, stack);
             if (stackId == DOCKED_STACK_ID) {
-                mService.getDefaultDisplayContentLocked().mDividerControllerLocked
-                        .notifyDockedStackExistsChanged(true);
+                dc.mDividerControllerLocked.notifyDockedStackExistsChanged(true);
             }
         }
 
@@ -303,14 +282,14 @@
         final int count = mChildren.size();
         for (int i = 0; i < count; ++i) {
             final DisplayContent dc = mChildren.get(i);
-            output.addAll(dc.getWindowList());
+            dc.getWindows(output);
         }
     }
 
     void getWindows(WindowList output, boolean visibleOnly, boolean appsOnly) {
         final int numDisplays = mChildren.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final WindowList windowList = mChildren.get(displayNdx).getWindowList();
+            final ReadOnlyWindowList windowList = mChildren.get(displayNdx).getReadOnlyWindowList();
             for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
                 final WindowState w = windowList.get(winNdx);
                 if ((!visibleOnly || w.mWinAnimator.getShown())
@@ -331,7 +310,7 @@
         }
         final int numDisplays = mChildren.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final WindowList windowList = mChildren.get(displayNdx).getWindowList();
+            final ReadOnlyWindowList windowList = mChildren.get(displayNdx).getReadOnlyWindowList();
             for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
                 final WindowState w = windowList.get(winNdx);
                 if (name != null) {
@@ -348,7 +327,7 @@
     WindowState findWindow(int hashCode) {
         final int numDisplays = mChildren.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final WindowList windows = mChildren.get(displayNdx).getWindowList();
+            final ReadOnlyWindowList windows = mChildren.get(displayNdx).getReadOnlyWindowList();
             final int numWindows = windows.size();
             for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
                 final WindowState w = windows.get(winNdx);
@@ -442,10 +421,10 @@
 
         // TODO(multi-display): By default we add this to the default display, but maybe we
         // should provide an API for a token to be added to any display?
-        final WindowToken token = new WindowToken(mService, binder, type, true,
-                getDisplayContent(DEFAULT_DISPLAY));
+        final DisplayContent dc = getDisplayContent(DEFAULT_DISPLAY);
+        final WindowToken token = new WindowToken(mService, binder, type, true, dc);
         if (type == TYPE_WALLPAPER) {
-            mService.mWallpaperControllerLocked.addWallpaperToken(token);
+            dc.mWallpaperController.addWallpaperToken(token);
         }
     }
 
@@ -566,8 +545,33 @@
         }
     }
 
-    /** Set new config and return array of ids of stacks that were changed during update. */
-    int[] setGlobalConfigurationIfNeeded(Configuration newConfiguration) {
+    /**
+     * Set new display override config and return array of ids of stacks that were changed during
+     * update. If called for the default display, global configuration will also be updated.
+     */
+    int[] setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration, int displayId) {
+        final DisplayContent displayContent = getDisplayContent(displayId);
+        if (displayContent == null) {
+            throw new IllegalArgumentException("Display not found for id: " + displayId);
+        }
+
+        final Configuration currentConfig = displayContent.getOverrideConfiguration();
+        final boolean configChanged = currentConfig.diff(newConfiguration) != 0;
+        if (!configChanged) {
+            return null;
+        }
+        displayContent.onOverrideConfigurationChanged(currentConfig);
+
+        if (displayId == DEFAULT_DISPLAY) {
+            // Override configuration of the default display duplicates global config. In this case
+            // we also want to update the global config.
+            return setGlobalConfigurationIfNeeded(newConfiguration);
+        } else {
+            return updateStackBoundsAfterConfigChange(displayId);
+        }
+    }
+
+    private int[] setGlobalConfigurationIfNeeded(Configuration newConfiguration) {
         final boolean configChanged = getConfiguration().diff(newConfiguration) != 0;
         if (!configChanged) {
             return null;
@@ -600,6 +604,16 @@
         return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
     }
 
+    /** Same as {@link #updateStackBoundsAfterConfigChange()} but only for a specific display. */
+    private int[] updateStackBoundsAfterConfigChange(int displayId) {
+        mChangedStackList.clear();
+
+        final DisplayContent dc = getDisplayContent(displayId);
+        dc.updateStackBoundsAfterConfigChange(mChangedStackList);
+
+        return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
+    }
+
     private void prepareFreezingTaskBounds() {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             mChildren.get(i).prepareFreezingTaskBounds();
@@ -608,7 +622,7 @@
 
     void setSecureSurfaceState(int userId, boolean disabled) {
         for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowList windows = mChildren.get(i).getWindowList();
+            final ReadOnlyWindowList windows = mChildren.get(i).getReadOnlyWindowList();
             for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                 final WindowState win = windows.get(winNdx);
                 if (win.mHasSurface && userId == UserHandle.getUserId(win.mOwnerUid)) {
@@ -621,17 +635,16 @@
     void updateAppOpsState() {
         final int count = mChildren.size();
         for (int i = 0; i < count; ++i) {
-            final WindowList windows = mChildren.get(i).getWindowList();
+            final ReadOnlyWindowList windows = mChildren.get(i).getReadOnlyWindowList();
             final int numWindows = windows.size();
             for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
                 final WindowState win = windows.get(winNdx);
-                if (win.mAppOp == AppOpsManager.OP_NONE) {
+                if (win.mAppOp == OP_NONE) {
                     continue;
                 }
                 final int mode = mService.mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
                         win.getOwningPackage());
-                win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED ||
-                        mode == AppOpsManager.MODE_DEFAULT);
+                win.setAppOpVisibilityLw(mode == MODE_ALLOWED || mode == MODE_DEFAULT);
             }
         }
     }
@@ -639,7 +652,7 @@
     boolean canShowStrictModeViolation(int pid) {
         final int count = mChildren.size();
         for (int i = 0; i < count; ++i) {
-            final WindowList windows = mChildren.get(i).getWindowList();
+            final ReadOnlyWindowList windows = mChildren.get(i).getReadOnlyWindowList();
             final int numWindows = windows.size();
             for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
                 final WindowState ws = windows.get(winNdx);
@@ -654,7 +667,7 @@
     void closeSystemDialogs(String reason) {
         final int count = mChildren.size();
         for (int i = 0; i < count; ++i) {
-            final WindowList windows = mChildren.get(i).getWindowList();
+            final ReadOnlyWindowList windows = mChildren.get(i).getReadOnlyWindowList();
             final int numWindows = windows.size();
             for (int j = 0; j < numWindows; ++j) {
                 final WindowState w = windows.get(j);
@@ -674,7 +687,7 @@
         try {
             for (int i = mChildren.size() - 1; i >= 0; i--) {
                 DisplayContent dc = mChildren.get(i);
-                final WindowList windows = dc.getWindowList();
+                final ReadOnlyWindowList windows = mChildren.get(i).getReadOnlyWindowList();
                 for (int j = windows.size() - 1; j >= 0; j--) {
                     final WindowState win = windows.get(j);
                     final AppWindowToken aToken = win.mAppToken;
@@ -708,85 +721,10 @@
     }
 
     void updateInputWindows(InputMonitor inputMonitor, WindowState inputFocus, boolean inDrag) {
-        final InputConsumerImpl navInputConsumer =
-                mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_NAVIGATION);
-        final InputConsumerImpl pipInputConsumer =
-                mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_PIP);
-        final InputConsumerImpl wallpaperInputConsumer =
-                mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_WALLPAPER);
-        boolean addInputConsumerHandle = navInputConsumer != null;
-        boolean addPipInputConsumerHandle = pipInputConsumer != null;
-        boolean addWallpaperInputConsumerHandle = wallpaperInputConsumer != null;
-        final Rect pipTouchableBounds = addPipInputConsumerHandle ? new Rect() : null;
-        final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
-        boolean disableWallpaperTouchEvents = false;
-
         final int count = mChildren.size();
         for (int i = 0; i < count; ++i) {
             final DisplayContent dc = mChildren.get(i);
-            final WindowList windows = dc.getWindowList();
-            for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-                final WindowState child = windows.get(winNdx);
-                final InputChannel inputChannel = child.mInputChannel;
-                final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
-                if (inputChannel == null || inputWindowHandle == null || child.mRemoved
-                        || child.isAdjustedForMinimizedDock()) {
-                    // Skip this window because it cannot possibly receive input.
-                    continue;
-                }
-
-                if (addPipInputConsumerHandle
-                        && child.getStackId() == PINNED_STACK_ID
-                        && inputWindowHandle.layer <= pipInputConsumer.mWindowHandle.layer) {
-                    // Update the bounds of the Pip input consumer to match the Pinned stack
-                    child.getStack().getBounds(pipTouchableBounds);
-                    pipInputConsumer.mWindowHandle.touchableRegion.set(pipTouchableBounds);
-                    inputMonitor.addInputWindowHandle(pipInputConsumer.mWindowHandle);
-                    addPipInputConsumerHandle = false;
-                }
-
-                if (addInputConsumerHandle
-                        && inputWindowHandle.layer <= navInputConsumer.mWindowHandle.layer) {
-                    inputMonitor.addInputWindowHandle(navInputConsumer.mWindowHandle);
-                    addInputConsumerHandle = false;
-                }
-
-                if (addWallpaperInputConsumerHandle) {
-                    if (child.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER &&
-                            child.isVisibleLw()) {
-                        // Add the wallpaper input consumer above the first visible wallpaper.
-                        inputMonitor.addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
-                        addWallpaperInputConsumerHandle = false;
-                    }
-                }
-
-                final int flags = child.mAttrs.flags;
-                final int privateFlags = child.mAttrs.privateFlags;
-                final int type = child.mAttrs.type;
-
-                final boolean hasFocus = child == inputFocus;
-                final boolean isVisible = child.isVisibleLw();
-                if ((privateFlags & PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS) != 0) {
-                    disableWallpaperTouchEvents = true;
-                }
-                final boolean hasWallpaper = wallpaperController.isWallpaperTarget(child)
-                        && (privateFlags & PRIVATE_FLAG_KEYGUARD) == 0
-                        && !disableWallpaperTouchEvents;
-
-                // If there's a drag in progress and 'child' is a potential drop target,
-                // make sure it's been told about the drag
-                if (inDrag && isVisible && dc.isDefaultDisplay) {
-                    mService.mDragState.sendDragStartedIfNeededLw(child);
-                }
-
-                inputMonitor.addInputWindowHandle(
-                        inputWindowHandle, child, flags, type, isVisible, hasFocus, hasWallpaper);
-            }
-        }
-
-        if (addWallpaperInputConsumerHandle) {
-            // No visible wallpaper found, add the wallpaper input consumer at the end.
-            inputMonitor.addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
+            dc.updateInputWindows(inputMonitor, inputFocus, inDrag);
         }
     }
 
@@ -801,57 +739,33 @@
 
         final long callingIdentity = Binder.clearCallingIdentity();
         try {
-            // There was some problem...   first, do a sanity check of the window list to make sure
+            // There was some problem...first, do a sanity check of the window list to make sure
             // we haven't left any dangling surfaces around.
 
             Slog.i(TAG_WM, "Out of memory for surface!  Looking for leaks...");
             final int numDisplays = mChildren.size();
             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-                final WindowList windows = mChildren.get(displayNdx).getWindowList();
-                final int numWindows = windows.size();
-                for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
-                    final WindowState ws = windows.get(winNdx);
-                    final WindowStateAnimator wsa = ws.mWinAnimator;
-                    if (wsa.mSurfaceController == null) {
-                        continue;
-                    }
-                    if (!mService.mSessions.contains(wsa.mSession)) {
-                        Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
-                                + ws + " surface=" + wsa.mSurfaceController
-                                + " token=" + ws.mToken
-                                + " pid=" + ws.mSession.mPid
-                                + " uid=" + ws.mSession.mUid);
-                        wsa.destroySurface();
-                        mService.mForceRemoves.add(ws);
-                        leakedSurface = true;
-                    } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
-                        Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
-                                + ws + " surface=" + wsa.mSurfaceController
-                                + " token=" + ws.mAppToken
-                                + " saved=" + ws.hasSavedSurface());
-                        if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
-                        wsa.destroySurface();
-                        leakedSurface = true;
-                    }
-                }
+                leakedSurface |= mChildren.get(displayNdx).destroyLeakedSurfaces();
             }
 
             if (!leakedSurface) {
                 Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
-                SparseIntArray pidCandidates = new SparseIntArray();
+                final SparseIntArray pidCandidates = new SparseIntArray();
                 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-                    final WindowList windows = mChildren.get(displayNdx).getWindowList();
+                    final ReadOnlyWindowList windows =
+                            mChildren.get(displayNdx).getReadOnlyWindowList();
                     final int numWindows = windows.size();
                     for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
                         final WindowState ws = windows.get(winNdx);
                         if (mService.mForceRemoves.contains(ws)) {
                             continue;
                         }
-                        WindowStateAnimator wsa = ws.mWinAnimator;
+                        final WindowStateAnimator wsa = ws.mWinAnimator;
                         if (wsa.mSurfaceController != null) {
                             pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
                         }
                     }
+
                     if (pidCandidates.size() > 0) {
                         int[] pids = new int[pidCandidates.size()];
                         for (int i = 0; i < pids.length; i++) {
@@ -951,14 +865,13 @@
                     "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
         }
 
-        final WindowList defaultWindows = defaultDisplay.getWindowList();
         final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
 
         // If we are ready to perform an app transition, check through all of the app tokens to be
         // shown and see if they are ready to go.
         if (mService.mAppTransition.isReady()) {
             defaultDisplay.pendingLayoutChanges |=
-                    surfacePlacer.handleAppTransitionReadyLocked(defaultWindows);
+                    surfacePlacer.handleAppTransitionReadyLocked();
             if (DEBUG_LAYOUT_REPEATS)
                 surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked",
                         defaultDisplay.pendingLayoutChanges);
@@ -1046,7 +959,7 @@
                 if (mService.mInputMethodWindow == win) {
                     mService.mInputMethodWindow = null;
                 }
-                if (mService.mWallpaperControllerLocked.isWallpaperTarget(win)) {
+                if (win.getDisplayContent().mWallpaperController.isWallpaperTarget(win)) {
                     wallpaperDestroyed = true;
                 }
                 win.destroyOrSaveSurface();
@@ -1063,7 +976,7 @@
                 if (!token.hasVisible) {
                     exitingTokens.remove(i);
                     if (token.windowType == TYPE_WALLPAPER) {
-                        mService.mWallpaperControllerLocked.removeWallpaperToken(token);
+                        displayContent.mWallpaperController.removeWallpaperToken(token);
                     }
                 }
             }
@@ -1144,8 +1057,10 @@
 
         if (mUpdateRotation) {
             if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
-            if (mService.updateRotationUncheckedLocked(false)) {
-                mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
+            // TODO(multi-display): Update rotation for different displays separately.
+            final int displayId = defaultDisplay.getDisplayId();
+            if (mService.updateRotationUncheckedLocked(false, displayId)) {
+                mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget();
             } else {
                 mUpdateRotation = false;
             }
@@ -1201,8 +1116,8 @@
                 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
     }
 
-    // TODO: Super crazy long method that should be broken down...
-    private void applySurfaceChangesTransaction(boolean recoveringMemory, int defaultDw, int defaultDh) {
+    private void applySurfaceChangesTransaction(boolean recoveringMemory, int defaultDw,
+            int defaultDh) {
         mHoldScreenWindow = null;
         mObscuringWindow = null;
 
@@ -1225,215 +1140,31 @@
         final int count = mChildren.size();
         for (int j = 0; j < count; ++j) {
             final DisplayContent dc = mChildren.get(j);
-            WindowList windows = dc.getWindowList();
-            DisplayInfo displayInfo = dc.getDisplayInfo();
-            final int displayId = dc.getDisplayId();
-            final int dw = displayInfo.logicalWidth;
-            final int dh = displayInfo.logicalHeight;
-            final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
-            final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
-
-            // Reset for each display.
-            mDisplayHasContent = false;
-            mPreferredRefreshRate = 0;
-            mPreferredModeId = 0;
-            mTmpUpdateAllDrawn.clear();
-
-            int repeats = 0;
-            do {
-                repeats++;
-                if (repeats > 6) {
-                    Slog.w(TAG, "Animation repeat aborted after too many iterations");
-                    dc.clearLayoutNeeded();
-                    break;
-                }
-
-                if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
-                        "On entry to LockedInner", dc.pendingLayoutChanges);
-
-                if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0
-                        && mService.mWallpaperControllerLocked.adjustWallpaperWindows()) {
-                    dc.assignWindowLayers(true /*setLayoutNeeded*/);
-                }
-
-                if (isDefaultDisplay
-                        && (dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
-                    if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
-                    if (mService.updateOrientationFromAppTokensLocked(true)) {
-                        dc.setLayoutNeeded();
-                        mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
-                    }
-                }
-
-                if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
-                    dc.setLayoutNeeded();
-                }
-
-                // FIRST LOOP: Perform a layout, if needed.
-                if (repeats < LAYOUT_REPEAT_THRESHOLD) {
-                    surfacePlacer.performLayoutLockedInner(dc, repeats == 1,
-                            false /* updateInputWindows */);
-                } else {
-                    Slog.w(TAG, "Layout repeat skipped after too many iterations");
-                }
-
-                // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
-                // it is animating.
-                dc.pendingLayoutChanges = 0;
-
-                if (isDefaultDisplay) {
-                    mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
-                    for (int i = windows.size() - 1; i >= 0; i--) {
-                        WindowState w = windows.get(i);
-                        if (w.mHasSurface) {
-                            mService.mPolicy.applyPostLayoutPolicyLw(
-                                    w, w.mAttrs, w.getParentWindow());
-                        }
-                    }
-                    dc.pendingLayoutChanges |=
-                            mService.mPolicy.finishPostLayoutPolicyLw();
-                    if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
-                            "after finishPostLayoutPolicyLw", dc.pendingLayoutChanges);
-                }
-            } while (dc.pendingLayoutChanges != 0);
-
-            mObscured = false;
-            mSyswin = false;
-            dc.resetDimming();
-
-            // Only used if default window
-            final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
-
-            for (int i = windows.size() - 1; i >= 0; i--) {
-                WindowState w = windows.get(i);
-                final Task task = w.getTask();
-                final boolean obscuredChanged = w.mObscured != mObscured;
-
-                // Update effect.
-                w.mObscured = mObscured;
-                if (!mObscured) {
-                    handleNotObscuredLocked(w, displayInfo);
-                }
-
-                w.applyDimLayerIfNeeded();
-
-                if (isDefaultDisplay && obscuredChanged && w.isVisibleLw()
-                        && mService.mWallpaperControllerLocked.isWallpaperTarget(w)) {
-                    // This is the wallpaper target and its obscured state changed... make sure the
-                    // current wallpaper's visibility has been updated accordingly.
-                    mService.mWallpaperControllerLocked.updateWallpaperVisibility();
-                }
-
-                w.handleWindowMovedIfNeeded();
-
-                final WindowStateAnimator winAnimator = w.mWinAnimator;
-
-                //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
-                w.mContentChanged = false;
-
-                // Moved from updateWindowsAndWallpaperLocked().
-                if (w.mHasSurface) {
-                    // Take care of the window being ready to display.
-                    final boolean committed = winAnimator.commitFinishDrawingLocked();
-                    if (isDefaultDisplay && committed) {
-                        if (w.mAttrs.type == TYPE_DREAM) {
-                            // HACK: When a dream is shown, it may at that point hide the lock
-                            // screen. So we need to redo the layout to let the phone window manager
-                            // make this happen.
-                            dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
-                            if (DEBUG_LAYOUT_REPEATS) {
-                                surfacePlacer.debugLayoutRepeats(
-                                        "dream and commitFinishDrawingLocked true",
-                                        dc.pendingLayoutChanges);
-                            }
-                        }
-                        if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
-                            if (DEBUG_WALLPAPER_LIGHT)
-                                Slog.v(TAG, "First draw done in potential wallpaper target " + w);
-                            mWallpaperMayChange = true;
-                            dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
-                            if (DEBUG_LAYOUT_REPEATS) {
-                                surfacePlacer.debugLayoutRepeats(
-                                        "wallpaper and commitFinishDrawingLocked true",
-                                        dc.pendingLayoutChanges);
-                            }
-                        }
-                    }
-                    if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) {
-                        // Updates the shown frame before we set up the surface. This is needed
-                        // because the resizing could change the top-left position (in addition to
-                        // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
-                        // position the surface.
-                        //
-                        // If an animation is being started, we can't call this method because the
-                        // animation hasn't processed its initial transformation yet, but in general
-                        // we do want to update the position if the window is animating.
-                        winAnimator.computeShownFrameLocked();
-                    }
-                    winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
-                }
-
-                final AppWindowToken atoken = w.mAppToken;
-                if (atoken != null) {
-                    final boolean updateAllDrawn = atoken.updateDrawnWindowStates(w);
-                    if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(atoken)) {
-                        mTmpUpdateAllDrawn.add(atoken);
-                    }
-                }
-
-                if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
-                        && w.isDisplayedLw()) {
-                    focusDisplayed = true;
-                }
-
-                w.updateResizingWindowIfNeeded();
-            }
-
-            mService.mDisplayManagerInternal.setDisplayProperties(displayId,
-                    mDisplayHasContent,
-                    mPreferredRefreshRate,
-                    mPreferredModeId,
-                    true /* inTraversal, must call performTraversalInTrans... below */);
-
-            dc.stopDimmingIfNeeded();
-
-            while (!mTmpUpdateAllDrawn.isEmpty()) {
-                final AppWindowToken atoken = mTmpUpdateAllDrawn.removeLast();
-                // See if any windows have been drawn, so they (and others associated with them)
-                // can now be shown.
-                atoken.updateAllDrawn(dc);
-            }
+            focusDisplayed |= dc.applySurfaceChangesTransaction(recoveringMemory);
         }
 
         if (focusDisplayed) {
             mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
         }
 
-        // Give the display manager a chance to adjust properties
-        // like display rotation if it needs to.
+        // Give the display manager a chance to adjust properties like display rotation if it needs
+        // to.
         mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
     }
 
     /**
      * @param w WindowState this method is applied to.
-     * @param dispInfo info of the display that the window's obscuring state is checked against.
+     * @param obscured True if there is a window on top of this obscuring the display.
+     * @param syswin System window?
+     * @return True when the display contains content to show the user. When false, the display
+     *          manager may choose to mirror or blank the display.
      */
-    private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
+    boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) {
         final WindowManager.LayoutParams attrs = w.mAttrs;
         final int attrFlags = attrs.flags;
         final boolean canBeSeen = w.isDisplayedLw();
         final int privateflags = attrs.privateFlags;
-
-        if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
-            // This window completely covers everything behind it,
-            // so we want to leave all of them as undimmed (for
-            // performance reasons).
-            if (!mObscured) {
-                mObscuringWindow = w;
-            }
-
-            mObscured = true;
-        }
+        boolean displayHasContent = false;
 
         if (w.mHasSurface && canBeSeen) {
             if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
@@ -1444,22 +1175,17 @@
                         + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
                         + Debug.getCallers(10));
             }
-            if (!mSyswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
+            if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
                 mScreenBrightness = w.mAttrs.screenBrightness;
             }
-            if (!mSyswin && w.mAttrs.buttonBrightness >= 0 && mButtonBrightness < 0) {
+            if (!syswin && w.mAttrs.buttonBrightness >= 0 && mButtonBrightness < 0) {
                 mButtonBrightness = w.mAttrs.buttonBrightness;
             }
-            if (!mSyswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
+            if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
                 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
             }
 
             final int type = attrs.type;
-            if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR
-                    || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
-                mSyswin = true;
-            }
-
             // This function assumes that the contents of the default display are processed first
             // before secondary displays.
             final DisplayContent displayContent = w.getDisplayContent();
@@ -1470,23 +1196,19 @@
                 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                     mObscureApplicationContentOnSecondaryDisplays = true;
                 }
-                mDisplayHasContent = true;
+                displayHasContent = true;
             } else if (displayContent != null &&
                     (!mObscureApplicationContentOnSecondaryDisplays
-                            || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
+                            || (obscured && type == TYPE_KEYGUARD_DIALOG))) {
                 // Allow full screen keyguard presentation dialogs to be seen.
-                mDisplayHasContent = true;
-            }
-            if (mPreferredRefreshRate == 0 && w.mAttrs.preferredRefreshRate != 0) {
-                mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
-            }
-            if (mPreferredModeId == 0 && w.mAttrs.preferredDisplayModeId != 0) {
-                mPreferredModeId = w.mAttrs.preferredDisplayModeId;
+                displayHasContent = true;
             }
             if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
                 mSustainedPerformanceModeCurrent = true;
             }
         }
+
+        return displayHasContent;
     }
 
     boolean copyAnimToLayoutParams() {
@@ -1583,7 +1305,7 @@
     void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
         final int numDisplays = mChildren.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final WindowList windowList = mChildren.get(displayNdx).getWindowList();
+            final ReadOnlyWindowList windowList = mChildren.get(displayNdx).getReadOnlyWindowList();
             for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
                 final WindowState w = windowList.get(winNdx);
                 if (windows == null || windows.contains(w)) {
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 8009207..ead70e1 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -460,7 +460,7 @@
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
             try {
-                mService.mWallpaperControllerLocked.setWindowWallpaperPosition(
+                mService.mRoot.mWallpaperController.setWindowWallpaperPosition(
                         mService.windowForClientLocked(this, window, true),
                         x, y, xStep, yStep);
             } finally {
@@ -471,7 +471,7 @@
 
     public void wallpaperOffsetsComplete(IBinder window) {
         synchronized (mService.mWindowMap) {
-            mService.mWallpaperControllerLocked.wallpaperOffsetsComplete(window);
+            mService.mRoot.mWallpaperController.wallpaperOffsetsComplete(window);
         }
     }
 
@@ -479,7 +479,7 @@
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
             try {
-                mService.mWallpaperControllerLocked.setWindowWallpaperDisplayOffset(
+                mService.mRoot.mWallpaperController.setWindowWallpaperDisplayOffset(
                         mService.windowForClientLocked(this, window, true), x, y);
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -492,7 +492,7 @@
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
             try {
-                return mService.mWallpaperControllerLocked.sendWindowWallpaperCommand(
+                return mService.mRoot.mWallpaperController.sendWindowWallpaperCommand(
                         mService.windowForClientLocked(this, window, true),
                         action, x, y, z, extras, sync);
             } finally {
@@ -503,7 +503,7 @@
 
     public void wallpaperCommandComplete(IBinder window, Bundle result) {
         synchronized (mService.mWindowMap) {
-            mService.mWallpaperControllerLocked.wallpaperCommandComplete(window);
+            mService.mRoot.mWallpaperController.wallpaperCommandComplete(window);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 19c9b7d..7f543f9 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -327,8 +327,9 @@
      *                    the adjusted bounds's top.
      */
     void alignToAdjustedBounds(Rect adjustedBounds, Rect tempInsetBounds, boolean alignBottom) {
-        final Configuration overrideConfig = getOverrideConfiguration();
-        if (!isResizeable() || Configuration.EMPTY.equals(overrideConfig)) {
+        // Task override config might be empty, while display or stack override config isn't, so
+        // we have to check merged override config here.
+        if (!isResizeable() || Configuration.EMPTY.equals(getMergedOverrideConfiguration())) {
             return;
         }
 
@@ -340,7 +341,7 @@
             mTmpRect2.offsetTo(adjustedBounds.left, adjustedBounds.top);
         }
         setTempInsetBounds(tempInsetBounds);
-        resizeLocked(mTmpRect2, overrideConfig, false /* forced */);
+        resizeLocked(mTmpRect2, getOverrideConfiguration(), false /* forced */);
     }
 
     /** Return true if the current bound can get outputted to the rest of the system as-is. */
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 9effb8d..4d8f29d 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -24,6 +24,7 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.res.Configuration.DENSITY_DPI_UNDEFINED;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.DOCKED_BOTTOM;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.DOCKED_LEFT;
@@ -38,7 +39,10 @@
 import static com.android.server.wm.WindowManagerService.LAYER_OFFSET_DIM;
 
 import android.app.ActivityManager.StackId;
+import android.app.IActivityManager;
 import android.content.res.Configuration;
+import android.graphics.Point;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Debug;
@@ -53,6 +57,7 @@
 import com.android.internal.policy.DividerSnapAlgorithm;
 import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
 import com.android.internal.policy.DockedDividerUtils;
+import com.android.internal.policy.PipSnapAlgorithm;
 import com.android.server.EventLogTags;
 
 import java.io.PrintWriter;
@@ -380,19 +385,25 @@
 
         mTmpRect2.set(mBounds);
         mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
-        if (mStackId == DOCKED_STACK_ID) {
-            repositionDockedStackAfterRotation(mTmpRect2);
-            snapDockedStackAfterRotation(mTmpRect2);
-            final int newDockSide = getDockSide(mTmpRect2);
+        switch (mStackId) {
+            case PINNED_STACK_ID:
+                mTmpRect2 = mDisplayContent.getPinnedStackController().getPostRotationBounds(
+                        mBounds, mTmpRect2);
+                break;
+            case DOCKED_STACK_ID:
+                repositionDockedStackAfterRotation(mTmpRect2);
+                snapDockedStackAfterRotation(mTmpRect2);
+                final int newDockSide = getDockSide(mTmpRect2);
 
-            // Update the dock create mode and clear the dock create bounds, these
-            // might change after a rotation and the original values will be invalid.
-            mService.setDockedStackCreateStateLocked(
-                    (newDockSide == DOCKED_LEFT || newDockSide == DOCKED_TOP)
-                    ? DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
-                    : DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT,
-                    null);
-            mDisplayContent.getDockedDividerController().notifyDockSideChanged(newDockSide);
+                // Update the dock create mode and clear the dock create bounds, these
+                // might change after a rotation and the original values will be invalid.
+                mService.setDockedStackCreateStateLocked(
+                        (newDockSide == DOCKED_LEFT || newDockSide == DOCKED_TOP)
+                                ? DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
+                                : DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT,
+                        null);
+                mDisplayContent.getDockedDividerController().notifyDockSideChanged(newDockSide);
+                break;
         }
 
         mBoundsAfterRotation.set(mTmpRect2);
@@ -448,8 +459,7 @@
 
         // Calculate the current position.
         final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
-        final int dividerSize = mService.getDefaultDisplayContentLocked()
-                .getDockedDividerController().getContentWidth();
+        final int dividerSize = mDisplayContent.getDockedDividerController().getContentWidth();
         final int dockSide = getDockSide(outBounds);
         final int dividerPosition = DockedDividerUtils.calculatePositionForBounds(outBounds,
                 dockSide, dividerSize);
@@ -783,13 +793,14 @@
             mAnimationBackgroundSurface.destroySurface();
             mAnimationBackgroundSurface = null;
         }
+        final DockedStackDividerController dividerController =
+                mDisplayContent.mDividerControllerLocked;
         mDisplayContent = null;
 
         mService.mWindowPlacerLocked.requestTraversal();
 
         if (mStackId == DOCKED_STACK_ID) {
-            mService.getDefaultDisplayContentLocked().mDividerControllerLocked
-                    .notifyDockedStackExistsChanged(false);
+            dividerController.notifyDockedStackExistsChanged(false);
         }
     }
 
@@ -1010,7 +1021,7 @@
         }
 
         if (dockSide == DOCKED_TOP) {
-            mService.getStableInsetsLocked(mTmpRect);
+            mService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
             int topInset = mTmpRect.top;
             mTmpAdjustedBounds.set(mBounds);
             mTmpAdjustedBounds.bottom =
@@ -1041,7 +1052,7 @@
         }
 
         if (dockSide == DOCKED_TOP) {
-            mService.getStableInsetsLocked(mTmpRect);
+            mService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
             int topInset = mTmpRect.top;
             return mBounds.bottom - topInset;
         } else if (dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 972a0cb..c9f1ffc 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -374,7 +374,7 @@
         return mWallpaperAnimLayerAdjustment;
     }
 
-    private void findWallpaperTarget(WindowList windows, FindWallpaperTargetResult result) {
+    private void findWallpaperTarget(ReadOnlyWindowList windows, FindWallpaperTargetResult result) {
         final WindowAnimator winAnimator = mService.mAnimator;
         result.reset();
         WindowState w = null;
@@ -457,7 +457,7 @@
 
     /** Updates the target wallpaper if needed and returns true if an update happened. */
     private boolean updateWallpaperWindowsTarget(
-            WindowList windows, FindWallpaperTargetResult result) {
+            ReadOnlyWindowList windows, FindWallpaperTargetResult result) {
 
         WindowState wallpaperTarget = result.wallpaperTarget;
         int wallpaperTargetIndex = result.wallpaperTargetIndex;
@@ -558,7 +558,7 @@
         return true;
     }
 
-    private boolean updateWallpaperWindowsTargetByLayer(WindowList windows,
+    private boolean updateWallpaperWindowsTargetByLayer(ReadOnlyWindowList windows,
             FindWallpaperTargetResult result) {
 
         WindowState wallpaperTarget = result.wallpaperTarget;
@@ -609,7 +609,7 @@
         return visible;
     }
 
-    private boolean updateWallpaperWindowsPlacement(WindowList windows,
+    private boolean updateWallpaperWindowsPlacement(ReadOnlyWindowList windows,
             WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible) {
 
         // TODO(multidisplay): Wallpapers on main screen only.
@@ -628,10 +628,9 @@
         return changed;
     }
 
-    boolean adjustWallpaperWindows() {
+    boolean adjustWallpaperWindows(ReadOnlyWindowList windows) {
         mService.mRoot.mWallpaperMayChange = false;
 
-        final WindowList windows = mService.getDefaultWindowListLocked();
         // First find top-most window that has asked to be on top of the wallpaper;
         // all wallpapers go behind it.
         findWallpaperTarget(windows, mFindResults);
@@ -726,8 +725,8 @@
      * Adjusts the wallpaper windows if the input display has a pending wallpaper layout or one of
      * the opening apps should be a wallpaper target.
      */
-    void adjustWallpaperWindowsForAppTransitionIfNeeded(
-            DisplayContent dc, ArraySet<AppWindowToken> openingApps, WindowList windows) {
+    void adjustWallpaperWindowsForAppTransitionIfNeeded(DisplayContent dc,
+            ArraySet<AppWindowToken> openingApps) {
         boolean adjust = false;
         if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
             adjust = true;
@@ -741,8 +740,8 @@
             }
         }
 
-        if (adjust && adjustWallpaperWindows()) {
-            dc.assignWindowLayers(true /*setLayoutNeeded*/);
+        if (adjust) {
+            dc.adjustWallpaperWindows();
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index fb6b09a..4c62245 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -16,28 +16,17 @@
 
 package com.android.server.wm;
 
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
-import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
-import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
-import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
-import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
@@ -48,14 +37,11 @@
 import android.util.SparseArray;
 import android.util.TimeUtils;
 import android.view.Choreographer;
-import android.view.Display;
 import android.view.SurfaceControl;
 import android.view.WindowManagerPolicy;
-import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 
 /**
  * Singleton class that carries out the animations and Surface operations in a separate task
@@ -65,7 +51,7 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowAnimator" : TAG_WM;
 
     /** How long to give statusbar to clear the private keyguard flag when animating out */
-    private static final long KEYGUARD_ANIM_TIMEOUT_MS = 1000;
+    static final long KEYGUARD_ANIM_TIMEOUT_MS = 1000;
 
     final WindowManagerService mService;
     final Context mContext;
@@ -85,7 +71,7 @@
 
     /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
      * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
-    private int mAnimTransactionSequence;
+    int mAnimTransactionSequence;
 
     /** Window currently running an animation that has requested it be detached
      * from the wallpaper.  This means we need to ensure the wallpaper is
@@ -120,9 +106,9 @@
     private final AppTokenList mTmpExitingAppTokens = new AppTokenList();
 
     /** The window that was previously hiding the Keyguard. */
-    private WindowState mLastShowWinWhenLocked;
+    WindowState mLastShowWinWhenLocked;
 
-    private String forceHidingToString() {
+    String forceHidingToString() {
         switch (mForceHiding) {
             case KEYGUARD_NOT_SHOWN:    return "KEYGUARD_NOT_SHOWN";
             case KEYGUARD_SHOWN:        return "KEYGUARD_SHOWN";
@@ -150,7 +136,7 @@
     void addDisplayLocked(final int displayId) {
         // Create the DisplayContentsAnimator object by retrieving it.
         getDisplayContentsAnimatorLocked(displayId);
-        if (displayId == Display.DEFAULT_DISPLAY) {
+        if (displayId == DEFAULT_DISPLAY) {
             mInitialized = true;
         }
     }
@@ -184,7 +170,7 @@
         return null;
     }
 
-    private boolean shouldForceHide(WindowState win) {
+    boolean shouldForceHide(WindowState win) {
         final WindowState imeTarget = mService.mInputMethodTarget;
         final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() &&
                 ((imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0
@@ -220,377 +206,10 @@
                 && !mKeyguardAnimatingIn;
         boolean hideDockDivider = win.mAttrs.type == TYPE_DOCK_DIVIDER
                 && win.getDisplayContent().getDockedStackLocked() == null;
-        return keyguardOn && !allowWhenLocked && (win.getDisplayId() == Display.DEFAULT_DISPLAY)
+        return keyguardOn && !allowWhenLocked && (win.getDisplayId() == DEFAULT_DISPLAY)
                 || hideDockDivider;
     }
 
-    private void updateWindowsLocked(final int displayId) {
-        ++mAnimTransactionSequence;
-
-        final WindowList windows = mService.getWindowListLocked(displayId);
-
-        final boolean keyguardGoingAwayToShade =
-                (mKeyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0;
-        final boolean keyguardGoingAwayNoAnimation =
-                (mKeyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0;
-        final boolean keyguardGoingAwayWithWallpaper =
-                (mKeyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0;
-
-        if (mKeyguardGoingAway) {
-            for (int i = windows.size() - 1; i >= 0; i--) {
-                WindowState win = windows.get(i);
-                if (!mPolicy.isKeyguardHostWindow(win.mAttrs)) {
-                    continue;
-                }
-                final WindowStateAnimator winAnimator = win.mWinAnimator;
-                if (mPolicy.isKeyguardShowingAndNotOccluded()) {
-                    if (!winAnimator.mAnimating) {
-                        if (DEBUG_KEYGUARD) Slog.d(TAG,
-                                "updateWindowsLocked: creating delay animation");
-
-                        // Create a new animation to delay until keyguard is gone on its own.
-                        winAnimator.mAnimation = new AlphaAnimation(1.0f, 1.0f);
-                        winAnimator.mAnimation.setDuration(KEYGUARD_ANIM_TIMEOUT_MS);
-                        winAnimator.mAnimationIsEntrance = false;
-                        winAnimator.mAnimationStartTime = -1;
-                        winAnimator.mKeyguardGoingAwayAnimation = true;
-                        winAnimator.mKeyguardGoingAwayWithWallpaper
-                                = keyguardGoingAwayWithWallpaper;
-                    }
-                } else {
-                    if (DEBUG_KEYGUARD) Slog.d(TAG,
-                            "updateWindowsLocked: StatusBar is no longer keyguard");
-                    mKeyguardGoingAway = false;
-                    winAnimator.clearAnimation();
-                }
-                break;
-            }
-        }
-
-        mForceHiding = KEYGUARD_NOT_SHOWN;
-
-        boolean wallpaperInUnForceHiding = false;
-        boolean startingInUnForceHiding = false;
-        ArrayList<WindowStateAnimator> unForceHiding = null;
-        WindowState wallpaper = null;
-        final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            WindowState win = windows.get(i);
-            WindowStateAnimator winAnimator = win.mWinAnimator;
-            final int flags = win.mAttrs.flags;
-            boolean canBeForceHidden = mPolicy.canBeForceHidden(win, win.mAttrs);
-            boolean shouldBeForceHidden = shouldForceHide(win);
-            if (winAnimator.hasSurface()) {
-                final boolean wasAnimating = winAnimator.mWasAnimating;
-                final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime);
-                winAnimator.mWasAnimating = nowAnimating;
-                orAnimating(nowAnimating);
-
-                if (DEBUG_WALLPAPER) {
-                    Slog.v(TAG, win + ": wasAnimating=" + wasAnimating +
-                            ", nowAnimating=" + nowAnimating);
-                }
-
-                if (wasAnimating && !winAnimator.mAnimating
-                        && wallpaperController.isWallpaperTarget(win)) {
-                    mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
-                    setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
-                            WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
-                    if (DEBUG_LAYOUT_REPEATS) {
-                        mWindowPlacerLocked.debugLayoutRepeats(
-                                "updateWindowsAndWallpaperLocked 2",
-                                getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
-                    }
-                }
-
-                if (mPolicy.isForceHiding(win.mAttrs)) {
-                    if (!wasAnimating && nowAnimating) {
-                        if (DEBUG_KEYGUARD || DEBUG_ANIM ||
-                                DEBUG_VISIBILITY) Slog.v(TAG,
-                                "Animation started that could impact force hide: " + win);
-                        mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
-                        setPendingLayoutChanges(displayId,
-                                WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
-                        if (DEBUG_LAYOUT_REPEATS) {
-                            mWindowPlacerLocked.debugLayoutRepeats(
-                                    "updateWindowsAndWallpaperLocked 3",
-                                    getPendingLayoutChanges(displayId));
-                        }
-                        mService.mFocusMayChange = true;
-                    } else if (mKeyguardGoingAway && !nowAnimating) {
-                        // Timeout!!
-                        Slog.e(TAG, "Timeout waiting for animation to startup");
-                        mPolicy.startKeyguardExitAnimation(0, 0);
-                        mKeyguardGoingAway = false;
-                    }
-                    if (win.isReadyForDisplay()) {
-                        if (nowAnimating && win.mWinAnimator.mKeyguardGoingAwayAnimation) {
-                            mForceHiding = KEYGUARD_ANIMATING_OUT;
-                        } else {
-                            mForceHiding = win.isDrawnLw() ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN;
-                        }
-                    }
-                    if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
-                            "Force hide " + forceHidingToString()
-                            + " hasSurface=" + win.mHasSurface
-                            + " policyVis=" + win.mPolicyVisibility
-                            + " destroying=" + win.mDestroying
-                            + " parentHidden=" + win.isParentWindowHidden()
-                            + " vis=" + win.mViewVisibility
-                            + " hidden=" + win.mToken.hidden
-                            + " anim=" + win.mWinAnimator.mAnimation);
-                } else if (canBeForceHidden) {
-                    if (shouldBeForceHidden) {
-                        if (!win.hideLw(false, false)) {
-                            // Was already hidden
-                            continue;
-                        }
-                        if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
-                                "Now policy hidden: " + win);
-                    } else {
-                        boolean applyExistingExitAnimation = mPostKeyguardExitAnimation != null
-                                && !mPostKeyguardExitAnimation.hasEnded()
-                                && !winAnimator.mKeyguardGoingAwayAnimation
-                                && win.hasDrawnLw()
-                                && !win.isChildWindow()
-                                && !win.mIsImWindow
-                                && displayId == Display.DEFAULT_DISPLAY;
-
-                        // If the window is already showing and we don't need to apply an existing
-                        // Keyguard exit animation, skip.
-                        if (!win.showLw(false, false) && !applyExistingExitAnimation) {
-                            continue;
-                        }
-                        final boolean visibleNow = win.isVisibleNow();
-                        if (!visibleNow) {
-                            // Couldn't really show, must showLw() again when win becomes visible.
-                            win.hideLw(false, false);
-                            continue;
-                        }
-                        if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
-                                "Now policy shown: " + win);
-                        if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0
-                                && !win.isChildWindow()) {
-                            if (unForceHiding == null) {
-                                unForceHiding = new ArrayList<>();
-                            }
-                            unForceHiding.add(winAnimator);
-                            if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
-                                wallpaperInUnForceHiding = true;
-                            }
-                            if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
-                                startingInUnForceHiding = true;
-                            }
-                        } else if (applyExistingExitAnimation) {
-                            // We're already in the middle of an animation. Use the existing
-                            // animation to bring in this window.
-                            if (DEBUG_KEYGUARD) Slog.v(TAG,
-                                    "Applying existing Keyguard exit animation to new window: win="
-                                            + win);
-
-                            Animation a = mPolicy.createForceHideEnterAnimation(false,
-                                    keyguardGoingAwayToShade);
-                            winAnimator.setAnimation(a, mPostKeyguardExitAnimation.getStartTime(),
-                                    STACK_CLIP_BEFORE_ANIM);
-                            winAnimator.mKeyguardGoingAwayAnimation = true;
-                            winAnimator.mKeyguardGoingAwayWithWallpaper
-                                    = keyguardGoingAwayWithWallpaper;
-                        }
-                        final WindowState currentFocus = mService.mCurrentFocus;
-                        if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
-                            // We are showing on top of the current
-                            // focus, so re-evaluate focus to make
-                            // sure it is correct.
-                            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG,
-                                    "updateWindowsLocked: setting mFocusMayChange true");
-                            mService.mFocusMayChange = true;
-                        }
-                    }
-                    if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
-                        mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
-                        setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
-                                WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
-                        if (DEBUG_LAYOUT_REPEATS) {
-                            mWindowPlacerLocked.debugLayoutRepeats(
-                                    "updateWindowsAndWallpaperLocked 4",
-                                    getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
-                        }
-                    }
-                }
-            }
-
-            // If the window doesn't have a surface, the only thing we care about is the correct
-            // policy visibility.
-            else if (canBeForceHidden) {
-                if (shouldBeForceHidden) {
-                    win.hideLw(false, false);
-                } else {
-                    win.showLw(false, false);
-                }
-            }
-
-            final AppWindowToken atoken = win.mAppToken;
-            if (winAnimator.mDrawState == READY_TO_SHOW) {
-                if (atoken == null || atoken.allDrawn) {
-                    if (win.performShowLocked()) {
-                        setPendingLayoutChanges(displayId,
-                                WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
-                        if (DEBUG_LAYOUT_REPEATS) {
-                            mWindowPlacerLocked.debugLayoutRepeats(
-                                    "updateWindowsAndWallpaperLocked 5",
-                                    getPendingLayoutChanges(displayId));
-                        }
-                    }
-                }
-            }
-            final AppWindowAnimator appAnimator = winAnimator.mAppAnimator;
-            if (appAnimator != null && appAnimator.thumbnail != null) {
-                if (appAnimator.thumbnailTransactionSeq != mAnimTransactionSequence) {
-                    appAnimator.thumbnailTransactionSeq = mAnimTransactionSequence;
-                    appAnimator.thumbnailLayer = 0;
-                }
-                if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) {
-                    appAnimator.thumbnailLayer = winAnimator.mAnimLayer;
-                }
-            }
-            if (win.mIsWallpaper) {
-                wallpaper = win;
-            }
-        } // end forall windows
-
-        // If we have windows that are being show due to them no longer
-        // being force-hidden, apply the appropriate animation to them if animations are not
-        // disabled.
-        if (unForceHiding != null) {
-            if (!keyguardGoingAwayNoAnimation) {
-                boolean first = true;
-                for (int i=unForceHiding.size()-1; i>=0; i--) {
-                    final WindowStateAnimator winAnimator = unForceHiding.get(i);
-                    Animation a = mPolicy.createForceHideEnterAnimation(
-                            wallpaperInUnForceHiding && !startingInUnForceHiding,
-                            keyguardGoingAwayToShade);
-                    if (a != null) {
-                        if (DEBUG_KEYGUARD) Slog.v(TAG,
-                                "Starting keyguard exit animation on window " + winAnimator.mWin);
-                        winAnimator.setAnimation(a, STACK_CLIP_BEFORE_ANIM);
-                        winAnimator.mKeyguardGoingAwayAnimation = true;
-                        winAnimator.mKeyguardGoingAwayWithWallpaper
-                                = keyguardGoingAwayWithWallpaper;
-                        if (first) {
-                            mPostKeyguardExitAnimation = a;
-                            mPostKeyguardExitAnimation.setStartTime(mCurrentTime);
-                            first = false;
-                        }
-                    }
-                }
-            } else if (mKeyguardGoingAway) {
-                mPolicy.startKeyguardExitAnimation(mCurrentTime, 0 /* duration */);
-                mKeyguardGoingAway = false;
-            }
-
-
-            // Wallpaper is going away in un-force-hide motion, animate it as well.
-            if (!wallpaperInUnForceHiding && wallpaper != null && !keyguardGoingAwayNoAnimation) {
-                if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: wallpaper animating away");
-                Animation a = mPolicy.createForceHideWallpaperExitAnimation(
-                        keyguardGoingAwayToShade);
-                if (a != null) {
-                    wallpaper.mWinAnimator.setAnimation(a);
-                }
-            }
-        }
-
-        if (mPostKeyguardExitAnimation != null) {
-            // We're in the midst of a keyguard exit animation.
-            if (mKeyguardGoingAway) {
-                mPolicy.startKeyguardExitAnimation(mCurrentTime +
-                        mPostKeyguardExitAnimation.getStartOffset(),
-                        mPostKeyguardExitAnimation.getDuration());
-                mKeyguardGoingAway = false;
-            }
-            // mPostKeyguardExitAnimation might either be ended normally, cancelled, or "orphaned",
-            // meaning that the window it was running on was removed. We check for hasEnded() for
-            // ended normally and cancelled case, and check the time for the "orphaned" case.
-            else if (mPostKeyguardExitAnimation.hasEnded()
-                    || mCurrentTime - mPostKeyguardExitAnimation.getStartTime()
-                            > mPostKeyguardExitAnimation.getDuration()) {
-                // Done with the animation, reset.
-                if (DEBUG_KEYGUARD) Slog.v(TAG, "Done with Keyguard exit animations.");
-                mPostKeyguardExitAnimation = null;
-            }
-        }
-
-        final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
-        if (winShowWhenLocked != null) {
-            mLastShowWinWhenLocked = winShowWhenLocked;
-        }
-    }
-
-    private void updateWallpaperLocked(int displayId) {
-        mService.mRoot.getDisplayContentOrCreate(displayId).resetAnimationBackgroundAnimator();
-
-        final WindowList windows = mService.getWindowListLocked(displayId);
-        WindowState detachedWallpaper = null;
-
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState win = windows.get(i);
-            WindowStateAnimator winAnimator = win.mWinAnimator;
-            if (winAnimator.mSurfaceController == null || !winAnimator.hasSurface()) {
-                continue;
-            }
-
-            final int flags = win.mAttrs.flags;
-
-            // If this window is animating, make a note that we have
-            // an animating window and take care of a request to run
-            // a detached wallpaper animation.
-            if (winAnimator.mAnimating) {
-                if (winAnimator.mAnimation != null) {
-                    if ((flags & FLAG_SHOW_WALLPAPER) != 0
-                            && winAnimator.mAnimation.getDetachWallpaper()) {
-                        detachedWallpaper = win;
-                    }
-                    final int color = winAnimator.mAnimation.getBackgroundColor();
-                    if (color != 0) {
-                        final TaskStack stack = win.getStack();
-                        if (stack != null) {
-                            stack.setAnimationBackground(winAnimator, color);
-                        }
-                    }
-                }
-                setAnimating(true);
-            }
-
-            // If this window's app token is running a detached wallpaper
-            // animation, make a note so we can ensure the wallpaper is
-            // displayed behind it.
-            final AppWindowAnimator appAnimator = winAnimator.mAppAnimator;
-            if (appAnimator != null && appAnimator.animation != null
-                    && appAnimator.animating) {
-                if ((flags & FLAG_SHOW_WALLPAPER) != 0
-                        && appAnimator.animation.getDetachWallpaper()) {
-                    detachedWallpaper = win;
-                }
-
-                final int color = appAnimator.animation.getBackgroundColor();
-                if (color != 0) {
-                    final TaskStack stack = win.getStack();
-                    if (stack != null) {
-                        stack.setAnimationBackground(winAnimator, color);
-                    }
-                }
-            }
-        } // end forall windows
-
-        if (mWindowDetachedWallpaper != detachedWallpaper) {
-            if (DEBUG_WALLPAPER) Slog.v(TAG,
-                    "Detached wallpaper changed from " + mWindowDetachedWallpaper
-                    + " to " + detachedWallpaper);
-            mWindowDetachedWallpaper = detachedWallpaper;
-            mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
-        }
-    }
-
     /** Locked on mService.mWindowMap. */
     private void animateLocked(long frameTimeNs) {
         if (!mInitialized) {
@@ -606,17 +225,17 @@
             Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
         }
 
-        if (SHOW_TRANSACTIONS) Slog.i(
-                TAG, ">>> OPEN TRANSACTION animateLocked");
+        if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION animateLocked");
         mService.openSurfaceTransaction();
         SurfaceControl.setAnimationTransaction();
         try {
+            final AccessibilityController accessibilityController =
+                    mService.mAccessibilityController;
             final int numDisplays = mDisplayContentsAnimators.size();
             for (int i = 0; i < numDisplays; i++) {
                 final int displayId = mDisplayContentsAnimators.keyAt(i);
-                final DisplayContent displayContent = mService.mRoot.getDisplayContentOrCreate(
-                        displayId);
-                displayContent.stepAppWindowsAnimation(mCurrentTime);
+                final DisplayContent dc = mService.mRoot.getDisplayContentOrCreate(displayId);
+                dc.stepAppWindowsAnimation(mCurrentTime);
                 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
 
                 final ScreenRotationAnimation screenRotationAnimation =
@@ -630,11 +249,10 @@
                         displayAnimator.mScreenRotationAnimation = null;
 
                         //TODO (multidisplay): Accessibility supported only for the default display.
-                        if (mService.mAccessibilityController != null
-                                && displayId == Display.DEFAULT_DISPLAY) {
-                            // We just finished rotation animation which means we did not
-                            // anounce the rotation and waited for it to end, announce now.
-                            mService.mAccessibilityController.onRotationChangedLocked(
+                        if (accessibilityController != null && dc.isDefaultDisplay) {
+                            // We just finished rotation animation which means we did not announce
+                            // the rotation and waited for it to end, announce now.
+                            accessibilityController.onRotationChangedLocked(
                                     mService.getDefaultDisplayContentLocked(), mService.mRotation);
                         }
                     }
@@ -642,22 +260,17 @@
 
                 // Update animations of all applications, including those
                 // associated with exiting/removed apps
-                updateWindowsLocked(displayId);
-                updateWallpaperLocked(displayId);
-
-                final WindowList windows = mService.getWindowListLocked(displayId);
-                final int N = windows.size();
-                for (int j = 0; j < N; j++) {
-                    windows.get(j).mWinAnimator.prepareSurfaceLocked(true);
-                }
+                ++mAnimTransactionSequence;
+                dc.updateWindowsForAnimator(this);
+                dc.updateWallpaperForAnimator(this);
+                dc.prepareWindowSurfaces();
             }
 
             for (int i = 0; i < numDisplays; i++) {
                 final int displayId = mDisplayContentsAnimators.keyAt(i);
-                final DisplayContent displayContent = mService.mRoot.getDisplayContentOrCreate(
-                        displayId);
+                final DisplayContent dc = mService.mRoot.getDisplayContentOrCreate(displayId);
 
-                displayContent.checkAppWindowsReadyToShow();
+                dc.checkAppWindowsReadyToShow();
 
                 final ScreenRotationAnimation screenRotationAnimation =
                         mDisplayContentsAnimators.valueAt(i).mScreenRotationAnimation;
@@ -665,11 +278,11 @@
                     screenRotationAnimation.updateSurfacesInTransaction();
                 }
 
-                orAnimating(displayContent.animateDimLayers());
-                orAnimating(displayContent.getDockedDividerController().animate(mCurrentTime));
+                orAnimating(dc.animateDimLayers());
+                orAnimating(dc.getDockedDividerController().animate(mCurrentTime));
                 //TODO (multidisplay): Magnification is supported only for the default display.
-                if (mService.mAccessibilityController != null && displayContent.isDefaultDisplay) {
-                    mService.mAccessibilityController.drawMagnifiedRegionBorderIfNeededLocked();
+                if (accessibilityController != null && dc.isDefaultDisplay) {
+                    accessibilityController.drawMagnifiedRegionBorderIfNeededLocked();
                 }
             }
 
@@ -688,8 +301,7 @@
             Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
         } finally {
             mService.closeSurfaceTransaction();
-            if (SHOW_TRANSACTIONS) Slog.i(
-                    TAG, "<<< CLOSE TRANSACTION animateLocked");
+            if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION animateLocked");
         }
 
         boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this);
@@ -726,7 +338,7 @@
             Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating
                     + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams)
                     + " mPendingLayoutChanges(DEFAULT_DISPLAY)="
-                    + Integer.toHexString(getPendingLayoutChanges(Display.DEFAULT_DISPLAY)));
+                    + Integer.toHexString(getPendingLayoutChanges(DEFAULT_DISPLAY)));
         }
     }
 
@@ -758,15 +370,10 @@
             pw.print(prefix); pw.print("DisplayContentsAnimator #");
                     pw.print(mDisplayContentsAnimators.keyAt(i));
                     pw.println(":");
-            DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
-            final WindowList windows =
-                    mService.getWindowListLocked(mDisplayContentsAnimators.keyAt(i));
-            final int N = windows.size();
-            for (int j = 0; j < N; j++) {
-                WindowStateAnimator wanim = windows.get(j).mWinAnimator;
-                pw.print(subPrefix); pw.print("Window #"); pw.print(j);
-                        pw.print(": "); pw.println(wanim);
-            }
+            final DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
+            final DisplayContent dc =
+                    mService.mRoot.getDisplayContentOrCreate(mDisplayContentsAnimators.keyAt(i));
+            dc.dumpWindowAnimators(pw, subPrefix);
             if (displayAnimator.mScreenRotationAnimation != null) {
                 pw.print(subPrefix); pw.println("mScreenRotationAnimation:");
                 displayAnimator.mScreenRotationAnimation.printTo(subSubPrefix, pw);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 285c40b..db61c3e 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -71,10 +71,14 @@
 
     final protected void setParent(WindowContainer parent) {
         mParent = parent;
-        // Update full configuration of this container and all its children.
-        onConfigurationChanged(mParent != null ? mParent.mFullConfiguration : Configuration.EMPTY);
-        // Update merged override configuration of this container and all its children.
-        onMergedOverrideConfigurationChanged();
+        // Removing parent usually means that we've detached this entity to destroy it or to attach
+        // to another parent. In both cases we don't need to update the configuration now.
+        if (mParent != null) {
+            // Update full configuration of this container and all its children.
+            onConfigurationChanged(mParent.mFullConfiguration);
+            // Update merged override configuration of this container and all its children.
+            onMergedOverrideConfigurationChanged();
+        }
     }
 
     // Temp. holders for a chain of containers we are currently processing.
@@ -95,22 +99,25 @@
                     + " is already a child of container=" + child.getParent().getName()
                     + " can't add to container=" + getName());
         }
-        child.setParent(this);
 
-        if (mChildren.isEmpty() || comparator == null) {
-            mChildren.add(child);
-            return;
-        }
-
-        final int count = mChildren.size();
-        for (int i = 0; i < count; i++) {
-            if (comparator.compare(child, mChildren.get(i)) < 0) {
-                mChildren.add(i, child);
-                return;
+        int positionToAdd = -1;
+        if (comparator != null) {
+            final int count = mChildren.size();
+            for (int i = 0; i < count; i++) {
+                if (comparator.compare(child, mChildren.get(i)) < 0) {
+                    positionToAdd = i;
+                    break;
+                }
             }
         }
 
-        mChildren.add(child);
+        if (positionToAdd == -1) {
+            mChildren.add(child);
+        } else {
+            mChildren.add(positionToAdd, child);
+        }
+        // Set the parent after we've actually added a child in case a subclass depends on this.
+        child.setParent(this);
     }
 
     /** Adds the input window container has a child of this container at the input index. */
@@ -121,8 +128,9 @@
                     + " is already a child of container=" + child.getParent().getName()
                     + " can't add to container=" + getName());
         }
-        child.setParent(this);
         mChildren.add(index, child);
+        // Set the parent after we've actually added a child in case a subclass depends on this.
+        child.setParent(this);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index e184e39..d94094a 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -19,7 +19,6 @@
 import android.util.Slog;
 import android.view.Display;
 
-import java.io.PrintWriter;
 import java.util.ArrayDeque;
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
@@ -27,7 +26,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.WindowManagerService.LAYER_OFFSET_DIM;
 import static com.android.server.wm.WindowManagerService.WINDOW_LAYER_MULTIPLIER;
 
 /**
@@ -63,7 +61,7 @@
     private WindowState mDockDivider = null;
     private ArrayDeque<WindowState> mReplacingWindows = new ArrayDeque<>();
 
-    final void assignWindowLayers(WindowList windows) {
+    final void assignWindowLayers(ReadOnlyWindowList windows) {
         if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based on windows=" + windows,
                 new RuntimeException("here").fillInStackTrace());
 
@@ -113,7 +111,7 @@
         if (DEBUG_LAYERS) logDebugLayers(windows);
     }
 
-    private void logDebugLayers(WindowList windows) {
+    private void logDebugLayers(ReadOnlyWindowList windows) {
         for (int i = 0, n = windows.size(); i < n; i++) {
             final WindowState w = windows.get(i);
             final WindowStateAnimator winAnimator = w.mWinAnimator;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d632014..7759705 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -97,6 +97,7 @@
 import android.view.IDockedStackListener;
 import android.view.IInputFilter;
 import android.view.IOnKeyguardExitResult;
+import android.view.IPinnedStackListener;
 import android.view.IRotationWatcher;
 import android.view.IWindow;
 import android.view.IWindowId;
@@ -142,7 +143,6 @@
 import com.android.server.UiThread;
 import com.android.server.Watchdog;
 import com.android.server.input.InputManagerService;
-import com.android.server.policy.PhoneWindowManager;
 import com.android.server.power.ShutdownThread;
 
 import java.io.BufferedWriter;
@@ -166,12 +166,14 @@
 import java.util.List;
 
 import static android.Manifest.permission.MANAGE_APP_TOKENS;
+import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.StatusBarManager.DISABLE_MASK;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
@@ -185,11 +187,9 @@
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
@@ -202,6 +202,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static com.android.server.EventLogTags.WM_TASK_CREATED;
 import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
@@ -217,7 +218,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
@@ -239,7 +239,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
 
 /** {@hide} */
 public class WindowManagerService extends IWindowManager.Stub
@@ -514,9 +513,9 @@
     // The root of the device window hierarchy.
     RootWindowContainer mRoot;
 
-    // TODO: Move several of this states to the RootWindowContainer
+    // TODO: Move several of this states to the RootWindowContainer or DisplayContent
     int mRotation = 0;
-    int mLastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+    int mLastOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
     boolean mAltOrientation = false;
 
     private boolean mKeyguardWaitingForActivityDrawn;
@@ -527,10 +526,10 @@
     private final SparseIntArray mTmpTaskIds = new SparseIntArray();
 
     boolean mForceResizableTasks = false;
+    boolean mSupportsPictureInPicture = false;
 
     int getDragLayerLocked() {
-        return mPolicy.windowTypeToLayerLw(LayoutParams.TYPE_DRAG) * TYPE_LAYER_MULTIPLIER
-                + TYPE_LAYER_OFFSET;
+        return mPolicy.windowTypeToLayerLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
     }
 
     class RotationWatcher {
@@ -561,8 +560,8 @@
 
     boolean mClientFreezingScreen = false;
     int mAppsFreezingScreen = 0;
-    int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-    int mLastKeyguardForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+    int mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+    int mLastKeyguardForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
 
     int mLayoutSeq = 0;
 
@@ -619,10 +618,6 @@
     // window list before it is used whenever window container order changes.
     final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<>();
 
-    /** Temporary list for comparison. Always clear this after use so we don't end up with
-     * orphaned windows references */
-    final ArrayList<WindowState> mTmpWindows = new ArrayList<>();
-
     boolean mHardKeyboardAvailable;
     WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
     SettingsObserver mSettingsObserver;
@@ -683,8 +678,6 @@
         }
     }
 
-    WallpaperController mWallpaperControllerLocked;
-
     boolean mAnimateWallpaperWithTarget;
 
     // TODO: Move to RootWindowContainer
@@ -978,7 +971,6 @@
         mDisplaySettings = new DisplaySettings();
         mDisplaySettings.readSettingsLocked();
 
-        mWallpaperControllerLocked = new WallpaperController(this);
         mWindowPlacerLocked = new WindowSurfacePlacer(this);
         mPolicy = policy;
 
@@ -1396,11 +1388,11 @@
             } else {
                 win.mToken.addWindow(win);
                 if (type == TYPE_WALLPAPER) {
-                    mWallpaperControllerLocked.clearLastWallpaperTimeoutTime();
+                    displayContent.mWallpaperController.clearLastWallpaperTimeoutTime();
                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
-                } else if (mWallpaperControllerLocked.isBelowWallpaperTarget(win)) {
+                } else if (displayContent.mWallpaperController.isBelowWallpaperTarget(win)) {
                     // If there is currently a wallpaper being shown, and
                     // the base layer of the new window is below the current
                     // layer of the target window, then adjust the wallpaper.
@@ -1415,7 +1407,7 @@
             win.applyAdjustForImeIfNeeded();
 
             if (type == TYPE_DOCK_DIVIDER) {
-                getDefaultDisplayContentLocked().getDockedDividerController().setWindow(win);
+                mRoot.getDisplayContent(displayId).getDockedDividerController().setWindow(win);
             }
 
             final WindowStateAnimator winAnimator = win.mWinAnimator;
@@ -1482,13 +1474,13 @@
             if (localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addWindow: New client "
                     + client.asBinder() + ": window=" + win + " Callers=" + Debug.getCallers(5));
 
-            if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
+            if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false, displayId)) {
                 reportNewConfig = true;
             }
         }
 
         if (reportNewConfig) {
-            sendNewConfiguration();
+            sendNewConfiguration(displayId);
         }
 
         Binder.restoreCallingIdentity(origId);
@@ -1674,14 +1666,14 @@
             atoken.postWindowRemoveStartingWindowCleanup(win);
         }
 
+        final DisplayContent dc = win.getDisplayContent();
         if (win.mAttrs.type == TYPE_WALLPAPER) {
-            mWallpaperControllerLocked.clearLastWallpaperTimeoutTime();
-            getDefaultDisplayContentLocked().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+            dc.mWallpaperController.clearLastWallpaperTimeoutTime();
+            dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
         } else if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
-            getDefaultDisplayContentLocked().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+            dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
         }
 
-        final DisplayContent dc = win.getDisplayContent();
         if (dc != null && dc.removeFromWindowList(win)) {
             if (!mWindowPlacerLocked.isInLayout()) {
                 dc.assignWindowLayers(true /* setLayoutNeeded */);
@@ -1789,7 +1781,7 @@
             if (mAccessibilityController != null) {
                 WindowState window = mWindowMap.get(token);
                 //TODO (multidisplay): Magnification is supported only for the default display.
-                if (window != null && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
+                if (window != null && window.getDisplayId() == DEFAULT_DISPLAY) {
                     mAccessibilityController.onRectangleOnScreenRequestedLocked(rectangle);
                 }
             }
@@ -1883,11 +1875,13 @@
                         == PackageManager.PERMISSION_GRANTED;
 
         long origId = Binder.clearCallingIdentity();
+        final int displayId;
         synchronized(mWindowMap) {
             WindowState win = windowForClientLocked(session, client, false);
             if (win == null) {
                 return 0;
             }
+            displayId = win.getDisplayId();
 
             WindowStateAnimator winAnimator = win.mWinAnimator;
             if (viewVisibility != View.GONE) {
@@ -2068,17 +2062,17 @@
             }
 
             if (wallpaperMayMove) {
-                getDefaultDisplayContentLocked().pendingLayoutChanges |=
+                win.getDisplayContent().pendingLayoutChanges |=
                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
             }
 
             win.setDisplayLayoutNeeded();
             win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
-            configChanged = updateOrientationFromAppTokensLocked(false);
+            configChanged = updateOrientationFromAppTokensLocked(false, displayId);
             mWindowPlacerLocked.performSurfacePlacement();
             if (toBeDisplayed && win.mIsWallpaper) {
-                DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
-                mWallpaperControllerLocked.updateWallpaperOffset(
+                DisplayInfo displayInfo = win.getDisplayContent().getDisplayInfo();
+                dc.mWallpaperController.updateWallpaperOffset(
                         win, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
             }
             if (win.mAppToken != null) {
@@ -2123,7 +2117,7 @@
         }
 
         if (configChanged) {
-            sendNewConfiguration();
+            sendNewConfiguration(displayId);
         }
         Binder.restoreCallingIdentity(origId);
         return result;
@@ -2146,7 +2140,7 @@
             // an exit.
             win.mAnimatingExit = true;
             win.mWinAnimator.mAnimating = true;
-        } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
+        } else if (win.getDisplayContent().mWallpaperController.isWallpaperTarget(win)) {
             // If the wallpaper is currently behind this
             // window, we need to change both of them inside
             // of a transaction to avoid artifacts.
@@ -2158,9 +2152,8 @@
             }
             win.destroyOrSaveSurface();
         }
-        //TODO (multidisplay): Magnification is supported only for the default
-        if (mAccessibilityController != null
-                && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
+        // TODO(multidisplay): Magnification is supported only for the default display.
+        if (mAccessibilityController != null && win.getDisplayId() == DEFAULT_DISPLAY) {
             mAccessibilityController.onWindowTransitionLocked(win, transit);
         }
         return focusMayChange;
@@ -2280,7 +2273,7 @@
         }
     }
 
-    public void finishDrawingWindow(Session session, IWindow client) {
+    void finishDrawingWindow(Session session, IWindow client) {
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mWindowMap) {
@@ -2289,7 +2282,7 @@
                         + (win != null ? win.mWinAnimator.drawStateToString() : "null"));
                 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
                     if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
-                        getDefaultDisplayContentLocked().pendingLayoutChanges |=
+                        win.getDisplayContent().pendingLayoutChanges |=
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
                     }
                     win.setDisplayLayoutNeeded();
@@ -2417,7 +2410,7 @@
                     final WindowToken wtoken = removedTokens.get(i);
                     wtoken.setExiting();
                     if (wtoken.windowType == TYPE_WALLPAPER) {
-                        mWallpaperControllerLocked.removeWallpaperToken(wtoken);
+                        wtoken.getDisplayContent().mWallpaperController.removeWallpaperToken(wtoken);
                     }
 
                     mInputMonitor.updateInputWindowsLw(true /*force*/);
@@ -2531,107 +2524,35 @@
         }
     }
 
-    public int getOrientationLocked() {
-        if (mDisplayFrozen) {
-            if (mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
-                if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
-                        "Display is frozen, return " + mLastWindowForcedOrientation);
-                // If the display is frozen, some activities may be in the middle
-                // of restarting, and thus have removed their old window.  If the
-                // window has the flag to hide the lock screen, then the lock screen
-                // can re-appear and inflict its own orientation on us.  Keep the
-                // orientation stable until this all settles down.
-                return mLastWindowForcedOrientation;
-            } else if (mPolicy.isKeyguardLocked()) {
-                // Use the last orientation the while the display is frozen with the
-                // keyguard locked. This could be the keyguard forced orientation or
-                // from a SHOW_WHEN_LOCKED window. We don't want to check the show when
-                // locked window directly though as things aren't stable while
-                // the display is frozen, for example the window could be momentarily unavailable
-                // due to activity relaunch.
-                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display is frozen while keyguard locked, "
-                        + "return " + mLastOrientation);
-                return mLastOrientation;
-            }
-        } else {
-            // TODO(multidisplay): Change to the correct display.
-            final WindowList windows = getDefaultWindowListLocked();
-            for (int pos = windows.size() - 1; pos >= 0; --pos) {
-                WindowState win = windows.get(pos);
-                if (win.mAppToken != null) {
-                    // We hit an application window. so the orientation will be determined by the
-                    // app window. No point in continuing further.
-                    break;
-                }
-                if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
-                    continue;
-                }
-                int req = win.mAttrs.screenOrientation;
-                if(req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND) {
-                    continue;
-                }
-
-                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
-                if (mPolicy.isKeyguardHostWindow(win.mAttrs)) {
-                    mLastKeyguardForcedOrientation = req;
-                }
-                return (mLastWindowForcedOrientation = req);
-            }
-            mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
-
-            if (mPolicy.isKeyguardLocked()) {
-                // The screen is locked and no top system window is requesting an orientation.
-                // Return either the orientation of the show-when-locked app (if there is any) or
-                // the orientation of the keyguard. No point in searching from the rest of apps.
-                WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
-                AppWindowToken appShowWhenLocked = winShowWhenLocked == null ?
-                        null : winShowWhenLocked.mAppToken;
-                if (appShowWhenLocked != null) {
-                    int req = appShowWhenLocked.getOrientation();
-                    if (req == SCREEN_ORIENTATION_BEHIND) {
-                        req = mLastKeyguardForcedOrientation;
-                    }
-                    if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Done at " + appShowWhenLocked
-                            + " -- show when locked, return " + req);
-                    return req;
-                }
-                if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
-                        "No one is requesting an orientation when the screen is locked");
-                return mLastKeyguardForcedOrientation;
-            }
-        }
-
-        // Top system windows are not requesting an orientation. Start searching from apps.
-        return getDefaultDisplayContentLocked().getOrientation();
-    }
-
     @Override
-    public Configuration updateOrientationFromAppTokens(
-            Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
+    public Configuration updateOrientationFromAppTokens(Configuration currentConfig,
+            IBinder freezeThisOneIfNeeded, int displayId) {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "updateOrientationFromAppTokens()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
-        Configuration config = null;
-        long ident = Binder.clearCallingIdentity();
-
-        synchronized(mWindowMap) {
-            config = updateOrientationFromAppTokensLocked(currentConfig,
-                    freezeThisOneIfNeeded);
+        final Configuration config;
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized(mWindowMap) {
+                config = updateOrientationFromAppTokensLocked(currentConfig, freezeThisOneIfNeeded,
+                        displayId);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
 
-        Binder.restoreCallingIdentity(ident);
         return config;
     }
 
-    private Configuration updateOrientationFromAppTokensLocked(
-            Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
+    private Configuration updateOrientationFromAppTokensLocked(Configuration currentConfig,
+            IBinder freezeThisOneIfNeeded, int displayId) {
         if (!mDisplayReady) {
             return null;
         }
         Configuration config = null;
 
-        if (updateOrientationFromAppTokensLocked(false)) {
+        if (updateOrientationFromAppTokensLocked(false, displayId)) {
             // If we changed the orientation but mOrientationChangeComplete is already true,
             // we used seamless rotation, and we don't need to freeze the screen.
             if (freezeThisOneIfNeeded != null && !mRoot.mOrientationChangeComplete) {
@@ -2640,7 +2561,7 @@
                     atoken.startFreezingScreen();
                 }
             }
-            config = computeNewConfigurationLocked();
+            config = computeNewConfigurationLocked(displayId);
 
         } else if (currentConfig != null) {
             // No obvious action we need to take, but if our current state mismatches the activity
@@ -2650,10 +2571,10 @@
             // to keep override configs clear of non-empty values (e.g. fontSize).
             mTempConfiguration.unset();
             mTempConfiguration.updateFrom(currentConfig);
-            computeScreenConfigurationLocked(mTempConfiguration);
+            computeScreenConfigurationLocked(mTempConfiguration, displayId);
             if (currentConfig.diff(mTempConfiguration) != 0) {
                 mWaitingForConfig = true;
-                final DisplayContent displayContent = getDefaultDisplayContentLocked();
+                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                 displayContent.setLayoutNeeded();
                 int anim[] = new int[2];
                 if (displayContent.isDimming()) {
@@ -2669,30 +2590,28 @@
         return config;
     }
 
-    /*
-     * Determine the new desired orientation of the display, returning
-     * a non-null new Configuration if it has changed from the current
-     * orientation.  IF TRUE IS RETURNED SOMEONE MUST CALL
-     * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
-     * SCREEN.  This will typically be done for you if you call
-     * sendNewConfiguration().
+    /**
+     * Determine the new desired orientation of the display, returning a non-null new Configuration
+     * if it has changed from the current orientation.  IF TRUE IS RETURNED SOMEONE MUST CALL
+     * {@link #setNewDisplayOverrideConfiguration(Configuration, int)} TO TELL THE WINDOW MANAGER IT
+     * CAN UNFREEZE THE SCREEN.  This will typically be done for you if you call
+     * {@link #sendNewConfiguration(int)}.
      *
-     * The orientation is computed from non-application windows first. If none of
-     * the non-application windows specify orientation, the orientation is computed from
-     * application tokens.
-     * @see android.view.IWindowManager#updateOrientationFromAppTokens(
-     * android.os.IBinder)
+     * The orientation is computed from non-application windows first. If none of the
+     * non-application windows specify orientation, the orientation is computed from application
+     * tokens.
+     * @see android.view.IWindowManager#updateOrientationFromAppTokens(Configuration, IBinder, int)
      */
-    boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
+    boolean updateOrientationFromAppTokensLocked(boolean inTransaction, int displayId) {
         long ident = Binder.clearCallingIdentity();
         try {
-            int req = getOrientationLocked();
+            final int req = mRoot.getDisplayContent(displayId).getOrientation();
             if (req != mLastOrientation) {
                 mLastOrientation = req;
                 //send a message to Policy indicating orientation change to take
                 //action like disabling/enabling sensors etc.,
                 mPolicy.setCurrentOrientationLw(req);
-                if (updateRotationUncheckedLocked(inTransaction)) {
+                if (updateRotationUncheckedLocked(inTransaction, displayId)) {
                     // changed
                     return true;
                 }
@@ -2718,8 +2637,8 @@
     }
 
     @Override
-    public int[] setNewConfiguration(Configuration config) {
-        if (!checkCallingPermission(MANAGE_APP_TOKENS, "setNewConfiguration()")) {
+    public int[] setNewDisplayOverrideConfiguration(Configuration overrideConfig, int displayId) {
+        if (!checkCallingPermission(MANAGE_APP_TOKENS, "setNewDisplayOverrideConfiguration()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
@@ -2728,7 +2647,7 @@
                 mWaitingForConfig = false;
                 mLastFinishedFreezeSource = "new-config";
             }
-            return mRoot.setGlobalConfigurationIfNeeded(config);
+            return mRoot.setDisplayOverrideConfigurationIfNeeded(overrideConfig, displayId);
         }
     }
 
@@ -3034,7 +2953,8 @@
                     return false;
                 }
                 if (windowShowWallpaper) {
-                    if (mWallpaperControllerLocked.getWallpaperTarget() == null) {
+                    if (wtoken.getDisplayContent().mWallpaperController.getWallpaperTarget()
+                            == null) {
                         // If this theme is requesting a wallpaper, and the wallpaper
                         // is not currently visible, then this effectively serves as
                         // an opaque window and our starting window transition animation
@@ -3348,51 +3268,6 @@
         mH.sendMessage(m);
     }
 
-    /** Rebuilds the input display's window list and does a relayout if something changed. */
-    private void rebuildAppWindowsAndLayoutIfNeededLocked(DisplayContent displayContent) {
-        final WindowList windows = displayContent.getWindowList();
-        mTmpWindows.addAll(windows);
-
-        displayContent.rebuildAppWindowList();
-
-        // Set displayContent.mLayoutNeeded if window order changed.
-        final int tmpSize = mTmpWindows.size();
-        final int winSize = windows.size();
-        int tmpNdx = 0, winNdx = 0;
-        while (tmpNdx < tmpSize && winNdx < winSize) {
-            // Skip over all exiting windows, they've been moved out of order.
-            WindowState tmp;
-            do {
-                tmp = mTmpWindows.get(tmpNdx++);
-            } while (tmpNdx < tmpSize && tmp.mAppToken != null && tmp.mAppToken.mIsExiting);
-
-            WindowState win;
-            do {
-                win = windows.get(winNdx++);
-            } while (winNdx < winSize && win.mAppToken != null && win.mAppToken.mIsExiting);
-
-            if (tmp != win) {
-                // Window order changed.
-                displayContent.setLayoutNeeded();
-                break;
-            }
-        }
-        if (tmpNdx != winNdx) {
-            // One list was different from the other.
-            displayContent.setLayoutNeeded();
-        }
-        mTmpWindows.clear();
-
-        if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
-                false /*updateInputWindows*/)) {
-            displayContent.assignWindowLayers(false /* setLayoutNeeded */);
-        }
-
-        mInputMonitor.setUpdateInputWindowsNeededLw();
-        mWindowPlacerLocked.performSurfacePlacement();
-        mInputMonitor.updateInputWindowsLw(false /*force*/);
-    }
-
     public void moveTaskToTop(int taskId) {
         final long origId = Binder.clearCallingIdentity();
         try {
@@ -3417,7 +3292,7 @@
                 if (mAppTransition.isTransitionSet()) {
                     task.setSendingToBottom(false);
                 }
-                rebuildAppWindowsAndLayoutIfNeededLocked(displayContent);
+                displayContent.rebuildAppWindowsAndLayoutIfNeeded();
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -3439,7 +3314,7 @@
                 if (mAppTransition.isTransitionSet()) {
                     task.setSendingToBottom(true);
                 }
-                rebuildAppWindowsAndLayoutIfNeededLocked(stack.getDisplayContent());
+                stack.getDisplayContent().rebuildAppWindowsAndLayoutIfNeeded();
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -3462,6 +3337,36 @@
         mDockedStackCreateBounds = bounds;
     }
 
+    @Override
+    public Rect getPictureInPictureDefaultBounds(int displayId) {
+        synchronized (mWindowMap) {
+            if (!mSupportsPictureInPicture) {
+                return new Rect();
+            }
+
+            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+            return displayContent.getPinnedStackController().getDefaultBounds();
+        }
+    }
+
+    @Override
+    public Rect getPictureInPictureMovementBounds(int displayId) {
+        synchronized (mWindowMap) {
+            if (!mSupportsPictureInPicture) {
+                return new Rect();
+            }
+
+            final Rect stackBounds = new Rect();
+            getStackBounds(PINNED_STACK_ID, stackBounds);
+            if (stackBounds.isEmpty()) {
+                return stackBounds;
+            }
+
+            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+            return displayContent.getPinnedStackController().getMovementBounds(stackBounds);
+        }
+    }
+
     /**
      * Create a new TaskStack and place it on a DisplayContent.
      * @param stackId The unique identifier of the new stack.
@@ -3481,21 +3386,16 @@
         }
     }
 
-    public void detachStack(int stackId) {
+    public void removeStack(int stackId) {
         synchronized (mWindowMap) {
             final TaskStack stack = mStackIdToStack.get(stackId);
             if (stack != null) {
                 stack.removeIfPossible();
+                mStackIdToStack.remove(stackId);
             }
         }
     }
 
-    public void removeStack(int stackId) {
-        synchronized (mWindowMap) {
-            mStackIdToStack.remove(stackId);
-        }
-    }
-
     public void removeTask(int taskId) {
         synchronized (mWindowMap) {
             Task task = mTaskIdToTask.get(taskId);
@@ -4216,64 +4116,7 @@
         performEnableScreen();
     }
 
-    private boolean checkWaitingForWindowsLocked() {
-
-        boolean haveBootMsg = false;
-        boolean haveApp = false;
-        // if the wallpaper service is disabled on the device, we're never going to have
-        // wallpaper, don't bother waiting for it
-        boolean haveWallpaper = false;
-        boolean wallpaperEnabled = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_enableWallpaperService)
-                && !mOnlyCore;
-        boolean haveKeyguard = true;
-        // TODO(multidisplay): Expand to all displays?
-        final WindowList windows = getDefaultWindowListLocked();
-        final int N = windows.size();
-        for (int i=0; i<N; i++) {
-            WindowState w = windows.get(i);
-            if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
-                return true;
-            }
-            if (w.isDrawnLw()) {
-                if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
-                    haveBootMsg = true;
-                } else if (w.mAttrs.type == TYPE_APPLICATION
-                        || w.mAttrs.type == TYPE_DRAWN_APPLICATION) {
-                    haveApp = true;
-                } else if (w.mAttrs.type == TYPE_WALLPAPER) {
-                    haveWallpaper = true;
-                } else if (w.mAttrs.type == TYPE_STATUS_BAR) {
-                    haveKeyguard = mPolicy.isKeyguardDrawnLw();
-                }
-            }
-        }
-
-        if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
-            Slog.i(TAG_WM, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
-                    + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
-                    + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
-                    + " haveKeyguard=" + haveKeyguard);
-        }
-
-        // If we are turning on the screen to show the boot message,
-        // don't do it until the boot message is actually displayed.
-        if (!mSystemBooted && !haveBootMsg) {
-            return true;
-        }
-
-        // If we are turning on the screen after the boot is completed
-        // normally, don't do so until we have the application and
-        // wallpaper.
-        if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
-                (wallpaperEnabled && !haveWallpaper))) {
-            return true;
-        }
-
-        return false;
-    }
-
-    public void performEnableScreen() {
+    private void performEnableScreen() {
         synchronized(mWindowMap) {
             if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
                     + " mForceDisplayEnabled=" + mForceDisplayEnabled
@@ -4289,7 +4132,9 @@
             }
 
             // Don't enable the screen until all existing windows have been drawn.
-            if (!mForceDisplayEnabled && checkWaitingForWindowsLocked()) {
+            if (!mForceDisplayEnabled
+                    // TODO(multidisplay): Expand to all displays?
+                    && getDefaultDisplayContentLocked().checkWaitingForWindows()) {
                 return;
             }
 
@@ -4534,29 +4379,6 @@
         SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
     }
 
-    private static void convertCropForSurfaceFlinger(Rect crop, int rot, int dw, int dh) {
-        if (rot == Surface.ROTATION_90) {
-            final int tmp = crop.top;
-            crop.top = dw - crop.right;
-            crop.right = crop.bottom;
-            crop.bottom = dw - crop.left;
-            crop.left = tmp;
-        } else if (rot == Surface.ROTATION_180) {
-            int tmp = crop.top;
-            crop.top = dh - crop.bottom;
-            crop.bottom = dh - tmp;
-            tmp = crop.right;
-            crop.right = dw - crop.left;
-            crop.left = dw - tmp;
-        } else if (rot == Surface.ROTATION_270) {
-            final int tmp = crop.top;
-            crop.top = crop.left;
-            crop.left = dh - crop.bottom;
-            crop.bottom = crop.right;
-            crop.right = dh - tmp;
-        }
-    }
-
     @Override
     public Bitmap screenshotWallpaper() {
         if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER,
@@ -4565,8 +4387,9 @@
         }
         try {
             Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenshotWallpaper");
-            return screenshotApplicationsInner(null, Display.DEFAULT_DISPLAY, -1, -1, true, 1f,
-                    Bitmap.Config.ARGB_8888, true);
+            return screenshotApplicationsInner(null /* appToken */, DEFAULT_DISPLAY, -1 /* width */,
+                    -1 /* height */, true /* includeFullDisplay */, 1f /* frameScale */,
+                    Bitmap.Config.ARGB_8888, true /* wallpaperOnly */);
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
         }
@@ -4584,15 +4407,13 @@
             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
         }
 
-        FgThread.getHandler().post(new Runnable() {
-            @Override
-            public void run() {
-                Bitmap bm = screenshotApplicationsInner(null, Display.DEFAULT_DISPLAY, -1, -1,
-                        true, 1f, Bitmap.Config.ARGB_8888, false);
-                try {
-                    receiver.send(bm);
-                } catch (RemoteException e) {
-                }
+        FgThread.getHandler().post(() -> {
+            Bitmap bm = screenshotApplicationsInner(null /* appToken */, DEFAULT_DISPLAY,
+                    -1 /* width */, -1 /* height */, true /* includeFullDisplay */,
+                    1f /* frameScale */, Bitmap.Config.ARGB_8888, false /* wallpaperOnly */);
+            try {
+                receiver.send(bm);
+            } catch (RemoteException e) {
             }
         });
 
@@ -4636,8 +4457,8 @@
      * @param config of the output bitmap
      * @param wallpaperOnly true if only the wallpaper layer should be included in the screenshot
      */
-    Bitmap screenshotApplicationsInner(IBinder appToken, int displayId, int width, int height,
-            boolean includeFullDisplay, float frameScale, Bitmap.Config config,
+    private Bitmap screenshotApplicationsInner(IBinder appToken, int displayId, int width,
+            int height, boolean includeFullDisplay, float frameScale, Bitmap.Config config,
             boolean wallpaperOnly) {
         final DisplayContent displayContent;
         synchronized(mWindowMap) {
@@ -4648,263 +4469,8 @@
                 return null;
             }
         }
-        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        int dw = displayInfo.logicalWidth;
-        int dh = displayInfo.logicalHeight;
-        if (dw == 0 || dh == 0) {
-            if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot of " + appToken
-                    + ": returning null. logical widthxheight=" + dw + "x" + dh);
-            return null;
-        }
-
-        Bitmap bm = null;
-
-        int maxLayer = 0;
-        final Rect frame = new Rect();
-        final Rect stackBounds = new Rect();
-
-        boolean screenshotReady;
-        int minLayer;
-        if (appToken == null && !wallpaperOnly) {
-            screenshotReady = true;
-            minLayer = 0;
-        } else {
-            screenshotReady = false;
-            minLayer = Integer.MAX_VALUE;
-        }
-
-        WindowState appWin = null;
-
-        boolean includeImeInScreenshot;
-        synchronized(mWindowMap) {
-            final AppWindowToken imeTargetAppToken =
-                    mInputMethodTarget != null ? mInputMethodTarget.mAppToken : null;
-            // We only include the Ime in the screenshot if the app we are screenshoting is the IME
-            // target and isn't in multi-window mode. We don't screenshot the IME in multi-window
-            // mode because the frame of the IME might not overlap with that of the app.
-            // E.g. IME target app at the top in split-screen mode and the IME at the bottom
-            // overlapping with the bottom app.
-            includeImeInScreenshot = imeTargetAppToken != null
-                    && imeTargetAppToken.appToken != null
-                    && imeTargetAppToken.appToken.asBinder() == appToken
-                    && !mInputMethodTarget.isInMultiWindowMode();
-        }
-
-        final int aboveAppLayer = (mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) + 1)
-                * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
-
-        synchronized(mWindowMap) {
-            // Figure out the part of the screen that is actually the app.
-            appWin = null;
-            final WindowList windows = displayContent.getWindowList();
-            for (int i = windows.size() - 1; i >= 0; i--) {
-                WindowState ws = windows.get(i);
-                if (!ws.mHasSurface) {
-                    continue;
-                }
-                if (ws.mLayer >= aboveAppLayer) {
-                    continue;
-                }
-                if (wallpaperOnly && !ws.mIsWallpaper) {
-                    continue;
-                }
-                if (ws.mIsImWindow) {
-                    if (!includeImeInScreenshot) {
-                        continue;
-                    }
-                } else if (ws.mIsWallpaper) {
-                    // If this is the wallpaper layer and we're only looking for the wallpaper layer
-                    // then the target window state is this one.
-                    if (wallpaperOnly) {
-                        appWin = ws;
-                    }
-
-                    if (appWin == null) {
-                        // We have not ran across the target window yet, so it is probably
-                        // behind the wallpaper. This can happen when the keyguard is up and
-                        // all windows are moved behind the wallpaper. We don't want to
-                        // include the wallpaper layer in the screenshot as it will coverup
-                        // the layer of the target window.
-                        continue;
-                    }
-                    // Fall through. The target window is in front of the wallpaper. For this
-                    // case we want to include the wallpaper layer in the screenshot because
-                    // the target window might have some transparent areas.
-                } else if (appToken != null) {
-                    if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
-                        // This app window is of no interest if it is not associated with the
-                        // screenshot app.
-                        continue;
-                    }
-                    appWin = ws;
-                }
-
-                // Include this window.
-
-                final WindowStateAnimator winAnim = ws.mWinAnimator;
-                int layer = winAnim.mSurfaceController.getLayer();
-                if (maxLayer < layer) {
-                    maxLayer = layer;
-                }
-                if (minLayer > layer) {
-                    minLayer = layer;
-                }
-
-                // Don't include wallpaper in bounds calculation
-                if (!includeFullDisplay && !ws.mIsWallpaper) {
-                    final Rect wf = ws.mFrame;
-                    final Rect cr = ws.mContentInsets;
-                    int left = wf.left + cr.left;
-                    int top = wf.top + cr.top;
-                    int right = wf.right - cr.right;
-                    int bottom = wf.bottom - cr.bottom;
-                    frame.union(left, top, right, bottom);
-                    ws.getVisibleBounds(stackBounds);
-                    if (!Rect.intersects(frame, stackBounds)) {
-                        // Set frame empty if there's no intersection.
-                        frame.setEmpty();
-                    }
-                }
-
-                final boolean foundTargetWs =
-                        (ws.mAppToken != null && ws.mAppToken.token == appToken)
-                        || (appWin != null && wallpaperOnly);
-                if (foundTargetWs && ws.isDisplayedLw() && winAnim.getShown()) {
-                    screenshotReady = true;
-                }
-
-                if (ws.isObscuringFullscreen(displayInfo)){
-                    break;
-                }
-            }
-
-            if (appToken != null && appWin == null) {
-                // Can't find a window to snapshot.
-                if (DEBUG_SCREENSHOT) Slog.i(TAG_WM,
-                        "Screenshot: Couldn't find a surface matching " + appToken);
-                return null;
-            }
-
-            if (!screenshotReady) {
-                Slog.i(TAG_WM, "Failed to capture screenshot of " + appToken +
-                        " appWin=" + (appWin == null ? "null" : (appWin + " drawState=" +
-                        appWin.mWinAnimator.mDrawState)));
-                return null;
-            }
-
-            // Screenshot is ready to be taken. Everything from here below will continue
-            // through the bottom of the loop and return a value. We only stay in the loop
-            // because we don't want to release the mWindowMap lock until the screenshot is
-            // taken.
-
-            if (maxLayer == 0) {
-                if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot of " + appToken
-                        + ": returning null maxLayer=" + maxLayer);
-                return null;
-            }
-
-            if (!includeFullDisplay) {
-                // Constrain frame to the screen size.
-                if (!frame.intersect(0, 0, dw, dh)) {
-                    frame.setEmpty();
-                }
-            } else {
-                // Caller just wants entire display.
-                frame.set(0, 0, dw, dh);
-            }
-            if (frame.isEmpty()) {
-                return null;
-            }
-
-            if (width < 0) {
-                width = (int) (frame.width() * frameScale);
-            }
-            if (height < 0) {
-                height = (int) (frame.height() * frameScale);
-            }
-
-            // Tell surface flinger what part of the image to crop. Take the top
-            // right part of the application, and crop the larger dimension to fit.
-            Rect crop = new Rect(frame);
-            if (width / (float) frame.width() < height / (float) frame.height()) {
-                int cropWidth = (int)((float)width / (float)height * frame.height());
-                crop.right = crop.left + cropWidth;
-            } else {
-                int cropHeight = (int)((float)height / (float)width * frame.width());
-                crop.bottom = crop.top + cropHeight;
-            }
-
-            // The screenshot API does not apply the current screen rotation.
-            int rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
-
-            if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
-                rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
-            }
-
-            // Surfaceflinger is not aware of orientation, so convert our logical
-            // crop to surfaceflinger's portrait orientation.
-            convertCropForSurfaceFlinger(crop, rot, dw, dh);
-
-            if (DEBUG_SCREENSHOT) {
-                Slog.i(TAG_WM, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
-                        + maxLayer + " appToken=" + appToken);
-                for (int i = 0; i < windows.size(); i++) {
-                    WindowState win = windows.get(i);
-                    WindowSurfaceController controller = win.mWinAnimator.mSurfaceController;
-                    Slog.i(TAG_WM, win + ": " + win.mLayer
-                            + " animLayer=" + win.mWinAnimator.mAnimLayer
-                            + " surfaceLayer=" + ((controller == null)
-                                ? "null" : controller.getLayer()));
-                }
-            }
-
-            ScreenRotationAnimation screenRotationAnimation =
-                    mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
-            final boolean inRotation = screenRotationAnimation != null &&
-                    screenRotationAnimation.isAnimating();
-            if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG_WM,
-                    "Taking screenshot while rotating");
-
-            // We force pending transactions to flush before taking
-            // the screenshot by pushing an empty synchronous transaction.
-            SurfaceControl.openTransaction();
-            SurfaceControl.closeTransactionSync();
-
-            bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
-                    inRotation, rot);
-            if (bm == null) {
-                Slog.w(TAG_WM, "Screenshot failure taking screenshot for (" + dw + "x" + dh
-                        + ") to layer " + maxLayer);
-                return null;
-            }
-        }
-
-        if (DEBUG_SCREENSHOT) {
-            // TEST IF IT's ALL BLACK
-            int[] buffer = new int[bm.getWidth() * bm.getHeight()];
-            bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
-            boolean allBlack = true;
-            final int firstColor = buffer[0];
-            for (int i = 0; i < buffer.length; i++) {
-                if (buffer[i] != firstColor) {
-                    allBlack = false;
-                    break;
-                }
-            }
-            if (allBlack) {
-                Slog.i(TAG_WM, "Screenshot " + appWin + " was monochrome(" +
-                        Integer.toHexString(firstColor) + ")! mSurfaceLayer=" +
-                        (appWin != null ?
-                                appWin.mWinAnimator.mSurfaceController.getLayer() : "null") +
-                        " minLayer=" + minLayer + " maxLayer=" + maxLayer);
-            }
-        }
-
-        // Create a copy of the screenshot that is immutable and backed in ashmem.
-        // This greatly reduces the overhead of passing the bitmap between processes.
-        Bitmap ret = bm.createAshmemBitmap(config);
-        bm.recycle();
-        return ret;
+        return displayContent.screenshotApplications(appToken, displayId, width, height,
+                includeFullDisplay, frameScale, config, wallpaperOnly);
     }
 
     /**
@@ -4993,16 +4559,17 @@
         if (mDeferredRotationPauseCount > 0) {
             mDeferredRotationPauseCount -= 1;
             if (mDeferredRotationPauseCount == 0) {
-                boolean changed = updateRotationUncheckedLocked(false);
+                // TODO(multi-display): Update rotation for different displays separately.
+                final int displayId = DEFAULT_DISPLAY;
+                final boolean changed = updateRotationUncheckedLocked(false, displayId);
                 if (changed) {
-                    mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
+                    mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayId).sendToTarget();
                 }
             }
         }
     }
 
-    private void updateRotationUnchecked(boolean alwaysSendConfiguration,
-            boolean forceRelayout) {
+    private void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
         if(DEBUG_ORIENTATION) Slog.v(TAG_WM, "updateRotationUnchecked:"
                 + " alwaysSendConfiguration=" + alwaysSendConfiguration
                 + " forceRelayout=" + forceRelayout);
@@ -5011,8 +4578,10 @@
 
         try {
             final boolean rotationChanged;
+            // TODO(multi-display): Update rotation for different displays separately.
+            int displayId = DEFAULT_DISPLAY;
             synchronized (mWindowMap) {
-                rotationChanged = updateRotationUncheckedLocked(false);
+                rotationChanged = updateRotationUncheckedLocked(false, displayId);
                 if (!rotationChanged || forceRelayout) {
                     getDefaultDisplayContentLocked().setLayoutNeeded();
                     mWindowPlacerLocked.performSurfacePlacement();
@@ -5020,7 +4589,7 @@
             }
 
             if (rotationChanged || alwaysSendConfiguration) {
-                sendNewConfiguration();
+                sendNewConfiguration(displayId);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -5028,14 +4597,14 @@
     }
 
 
-    // TODO(multidisplay): Rotate any display?
+    // TODO(multidisplay): Rotate any display? Move to DisplayContent
     /**
-     * Updates the current rotation.
+     * Updates the current rotation of the specified display.
      *
-     * Returns true if the rotation has been changed.  In this case YOU
-     * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
+     * Returns true if the rotation has been changed.  In this case YOU MUST CALL
+     * {@link #sendNewConfiguration(int)} TO UNFREEZE THE SCREEN.
      */
-    boolean updateRotationUncheckedLocked(boolean inTransaction) {
+    boolean updateRotationUncheckedLocked(boolean inTransaction, int displayId) {
         if (mDeferredRotationPauseCount > 0) {
             // Rotation updates have been paused temporarily.  Defer the update until
             // updates have been resumed.
@@ -5044,7 +4613,7 @@
         }
 
         ScreenRotationAnimation screenRotationAnimation =
-                mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
+                mAnimator.getScreenRotationAnimationLocked(displayId);
         if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
             // Rotation updates cannot be performed while the previous rotation change
             // animation is still in progress.  Skip this update.  We will try updating
@@ -5056,7 +4625,8 @@
             // Even if the screen rotation animation has finished (e.g. isAnimating
             // returns false), there is still some time where we haven't yet unfrozen
             // the display. We also need to abort rotation here.
-            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, still finishing previous rotation");
+            if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
+                    "Deferring rotation, still finishing previous rotation");
             return false;
         }
 
@@ -5066,8 +4636,8 @@
             return false;
         }
 
-        final DisplayContent displayContent = getDefaultDisplayContentLocked();
-        final WindowList windows = displayContent.getWindowList();
+        final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+        final ReadOnlyWindowList windows = displayContent.getReadOnlyWindowList();
 
         final int oldRotation = mRotation;
         int rotation = mPolicy.rotationForOrientationLw(mLastOrientation, mRotation);
@@ -5107,24 +4677,18 @@
         boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
                 mLastOrientation, rotation);
 
-        if (DEBUG_ORIENTATION) {
-            Slog.v(TAG_WM, "Selected orientation "
-                    + mLastOrientation + ", got rotation " + rotation
-                    + " which has " + (altOrientation ? "incompatible" : "compatible")
-                    + " metrics");
-        }
+        if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Selected orientation " + mLastOrientation
+                + ", got rotation " + rotation + " which has "
+                + (altOrientation ? "incompatible" : "compatible") + " metrics");
 
         if (mRotation == rotation && mAltOrientation == altOrientation) {
             // No change.
             return false;
         }
 
-        if (DEBUG_ORIENTATION) {
-            Slog.v(TAG_WM,
-                "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
-                + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
-                + ", lastOrientation=" + mLastOrientation);
-        }
+        if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Rotation changed to " + rotation
+                + (altOrientation ? " (alt)" : "") + " from " + mRotation
+                + (mAltOrientation ? " (alt)" : "") + ", lastOrientation=" + mLastOrientation);
 
         mRotation = rotation;
         mAltOrientation = altOrientation;
@@ -5146,7 +4710,7 @@
             startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
             // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
             screenRotationAnimation =
-                mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
+                mAnimator.getScreenRotationAnimationLocked(displayId);
         } else {
             // The screen rotation animation uses a screenshot to freeze the screen
             // while windows resize underneath.
@@ -5164,7 +4728,7 @@
         // the top of the method, the caller is obligated to call computeNewConfigurationLocked().
         // By updating the Display info here it will be available to
         // computeScreenConfigurationLocked later.
-        updateDisplayAndOrientationLocked(mRoot.getConfiguration().uiMode);
+        updateDisplayAndOrientationLocked(displayContent.getConfiguration().uiMode, displayId);
 
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
         if (!inTransaction) {
@@ -5216,6 +4780,7 @@
                 w.mLastFreezeDuration = 0;
             }
         }
+
         if (rotateSeamlessly) {
             mH.removeMessages(H.SEAMLESS_ROTATION_TIMEOUT);
             mH.sendEmptyMessageDelayed(H.SEAMLESS_ROTATION_TIMEOUT, SEAMLESS_ROTATION_TIMEOUT_DURATION);
@@ -5232,7 +4797,7 @@
         // Announce rotation only if we will not animate as we already have the
         // windows in final state. Otherwise, we make this call at the rotation end.
         if (screenRotationAnimation == null && mAccessibilityController != null
-                && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) {
+                && displayContent.getDisplayId() == DEFAULT_DISPLAY) {
             mAccessibilityController.onRotationChangedLocked(getDefaultDisplayContentLocked(),
                     rotation);
         }
@@ -5697,13 +5262,14 @@
     }
 
     /**
-     * Instruct the Activity Manager to fetch new configurations, update global configuration
-     * and broadcast changes to config-changed listeners if appropriate.
+     * Instruct the Activity Manager to fetch and update the current display's configuration and
+     * broadcast them to config-changed listeners if appropriate.
      * NOTE: Can't be called with the window manager lock held since it call into activity manager.
      */
-    void sendNewConfiguration() {
+    void sendNewConfiguration(int displayId) {
         try {
-            final boolean configUpdated = mActivityManager.updateConfiguration(null);
+            final boolean configUpdated = mActivityManager.updateDisplayOverrideConfiguration(
+                    null /* values */, displayId);
             if (!configUpdated) {
                 // Something changed (E.g. device rotation), but no configuration update is needed.
                 // E.g. changing device rotation by 180 degrees. Go ahead and perform surface
@@ -5713,7 +5279,7 @@
                     if (mWaitingForConfig) {
                         mWaitingForConfig = false;
                         mLastFinishedFreezeSource = "config-unchanged";
-                        getDefaultDisplayContentLocked().setLayoutNeeded();
+                        mRoot.getDisplayContent(displayId).setLayoutNeeded();
                         mWindowPlacerLocked.performSurfacePlacement();
                     }
                 }
@@ -5722,18 +5288,18 @@
         }
     }
 
-    public Configuration computeNewConfiguration() {
+    public Configuration computeNewConfiguration(int displayId) {
         synchronized (mWindowMap) {
-            return computeNewConfigurationLocked();
+            return computeNewConfigurationLocked(displayId);
         }
     }
 
-    private Configuration computeNewConfigurationLocked() {
+    private Configuration computeNewConfigurationLocked(int displayId) {
         if (!mDisplayReady) {
             return null;
         }
-        Configuration config = new Configuration();
-        computeScreenConfigurationLocked(config);
+        final Configuration config = new Configuration();
+        computeScreenConfigurationLocked(config, displayId);
         return config;
     }
 
@@ -5842,9 +5408,8 @@
     }
 
     /** Do not call if mDisplayReady == false */
-    DisplayInfo updateDisplayAndOrientationLocked(int uiMode) {
-        // TODO(multidisplay): For now, apply Configuration to main screen only.
-        final DisplayContent displayContent = getDefaultDisplayContentLocked();
+    private DisplayInfo updateDisplayAndOrientationLocked(int uiMode, int displayId) {
+        final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
 
         // Use the effective "visual" dimensions based on current rotation
         final boolean rotated = (mRotation == Surface.ROTATION_90
@@ -5905,9 +5470,8 @@
     }
 
     /** Do not call if mDisplayReady == false */
-    void computeScreenConfigurationLocked(Configuration config) {
-        final DisplayInfo displayInfo = updateDisplayAndOrientationLocked(
-                config.uiMode);
+    private void computeScreenConfigurationLocked(Configuration config, int displayId) {
+        final DisplayInfo displayInfo = updateDisplayAndOrientationLocked(config.uiMode, displayId);
 
         final int dw = displayInfo.logicalWidth;
         final int dh = displayInfo.logicalHeight;
@@ -6469,7 +6033,7 @@
                     synchronized(mWindowMap) {
                         // TODO(multidisplay): Accessibility supported only of default desiplay.
                         if (mAccessibilityController != null && getDefaultDisplayContentLocked()
-                                .getDisplayId() == Display.DEFAULT_DISPLAY) {
+                                .getDisplayId() == DEFAULT_DISPLAY) {
                             accessibilityController = mAccessibilityController;
                         }
 
@@ -6546,11 +6110,9 @@
 
                     View view = null;
                     try {
-                        final Configuration overrideConfig =
-                                wtoken != null ? wtoken.getMergedOverrideConfiguration() : null;
                         view = mPolicy.addStartingWindow(wtoken.token, sd.pkg, sd.theme,
                             sd.compatInfo, sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo,
-                            sd.windowFlags, overrideConfig);
+                            sd.windowFlags, wtoken.getMergedOverrideConfiguration());
                     } catch (Exception e) {
                         Slog.w(TAG_WM, "Exception when adding starting window", e);
                     }
@@ -6688,21 +6250,7 @@
                 case WINDOW_FREEZE_TIMEOUT: {
                     // TODO(multidisplay): Can non-default displays rotate?
                     synchronized (mWindowMap) {
-                        Slog.w(TAG_WM, "Window freeze timeout expired.");
-                        mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
-                        final WindowList windows = getDefaultWindowListLocked();
-                        int i = windows.size();
-                        while (i > 0) {
-                            i--;
-                            WindowState w = windows.get(i);
-                            if (w.mOrientationChanging) {
-                                w.mOrientationChanging = false;
-                                w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
-                                        - mDisplayFreezeTime);
-                                Slog.w(TAG_WM, "Force clearing orientation change: " + w);
-                            }
-                        }
-                        mWindowPlacerLocked.performSurfacePlacement();
+                        getDefaultDisplayContentLocked().onWindowFreezeTimeout();
                     }
                     break;
                 }
@@ -6811,8 +6359,9 @@
                 }
 
                 case SEND_NEW_CONFIGURATION: {
-                    removeMessages(SEND_NEW_CONFIGURATION);
-                    sendNewConfiguration();
+                    removeMessages(SEND_NEW_CONFIGURATION, msg.obj);
+                    final int displayId = (Integer) msg.obj;
+                    sendNewConfiguration(displayId);
                     break;
                 }
 
@@ -7003,7 +6552,7 @@
                 break;
                 case WALLPAPER_DRAW_PENDING_TIMEOUT: {
                     synchronized (mWindowMap) {
-                        if (mWallpaperControllerLocked.processWallpaperDrawPendingTimeout()) {
+                        if (mRoot.mWallpaperController.processWallpaperDrawPendingTimeout()) {
                             mWindowPlacerLocked.performSurfacePlacement();
                         }
                     }
@@ -7093,20 +6642,8 @@
                     // Rotation only supported on primary display.
                     // TODO(multi-display)
                     synchronized(mWindowMap) {
-                        final DisplayContent displayContent = getDefaultDisplayContentLocked();
-                        final WindowList windows = displayContent.getWindowList();
-                        boolean layoutNeeded = false;
-                        for (int i = windows.size() - 1; i >= 0; i--) {
-                            WindowState w = windows.get(i);
-                            if (w.mSeamlesslyRotated) {
-                                layoutNeeded = true;
-                                w.setDisplayLayoutNeeded();
-                                markForSeamlessRotation(w, false);
-                            }
-                        }
-                        if (layoutNeeded) {
-                            mWindowPlacerLocked.performSurfacePlacement();
-                        }
+                        final DisplayContent dc = getDefaultDisplayContentLocked();
+                        dc.onSeamlessRotationTimeout();
                     }
                 }
                 break;
@@ -7149,45 +6686,9 @@
     @Override
     public boolean inputMethodClientHasFocus(IInputMethodClient client) {
         synchronized (mWindowMap) {
-            // The focus for the client is the window immediately below
-            // where we would place the input method window.
             // TODO: multi-display
-            int idx = getDefaultDisplayContentLocked().findDesiredInputMethodWindowIndex(false);
-            if (idx > 0) {
-                // TODO(multidisplay): IMEs are only supported on the default display.
-                WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
-                if (DEBUG_INPUT_METHOD) {
-                    Slog.i(TAG_WM, "Desired input method target: " + imFocus);
-                    Slog.i(TAG_WM, "Current focus: " + mCurrentFocus);
-                    Slog.i(TAG_WM, "Last focus: " + mLastFocus);
-                }
-                if (imFocus != null) {
-                    // This may be a starting window, in which case we still want
-                    // to count it as okay.
-                    if (imFocus.mAttrs.type == TYPE_APPLICATION_STARTING
-                            && imFocus.mAppToken != null) {
-                        // The client has definitely started, so it really should
-                        // have a window in this app token.  Let's look for it.
-                        final WindowState w = imFocus.mAppToken.getFirstNonStartingWindow();
-                        if (w != null) {
-                            if (DEBUG_INPUT_METHOD) Slog.i(TAG_WM,
-                                    "Switching to real app window: " + w);
-                            imFocus = w;
-                        }
-                    }
-                    if (DEBUG_INPUT_METHOD) {
-                        Slog.i(TAG_WM, "IM target client: " + imFocus.mSession.mClient);
-                        if (imFocus.mSession.mClient != null) {
-                            Slog.i(TAG_WM, "IM target client binder: "
-                                    + imFocus.mSession.mClient.asBinder());
-                            Slog.i(TAG_WM, "Requesting client binder: " + client.asBinder());
-                        }
-                    }
-                    if (imFocus.mSession.mClient != null &&
-                            imFocus.mSession.mClient.asBinder() == client.asBinder()) {
-                        return true;
-                    }
-                }
+            if (getDefaultDisplayContentLocked().inputMethodClientHasFocus(client)) {
+                return true;
             }
 
             // Okay, how about this...  what is the current focus?
@@ -7236,7 +6737,7 @@
             throw new SecurityException("Must hold permission " +
                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
         }
-        if (displayId != Display.DEFAULT_DISPLAY) {
+        if (displayId != DEFAULT_DISPLAY) {
             throw new IllegalArgumentException("Can only set the default display");
         }
         final long ident = Binder.clearCallingIdentity();
@@ -7271,7 +6772,7 @@
             throw new SecurityException("Must hold permission " +
                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
         }
-        if (displayId != Display.DEFAULT_DISPLAY) {
+        if (displayId != DEFAULT_DISPLAY) {
             throw new IllegalArgumentException("Can only set the default display");
         }
         final long ident = Binder.clearCallingIdentity();
@@ -7354,7 +6855,7 @@
             throw new SecurityException("Must hold permission " +
                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
         }
-        if (displayId != Display.DEFAULT_DISPLAY) {
+        if (displayId != DEFAULT_DISPLAY) {
             throw new IllegalArgumentException("Can only set the default display");
         }
         final long ident = Binder.clearCallingIdentity();
@@ -7403,7 +6904,7 @@
             throw new SecurityException("Must hold permission " +
                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
         }
-        if (displayId != Display.DEFAULT_DISPLAY) {
+        if (displayId != DEFAULT_DISPLAY) {
             throw new IllegalArgumentException("Can only set the default display");
         }
 
@@ -7434,7 +6935,7 @@
             throw new SecurityException("Must hold permission " +
                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
         }
-        if (displayId != Display.DEFAULT_DISPLAY) {
+        if (displayId != DEFAULT_DISPLAY) {
             throw new IllegalArgumentException("Can only set the default display");
         }
 
@@ -7496,16 +6997,19 @@
         configureDisplayPolicyLocked(displayContent);
         displayContent.setLayoutNeeded();
 
-        boolean configChanged = updateOrientationFromAppTokensLocked(false);
-        final Configuration globalConfig = mRoot.getConfiguration();
-        mTempConfiguration.setTo(globalConfig);
-        computeScreenConfigurationLocked(mTempConfiguration);
-        configChanged |= globalConfig.diff(mTempConfiguration) != 0;
+        final int displayId = displayContent.getDisplayId();
+        boolean configChanged = updateOrientationFromAppTokensLocked(false /* inTransaction */,
+                displayId);
+        final Configuration currentDisplayConfig = displayContent.getConfiguration();
+        mTempConfiguration.setTo(currentDisplayConfig);
+        computeScreenConfigurationLocked(mTempConfiguration, displayId);
+        configChanged |= currentDisplayConfig.diff(mTempConfiguration) != 0;
 
         if (configChanged) {
             mWaitingForConfig = true;
-            startFreezingDisplayLocked(false, 0, 0);
-            mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
+            startFreezingDisplayLocked(false /* inTransaction */, 0 /* exitAnim */,
+                    0 /* enterAnim */);
+            mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayId).sendToTarget();
         }
 
         mWindowPlacerLocked.performSurfacePlacement();
@@ -7627,13 +7131,14 @@
         }
         mNoAnimationNotifyOnTransitionFinished.clear();
 
-        mWallpaperControllerLocked.hideDeferredWallpapersIfNeeded();
-
         // TODO: multi-display.
         final DisplayContent dc = getDefaultDisplayContentLocked();
+
+        dc.mWallpaperController.hideDeferredWallpapersIfNeeded();
+
         dc.onAppTransitionDone();
 
-        changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
+        changes |= FINISH_LAYOUT_REDO_LAYOUT;
         if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG_WM,
                 "Wallpaper layer changed: assigning layers + relayout");
         dc.moveInputMethodWindowsIfNeeded(true);
@@ -7718,6 +7223,7 @@
         }
     }
 
+    // TODO: Move to DisplayContent
     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
         WindowState newFocus = mRoot.computeFocusedWindow();
         if (mCurrentFocus != newFocus) {
@@ -7747,9 +7253,8 @@
             if (imWindowChanged && oldFocus != mInputMethodWindow) {
                 // Focus of the input method window changed. Perform layout if needed.
                 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
-                    mWindowPlacerLocked.performLayoutLockedInner(displayContent, true /*initial*/,
-                            updateInputWindows);
-                    focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
+                    displayContent.performLayout(true /*initial*/,  updateInputWindows);
+                    focusChanged &= ~FINISH_LAYOUT_REDO_LAYOUT;
                 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
                     // Client will do the layout, but we need to assign layers
                     // for handleNewWindowLocked() below.
@@ -7757,12 +7262,11 @@
                 }
             }
 
-            if ((focusChanged & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
+            if ((focusChanged & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
                 // The change in focus caused us to need to do a layout.  Okay.
                 displayContent.setLayoutNeeded();
                 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
-                    mWindowPlacerLocked.performLayoutLockedInner(displayContent, true /*initial*/,
-                            updateInputWindows);
+                    displayContent.performLayout(true /*initial*/, updateInputWindows);
                 }
             }
 
@@ -7774,11 +7278,10 @@
 
             displayContent.adjustForImeIfNeeded();
 
-            // We may need to schedule some toast windows to be removed. The
-            // toasts for an app that does not have input focus are removed
-            // within a timeout to prevent apps to redress other apps' UI.
-            getDefaultDisplayContentLocked().scheduleToastWindowsTimeoutIfNeededLocked(
-                        oldFocus, newFocus);
+            // We may need to schedule some toast windows to be removed. The toasts for an app that
+            // does not have input focus are removed within a timeout to prevent apps to redress
+            // other apps' UI.
+            displayContent.scheduleToastWindowsTimeoutIfNeededLocked(oldFocus, newFocus);
 
             Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
             return true;
@@ -7835,16 +7338,7 @@
             }
 
             // Check whether the current screen contains any secure content.
-            boolean isSecure = false;
-            final WindowList windows = getDefaultWindowListLocked();
-            final int N = windows.size();
-            for (int i = 0; i < N; i++) {
-                WindowState ws = windows.get(i);
-                if (ws.isOnScreen() && (ws.mAttrs.flags & FLAG_SECURE) != 0) {
-                    isSecure = true;
-                    break;
-                }
-            }
+            boolean isSecure = displayContent.hasSecureWindowOnScreen();
 
             // TODO(multidisplay): rotation on main screen only.
             displayContent.updateDisplayInfo();
@@ -7931,7 +7425,7 @@
         // to avoid inconsistent states.  However, something interesting
         // could have actually changed during that time so re-evaluate it
         // now to catch that.
-        configChanged = updateOrientationFromAppTokensLocked(false);
+        configChanged = updateOrientationFromAppTokensLocked(false, displayId);
 
         // A little kludge: a lot could have happened while the
         // display was frozen, so now that we are coming back we
@@ -7945,11 +7439,11 @@
 
         if (updateRotation) {
             if (DEBUG_ORIENTATION) Slog.d(TAG_WM, "Performing post-rotate rotation");
-            configChanged |= updateRotationUncheckedLocked(false);
+            configChanged |= updateRotationUncheckedLocked(false, displayId);
         }
 
         if (configChanged) {
-            mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
+            mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayId).sendToTarget();
         }
     }
 
@@ -8050,8 +7544,8 @@
         }
     }
 
-    // TOOD(multidisplay): StatusBar on multiple screens?
-    boolean updateStatusBarVisibilityLocked(int visibility) {
+    // TODO(multidisplay): StatusBar on multiple screens?
+    private boolean updateStatusBarVisibilityLocked(int visibility) {
         if (mLastDispatchedSystemUiVisibility == visibility) {
             return false;
         }
@@ -8064,26 +7558,7 @@
 
         mLastDispatchedSystemUiVisibility = visibility;
         mInputManager.setSystemUiVisibility(visibility);
-        final WindowList windows = getDefaultWindowListLocked();
-        final int N = windows.size();
-        for (int i = 0; i < N; i++) {
-            WindowState ws = windows.get(i);
-            try {
-                int curValue = ws.mSystemUiVisibility;
-                int diff = (curValue ^ visibility) & globalDiff;
-                int newValue = (curValue&~diff) | (visibility&diff);
-                if (newValue != curValue) {
-                    ws.mSeq++;
-                    ws.mSystemUiVisibility = newValue;
-                }
-                if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
-                    ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
-                            visibility, newValue, diff);
-                }
-            } catch (RemoteException e) {
-                // so sorry
-            }
-        }
+        getDefaultDisplayContentLocked().updateSystemUiVisibility(visibility, globalDiff);
         return true;
     }
 
@@ -8228,7 +7703,7 @@
     private void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
         pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
         mRoot.dumpTokens(pw, dumpAll);
-        mWallpaperControllerLocked.dumpTokens(pw, "  ", dumpAll);
+        mRoot.mWallpaperController.dumpTokens(pw, "  ", dumpAll);
         if (!mFinishedStarting.isEmpty()) {
             pw.println();
             pw.println("  Finishing start of application tokens:");
@@ -8412,7 +7887,7 @@
                 pw.print("  mInputMethodWindow="); pw.println(mInputMethodWindow);
             }
             mWindowPlacerLocked.dump(pw, "  ");
-            mWallpaperControllerLocked.dump(pw, "  ");
+            mRoot.mWallpaperController.dump(pw, "  ");
             pw.print("  mSystemBooted="); pw.print(mSystemBooted);
                     pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
 
@@ -8439,8 +7914,9 @@
         }
     }
 
-    boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti, boolean dumpAll) {
-        WindowList windows = new WindowList();
+    private boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti,
+            boolean dumpAll) {
+        final WindowList windows = new WindowList();
         if ("apps".equals(name) || "visible".equals(name) || "visible-apps".equals(name)) {
             final boolean appsOnly = name.contains("apps");
             final boolean visibleOnly = name.contains("visible");
@@ -8467,7 +7943,7 @@
         return true;
     }
 
-    void dumpLastANRLocked(PrintWriter pw) {
+    private void dumpLastANRLocked(PrintWriter pw) {
         pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
         if (mLastANRState == null) {
             pw.println("  <no ANR has occurred since boot>");
@@ -8485,8 +7961,7 @@
      * @param windowState The window that ANR'd, may be null.
      * @param reason The reason for the ANR, may be null.
      */
-    public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState,
-            String reason) {
+    void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState, String reason) {
         StringWriter sw = new StringWriter();
         PrintWriter pw = new FastPrintWriter(sw, false, 1024);
         pw.println("  ANR time: " + DateFormat.getInstance().format(new Date()));
@@ -8541,6 +8016,7 @@
                 pw.println("    a[animator]: animator state");
                 pw.println("    s[essions]: active sessions");
                 pw.println("    surfaces: active surfaces (debugging enabled only)");
+                pw.println("    pip: PIP state");
                 pw.println("    d[isplays]: active display contents");
                 pw.println("    t[okens]: token list");
                 pw.println("    w[indows]: window list");
@@ -8613,6 +8089,18 @@
                     pw.println(output.toString());
                 }
                 return;
+            } else if ("pip".equals(cmd)) {
+                synchronized(mWindowMap) {
+                    pw.print("defaultBounds=");
+                    getPictureInPictureDefaultBounds(DEFAULT_DISPLAY).printShortString(pw);
+                    pw.println();
+                    pw.print("movementBounds=");
+                    getPictureInPictureMovementBounds(DEFAULT_DISPLAY).printShortString(pw);
+                    pw.println();
+                    getDefaultDisplayContentLocked().getPinnedStackController().dump("", pw);
+                    pw.println();
+                }
+                return;
             } else {
                 // Dumping a single name?
                 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
@@ -8676,7 +8164,7 @@
     }
 
     // TODO: All the display method below should probably be moved into the RootWindowContainer...
-    public void createDisplayContentLocked(final Display display) {
+    private void createDisplayContentLocked(final Display display) {
         if (display == null) {
             throw new IllegalArgumentException("getDisplayContent: display must not be null");
         }
@@ -8684,28 +8172,16 @@
     }
 
     // There is an inherent assumption that this will never return null.
-    public DisplayContent getDefaultDisplayContentLocked() {
-        return mRoot.getDisplayContentOrCreate(Display.DEFAULT_DISPLAY);
+    // TODO(multi-display): Inspect all the call-points of this method to see if they make sense to
+    // support non-default display.
+    DisplayContent getDefaultDisplayContentLocked() {
+        return mRoot.getDisplayContentOrCreate(DEFAULT_DISPLAY);
     }
 
-    public WindowList getDefaultWindowListLocked() {
-        return getDefaultDisplayContentLocked().getWindowList();
-    }
-
-    public DisplayInfo getDefaultDisplayInfoLocked() {
+    private DisplayInfo getDefaultDisplayInfoLocked() {
         return getDefaultDisplayContentLocked().getDisplayInfo();
     }
 
-    /**
-     * Return the list of WindowStates associated on the passed display.
-     * @param displayId The screen to return windows from.
-     * @return The list of WindowStates on the screen, or null if the there is no screen.
-     */
-    WindowList getWindowListLocked(final int displayId) {
-        final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
-        return displayContent != null ? displayContent.getWindowList() : null;
-    }
-
     public void onDisplayAdded(int displayId) {
         mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
     }
@@ -8901,13 +8377,19 @@
         }
     }
 
+    public void setSupportsPictureInPicture(boolean supportsPictureInPicture) {
+        synchronized (mWindowMap) {
+            mSupportsPictureInPicture = supportsPictureInPicture;
+        }
+    }
+
     static int dipToPixel(int dip, DisplayMetrics displayMetrics) {
         return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics);
     }
 
     @Override
     public void registerDockedStackListener(IDockedStackListener listener) {
-        if (!checkCallingPermission(android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS,
+        if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS,
                 "registerDockedStackListener()")) {
             return;
         }
@@ -8917,6 +8399,21 @@
     }
 
     @Override
+    public void registerPinnedStackListener(int displayId, IPinnedStackListener listener) {
+        if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS,
+                "registerPinnedStackListener()")) {
+            return;
+        }
+        if (!mSupportsPictureInPicture) {
+            return;
+        }
+        synchronized (mWindowMap) {
+            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+            displayContent.getPinnedStackController().registerPinnedStackListener(listener);
+        }
+    }
+
+    @Override
     public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
         try {
             WindowState focusedWindow = getFocusedWindow();
@@ -8928,15 +8425,19 @@
     }
 
     @Override
-    public void getStableInsets(Rect outInsets) throws RemoteException {
+    public void getStableInsets(int displayId, Rect outInsets) throws RemoteException {
         synchronized (mWindowMap) {
-            getStableInsetsLocked(outInsets);
+            getStableInsetsLocked(displayId, outInsets);
         }
     }
 
-    void getStableInsetsLocked(Rect outInsets) {
-        final DisplayInfo di = getDefaultDisplayInfoLocked();
-        mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, outInsets);
+    void getStableInsetsLocked(int displayId, Rect outInsets) {
+        outInsets.setEmpty();
+        final DisplayContent dc = mRoot.getDisplayContent(displayId);
+        if (dc != null) {
+            final DisplayInfo di = dc.getDisplayInfo();
+            mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, outInsets);
+        }
     }
 
     private void getNonDecorInsetsLocked(Rect outInsets) {
@@ -8952,7 +8453,7 @@
      */
     public void subtractStableInsets(Rect inOutBounds) {
         synchronized (mWindowMap) {
-            getStableInsetsLocked(mTmpRect2);
+            getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect2);
             final DisplayInfo di = getDefaultDisplayInfoLocked();
             mTmpRect.set(0, 0, di.logicalWidth, di.logicalHeight);
             subtractInsets(mTmpRect, mTmpRect2, inOutBounds);
@@ -9085,8 +8586,7 @@
     @Override
     public void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)
             throws RemoteException {
-        if (!checkCallingPermission(Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS,
-                "registerShortcutKey")) {
+        if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS, "registerShortcutKey")) {
             throw new SecurityException(
                     "Requires REGISTER_WINDOW_MANAGER_LISTENERS permission");
         }
@@ -9107,8 +8607,9 @@
             if (DEBUG_ORIENTATION) {
                 Slog.i(TAG, "Performing post-rotate rotation after seamless rotation");
             }
-            if (updateRotationUncheckedLocked(false)) {
-                mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
+            final int displayId = w.getDisplayId();
+            if (updateRotationUncheckedLocked(false, displayId)) {
+                mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayId).sendToTarget();
             }
         }
     }
@@ -9235,24 +8736,7 @@
             boolean allWindowsDrawn = false;
             synchronized (mWindowMap) {
                 mWaitingForDrawnCallback = callback;
-                final WindowList windows = getDefaultWindowListLocked();
-                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-                    final WindowState win = windows.get(winNdx);
-                    final boolean isForceHiding = mPolicy.isForceHiding(win.mAttrs);
-                    final boolean keyguard = mPolicy.isKeyguardHostWindow(win.mAttrs);
-                    if (win.isVisibleLw()
-                            && (win.mAppToken != null || isForceHiding || keyguard)) {
-                        win.mWinAnimator.mDrawState = DRAW_PENDING;
-                        // Force add to mResizingWindows.
-                        win.mLastContentInsets.set(-1, -1, -1, -1);
-                        mWaitingForDrawn.add(win);
-
-                        // No need to wait for the windows below Keyguard.
-                        if (isForceHiding) {
-                            break;
-                        }
-                    }
-                }
+                getDefaultDisplayContentLocked().waitForAllWindowsDrawn();
                 mWindowPlacerLocked.requestTraversal();
                 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
                 if (mWaitingForDrawn.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index e2c608f..59caa14 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -38,7 +38,6 @@
 import android.util.DisplayMetrics;
 import android.util.Slog;
 import android.util.TimeUtils;
-import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Gravity;
 import android.view.IApplicationToken;
@@ -137,9 +136,51 @@
 import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
 
 class WindowList extends ArrayList<WindowState> {
-    WindowList() {}
-    WindowList(WindowList windowList) {
-        super(windowList);
+
+    /**
+     * Read-only interface for the window list that the creator of the window list can pass-out to
+     * other users to prevent them from modifying the window list.
+     */
+    private ReadOnlyWindowList mReadOnly;
+
+    WindowList() {
+        mReadOnly = new ReadOnlyWindowList(this);
+    }
+
+    /** Returns the read-only interface for this window list. */
+    ReadOnlyWindowList getReadOnly() {
+        return mReadOnly;
+    }
+}
+
+/**
+ * Read-only interface for a list of windows. It is common for the owner of a list of windows to
+ * want to provide a way for external classes to iterate of its windows, but prevent them from
+ * modifying the list in any way. This call provides a way for them to do that by wrapping the
+ * original window list and only exposing the read-only APIs.
+ */
+final class ReadOnlyWindowList {
+    // List of windows this read-only class is tied to.
+    private final WindowList mWindows;
+
+    ReadOnlyWindowList(WindowList windows) {
+        mWindows = windows;
+    }
+
+    WindowState get(int index) {
+        return mWindows.get(index);
+    }
+
+    int indexOf(WindowState w) {
+        return mWindows.indexOf(w);
+    }
+
+    int size() {
+        return mWindows.size();
+    }
+
+    boolean isEmpty() {
+        return mWindows.isEmpty();
     }
 }
 
@@ -690,8 +731,9 @@
     }
 
     @Override
-    public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf,
-            Rect osf) {
+    public void computeFrameLw(Rect parentFrame, Rect displayFrame, Rect overscanFrame,
+            Rect contentFrame, Rect visibleFrame, Rect decorFrame, Rect stableFrame,
+            Rect outsetFrame) {
         if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
             // This window is being replaced and either already got information that it's being
             // removed or we are still waiting for some information. Because of this we don't
@@ -727,10 +769,10 @@
         final int layoutYDiff;
         if (fullscreenTask || layoutInParentFrame()) {
             // We use the parent frame as the containing frame for fullscreen and child windows
-            mContainingFrame.set(pf);
-            mDisplayFrame.set(df);
-            layoutDisplayFrame = df;
-            layoutContainingFrame = pf;
+            mContainingFrame.set(parentFrame);
+            mDisplayFrame.set(displayFrame);
+            layoutDisplayFrame = displayFrame;
+            layoutContainingFrame = parentFrame;
             layoutXDiff = 0;
             layoutYDiff = 0;
         } else {
@@ -746,15 +788,15 @@
             final WindowState imeWin = mService.mInputMethodWindow;
             // IME is up and obscuring this window. Adjust the window position so it is visible.
             if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this) {
-                    if (windowsAreFloating && mContainingFrame.bottom > cf.bottom) {
+                    if (windowsAreFloating && mContainingFrame.bottom > contentFrame.bottom) {
                         // In freeform we want to move the top up directly.
-                        // TODO: Investigate why this is cf not pf.
-                        mContainingFrame.top -= mContainingFrame.bottom - cf.bottom;
-                    } else if (mContainingFrame.bottom > pf.bottom) {
+                        // TODO: Investigate why this is contentFrame not parentFrame.
+                        mContainingFrame.top -= mContainingFrame.bottom - contentFrame.bottom;
+                    } else if (mContainingFrame.bottom > parentFrame.bottom) {
                         // But in docked we want to behave like fullscreen
                         // and behave as if the task were given smaller bounds
                         // for the purposes of layout.
-                        mContainingFrame.bottom = pf.bottom;
+                        mContainingFrame.bottom = parentFrame.bottom;
                     }
             }
 
@@ -763,7 +805,7 @@
                 // if it wasn't set already. No need to intersect it with the (visible)
                 // "content frame" since it is allowed to be outside the visible desktop.
                 if (mContainingFrame.isEmpty()) {
-                    mContainingFrame.set(cf);
+                    mContainingFrame.set(contentFrame);
                 }
             }
             mDisplayFrame.set(mContainingFrame);
@@ -771,22 +813,22 @@
             layoutYDiff = !mInsetFrame.isEmpty() ? mInsetFrame.top - mContainingFrame.top : 0;
             layoutContainingFrame = !mInsetFrame.isEmpty() ? mInsetFrame : mContainingFrame;
             mTmpRect.set(0, 0, dc.getDisplayInfo().logicalWidth, dc.getDisplayInfo().logicalHeight);
-            subtractInsets(mDisplayFrame, layoutContainingFrame, df, mTmpRect);
+            subtractInsets(mDisplayFrame, layoutContainingFrame, displayFrame, mTmpRect);
             if (!layoutInParentFrame()) {
-                subtractInsets(mContainingFrame, layoutContainingFrame, pf, mTmpRect);
-                subtractInsets(mInsetFrame, layoutContainingFrame, pf, mTmpRect);
+                subtractInsets(mContainingFrame, layoutContainingFrame, parentFrame, mTmpRect);
+                subtractInsets(mInsetFrame, layoutContainingFrame, parentFrame, mTmpRect);
             }
-            layoutDisplayFrame = df;
+            layoutDisplayFrame = displayFrame;
             layoutDisplayFrame.intersect(layoutContainingFrame);
         }
 
         final int pw = mContainingFrame.width();
         final int ph = mContainingFrame.height();
 
-        if (!mParentFrame.equals(pf)) {
+        if (!mParentFrame.equals(parentFrame)) {
             //Slog.i(TAG_WM, "Window " + this + " content frame from " + mParentFrame
-            //        + " to " + pf);
-            mParentFrame.set(pf);
+            //        + " to " + parentFrame);
+            mParentFrame.set(parentFrame);
             mContentChanged = true;
         }
         if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
@@ -795,14 +837,14 @@
             mContentChanged = true;
         }
 
-        mOverscanFrame.set(of);
-        mContentFrame.set(cf);
-        mVisibleFrame.set(vf);
-        mDecorFrame.set(dcf);
-        mStableFrame.set(sf);
-        final boolean hasOutsets = osf != null;
+        mOverscanFrame.set(overscanFrame);
+        mContentFrame.set(contentFrame);
+        mVisibleFrame.set(visibleFrame);
+        mDecorFrame.set(decorFrame);
+        mStableFrame.set(stableFrame);
+        final boolean hasOutsets = outsetFrame != null;
         if (hasOutsets) {
-            mOutsetFrame.set(osf);
+            mOutsetFrame.set(outsetFrame);
         }
 
         final int fw = mFrame.width();
@@ -889,8 +931,10 @@
             getDisplayContent().getLogicalDisplayRect(mTmpRect);
             // Override right and/or bottom insets in case if the frame doesn't fit the screen in
             // non-fullscreen mode.
-            boolean overrideRightInset = !fullscreenTask && mFrame.right > mTmpRect.right;
-            boolean overrideBottomInset = !fullscreenTask && mFrame.bottom > mTmpRect.bottom;
+            boolean overrideRightInset = !windowsAreFloating && !fullscreenTask &&
+                    mFrame.right > mTmpRect.right;
+            boolean overrideBottomInset = !windowsAreFloating && !fullscreenTask &&
+                    mFrame.bottom > mTmpRect.bottom;
             mContentInsets.set(mContentFrame.left - mFrame.left,
                     mContentFrame.top - mFrame.top,
                     overrideRightInset ? mTmpRect.right - mContentFrame.right
@@ -940,7 +984,7 @@
             final DisplayContent displayContent = getDisplayContent();
             if (displayContent != null) {
                 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-                mService.mWallpaperControllerLocked.updateWallpaperOffset(
+                getDisplayContent().mWallpaperController.updateWallpaperOffset(
                         this, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
             }
         }
@@ -1668,7 +1712,7 @@
 
         //TODO (multidisplay): Accessibility supported only for the default display.
         if (mService.mAccessibilityController != null
-                && getDisplayContent().getDisplayId() == Display.DEFAULT_DISPLAY) {
+                && getDisplayContent().getDisplayId() == DEFAULT_DISPLAY) {
             mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
         }
 
@@ -1829,6 +1873,8 @@
         // Visibility of the removed window. Will be used later to update orientation later on.
         boolean wasVisible = false;
 
+        final int displayId = getDisplayId();
+
         // First, see if we need to run an animation. If we do, we have to hold off on removing the
         // window until the animation is done. If the display is frozen, just remove immediately,
         // since the animation wouldn't be seen.
@@ -1889,8 +1935,7 @@
                     mAnimatingExit = true;
                 }
                 //TODO (multidisplay): Magnification is supported only for the default display.
-                if (mService.mAccessibilityController != null
-                        && getDisplayId() == Display.DEFAULT_DISPLAY) {
+                if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
                     mService.mAccessibilityController.onWindowTransitionLocked(this, transit);
                 }
             }
@@ -1920,8 +1965,8 @@
         removeImmediately();
         // Removing a visible window will effect the computed orientation
         // So just update orientation if needed.
-        if (wasVisible && mService.updateOrientationFromAppTokensLocked(false)) {
-            mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
+        if (wasVisible && mService.updateOrientationFromAppTokensLocked(false, displayId)) {
+            mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget();
         }
         mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
         Binder.restoreCallingIdentity(origId);
@@ -1967,7 +2012,7 @@
         if (mIsImWindow) {
             specialAdjustment = getDisplayContent().mInputMethodAnimLayerAdjustment;
         } else if (mIsWallpaper) {
-            specialAdjustment = mService.mWallpaperControllerLocked.getAnimLayerAdjustment();
+            specialAdjustment = getDisplayContent().mWallpaperController.getAnimLayerAdjustment();
         }
 
         return mLayer + specialAdjustment;
@@ -2549,7 +2594,7 @@
         clearAnimatingWithSavedSurface();
         mDestroying = true;
         mWinAnimator.hide("stopUsingSavedSurface");
-        mService.mWallpaperControllerLocked.hideWallpapers(this);
+        getDisplayContent().mWallpaperController.hideWallpapers(this);
     }
 
     void markSavedSurfaceExiting() {
@@ -3035,8 +3080,7 @@
             }
 
             //TODO (multidisplay): Accessibility supported only for the default display.
-            if (mService.mAccessibilityController != null
-                    && getDisplayId() == Display.DEFAULT_DISPLAY) {
+            if (mService.mAccessibilityController != null && getDisplayId() == DEFAULT_DISPLAY) {
                 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
             }
 
@@ -3872,7 +3916,6 @@
             dc.addToWindowList(this, index);
             index++;
         }
-        mService.mWindowsChanged = true;
         return index;
     }
 
@@ -3957,7 +4000,7 @@
             }
         }
         mAnimatingExit = false;
-        mService.mWallpaperControllerLocked.hideWallpapers(this);
+        getDisplayContent().mWallpaperController.hideWallpapers(this);
     }
 
     boolean clearAnimatingFlags() {
@@ -4024,7 +4067,7 @@
      */
     void dispatchWallpaperVisibility(final boolean visible) {
         final boolean hideAllowed =
-                mService.mWallpaperControllerLocked.mDeferredHideWallpaper == null;
+                getDisplayContent().mWallpaperController.mDeferredHideWallpaper == null;
 
         // Only send notification if the visibility actually changed and we are not trying to hide
         // the wallpaper when we are deferring hiding of the wallpaper.
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 12e5bce..2aeb50b 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -262,7 +262,7 @@
         mSession = win.mSession;
         mAttrType = win.mAttrs.type;
         mIsWallpaper = win.mIsWallpaper;
-        mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
+        mWallpaperControllerLocked = mService.mRoot.mWallpaperController;
     }
 
     public void setAnimation(Animation anim, long startTime, int stackClip) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 368484a..c48a585 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -58,6 +58,12 @@
     private float mSurfaceW = 0;
     private float mSurfaceH = 0;
 
+    // Initialize to the identity matrix.
+    private float mLastDsdx = 1;
+    private float mLastDtdx = 0;
+    private float mLastDsdy = 0;
+    private float mLastDtdy = 1;
+
     private float mSurfaceAlpha = 0;
 
     private int mSurfaceLayer = 0;
@@ -285,6 +291,17 @@
 
     void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy,
             boolean recoveringMemory) {
+        final boolean matrixChanged = mLastDsdx != dsdx || mLastDtdx != dtdx ||
+                                      mLastDsdy != dsdy || mLastDtdy != dtdy;
+        if (!matrixChanged) {
+            return;
+        }
+
+        mLastDsdx = dsdx;
+        mLastDtdx = dtdx;
+        mLastDsdy = dsdy;
+        mLastDtdy = dtdy;
+
         try {
             if (SHOW_TRANSACTIONS) logSurface(
                     "MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
@@ -300,7 +317,6 @@
                 mAnimator.reclaimSomeSurfaceMemory("matrix", true);
             }
         }
-        return;
     }
 
     boolean setSizeInTransaction(int width, int height, boolean recoveringMemory) {
@@ -337,6 +353,10 @@
                 mSurfaceControl.setAlpha(alpha);
                 mSurfaceLayer = layer;
                 mSurfaceControl.setLayer(layer);
+                mLastDsdx = dsdx;
+                mLastDtdx = dtdx;
+                mLastDsdy = dsdy;
+                mLastDtdy = dtdy;
                 mSurfaceControl.setMatrix(
                         dsdx, dtdx, dsdy, dtdy);
 
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 3522240..63820e5 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -96,7 +96,7 @@
 
     public WindowSurfacePlacer(WindowManagerService service) {
         mService = service;
-        mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
+        mWallpaperControllerLocked = mService.mRoot.mWallpaperController;
     }
 
     /**
@@ -213,180 +213,10 @@
         return mInLayout;
     }
 
-    final void performLayoutLockedInner(final DisplayContent displayContent,
-            boolean initial, boolean updateInputWindows) {
-        if (!displayContent.isLayoutNeeded()) {
-            return;
-        }
-        displayContent.clearLayoutNeeded();
-        WindowList windows = displayContent.getWindowList();
-        boolean isDefaultDisplay = displayContent.isDefaultDisplay;
-
-        DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final int dw = displayInfo.logicalWidth;
-        final int dh = displayInfo.logicalHeight;
-
-        final int N = windows.size();
-        int i;
-
-        if (DEBUG_LAYOUT) {
-            Slog.v(TAG, "-------------------------------------");
-            Slog.v(TAG, "performLayout: needed=" + displayContent.isLayoutNeeded()
-                    + " dw=" + dw + " dh=" + dh);
-        }
-
-        mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation,
-                displayContent.getConfiguration().uiMode);
-        if (isDefaultDisplay) {
-            // Not needed on non-default displays.
-            mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
-            mService.mScreenRect.set(0, 0, dw, dh);
-        }
-
-        mService.mPolicy.getContentRectLw(mTmpContentRect);
-        displayContent.resize(mTmpContentRect);
-
-        int seq = mService.mLayoutSeq+1;
-        if (seq < 0) seq = 0;
-        mService.mLayoutSeq = seq;
-
-        boolean behindDream = false;
-
-        // First perform layout of any root windows (not attached
-        // to another window).
-        int topAttached = -1;
-        for (i = N-1; i >= 0; i--) {
-            final WindowState win = windows.get(i);
-
-            // Don't do layout of a window if it is not visible, or
-            // soon won't be visible, to avoid wasting time and funky
-            // changes while a window is animating away.
-            final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
-                    || win.isGoneForLayoutLw();
-
-            if (DEBUG_LAYOUT && !win.mLayoutAttached) {
-                Slog.v(TAG, "1ST PASS " + win
-                        + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
-                        + " mLayoutAttached=" + win.mLayoutAttached
-                        + " screen changed=" + win.isConfigChanged());
-                final AppWindowToken atoken = win.mAppToken;
-                if (gone) Slog.v(TAG, "  GONE: mViewVisibility="
-                        + win.mViewVisibility + " mRelayoutCalled="
-                        + win.mRelayoutCalled + " hidden="
-                        + win.mToken.hidden + " hiddenRequested="
-                        + (atoken != null && atoken.hiddenRequested)
-                        + " parentHidden=" + win.isParentWindowHidden());
-                else Slog.v(TAG, "  VIS: mViewVisibility="
-                        + win.mViewVisibility + " mRelayoutCalled="
-                        + win.mRelayoutCalled + " hidden="
-                        + win.mToken.hidden + " hiddenRequested="
-                        + (atoken != null && atoken.hiddenRequested)
-                        + " parentHidden=" + win.isParentWindowHidden());
-            }
-
-            // If this view is GONE, then skip it -- keep the current
-            // frame, and let the caller know so they can ignore it
-            // if they want.  (We do the normal layout for INVISIBLE
-            // windows, since that means "perform layout as normal,
-            // just don't display").
-            if (!gone || !win.mHaveFrame || win.mLayoutNeeded
-                    || ((win.isConfigChanged() || win.setReportResizeHints())
-                            && !win.isGoneForLayoutLw() &&
-                            ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
-                            (win.mHasSurface && win.mAppToken != null &&
-                            win.mAppToken.layoutConfigChanges)))) {
-                if (!win.mLayoutAttached) {
-                    if (initial) {
-                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
-                        win.mContentChanged = false;
-                    }
-                    if (win.mAttrs.type == TYPE_DREAM) {
-                        // Don't layout windows behind a dream, so that if it
-                        // does stuff like hide the status bar we won't get a
-                        // bad transition when it goes away.
-                        behindDream = true;
-                    }
-                    win.mLayoutNeeded = false;
-                    win.prelayout();
-                    mService.mPolicy.layoutWindowLw(win, null);
-                    win.mLayoutSeq = seq;
-
-                    // Window frames may have changed. Update dim layer with the new bounds.
-                    final Task task = win.getTask();
-                    if (task != null) {
-                        displayContent.mDimLayerController.updateDimLayer(task);
-                    }
-
-                    if (DEBUG_LAYOUT) Slog.v(TAG,
-                            "  LAYOUT: mFrame="
-                            + win.mFrame + " mContainingFrame="
-                            + win.mContainingFrame + " mDisplayFrame="
-                            + win.mDisplayFrame);
-                } else {
-                    if (topAttached < 0) topAttached = i;
-                }
-            }
-        }
-
-        boolean attachedBehindDream = false;
-
-        // Now perform layout of attached windows, which usually
-        // depend on the position of the window they are attached to.
-        // XXX does not deal with windows that are attached to windows
-        // that are themselves attached.
-        for (i = topAttached; i >= 0; i--) {
-            final WindowState win = windows.get(i);
-
-            if (win.mLayoutAttached) {
-                if (DEBUG_LAYOUT) Slog.v(TAG,
-                        "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
-                        + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
-                // If this view is GONE, then skip it -- keep the current
-                // frame, and let the caller know so they can ignore it
-                // if they want.  (We do the normal layout for INVISIBLE
-                // windows, since that means "perform layout as normal,
-                // just don't display").
-                if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
-                    continue;
-                }
-                if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
-                        || !win.mHaveFrame || win.mLayoutNeeded) {
-                    if (initial) {
-                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
-                        win.mContentChanged = false;
-                    }
-                    win.mLayoutNeeded = false;
-                    win.prelayout();
-                    mService.mPolicy.layoutWindowLw(win, win.getParentWindow());
-                    win.mLayoutSeq = seq;
-                    if (DEBUG_LAYOUT) Slog.v(TAG,
-                            "  LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
-                            + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
-                }
-            } else if (win.mAttrs.type == TYPE_DREAM) {
-                // Don't layout windows behind a dream, so that if it
-                // does stuff like hide the status bar we won't get a
-                // bad transition when it goes away.
-                attachedBehindDream = behindDream;
-            }
-        }
-
-        // Window frames may have changed. Tell the input dispatcher about it.
-        mService.mInputMonitor.layoutInputConsumers(dw, dh);
-        mService.mInputMonitor.setUpdateInputWindowsNeededLw();
-        if (updateInputWindows) {
-            mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
-        }
-
-        mService.mPolicy.finishLayoutLw();
-        mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
-    }
-
     /**
-     * @param windows List of windows on default display.
      * @return bitmap indicating if another pass through layout must be made.
      */
-    int handleAppTransitionReadyLocked(WindowList windows) {
+    int handleAppTransitionReadyLocked() {
         int appsCount = mService.mOpeningApps.size();
         if (!transitionGoodToGo(appsCount)) {
             return 0;
@@ -429,7 +259,7 @@
         // (like the clearAnimatingFlags() above) might affect wallpaper target result.
         // Or, the opening app window should be a wallpaper target.
         mWallpaperControllerLocked.adjustWallpaperWindowsForAppTransitionIfNeeded(displayContent,
-                mService.mOpeningApps, windows);
+                mService.mOpeningApps);
 
         final WindowState lowerWallpaperTarget =
                 mWallpaperControllerLocked.getLowerWallpaperTarget();
@@ -533,7 +363,7 @@
         // TODO: Probably not needed once the window list always has the right z-ordering
         // when the window hierarchy is updated.
         final DisplayContent dc = mService.getDefaultDisplayContentLocked();
-        if (windows == dc.getWindowList() && !dc.moveInputMethodWindowsIfNeeded(true)) {
+        if (!dc.moveInputMethodWindowsIfNeeded(true)) {
             dc.assignWindowLayers(false /*setLayoutNeeded*/);
         }
         mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 4736668..38f25e0 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -24,6 +24,7 @@
 import android.view.DisplayInfo;
 
 import java.io.PrintWriter;
+import java.util.Comparator;
 
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
@@ -82,6 +83,26 @@
     // The display this token is on.
     private DisplayContent mDisplayContent;
 
+    /**
+     * Compares two child window of this token and returns -1 if the first is lesser than the
+     * second in terms of z-order and 1 otherwise.
+     */
+    private final Comparator<WindowState> mWindowComparator =
+            (WindowState newWindow, WindowState existingWindow) -> {
+        final WindowToken token = WindowToken.this;
+        if (newWindow.mToken != token) {
+            throw new IllegalArgumentException("newWindow=" + newWindow
+                    + " is not a child of token=" + token);
+        }
+
+        if (existingWindow.mToken != token) {
+            throw new IllegalArgumentException("existingWindow=" + existingWindow
+                    + " is not a child of token=" + token);
+        }
+
+        return isFirstChildWindowGreaterThanSecond(newWindow, existingWindow) ? 1 : -1;
+    };
+
     WindowToken(WindowManagerService service, IBinder _token, int type, boolean _explicit,
             DisplayContent dc) {
         mService = service;
@@ -168,19 +189,31 @@
         return -1;
     }
 
+    /**
+     * Returns true if the new window is considered greater than the existing window in terms of
+     * z-order.
+     */
+    protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
+            WindowState existingWindow) {
+        // By default the first window isn't greater than the second to preserve existing logic of
+        // how new windows are added to the token
+        return false;
+    }
+
     void addWindow(final WindowState win) {
-        if (DEBUG_FOCUS) Slog.d(TAG_WM, "addWindow: win=" + win + " Callers=" + Debug.getCallers(5));
+        if (DEBUG_FOCUS) Slog.d(TAG_WM,
+                "addWindow: win=" + win + " Callers=" + Debug.getCallers(5));
 
         if (!win.isChildWindow()) {
-            int tokenWindowsPos = 0;
             if (asAppWindowToken() != null) {
-                tokenWindowsPos = mDisplayContent.addAppWindowToWindowList(win);
+                mDisplayContent.addAppWindowToWindowList(win);
             } else {
                 mDisplayContent.addNonAppWindowToWindowList(win);
             }
+
             if (!mChildren.contains(win)) {
                 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this);
-                addChild(win, tokenWindowsPos);
+                addChild(win, mWindowComparator);
             }
         } else {
             mDisplayContent.addChildWindowToWindowList(win);
@@ -202,7 +235,6 @@
         if (!mChildren.contains(win)) {
             addChild(win, null);
         }
-        mService.mWindowsChanged = true;
         mDisplayContent.moveInputMethodDialogs(pos + 1);
     }
 
@@ -269,7 +301,7 @@
     }
 
     void updateWallpaperOffset(int dw, int dh, boolean sync) {
-        final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
+        final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
         for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
             final WindowState wallpaper = mChildren.get(wallpaperNdx);
             if (wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, sync)) {
@@ -294,7 +326,7 @@
             mDisplayContent.setLayoutNeeded();
         }
 
-        final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
+        final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
         for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
             final WindowState wallpaper = mChildren.get(wallpaperNdx);
             if (visible) {
@@ -305,8 +337,9 @@
         }
     }
 
-    boolean updateWallpaperWindowsPlacement(WindowList windowList, WindowState wallpaperTarget,
-            int wallpaperTargetIndex, boolean visible, int dw, int dh, int wallpaperAnimLayerAdj) {
+    boolean updateWallpaperWindowsPlacement(ReadOnlyWindowList windowList,
+            WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible, int dw, int dh,
+            int wallpaperAnimLayerAdj) {
 
         boolean changed = false;
         if (hidden == visible) {
@@ -317,7 +350,7 @@
             mDisplayContent.setLayoutNeeded();
         }
 
-        final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
+        final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
         for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
             final WindowState wallpaper = mChildren.get(wallpaperNdx);
 
@@ -346,8 +379,7 @@
             if (oldIndex >= 0) {
                 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
                         "Wallpaper removing at " + oldIndex + ": " + wallpaper);
-                windowList.remove(oldIndex);
-                mService.mWindowsChanged = true;
+                mDisplayContent.removeFromWindowList(wallpaper);
                 if (oldIndex < wallpaperTargetIndex) {
                     wallpaperTargetIndex--;
                 }
@@ -370,8 +402,7 @@
                     || (DEBUG_ADD_REMOVE && oldIndex != insertionIndex)) Slog.v(TAG,
                     "Moving wallpaper " + wallpaper + " from " + oldIndex + " to " + insertionIndex);
 
-            windowList.add(insertionIndex, wallpaper);
-            mService.mWindowsChanged = true;
+            mDisplayContent.addToWindowList(wallpaper, insertionIndex);
             changed = true;
         }
 
@@ -382,7 +413,7 @@
      * @return The index in {@param windows} of the lowest window that is currently on screen and
      *         not hidden by the policy.
      */
-    private int findLowestWindowOnScreen(WindowList windowList) {
+    private int findLowestWindowOnScreen(ReadOnlyWindowList windowList) {
         final int size = windowList.size();
         for (int index = 0; index < size; index++) {
             final WindowState win = windowList.get(index);
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index d328ade..2c46413 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -70,3 +70,6 @@
     android.hardware.power@1.0 \
     android.hardware.vibrator@1.0 \
     android.hardware.light@2.0 \
+    android.hardware.vr@1.0 \
+    android.hardware.audio.common@2.0 \
+    android.hardware.tv.input@1.0 \
diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp
index 795f6aa..a2b79ff 100644
--- a/services/core/jni/com_android_server_UsbHostManager.cpp
+++ b/services/core/jni/com_android_server_UsbHostManager.cpp
@@ -34,6 +34,8 @@
 namespace android
 {
 
+static const int USB_CONTROL_TRANSFER_TIMEOUT_MS = 200;
+
 static struct parcel_file_descriptor_offsets_t
 {
     jclass mClass;
@@ -69,10 +71,13 @@
     jobject thiz = (jobject)client_data;
     const usb_device_descriptor* deviceDesc = usb_device_get_device_descriptor(device);
 
-    char *manufacturer = usb_device_get_manufacturer_name(device);
-    char *product = usb_device_get_product_name(device);
+    char *manufacturer = usb_device_get_manufacturer_name(device,
+            USB_CONTROL_TRANSFER_TIMEOUT_MS);
+    char *product = usb_device_get_product_name(device,
+            USB_CONTROL_TRANSFER_TIMEOUT_MS);
     int version = usb_device_get_version(device);
-    char *serial = usb_device_get_serial(device);
+    char *serial = usb_device_get_serial(device,
+            USB_CONTROL_TRANSFER_TIMEOUT_MS);
 
     jstring deviceName = env->NewStringUTF(devname);
     jstring manufacturerName = AndroidRuntime::NewStringLatin1(env, manufacturer);
@@ -99,7 +104,8 @@
     while ((desc = usb_descriptor_iter_next(&iter)) != NULL) {
         if (desc->bDescriptorType == USB_DT_CONFIG) {
             struct usb_config_descriptor *config = (struct usb_config_descriptor *)desc;
-            char *name = usb_device_get_string(device, config->iConfiguration);
+            char *name = usb_device_get_string(device, config->iConfiguration,
+                    USB_CONTROL_TRANSFER_TIMEOUT_MS);
             jstring configName = AndroidRuntime::NewStringLatin1(env, name);
 
             env->CallVoidMethod(thiz, method_addUsbConfiguration,
@@ -110,7 +116,8 @@
             free(name);
         } else if (desc->bDescriptorType == USB_DT_INTERFACE) {
             struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)desc;
-            char *name = usb_device_get_string(device, interface->iInterface);
+            char *name = usb_device_get_string(device, interface->iInterface,
+                    USB_CONTROL_TRANSFER_TIMEOUT_MS);
             jstring interfaceName = AndroidRuntime::NewStringLatin1(env, name);
 
             env->CallVoidMethod(thiz, method_addUsbInterface,
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index cc52260..118562f 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -29,7 +29,6 @@
 
 #include <stdio.h>
 
-using android::hardware::getService;
 using android::hardware::vibrator::V1_0::IVibrator;
 using android::hardware::vibrator::V1_0::Status;
 
diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp
index e34a8e8..179fba0 100644
--- a/services/core/jni/com_android_server_tv_TvInputHal.cpp
+++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp
@@ -24,6 +24,9 @@
 #include "JNIHelp.h"
 #include "jni.h"
 
+#include <android/hardware/tv/input/1.0/ITvInputCallback.h>
+#include <android/hardware/tv/input/1.0/ITvInput.h>
+#include <android/hardware/tv/input/1.0/types.h>
 #include <gui/Surface.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
@@ -32,6 +35,20 @@
 #include <utils/NativeHandle.h>
 #include <hardware/tv_input.h>
 
+using ::android::hardware::audio::common::V2_0::AudioDevice;
+using ::android::hardware::tv::input::V1_0::ITvInput;
+using ::android::hardware::tv::input::V1_0::ITvInputCallback;
+using ::android::hardware::tv::input::V1_0::Result;
+using ::android::hardware::tv::input::V1_0::TvInputDeviceInfo;
+using ::android::hardware::tv::input::V1_0::TvInputEvent;
+using ::android::hardware::tv::input::V1_0::TvInputEventType;
+using ::android::hardware::tv::input::V1_0::TvInputType;
+using ::android::hardware::tv::input::V1_0::TvStreamConfig;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+
 namespace android {
 
 static struct {
@@ -239,9 +256,9 @@
 
     int addOrUpdateStream(int deviceId, int streamId, const sp<Surface>& surface);
     int removeStream(int deviceId, int streamId);
-    const tv_stream_config_t* getStreamConfigs(int deviceId, int* numConfigs);
+    const hidl_vec<TvStreamConfig> getStreamConfigs(int deviceId);
 
-    void onDeviceAvailable(const tv_input_device_info_t& info);
+    void onDeviceAvailable(const TvInputDeviceInfo& info);
     void onDeviceUnavailable(int deviceId);
     void onStreamConfigurationsChanged(int deviceId);
     void onCaptured(int deviceId, int streamId, uint32_t seq, bool succeeded);
@@ -263,73 +280,60 @@
 
     class NotifyHandler : public MessageHandler {
     public:
-        NotifyHandler(JTvInputHal* hal, const tv_input_event_t* event);
-        ~NotifyHandler();
+        NotifyHandler(JTvInputHal* hal, const TvInputEvent& event);
 
         virtual void handleMessage(const Message& message);
 
     private:
-        tv_input_event_t mEvent;
+        TvInputEvent mEvent;
         JTvInputHal* mHal;
     };
 
-    JTvInputHal(JNIEnv* env, jobject thiz, tv_input_device_t* dev, const sp<Looper>& looper);
+    class TvInputCallback : public ITvInputCallback {
+    public:
+        TvInputCallback(JTvInputHal* hal);
+        Return<void> notify(const TvInputEvent& event) override;
+    private:
+        JTvInputHal* mHal;
+    };
 
-    static void notify(
-            tv_input_device_t* dev, tv_input_event_t* event, void* data);
-
-    static void cloneTvInputEvent(
-            tv_input_event_t* dstEvent, const tv_input_event_t* srcEvent);
+    JTvInputHal(JNIEnv* env, jobject thiz, sp<ITvInput> tvInput, const sp<Looper>& looper);
 
     Mutex mLock;
     jweak mThiz;
-    tv_input_device_t* mDevice;
-    tv_input_callback_ops_t mCallback;
     sp<Looper> mLooper;
 
     KeyedVector<int, KeyedVector<int, Connection> > mConnections;
+
+    sp<ITvInput> mTvInput;
+    sp<ITvInputCallback> mTvInputCallback;
 };
 
-JTvInputHal::JTvInputHal(JNIEnv* env, jobject thiz, tv_input_device_t* device,
+JTvInputHal::JTvInputHal(JNIEnv* env, jobject thiz, sp<ITvInput> tvInput,
         const sp<Looper>& looper) {
     mThiz = env->NewWeakGlobalRef(thiz);
-    mDevice = device;
-    mCallback.notify = &JTvInputHal::notify;
+    mTvInput = tvInput;
     mLooper = looper;
-
-    mDevice->initialize(mDevice, &mCallback, this);
+    mTvInputCallback = new TvInputCallback(this);
+    mTvInput->setCallback(mTvInputCallback);
 }
 
 JTvInputHal::~JTvInputHal() {
-    mDevice->common.close((hw_device_t*)mDevice);
-
+    mTvInput->setCallback(nullptr);
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     env->DeleteWeakGlobalRef(mThiz);
     mThiz = NULL;
 }
 
 JTvInputHal* JTvInputHal::createInstance(JNIEnv* env, jobject thiz, const sp<Looper>& looper) {
-    tv_input_module_t* module = NULL;
-    status_t err = hw_get_module(TV_INPUT_HARDWARE_MODULE_ID,
-            (hw_module_t const**)&module);
-    if (err) {
-        ALOGE("Couldn't load %s module (%s)",
-                TV_INPUT_HARDWARE_MODULE_ID, strerror(-err));
-        return 0;
+    // TODO(b/31632518)
+    sp<ITvInput> tvInput = ITvInput::getService("tv.input");
+    if (tvInput == nullptr) {
+        ALOGE("Couldn't get tv.input service.");
+        return nullptr;
     }
 
-    tv_input_device_t* device = NULL;
-    err = module->common.methods->open(
-            (hw_module_t*)module,
-            TV_INPUT_DEFAULT_DEVICE,
-            (hw_device_t**)&device);
-    if (err) {
-        ALOGE("Couldn't open %s device (%s)",
-                TV_INPUT_DEFAULT_DEVICE, strerror(-err));
-        return 0;
-    }
-
-    return new JTvInputHal(env, thiz, device, looper);
+    return new JTvInputHal(env, thiz, tvInput, looper);
 }
 
 int JTvInputHal::addOrUpdateStream(int deviceId, int streamId, const sp<Surface>& surface) {
@@ -353,16 +357,22 @@
     }
     if (connection.mSourceHandle == NULL && connection.mThread == NULL) {
         // Need to configure stream
-        int numConfigs = 0;
-        const tv_stream_config_t* configs = NULL;
-        if (mDevice->get_stream_configurations(
-                mDevice, deviceId, &numConfigs, &configs) != 0) {
-            ALOGE("Couldn't get stream configs");
+        Result result = Result::UNKNOWN;
+        hidl_vec<TvStreamConfig> list;
+        mTvInput->getStreamConfigurations(deviceId,
+                [&result, &list](Result res, hidl_vec<TvStreamConfig> configs) {
+                    result = res;
+                    if (res == Result::OK) {
+                        list = configs;
+                    }
+                });
+        if (result != Result::OK) {
+            ALOGE("Couldn't get stream configs for device id:%d result:%d", deviceId, result);
             return UNKNOWN_ERROR;
         }
         int configIndex = -1;
-        for (int i = 0; i < numConfigs; ++i) {
-            if (configs[i].stream_id == streamId) {
+        for (size_t i = 0; i < list.size(); ++i) {
+            if (list[i].streamId == streamId) {
                 configIndex = i;
                 break;
             }
@@ -371,34 +381,27 @@
             ALOGE("Cannot find a config with given stream ID: %d", streamId);
             return BAD_VALUE;
         }
-        connection.mStreamType = configs[configIndex].type;
+        connection.mStreamType = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE;
 
-        tv_stream_t stream;
-        stream.stream_id = configs[configIndex].stream_id;
-        if (connection.mStreamType == TV_STREAM_TYPE_BUFFER_PRODUCER) {
-            stream.buffer_producer.width = configs[configIndex].max_video_width;
-            stream.buffer_producer.height = configs[configIndex].max_video_height;
-        }
-        if (mDevice->open_stream(mDevice, deviceId, &stream) != 0) {
-            ALOGE("Couldn't add stream");
+        result = Result::UNKNOWN;
+        const native_handle_t* sidebandStream;
+        mTvInput->openStream(deviceId, streamId,
+                [&result, &sidebandStream](Result res, const native_handle_t* handle) {
+                    result = res;
+                    if (res == Result::OK) {
+                        sidebandStream = handle;
+                    }
+                });
+        if (result != Result::OK) {
+            ALOGE("Couldn't open stream. device id:%d stream id:%d result:%d", deviceId, streamId,
+                    result);
             return UNKNOWN_ERROR;
         }
-        if (connection.mStreamType == TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE) {
-            connection.mSourceHandle = NativeHandle::create(
-                    stream.sideband_stream_source_handle, false);
-        } else if (connection.mStreamType == TV_STREAM_TYPE_BUFFER_PRODUCER) {
-            if (connection.mThread != NULL) {
-                connection.mThread->shutdown();
-            }
-            connection.mThread = new BufferProducerThread(mDevice, deviceId, &stream);
-            connection.mThread->run("BufferProducerThread");
-        }
+        connection.mSourceHandle = NativeHandle::create((native_handle_t*)sidebandStream, false);
     }
     connection.mSurface = surface;
-    if (connection.mStreamType == TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE) {
+    if (connection.mSurface != nullptr) {
         connection.mSurface->setSidebandStream(connection.mSourceHandle);
-    } else if (connection.mStreamType == TV_STREAM_TYPE_BUFFER_PRODUCER) {
-        connection.mThread->setSurface(surface);
     }
     return NO_ERROR;
 }
@@ -421,8 +424,8 @@
         connection.mThread->shutdown();
         connection.mThread.clear();
     }
-    if (mDevice->close_stream(mDevice, deviceId, streamId) != 0) {
-        ALOGE("Couldn't remove stream");
+    if (mTvInput->closeStream(deviceId, streamId) != Result::OK) {
+        ALOGE("Couldn't close stream. device id:%d stream id:%d", deviceId, streamId);
         return BAD_VALUE;
     }
     if (connection.mSourceHandle != NULL) {
@@ -431,41 +434,26 @@
     return NO_ERROR;
 }
 
-const tv_stream_config_t* JTvInputHal::getStreamConfigs(int deviceId, int* numConfigs) {
-    const tv_stream_config_t* configs = NULL;
-    if (mDevice->get_stream_configurations(
-            mDevice, deviceId, numConfigs, &configs) != 0) {
-        ALOGE("Couldn't get stream configs");
-        return NULL;
+const hidl_vec<TvStreamConfig> JTvInputHal::getStreamConfigs(int deviceId) {
+    Result result = Result::UNKNOWN;
+    hidl_vec<TvStreamConfig> list;
+    mTvInput->getStreamConfigurations(deviceId,
+            [&result, &list](Result res, hidl_vec<TvStreamConfig> configs) {
+                result = res;
+                if (res == Result::OK) {
+                    list = configs;
+                }
+            });
+    if (result != Result::OK) {
+        ALOGE("Couldn't get stream configs for device id:%d result:%d", deviceId, result);
     }
-    return configs;
+    return list;
 }
 
-// static
-void JTvInputHal::notify(
-        tv_input_device_t* dev, tv_input_event_t* event, void* data) {
-    JTvInputHal* thiz = (JTvInputHal*)data;
-    thiz->mLooper->sendMessage(new NotifyHandler(thiz, event), event->type);
-}
-
-// static
-void JTvInputHal::cloneTvInputEvent(
-        tv_input_event_t* dstEvent, const tv_input_event_t* srcEvent) {
-    memcpy(dstEvent, srcEvent, sizeof(tv_input_event_t));
-    if ((srcEvent->type == TV_INPUT_EVENT_DEVICE_AVAILABLE ||
-            srcEvent->type == TV_INPUT_EVENT_DEVICE_UNAVAILABLE ||
-            srcEvent->type == TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED) &&
-            srcEvent->device_info.audio_address != NULL){
-        char* audio_address = new char[strlen(srcEvent->device_info.audio_address) + 1];
-        strcpy(audio_address, srcEvent->device_info.audio_address);
-        dstEvent->device_info.audio_address = audio_address;
-    }
-}
-
-void JTvInputHal::onDeviceAvailable(const tv_input_device_info_t& info) {
+void JTvInputHal::onDeviceAvailable(const TvInputDeviceInfo& info) {
     {
         Mutex::Autolock autoLock(&mLock);
-        mConnections.add(info.device_id, KeyedVector<int, Connection>());
+        mConnections.add(info.deviceId, KeyedVector<int, Connection>());
     }
     JNIEnv* env = AndroidRuntime::getJNIEnv();
 
@@ -473,17 +461,20 @@
             gTvInputHardwareInfoBuilderClassInfo.clazz,
             gTvInputHardwareInfoBuilderClassInfo.constructor);
     env->CallObjectMethod(
-            builder, gTvInputHardwareInfoBuilderClassInfo.deviceId, info.device_id);
+            builder, gTvInputHardwareInfoBuilderClassInfo.deviceId, info.deviceId);
     env->CallObjectMethod(
             builder, gTvInputHardwareInfoBuilderClassInfo.type, info.type);
-    if (info.type == TV_INPUT_TYPE_HDMI) {
+    if (info.type == TvInputType::HDMI) {
         env->CallObjectMethod(
-                builder, gTvInputHardwareInfoBuilderClassInfo.hdmiPortId, info.hdmi.port_id);
+                builder, gTvInputHardwareInfoBuilderClassInfo.hdmiPortId, info.portId);
     }
     env->CallObjectMethod(
-            builder, gTvInputHardwareInfoBuilderClassInfo.audioType, info.audio_type);
-    if (info.audio_type != AUDIO_DEVICE_NONE) {
-        jstring audioAddress = env->NewStringUTF(info.audio_address);
+            builder, gTvInputHardwareInfoBuilderClassInfo.audioType, info.audioType);
+    if (info.audioType != AudioDevice::NONE) {
+        uint8_t buffer[info.audioAddress.size() + 1];
+        memcpy(buffer, info.audioAddress.data(), info.audioAddress.size());
+        buffer[info.audioAddress.size()] = '\0';
+        jstring audioAddress = env->NewStringUTF(reinterpret_cast<const char *>(buffer));
         env->CallObjectMethod(
                 builder, gTvInputHardwareInfoBuilderClassInfo.audioAddress, audioAddress);
         env->DeleteLocalRef(audioAddress);
@@ -556,48 +547,37 @@
     }
 }
 
-JTvInputHal::NotifyHandler::NotifyHandler(JTvInputHal* hal, const tv_input_event_t* event) {
+JTvInputHal::NotifyHandler::NotifyHandler(JTvInputHal* hal, const TvInputEvent& event) {
     mHal = hal;
-    cloneTvInputEvent(&mEvent, event);
-}
-
-JTvInputHal::NotifyHandler::~NotifyHandler() {
-    if ((mEvent.type == TV_INPUT_EVENT_DEVICE_AVAILABLE ||
-            mEvent.type == TV_INPUT_EVENT_DEVICE_UNAVAILABLE ||
-            mEvent.type == TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED) &&
-            mEvent.device_info.audio_address != NULL) {
-        delete mEvent.device_info.audio_address;
-    }
+    mEvent = event;
 }
 
 void JTvInputHal::NotifyHandler::handleMessage(const Message& message) {
     switch (mEvent.type) {
-        case TV_INPUT_EVENT_DEVICE_AVAILABLE: {
-            mHal->onDeviceAvailable(mEvent.device_info);
+        case TvInputEventType::DEVICE_AVAILABLE: {
+            mHal->onDeviceAvailable(mEvent.deviceInfo);
         } break;
-        case TV_INPUT_EVENT_DEVICE_UNAVAILABLE: {
-            mHal->onDeviceUnavailable(mEvent.device_info.device_id);
+        case TvInputEventType::DEVICE_UNAVAILABLE: {
+            mHal->onDeviceUnavailable(mEvent.deviceInfo.deviceId);
         } break;
-        case TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED: {
-            mHal->onStreamConfigurationsChanged(mEvent.device_info.device_id);
-        } break;
-        case TV_INPUT_EVENT_CAPTURE_SUCCEEDED: {
-            mHal->onCaptured(mEvent.capture_result.device_id,
-                             mEvent.capture_result.stream_id,
-                             mEvent.capture_result.seq,
-                             true /* succeeded */);
-        } break;
-        case TV_INPUT_EVENT_CAPTURE_FAILED: {
-            mHal->onCaptured(mEvent.capture_result.device_id,
-                             mEvent.capture_result.stream_id,
-                             mEvent.capture_result.seq,
-                             false /* succeeded */);
+        case TvInputEventType::STREAM_CONFIGURATIONS_CHANGED: {
+            mHal->onStreamConfigurationsChanged(mEvent.deviceInfo.deviceId);
         } break;
         default:
             ALOGE("Unrecognizable event");
     }
 }
 
+JTvInputHal::TvInputCallback::TvInputCallback(JTvInputHal* hal) {
+    mHal = hal;
+}
+
+Return<void> JTvInputHal::TvInputCallback::notify(const TvInputEvent& event) {
+    // TODO(b/32200867): Ensure the event type values are in sync with the framework code.
+    mHal->mLooper->sendMessage(new NotifyHandler(mHal, event), static_cast<int>(event.type));
+    return Void();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 static jlong nativeOpen(JNIEnv* env, jobject thiz, jobject messageQueueObj) {
@@ -628,22 +608,22 @@
 static jobjectArray nativeGetStreamConfigs(JNIEnv* env, jclass clazz,
         jlong ptr, jint deviceId, jint generation) {
     JTvInputHal* tvInputHal = (JTvInputHal*)ptr;
-    int numConfigs = 0;
-    const tv_stream_config_t* configs = tvInputHal->getStreamConfigs(deviceId, &numConfigs);
+    const hidl_vec<TvStreamConfig> configs = tvInputHal->getStreamConfigs(deviceId);
 
-    jobjectArray result = env->NewObjectArray(numConfigs, gTvStreamConfigClassInfo.clazz, NULL);
-    for (int i = 0; i < numConfigs; ++i) {
+    jobjectArray result = env->NewObjectArray(configs.size(), gTvStreamConfigClassInfo.clazz, NULL);
+    for (size_t i = 0; i < configs.size(); ++i) {
         jobject builder = env->NewObject(
                 gTvStreamConfigBuilderClassInfo.clazz,
                 gTvStreamConfigBuilderClassInfo.constructor);
         env->CallObjectMethod(
-                builder, gTvStreamConfigBuilderClassInfo.streamId, configs[i].stream_id);
+                builder, gTvStreamConfigBuilderClassInfo.streamId, configs[i].streamId);
         env->CallObjectMethod(
-                builder, gTvStreamConfigBuilderClassInfo.type, configs[i].type);
+                builder, gTvStreamConfigBuilderClassInfo.type,
+                        TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE);
         env->CallObjectMethod(
-                builder, gTvStreamConfigBuilderClassInfo.maxWidth, configs[i].max_video_width);
+                builder, gTvStreamConfigBuilderClassInfo.maxWidth, configs[i].maxVideoWidth);
         env->CallObjectMethod(
-                builder, gTvStreamConfigBuilderClassInfo.maxHeight, configs[i].max_video_height);
+                builder, gTvStreamConfigBuilderClassInfo.maxHeight, configs[i].maxVideoHeight);
         env->CallObjectMethod(
                 builder, gTvStreamConfigBuilderClassInfo.generation, generation);
 
diff --git a/services/core/jni/com_android_server_vr_VrManagerService.cpp b/services/core/jni/com_android_server_vr_VrManagerService.cpp
index 1aba43b..e06e051 100644
--- a/services/core/jni/com_android_server_vr_VrManagerService.cpp
+++ b/services/core/jni/com_android_server_vr_VrManagerService.cpp
@@ -20,44 +20,41 @@
 #include <jni.h>
 #include <JNIHelp.h>
 
+#include <android/hardware/vr/1.0/IVr.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
-#include <hardware/hardware.h>
-#include <hardware/vr.h>
 
 namespace android {
 
-static vr_module_t *gVrHardwareModule = NULL;
+using ::android::hardware::vr::V1_0::IVr;
 
+static sp<IVr> gVr;
 
 static void init_native(JNIEnv* /* env */, jclass /* clazz */) {
-    if (gVrHardwareModule != NULL) {
+    // TODO(b/31632518)
+    if (gVr != nullptr) {
         // This call path should never be hit.
-        ALOGE("%s: May not initialize VR hardware module more than once!", __FUNCTION__);
+        ALOGE("%s: May not initialize IVr interface module more than once!", __FUNCTION__);
         return;
     }
 
-    int err = hw_get_module(VR_HARDWARE_MODULE_ID, (hw_module_t const**)&gVrHardwareModule);
-    if (err) {
-        ALOGW("%s: Could not open VR hardware module, error %s (%d).", __FUNCTION__,
-                strerror(-err), err);
+    gVr = IVr::getService("vr");
+    if (gVr == nullptr) {
+        ALOGW("%s: Could not open IVr interface", __FUNCTION__);
         return;
     }
 
-    // Call init method if implemented.
-    if (gVrHardwareModule->init) {
-        gVrHardwareModule->init(gVrHardwareModule);
-    }
+    gVr->init();
 }
 
 static void setVrMode_native(JNIEnv* /* env */, jclass /* clazz */, jboolean enabled) {
-    if (gVrHardwareModule == NULL) {
+    if (gVr == nullptr) {
         // There is no VR hardware module implemented, do nothing.
         return;
     }
 
     // Call set_vr_mode method, this must be implemented if the HAL exists.
-    gVrHardwareModule->set_vr_mode(gVrHardwareModule, static_cast<bool>(enabled));
+    gVr->setVrMode(static_cast<bool>(enabled));
 }
 
 static const JNINativeMethod method_table[] = {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 5106c32..1ecb3d3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -51,6 +51,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.app.admin.IDevicePolicyManager;
+import android.app.admin.PasswordMetrics;
 import android.app.admin.SecurityLog;
 import android.app.admin.SecurityLog.SecurityEvent;
 import android.app.admin.SystemUpdatePolicy;
@@ -178,7 +179,7 @@
  */
 public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
 
-    private static final String LOG_TAG = "DevicePolicyManagerService";
+    private static final String LOG_TAG = "DevicePolicyManager";
 
     private static final boolean VERBOSE_LOG = false; // DO NOT SUBMIT WITH TRUE
 
@@ -425,14 +426,7 @@
     }
 
     public static class DevicePolicyData {
-        int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
-        int mActivePasswordLength = 0;
-        int mActivePasswordUpperCase = 0;
-        int mActivePasswordLowerCase = 0;
-        int mActivePasswordLetters = 0;
-        int mActivePasswordNumeric = 0;
-        int mActivePasswordSymbols = 0;
-        int mActivePasswordNonLetter = 0;
+        @NonNull PasswordMetrics mActivePasswordMetrics = new PasswordMetrics();
         int mFailedPasswordAttempts = 0;
 
         int mUserHandle;
@@ -598,31 +592,23 @@
 
         final DeviceAdminInfo info;
 
-        int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
-
-        static final int DEF_MINIMUM_PASSWORD_LENGTH = 0;
-        int minimumPasswordLength = DEF_MINIMUM_PASSWORD_LENGTH;
 
         static final int DEF_PASSWORD_HISTORY_LENGTH = 0;
         int passwordHistoryLength = DEF_PASSWORD_HISTORY_LENGTH;
 
-        static final int DEF_MINIMUM_PASSWORD_UPPER_CASE = 0;
-        int minimumPasswordUpperCase = DEF_MINIMUM_PASSWORD_UPPER_CASE;
-
-        static final int DEF_MINIMUM_PASSWORD_LOWER_CASE = 0;
-        int minimumPasswordLowerCase = DEF_MINIMUM_PASSWORD_LOWER_CASE;
-
+        static final int DEF_MINIMUM_PASSWORD_LENGTH = 0;
         static final int DEF_MINIMUM_PASSWORD_LETTERS = 1;
-        int minimumPasswordLetters = DEF_MINIMUM_PASSWORD_LETTERS;
-
+        static final int DEF_MINIMUM_PASSWORD_UPPER_CASE = 0;
+        static final int DEF_MINIMUM_PASSWORD_LOWER_CASE = 0;
         static final int DEF_MINIMUM_PASSWORD_NUMERIC = 1;
-        int minimumPasswordNumeric = DEF_MINIMUM_PASSWORD_NUMERIC;
-
         static final int DEF_MINIMUM_PASSWORD_SYMBOLS = 1;
-        int minimumPasswordSymbols = DEF_MINIMUM_PASSWORD_SYMBOLS;
-
         static final int DEF_MINIMUM_PASSWORD_NON_LETTER = 0;
-        int minimumPasswordNonLetter = DEF_MINIMUM_PASSWORD_NON_LETTER;
+        @NonNull
+        PasswordMetrics minimumPasswordMetrics = new PasswordMetrics(
+                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, DEF_MINIMUM_PASSWORD_LENGTH,
+                DEF_MINIMUM_PASSWORD_LETTERS, DEF_MINIMUM_PASSWORD_UPPER_CASE,
+                DEF_MINIMUM_PASSWORD_LOWER_CASE, DEF_MINIMUM_PASSWORD_NUMERIC,
+                DEF_MINIMUM_PASSWORD_SYMBOLS, DEF_MINIMUM_PASSWORD_NON_LETTER);
 
         static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0;
         long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK;
@@ -728,13 +714,15 @@
             out.startTag(null, TAG_POLICIES);
             info.writePoliciesToXml(out);
             out.endTag(null, TAG_POLICIES);
-            if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+            if (minimumPasswordMetrics.quality
+                    != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
                 out.startTag(null, TAG_PASSWORD_QUALITY);
-                out.attribute(null, ATTR_VALUE, Integer.toString(passwordQuality));
+                out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordMetrics.quality));
                 out.endTag(null, TAG_PASSWORD_QUALITY);
-                if (minimumPasswordLength != DEF_MINIMUM_PASSWORD_LENGTH) {
+                if (minimumPasswordMetrics.length != DEF_MINIMUM_PASSWORD_LENGTH) {
                     out.startTag(null, TAG_MIN_PASSWORD_LENGTH);
-                    out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordLength));
+                    out.attribute(
+                            null, ATTR_VALUE, Integer.toString(minimumPasswordMetrics.length));
                     out.endTag(null, TAG_MIN_PASSWORD_LENGTH);
                 }
                 if(passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) {
@@ -742,34 +730,40 @@
                     out.attribute(null, ATTR_VALUE, Integer.toString(passwordHistoryLength));
                     out.endTag(null, TAG_PASSWORD_HISTORY_LENGTH);
                 }
-                if (minimumPasswordUpperCase != DEF_MINIMUM_PASSWORD_UPPER_CASE) {
+                if (minimumPasswordMetrics.upperCase != DEF_MINIMUM_PASSWORD_UPPER_CASE) {
                     out.startTag(null, TAG_MIN_PASSWORD_UPPERCASE);
-                    out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordUpperCase));
+                    out.attribute(
+                            null, ATTR_VALUE, Integer.toString(minimumPasswordMetrics.upperCase));
                     out.endTag(null, TAG_MIN_PASSWORD_UPPERCASE);
                 }
-                if (minimumPasswordLowerCase != DEF_MINIMUM_PASSWORD_LOWER_CASE) {
+                if (minimumPasswordMetrics.lowerCase != DEF_MINIMUM_PASSWORD_LOWER_CASE) {
                     out.startTag(null, TAG_MIN_PASSWORD_LOWERCASE);
-                    out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordLowerCase));
+                    out.attribute(
+                            null, ATTR_VALUE, Integer.toString(minimumPasswordMetrics.lowerCase));
                     out.endTag(null, TAG_MIN_PASSWORD_LOWERCASE);
                 }
-                if (minimumPasswordLetters != DEF_MINIMUM_PASSWORD_LETTERS) {
+                if (minimumPasswordMetrics.letters != DEF_MINIMUM_PASSWORD_LETTERS) {
                     out.startTag(null, TAG_MIN_PASSWORD_LETTERS);
-                    out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordLetters));
+                    out.attribute(
+                            null, ATTR_VALUE, Integer.toString(minimumPasswordMetrics.letters));
                     out.endTag(null, TAG_MIN_PASSWORD_LETTERS);
                 }
-                if (minimumPasswordNumeric != DEF_MINIMUM_PASSWORD_NUMERIC) {
+                if (minimumPasswordMetrics.numeric != DEF_MINIMUM_PASSWORD_NUMERIC) {
                     out.startTag(null, TAG_MIN_PASSWORD_NUMERIC);
-                    out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordNumeric));
+                    out.attribute(
+                            null, ATTR_VALUE, Integer.toString(minimumPasswordMetrics.numeric));
                     out.endTag(null, TAG_MIN_PASSWORD_NUMERIC);
                 }
-                if (minimumPasswordSymbols != DEF_MINIMUM_PASSWORD_SYMBOLS) {
+                if (minimumPasswordMetrics.symbols != DEF_MINIMUM_PASSWORD_SYMBOLS) {
                     out.startTag(null, TAG_MIN_PASSWORD_SYMBOLS);
-                    out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordSymbols));
+                    out.attribute(
+                            null, ATTR_VALUE, Integer.toString(minimumPasswordMetrics.symbols));
                     out.endTag(null, TAG_MIN_PASSWORD_SYMBOLS);
                 }
-                if (minimumPasswordNonLetter > DEF_MINIMUM_PASSWORD_NON_LETTER) {
+                if (minimumPasswordMetrics.nonLetter > DEF_MINIMUM_PASSWORD_NON_LETTER) {
                     out.startTag(null, TAG_MIN_PASSWORD_NONLETTER);
-                    out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordNonLetter));
+                    out.attribute(
+                            null, ATTR_VALUE, Integer.toString(minimumPasswordMetrics.nonLetter));
                     out.endTag(null, TAG_MIN_PASSWORD_NONLETTER);
                 }
             }
@@ -968,31 +962,31 @@
                 if (TAG_POLICIES.equals(tag)) {
                     info.readPoliciesFromXml(parser);
                 } else if (TAG_PASSWORD_QUALITY.equals(tag)) {
-                    passwordQuality = Integer.parseInt(
+                    minimumPasswordMetrics.quality = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_MIN_PASSWORD_LENGTH.equals(tag)) {
-                    minimumPasswordLength = Integer.parseInt(
+                    minimumPasswordMetrics.length = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_PASSWORD_HISTORY_LENGTH.equals(tag)) {
                     passwordHistoryLength = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_MIN_PASSWORD_UPPERCASE.equals(tag)) {
-                    minimumPasswordUpperCase = Integer.parseInt(
+                    minimumPasswordMetrics.upperCase = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_MIN_PASSWORD_LOWERCASE.equals(tag)) {
-                    minimumPasswordLowerCase = Integer.parseInt(
+                    minimumPasswordMetrics.lowerCase = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_MIN_PASSWORD_LETTERS.equals(tag)) {
-                    minimumPasswordLetters = Integer.parseInt(
+                    minimumPasswordMetrics.letters = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_MIN_PASSWORD_NUMERIC.equals(tag)) {
-                    minimumPasswordNumeric = Integer.parseInt(
+                    minimumPasswordMetrics.numeric = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_MIN_PASSWORD_SYMBOLS.equals(tag)) {
-                    minimumPasswordSymbols = Integer.parseInt(
+                    minimumPasswordMetrics.symbols = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_MIN_PASSWORD_NONLETTER.equals(tag)) {
-                    minimumPasswordNonLetter = Integer.parseInt(
+                    minimumPasswordMetrics.nonLetter = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) {
                     maximumTimeToUnlock = Long.parseLong(
@@ -1232,23 +1226,23 @@
                 }
             }
             pw.print(prefix); pw.print("passwordQuality=0x");
-                    pw.println(Integer.toHexString(passwordQuality));
+                    pw.println(Integer.toHexString(minimumPasswordMetrics.quality));
             pw.print(prefix); pw.print("minimumPasswordLength=");
-                    pw.println(minimumPasswordLength);
+                    pw.println(minimumPasswordMetrics.length);
             pw.print(prefix); pw.print("passwordHistoryLength=");
                     pw.println(passwordHistoryLength);
             pw.print(prefix); pw.print("minimumPasswordUpperCase=");
-                    pw.println(minimumPasswordUpperCase);
+                    pw.println(minimumPasswordMetrics.upperCase);
             pw.print(prefix); pw.print("minimumPasswordLowerCase=");
-                    pw.println(minimumPasswordLowerCase);
+                    pw.println(minimumPasswordMetrics.lowerCase);
             pw.print(prefix); pw.print("minimumPasswordLetters=");
-                    pw.println(minimumPasswordLetters);
+                    pw.println(minimumPasswordMetrics.letters);
             pw.print(prefix); pw.print("minimumPasswordNumeric=");
-                    pw.println(minimumPasswordNumeric);
+                    pw.println(minimumPasswordMetrics.numeric);
             pw.print(prefix); pw.print("minimumPasswordSymbols=");
-                    pw.println(minimumPasswordSymbols);
+                    pw.println(minimumPasswordMetrics.symbols);
             pw.print(prefix); pw.print("minimumPasswordNonLetter=");
-                    pw.println(minimumPasswordNonLetter);
+                    pw.println(minimumPasswordMetrics.nonLetter);
             pw.print(prefix); pw.print("maximumTimeToUnlock=");
                     pw.println(maximumTimeToUnlock);
             pw.print(prefix); pw.print("strongAuthUnlockTimeout=");
@@ -2281,20 +2275,17 @@
                 out.endTag(null, "failed-password-attempts");
             }
 
-            if (policy.mActivePasswordQuality != 0 || policy.mActivePasswordLength != 0
-                    || policy.mActivePasswordUpperCase != 0 || policy.mActivePasswordLowerCase != 0
-                    || policy.mActivePasswordLetters != 0 || policy.mActivePasswordNumeric != 0
-                    || policy.mActivePasswordSymbols != 0 || policy.mActivePasswordNonLetter != 0) {
+            final PasswordMetrics metrics = policy.mActivePasswordMetrics;
+            if (!metrics.isDefault()) {
                 out.startTag(null, "active-password");
-                out.attribute(null, "quality", Integer.toString(policy.mActivePasswordQuality));
-                out.attribute(null, "length", Integer.toString(policy.mActivePasswordLength));
-                out.attribute(null, "uppercase", Integer.toString(policy.mActivePasswordUpperCase));
-                out.attribute(null, "lowercase", Integer.toString(policy.mActivePasswordLowerCase));
-                out.attribute(null, "letters", Integer.toString(policy.mActivePasswordLetters));
-                out.attribute(null, "numeric", Integer
-                        .toString(policy.mActivePasswordNumeric));
-                out.attribute(null, "symbols", Integer.toString(policy.mActivePasswordSymbols));
-                out.attribute(null, "nonletter", Integer.toString(policy.mActivePasswordNonLetter));
+                out.attribute(null, "quality", Integer.toString(metrics.quality));
+                out.attribute(null, "length", Integer.toString(metrics.length));
+                out.attribute(null, "uppercase", Integer.toString(metrics.upperCase));
+                out.attribute(null, "lowercase", Integer.toString(metrics.lowerCase));
+                out.attribute(null, "letters", Integer.toString(metrics.letters));
+                out.attribute(null, "numeric", Integer.toString(metrics.numeric));
+                out.attribute(null, "symbols", Integer.toString(metrics.symbols));
+                out.attribute(null, "nonletter", Integer.toString(metrics.nonLetter));
                 out.endTag(null, "active-password");
             }
 
@@ -2464,22 +2455,15 @@
                     policy.mPasswordOwner = Integer.parseInt(
                             parser.getAttributeValue(null, "value"));
                 } else if ("active-password".equals(tag)) {
-                    policy.mActivePasswordQuality = Integer.parseInt(
-                            parser.getAttributeValue(null, "quality"));
-                    policy.mActivePasswordLength = Integer.parseInt(
-                            parser.getAttributeValue(null, "length"));
-                    policy.mActivePasswordUpperCase = Integer.parseInt(
-                            parser.getAttributeValue(null, "uppercase"));
-                    policy.mActivePasswordLowerCase = Integer.parseInt(
-                            parser.getAttributeValue(null, "lowercase"));
-                    policy.mActivePasswordLetters = Integer.parseInt(
-                            parser.getAttributeValue(null, "letters"));
-                    policy.mActivePasswordNumeric = Integer.parseInt(
-                            parser.getAttributeValue(null, "numeric"));
-                    policy.mActivePasswordSymbols = Integer.parseInt(
-                            parser.getAttributeValue(null, "symbols"));
-                    policy.mActivePasswordNonLetter = Integer.parseInt(
-                            parser.getAttributeValue(null, "nonletter"));
+                    final PasswordMetrics m = policy.mActivePasswordMetrics;
+                    m.quality = Integer.parseInt(parser.getAttributeValue(null, "quality"));
+                    m.length = Integer.parseInt(parser.getAttributeValue(null, "length"));
+                    m.upperCase = Integer.parseInt(parser.getAttributeValue(null, "uppercase"));
+                    m.lowerCase = Integer.parseInt(parser.getAttributeValue(null, "lowercase"));
+                    m.letters = Integer.parseInt(parser.getAttributeValue(null, "letters"));
+                    m.numeric = Integer.parseInt(parser.getAttributeValue(null, "numeric"));
+                    m.symbols = Integer.parseInt(parser.getAttributeValue(null, "symbols"));
+                    m.nonLetter = Integer.parseInt(parser.getAttributeValue(null, "nonletter"));
                 } else if (TAG_ACCEPTED_CA_CERTIFICATES.equals(tag)) {
                     policy.mAcceptedCaCertificates.add(parser.getAttributeValue(null, ATTR_NAME));
                 } else if (TAG_LOCK_TASK_COMPONENTS.equals(tag)) {
@@ -2525,19 +2509,12 @@
         final long identity = mInjector.binderClearCallingIdentity();
         try {
             int actualPasswordQuality = mLockPatternUtils.getActivePasswordQuality(userHandle);
-            if (actualPasswordQuality < policy.mActivePasswordQuality) {
+            if (actualPasswordQuality < policy.mActivePasswordMetrics.quality) {
                 Slog.w(LOG_TAG, "Active password quality 0x"
-                        + Integer.toHexString(policy.mActivePasswordQuality)
+                        + Integer.toHexString(policy.mActivePasswordMetrics.quality)
                         + " does not match actual quality 0x"
                         + Integer.toHexString(actualPasswordQuality));
-                policy.mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
-                policy.mActivePasswordLength = 0;
-                policy.mActivePasswordUpperCase = 0;
-                policy.mActivePasswordLowerCase = 0;
-                policy.mActivePasswordLetters = 0;
-                policy.mActivePasswordNumeric = 0;
-                policy.mActivePasswordSymbols = 0;
-                policy.mActivePasswordNonLetter = 0;
+                policy.mActivePasswordMetrics = new PasswordMetrics();
             }
         } finally {
             mInjector.binderRestoreCallingIdentity(identity);
@@ -3127,8 +3104,8 @@
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.passwordQuality != quality) {
-                ap.passwordQuality = quality;
+            if (ap.minimumPasswordMetrics.quality != quality) {
+                ap.minimumPasswordMetrics.quality = quality;
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3145,7 +3122,7 @@
 
             if (who != null) {
                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
-                return admin != null ? admin.passwordQuality : mode;
+                return admin != null ? admin.minimumPasswordMetrics.quality : mode;
             }
 
             // Return the strictest policy across all participating admins.
@@ -3154,8 +3131,8 @@
             final int N = admins.size();
             for (int i = 0; i < N; i++) {
                 ActiveAdmin admin = admins.get(i);
-                if (mode < admin.passwordQuality) {
-                    mode = admin.passwordQuality;
+                if (mode < admin.minimumPasswordMetrics.quality) {
+                    mode = admin.minimumPasswordMetrics.quality;
                 }
             }
             return mode;
@@ -3214,8 +3191,8 @@
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordLength != length) {
-                ap.minimumPasswordLength = length;
+            if (ap.minimumPasswordMetrics.length != length) {
+                ap.minimumPasswordMetrics.length = length;
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3232,7 +3209,7 @@
 
             if (who != null) {
                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
-                return admin != null ? admin.minimumPasswordLength : length;
+                return admin != null ? admin.minimumPasswordMetrics.length : length;
             }
 
             // Return the strictest policy across all participating admins.
@@ -3241,8 +3218,8 @@
             final int N = admins.size();
             for (int i = 0; i < N; i++) {
                 ActiveAdmin admin = admins.get(i);
-                if (length < admin.minimumPasswordLength) {
-                    length = admin.minimumPasswordLength;
+                if (length < admin.minimumPasswordMetrics.length) {
+                    length = admin.minimumPasswordMetrics.length;
                 }
             }
             return length;
@@ -3469,8 +3446,8 @@
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordUpperCase != length) {
-                ap.minimumPasswordUpperCase = length;
+            if (ap.minimumPasswordMetrics.upperCase != length) {
+                ap.minimumPasswordMetrics.upperCase = length;
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3487,7 +3464,7 @@
 
             if (who != null) {
                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
-                return admin != null ? admin.minimumPasswordUpperCase : length;
+                return admin != null ? admin.minimumPasswordMetrics.upperCase : length;
             }
 
             // Return the strictest policy across all participating admins.
@@ -3496,8 +3473,8 @@
             final int N = admins.size();
             for (int i = 0; i < N; i++) {
                 ActiveAdmin admin = admins.get(i);
-                if (length < admin.minimumPasswordUpperCase) {
-                    length = admin.minimumPasswordUpperCase;
+                if (length < admin.minimumPasswordMetrics.upperCase) {
+                    length = admin.minimumPasswordMetrics.upperCase;
                 }
             }
             return length;
@@ -3510,8 +3487,8 @@
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordLowerCase != length) {
-                ap.minimumPasswordLowerCase = length;
+            if (ap.minimumPasswordMetrics.lowerCase != length) {
+                ap.minimumPasswordMetrics.lowerCase = length;
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3528,7 +3505,7 @@
 
             if (who != null) {
                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
-                return admin != null ? admin.minimumPasswordLowerCase : length;
+                return admin != null ? admin.minimumPasswordMetrics.lowerCase : length;
             }
 
             // Return the strictest policy across all participating admins.
@@ -3537,8 +3514,8 @@
             final int N = admins.size();
             for (int i = 0; i < N; i++) {
                 ActiveAdmin admin = admins.get(i);
-                if (length < admin.minimumPasswordLowerCase) {
-                    length = admin.minimumPasswordLowerCase;
+                if (length < admin.minimumPasswordMetrics.lowerCase) {
+                    length = admin.minimumPasswordMetrics.lowerCase;
                 }
             }
             return length;
@@ -3554,8 +3531,8 @@
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordLetters != length) {
-                ap.minimumPasswordLetters = length;
+            if (ap.minimumPasswordMetrics.letters != length) {
+                ap.minimumPasswordMetrics.letters = length;
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3572,7 +3549,7 @@
 
             if (who != null) {
                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
-                return admin != null ? admin.minimumPasswordLetters : length;
+                return admin != null ? admin.minimumPasswordMetrics.letters : length;
             }
 
             // Return the strictest policy across all participating admins.
@@ -3584,8 +3561,8 @@
                 if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
                     continue;
                 }
-                if (length < admin.minimumPasswordLetters) {
-                    length = admin.minimumPasswordLetters;
+                if (length < admin.minimumPasswordMetrics.letters) {
+                    length = admin.minimumPasswordMetrics.letters;
                 }
             }
             return length;
@@ -3601,8 +3578,8 @@
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordNumeric != length) {
-                ap.minimumPasswordNumeric = length;
+            if (ap.minimumPasswordMetrics.numeric != length) {
+                ap.minimumPasswordMetrics.numeric = length;
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3619,7 +3596,7 @@
 
             if (who != null) {
                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
-                return admin != null ? admin.minimumPasswordNumeric : length;
+                return admin != null ? admin.minimumPasswordMetrics.numeric : length;
             }
 
             // Return the strictest policy across all participating admins.
@@ -3631,8 +3608,8 @@
                 if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
                     continue;
                 }
-                if (length < admin.minimumPasswordNumeric) {
-                    length = admin.minimumPasswordNumeric;
+                if (length < admin.minimumPasswordMetrics.numeric) {
+                    length = admin.minimumPasswordMetrics.numeric;
                 }
             }
             return length;
@@ -3648,8 +3625,8 @@
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordSymbols != length) {
-                ap.minimumPasswordSymbols = length;
+            if (ap.minimumPasswordMetrics.symbols != length) {
+                ap.minimumPasswordMetrics.symbols = length;
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3666,7 +3643,7 @@
 
             if (who != null) {
                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
-                return admin != null ? admin.minimumPasswordSymbols : length;
+                return admin != null ? admin.minimumPasswordMetrics.symbols : length;
             }
 
             // Return the strictest policy across all participating admins.
@@ -3678,8 +3655,8 @@
                 if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
                     continue;
                 }
-                if (length < admin.minimumPasswordSymbols) {
-                    length = admin.minimumPasswordSymbols;
+                if (length < admin.minimumPasswordMetrics.symbols) {
+                    length = admin.minimumPasswordMetrics.symbols;
                 }
             }
             return length;
@@ -3695,8 +3672,8 @@
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
-            if (ap.minimumPasswordNonLetter != length) {
-                ap.minimumPasswordNonLetter = length;
+            if (ap.minimumPasswordMetrics.nonLetter != length) {
+                ap.minimumPasswordMetrics.nonLetter = length;
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3713,7 +3690,7 @@
 
             if (who != null) {
                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
-                return admin != null ? admin.minimumPasswordNonLetter : length;
+                return admin != null ? admin.minimumPasswordMetrics.nonLetter : length;
             }
 
             // Return the strictest policy across all participating admins.
@@ -3725,8 +3702,8 @@
                 if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
                     continue;
                 }
-                if (length < admin.minimumPasswordNonLetter) {
-                    length = admin.minimumPasswordNonLetter;
+                if (length < admin.minimumPasswordMetrics.nonLetter) {
+                    length = admin.minimumPasswordMetrics.nonLetter;
                 }
             }
             return length;
@@ -3767,28 +3744,28 @@
     private boolean isActivePasswordSufficientForUserLocked(
             DevicePolicyData policy, int userHandle, boolean parent) {
         final int requiredPasswordQuality = getPasswordQuality(null, userHandle, parent);
-        if (policy.mActivePasswordQuality < requiredPasswordQuality) {
+        if (policy.mActivePasswordMetrics.quality < requiredPasswordQuality) {
             return false;
         }
         if (requiredPasswordQuality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
-                && policy.mActivePasswordLength < getPasswordMinimumLength(
+                && policy.mActivePasswordMetrics.length < getPasswordMinimumLength(
                         null, userHandle, parent)) {
             return false;
         }
         if (requiredPasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
             return true;
         }
-        return policy.mActivePasswordUpperCase >= getPasswordMinimumUpperCase(
+        return policy.mActivePasswordMetrics.upperCase >= getPasswordMinimumUpperCase(
                     null, userHandle, parent)
-                && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(
+                && policy.mActivePasswordMetrics.lowerCase >= getPasswordMinimumLowerCase(
                         null, userHandle, parent)
-                && policy.mActivePasswordLetters >= getPasswordMinimumLetters(
+                && policy.mActivePasswordMetrics.letters >= getPasswordMinimumLetters(
                         null, userHandle, parent)
-                && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(
+                && policy.mActivePasswordMetrics.numeric >= getPasswordMinimumNumeric(
                         null, userHandle, parent)
-                && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(
+                && policy.mActivePasswordMetrics.symbols >= getPasswordMinimumSymbols(
                         null, userHandle, parent)
-                && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(
+                && policy.mActivePasswordMetrics.nonLetter >= getPasswordMinimumNonLetter(
                         null, userHandle, parent);
     }
 
@@ -3982,8 +3959,9 @@
             if (quality == DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
                 quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
             }
+            final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password);
             if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
-                int realQuality = LockPatternUtils.computePasswordQuality(password);
+                final int realQuality = metrics.quality;
                 if (realQuality < quality
                         && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
                     Slog.w(LOG_TAG, "resetPassword: password quality 0x"
@@ -4001,67 +3979,48 @@
                 return false;
             }
             if (quality == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
-                int letters = 0;
-                int uppercase = 0;
-                int lowercase = 0;
-                int numbers = 0;
-                int symbols = 0;
-                int nonletter = 0;
-                for (int i = 0; i < password.length(); i++) {
-                    char c = password.charAt(i);
-                    if (c >= 'A' && c <= 'Z') {
-                        letters++;
-                        uppercase++;
-                    } else if (c >= 'a' && c <= 'z') {
-                        letters++;
-                        lowercase++;
-                    } else if (c >= '0' && c <= '9') {
-                        numbers++;
-                        nonletter++;
-                    } else {
-                        symbols++;
-                        nonletter++;
-                    }
-                }
                 int neededLetters = getPasswordMinimumLetters(null, userHandle, /* parent */ false);
-                if(letters < neededLetters) {
-                    Slog.w(LOG_TAG, "resetPassword: number of letters " + letters
+                if(metrics.letters < neededLetters) {
+                    Slog.w(LOG_TAG, "resetPassword: number of letters " + metrics.letters
                             + " does not meet required number of letters " + neededLetters);
                     return false;
                 }
-                int neededNumbers = getPasswordMinimumNumeric(null, userHandle, /* parent */ false);
-                if (numbers < neededNumbers) {
-                    Slog.w(LOG_TAG, "resetPassword: number of numerical digits " + numbers
+                int neededNumeric = getPasswordMinimumNumeric(null, userHandle, /* parent */ false);
+                if (metrics.numeric < neededNumeric) {
+                    Slog.w(LOG_TAG, "resetPassword: number of numerical digits " + metrics.numeric
                             + " does not meet required number of numerical digits "
-                            + neededNumbers);
+                            + neededNumeric);
                     return false;
                 }
                 int neededLowerCase = getPasswordMinimumLowerCase(
                         null, userHandle, /* parent */ false);
-                if (lowercase < neededLowerCase) {
-                    Slog.w(LOG_TAG, "resetPassword: number of lowercase letters " + lowercase
+                if (metrics.lowerCase < neededLowerCase) {
+                    Slog.w(LOG_TAG, "resetPassword: number of lowercase letters "
+                            + metrics.lowerCase
                             + " does not meet required number of lowercase letters "
                             + neededLowerCase);
                     return false;
                 }
                 int neededUpperCase = getPasswordMinimumUpperCase(
                         null, userHandle, /* parent */ false);
-                if (uppercase < neededUpperCase) {
-                    Slog.w(LOG_TAG, "resetPassword: number of uppercase letters " + uppercase
+                if (metrics.upperCase < neededUpperCase) {
+                    Slog.w(LOG_TAG, "resetPassword: number of uppercase letters "
+                            + metrics.upperCase
                             + " does not meet required number of uppercase letters "
                             + neededUpperCase);
                     return false;
                 }
                 int neededSymbols = getPasswordMinimumSymbols(null, userHandle, /* parent */ false);
-                if (symbols < neededSymbols) {
-                    Slog.w(LOG_TAG, "resetPassword: number of special symbols " + symbols
+                if (metrics.symbols < neededSymbols) {
+                    Slog.w(LOG_TAG, "resetPassword: number of special symbols " + metrics.symbols
                             + " does not meet required number of special symbols " + neededSymbols);
                     return false;
                 }
                 int neededNonLetter = getPasswordMinimumNonLetter(
                         null, userHandle, /* parent */ false);
-                if (nonletter < neededNonLetter) {
-                    Slog.w(LOG_TAG, "resetPassword: number of non-letter characters " + nonletter
+                if (metrics.nonLetter < neededNonLetter) {
+                    Slog.w(LOG_TAG, "resetPassword: number of non-letter characters "
+                            + metrics.nonLetter
                             + " does not meet required number of non-letter characters "
                             + neededNonLetter);
                     return false;
@@ -4850,8 +4809,7 @@
     }
 
     @Override
-    public void setActivePasswordState(int quality, int length, int letters, int uppercase,
-            int lowercase, int numbers, int symbols, int nonletter, int userHandle) {
+    public void setActivePasswordState(PasswordMetrics metrics, int userHandle) {
         if (!mHasFeature) {
             return;
         }
@@ -4864,21 +4822,14 @@
 
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.BIND_DEVICE_ADMIN, null);
-        validateQualityConstant(quality);
+        validateQualityConstant(metrics.quality);
 
         DevicePolicyData policy = getUserData(userHandle);
 
         long ident = mInjector.binderClearCallingIdentity();
         try {
             synchronized (this) {
-                policy.mActivePasswordQuality = quality;
-                policy.mActivePasswordLength = length;
-                policy.mActivePasswordLetters = letters;
-                policy.mActivePasswordLowerCase = lowercase;
-                policy.mActivePasswordUpperCase = uppercase;
-                policy.mActivePasswordNumeric = numbers;
-                policy.mActivePasswordSymbols = symbols;
-                policy.mActivePasswordNonLetter = nonletter;
+                policy.mActivePasswordMetrics = metrics;
                 policy.mFailedPasswordAttempts = 0;
                 saveSettingsLocked(userHandle);
                 updatePasswordExpirationsLocked(userHandle);
@@ -7389,15 +7340,25 @@
     @Override
     public boolean removeUser(ComponentName who, UserHandle userHandle) {
         Preconditions.checkNotNull(who, "ComponentName is null");
+        UserHandle callingUserHandle = mInjector.binderGetCallingUserHandle();
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
-
-            long id = mInjector.binderClearCallingIdentity();
-            try {
-                return mUserManager.removeUser(userHandle.getIdentifier());
-            } finally {
-                mInjector.binderRestoreCallingIdentity(id);
+        }
+        final long id = mInjector.binderClearCallingIdentity();
+        try {
+            int restrictionSource = mUserManager.getUserRestrictionSource(
+                    UserManager.DISALLOW_REMOVE_USER, callingUserHandle);
+            if (restrictionSource != UserManager.RESTRICTION_NOT_SET
+                    && restrictionSource != UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) {
+                Log.w(LOG_TAG, "The device owner cannot remove a user because "
+                        + "DISALLOW_REMOVE_USER is enabled, and was not set by the device "
+                        + "owner");
+                return false;
             }
+            return mUserManagerInternal.removeUserEvenWhenDisallowed(
+                    userHandle.getIdentifier());
+        } finally {
+            mInjector.binderRestoreCallingIdentity(id);
         }
     }
 
@@ -8437,10 +8398,10 @@
 
     /**
      * Returns true if specified admin is allowed to limit passwords and has a
-     * {@code passwordQuality} of at least {@code minPasswordQuality}
+     * {@code minimumPasswordMetrics.quality} of at least {@code minPasswordQuality}
      */
     private static boolean isLimitPasswordAllowed(ActiveAdmin admin, int minPasswordQuality) {
-        if (admin.passwordQuality < minPasswordQuality) {
+        if (admin.minimumPasswordMetrics.quality < minPasswordQuality) {
             return false;
         }
         return admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 85b0d96..62947eb 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -118,6 +118,8 @@
 import java.util.Timer;
 import java.util.TimerTask;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+
 public final class SystemServer {
     private static final String TAG = "SystemServer";
 
@@ -1403,7 +1405,7 @@
         // Update the configuration for this context by hand, because we're going
         // to start using it before the config change done in wm.systemReady() will
         // propagate to it.
-        Configuration config = wm.computeNewConfiguration();
+        final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);
         DisplayMetrics metrics = new DisplayMetrics();
         WindowManager w = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
         w.getDefaultDisplay().getMetrics(metrics);
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index ffbea9f..8dd05b1 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -40,6 +40,7 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.PacketSocketAddress;
+import android.util.EventLog;
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.TimeUtils;
@@ -369,6 +370,13 @@
                     if (PACKET_DBG) {
                         Log.d(TAG, HexDump.dumpHexString(mPacket, 0, length));
                     }
+                    if (e.errorCode == DhcpErrorEvent.DHCP_NO_COOKIE) {
+                        int snetTagId = 0x534e4554;
+                        String bugId = "31850211";
+                        int uid = -1;
+                        String data = DhcpPacket.ParseException.class.getName();
+                        EventLog.writeEvent(snetTagId, bugId, uid, data);
+                    }
                     logError(e.errorCode);
                 }
             }
diff --git a/services/tests/runtests.py b/services/tests/runtests.py
new file mode 100755
index 0000000..35fec90f
--- /dev/null
+++ b/services/tests/runtests.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2016 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.
+
+import os
+import subprocess
+import sys
+
+INSTRUMENTED_PACKAGE_RUNNER = ('com.android.frameworks.servicestests/'
+                               'android.support.test.runner.AndroidJUnitRunner')
+
+PACKAGE_WHITELIST = (
+    'android.net',
+    'com.android.server.connectivity',
+)
+
+COLOR_RED = '\033[0;31m'
+COLOR_NONE ='\033[0m'
+
+def run(shell_command, echo=True):
+    if echo:
+        print '%s + %s%s' % (
+                COLOR_RED,
+                echo if isinstance(echo, str) else shell_command,
+                COLOR_NONE)
+    return subprocess.check_call(shell_command, shell=True)
+
+
+def main():
+    build_top = os.environ.get('ANDROID_BUILD_TOP', None)
+    out_dir = os.environ.get('OUT', None)
+    if build_top is None or out_dir is None:
+        print 'You need to source and lunch before you can use this script'
+        return 1
+
+    print 'Building tests...'
+    run('make -j32 -C %s -f build/core/main.mk '
+        'MODULES-IN-frameworks-base-services-tests-servicestests' % build_top,
+        echo='mmma -j32 %s/frameworks/base/services/tests/servicestests' %
+             build_top)
+
+    print 'Installing tests...'
+    run('adb root')
+    run('adb wait-for-device')
+    apk_path = (
+            '%s/data/app/FrameworksServicesTests/FrameworksServicesTests.apk' %
+            out_dir)
+    run('adb install -r -g "%s"' % apk_path)
+
+    print 'Running tests...'
+    if len(sys.argv) != 1:
+        run('adb shell am instrument -w "%s" %s' %
+            (INSTRUMENTED_PACKAGE_RUNNER, ' '.join(sys.argv[1:])))
+        return 0
+
+    # It would be nice if the activity manager accepted a list of packages, but
+    # in lieu of that...
+    for package in PACKAGE_WHITELIST:
+        run('adb shell am instrument -w -e package %s %s' %
+            (package, INSTRUMENTED_PACKAGE_RUNNER))
+
+    return 0
+
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 3548f28..4165467 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -4,9 +4,9 @@
      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.
@@ -30,6 +30,7 @@
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
     <uses-permission android:name="android.permission.REAL_GET_TASKS" />
     <uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
+    <uses-permission android:name="android.permission.REORDER_TASKS" />
     <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
     <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
     <uses-permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
@@ -159,6 +160,9 @@
 
         <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityA" />
         <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityB" />
+        <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityRequestedOrientationChange" />
+        <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityTaskChangeCallbacks" />
+        <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityTaskDescriptionChange" />
 
     </application>
 
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index 0d5daa5..f841bf9 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -24,6 +24,7 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 import com.android.server.net.BaseNetworkObserver;
+import com.android.internal.util.test.BroadcastInterceptingContext;
 
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index bd07d8b..25a421e 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -95,7 +95,8 @@
 import android.util.Log;
 import android.util.TrustedTime;
 
-import com.android.server.BroadcastInterceptingContext.FutureIntent;
+import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent;
 import com.android.server.net.NetworkPolicyManagerInternal;
 import com.android.server.net.NetworkPolicyManagerService;
 
diff --git a/services/tests/servicestests/src/com/android/server/am/ConfigurationContainerTests.java b/services/tests/servicestests/src/com/android/server/am/ConfigurationContainerTests.java
index 92c442e..fd2fb4b 100644
--- a/services/tests/servicestests/src/com/android/server/am/ConfigurationContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ConfigurationContainerTests.java
@@ -97,22 +97,30 @@
         final Configuration childOverrideConfig = new Configuration();
         childOverrideConfig.densityDpi = 320;
         child.onOverrideConfigurationChanged(childOverrideConfig);
+        final Configuration mergedOverrideConfig = new Configuration(root.getConfiguration());
+        mergedOverrideConfig.updateFrom(childOverrideConfig);
 
         // Check configuration update when child is removed from parent.
         root.removeChild(child);
         assertEquals(childOverrideConfig, child.getOverrideConfiguration());
-        assertEquals(childOverrideConfig, child.getMergedOverrideConfiguration());
-        assertEquals(childOverrideConfig, child.getConfiguration());
+        assertEquals(mergedOverrideConfig, child.getMergedOverrideConfiguration());
+        assertEquals(mergedOverrideConfig, child.getConfiguration());
 
         // It may be paranoia... but let's check if parent's config didn't change after removal.
         assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
         assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
         assertEquals(rootOverrideConfig, root.getConfiguration());
 
-        // Check configuration update when child is added to parent.
-        final Configuration mergedOverrideConfig = new Configuration(root.getConfiguration());
+        // Init different root
+        final TestConfigurationContainer root2 = new TestConfigurationContainer();
+        final Configuration rootOverrideConfig2 = new Configuration();
+        rootOverrideConfig2.fontScale = 1.1f;
+        root2.onOverrideConfigurationChanged(rootOverrideConfig2);
+
+        // Check configuration update when child is added to different parent.
+        mergedOverrideConfig.setTo(rootOverrideConfig2);
         mergedOverrideConfig.updateFrom(childOverrideConfig);
-        root.addChild(child);
+        root2.addChild(child);
         assertEquals(childOverrideConfig, child.getOverrideConfiguration());
         assertEquals(mergedOverrideConfig, child.getMergedOverrideConfiguration());
         assertEquals(mergedOverrideConfig, child.getConfiguration());
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
index b47d17e..c9c691d 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
@@ -17,21 +17,33 @@
 package com.android.server.am;
 
 import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.app.Activity;
+import android.app.ActivityManager.TaskDescription;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.ITaskStackListener;
+import android.app.Instrumentation.ActivityMonitor;
+import android.app.TaskStackListener;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.Resources.Theme;
 import android.os.RemoteException;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.UiDevice;
-
+import android.text.TextUtils;
+import android.util.Pair;
 import com.android.internal.annotations.GuardedBy;
-
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -39,9 +51,10 @@
 
 @MediumTest
 @RunWith(AndroidJUnit4.class)
-public class TaskStackChangedListenerTest extends ITaskStackListener.Stub {
+public class TaskStackChangedListenerTest {
 
     private IActivityManager mService;
+    private ITaskStackListener mTaskStackListener;
 
     private static final Object sLock = new Object();
     @GuardedBy("sLock")
@@ -51,11 +64,25 @@
     @Before
     public void setUp() throws Exception {
         mService = ActivityManagerNative.getDefault();
-        mService.registerTaskStackListener(this);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mService.unregisterTaskStackListener(mTaskStackListener);
+        mTaskStackListener = null;
     }
 
     @Test
     public void testTaskStackChanged_afterFinish() throws Exception {
+        registerTaskStackChangedListener(new TaskStackListener() {
+            @Override
+            public void onTaskStackChanged() throws RemoteException {
+                synchronized (sLock) {
+                    sTaskStackChangedCalled = true;
+                }
+            }
+        });
+
         Context ctx = InstrumentationRegistry.getContext();
         ctx.startActivity(new Intent(ctx, ActivityA.class));
         UiDevice.getInstance(getInstrumentation()).waitForIdle();
@@ -65,31 +92,151 @@
         Assert.assertTrue(sActivityBResumed);
     }
 
-    @Override
-    public void onTaskStackChanged() throws RemoteException {
-        synchronized (sLock) {
-            sTaskStackChangedCalled = true;
+    @Test
+    public void testTaskDescriptionChanged() throws Exception {
+        final Object[] params = new Object[2];
+        final CountDownLatch latch = new CountDownLatch(1);
+        registerTaskStackChangedListener(new TaskStackListener() {
+            int taskId = -1;
+
+            @Override
+            public void onTaskCreated(int taskId, ComponentName componentName)
+                    throws RemoteException {
+                this.taskId = taskId;
+            }
+            @Override
+            public void onTaskDescriptionChanged(int taskId, TaskDescription td)
+                    throws RemoteException {
+                if (this.taskId == taskId && !TextUtils.isEmpty(td.getLabel())) {
+                    params[0] = taskId;
+                    params[1] = td;
+                    latch.countDown();
+                }
+            }
+        });
+        final Activity activity = startTestActivity(ActivityTaskDescriptionChange.class);
+        waitForCallback(latch);
+        assertEquals(activity.getTaskId(), params[0]);
+        assertEquals("Test Label", ((TaskDescription) params[1]).getLabel());
+    }
+
+    @Test
+    public void testActivityRequestedOrientationChanged() throws Exception {
+        final int[] params = new int[2];
+        final CountDownLatch latch = new CountDownLatch(1);
+        registerTaskStackChangedListener(new TaskStackListener() {
+            @Override
+            public void onActivityRequestedOrientationChanged(int taskId,
+                    int requestedOrientation) {
+                params[0] = taskId;
+                params[1] = requestedOrientation;
+                latch.countDown();
+            }
+        });
+        final Activity activity = startTestActivity(ActivityRequestedOrientationChange.class);
+        waitForCallback(latch);
+        assertEquals(activity.getTaskId(), params[0]);
+        assertEquals(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, params[1]);
+    }
+
+    @Test
+    /**
+     * Tests for onTaskCreated, onTaskMovedToFront, onTaskRemoved and onTaskRemovalStarted.
+     */
+    public void testTaskChangeCallBacks() throws Exception {
+        final Object[] params = new Object[2];
+        final CountDownLatch taskCreatedLaunchLatch = new CountDownLatch(1);
+        final CountDownLatch taskMovedToFrontLatch = new CountDownLatch(1);
+        final CountDownLatch taskRemovedLatch = new CountDownLatch(1);
+        final CountDownLatch taskRemovalStartedLatch = new CountDownLatch(1);
+        final CountDownLatch onDetachedFromWindowLatch = new CountDownLatch(1);
+        registerTaskStackChangedListener(new TaskStackListener() {
+            @Override
+            public void onTaskCreated(int taskId, ComponentName componentName)
+                    throws RemoteException {
+                params[0] = taskId;
+                params[1] = componentName;
+                taskCreatedLaunchLatch.countDown();
+            }
+
+            @Override
+            public void onTaskMovedToFront(int taskId) throws RemoteException {
+                params[0] = taskId;
+                taskMovedToFrontLatch.countDown();
+            }
+
+            @Override
+            public void onTaskRemovalStarted(int taskId) {
+                params[0] = taskId;
+                taskRemovalStartedLatch.countDown();
+            }
+
+            @Override
+            public void onTaskRemoved(int taskId) throws RemoteException {
+                params[0] = taskId;
+                taskRemovedLatch.countDown();
+            }
+        });
+
+        final ActivityTaskChangeCallbacks activity =
+                (ActivityTaskChangeCallbacks) startTestActivity(ActivityTaskChangeCallbacks.class);
+        final int id = activity.getTaskId();
+
+        // Test for onTaskCreated.
+        waitForCallback(taskCreatedLaunchLatch);
+        assertEquals(id, params[0]);
+        ComponentName componentName = (ComponentName) params[1];
+        assertEquals(ActivityTaskChangeCallbacks.class.getName(), componentName.getClassName());
+
+        // Test for onTaskMovedToFront.
+        assertEquals(1, taskMovedToFrontLatch.getCount());
+        mService.moveTaskToFront(id, 0, null);
+        waitForCallback(taskMovedToFrontLatch);
+        assertEquals(activity.getTaskId(), params[0]);
+
+        // Test for onTaskRemovalStarted.
+        assertEquals(1, taskRemovalStartedLatch.getCount());
+        activity.finishAndRemoveTask();
+        waitForCallback(taskRemovalStartedLatch);
+        // onTaskRemovalStarted happens before the activity's window is removed.
+        assertFalse(activity.onDetachedFromWindowCalled);
+        assertEquals(id, params[0]);
+
+        // Test for onTaskRemoved.
+        assertEquals(1, taskRemovedLatch.getCount());
+        waitForCallback(taskRemovedLatch);
+        assertEquals(id, params[0]);
+        assertTrue(activity.onDetachedFromWindowCalled);
+    }
+
+    /**
+     * Starts the provided activity and returns the started instance.
+     */
+    private Activity startTestActivity(Class<?> activityClass) {
+        final Context context = InstrumentationRegistry.getContext();
+        final ActivityMonitor monitor =
+                new ActivityMonitor(activityClass.getName(), null, false);
+        InstrumentationRegistry.getInstrumentation().addMonitor(monitor);
+        context.startActivity(new Intent(context, activityClass));
+        final Activity activity = monitor.waitForActivityWithTimeout(1000);
+        if (activity == null) {
+            throw new RuntimeException("Timed out waiting for Activity");
         }
+        return activity;
     }
 
-    @Override
-    public void onActivityPinned() throws RemoteException {
+    private void registerTaskStackChangedListener(ITaskStackListener listener) throws Exception {
+        mTaskStackListener = listener;
+        mService.registerTaskStackListener(listener);
     }
 
-    @Override
-    public void onPinnedActivityRestartAttempt() throws RemoteException {
-    }
-
-    @Override
-    public void onPinnedStackAnimationEnded() throws RemoteException {
-    }
-
-    @Override
-    public void onActivityForcedResizable(String packageName, int taskId) throws RemoteException {
-    }
-
-    @Override
-    public void onActivityDismissingDockedStack() throws RemoteException {
+    private void waitForCallback(CountDownLatch latch) {
+        try {
+        final boolean result = latch.await(2, TimeUnit.SECONDS);
+            if (!result) {
+                throw new RuntimeException("Timed out waiting for task stack change notification");
+            }
+        }catch (InterruptedException e) {}
     }
 
     public static class ActivityA extends Activity {
@@ -120,4 +267,31 @@
             finish();
         }
     }
+
+    public static class ActivityRequestedOrientationChange extends Activity {
+        @Override
+        protected void onPostResume() {
+            super.onPostResume();
+            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+            finish();
+        }
+    }
+
+    public static class ActivityTaskDescriptionChange extends Activity {
+        @Override
+        protected void onPostResume() {
+            super.onPostResume();
+            setTaskDescription(new TaskDescription("Test Label"));
+            finish();
+        }
+    }
+
+    public static class ActivityTaskChangeCallbacks extends Activity {
+        public boolean onDetachedFromWindowCalled = false;;
+
+        @Override
+        public void onDetachedFromWindow() {
+            onDetachedFromWindowCalled = true;
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
index 8c96226..f2cf90c 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
@@ -88,7 +88,7 @@
 import android.util.TrustedTime;
 
 import com.android.internal.net.VpnInfo;
-import com.android.server.BroadcastInterceptingContext;
+import com.android.internal.util.test.BroadcastInterceptingContext;
 import com.android.server.net.NetworkStatsService;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
index 222436c..3eeeaf6 100644
--- a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
+++ b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
@@ -34,7 +34,7 @@
 import android.support.test.filters.SmallTest;
 import android.test.mock.MockContentResolver;
 
-import com.android.internal.util.FakeSettingsProvider;
+import com.android.internal.util.test.FakeSettingsProvider;
 
 import org.junit.After;
 import org.junit.Before;
@@ -146,4 +146,4 @@
                 Settings.Secure.getStringForUser(mContentResolver,
                         Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER));
     }
-}
\ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
index e4473ad..d53fdf6 100644
--- a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
@@ -61,7 +61,7 @@
 import android.test.mock.MockContentResolver;
 import android.util.ArrayMap;
 
-import com.android.internal.util.FakeSettingsProvider;
+import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.SystemService;
 import com.android.server.retaildemo.RetailDemoModeService.Injector;
diff --git a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
index b5eb77c..763c50b 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
@@ -118,4 +118,7 @@
         }
         throw new NameNotFoundException();
     }
+
+    @Override
+    public void setMultiprocessEnabled(boolean enabled) {}
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 74e8c9d..d933cb3 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -29,17 +29,19 @@
 import android.view.WindowManager;
 
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Tests for the {@link WindowState} class.
  *
- * Build: mmma -j32 frameworks/base/services/tests/servicestests
- * Install: adb install -r out/target/product/$TARGET_PRODUCT/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
- * Run: adb shell am instrument -w -e class com.android.server.wm.AppWindowTokenTests com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.AppWindowTokenTests
  */
 @SmallTest
 @Presubmit
@@ -56,6 +58,36 @@
     }
 
     @Test
+    public void testAddWindow_Order() throws Exception {
+        final TestAppWindowToken token = new TestAppWindowToken();
+
+        assertEquals(0, token.getWindowsCount());
+
+        final WindowState win1 = createWindow(null, TYPE_APPLICATION, token);
+        final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, token);
+        final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, token);
+        final WindowState win4 = createWindow(null, TYPE_APPLICATION, token);
+
+        token.addWindow(win1);
+        token.addWindow(startingWin);
+        token.addWindow(baseWin);
+        token.addWindow(win4);
+
+        // Should not contain the windows that were added above.
+        assertEquals(4, token.getWindowsCount());
+        assertTrue(token.hasWindow(win1));
+        assertTrue(token.hasWindow(startingWin));
+        assertTrue(token.hasWindow(baseWin));
+        assertTrue(token.hasWindow(win4));
+
+        // The starting window should be on-top of all other windows.
+        assertEquals(startingWin, token.getLastChild());
+
+        // The base application window should be below all other windows.
+        assertEquals(baseWin, token.getFirstChild());
+    }
+
+    @Test
     public void testFindMainWindow() throws Exception {
         final TestAppWindowToken token = new TestAppWindowToken();
 
@@ -93,5 +125,13 @@
         boolean hasWindow(WindowState w) {
             return mChildren.contains(w);
         }
+
+        WindowState getFirstChild() {
+            return mChildren.getFirst();
+        }
+
+        WindowState getLastChild() {
+            return mChildren.getLast();
+        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
index 6eb347b..0ccd0ad 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
@@ -42,9 +42,8 @@
 /**
  * Test class for {@link WindowContainer}.
  *
- * Build: mmma -j32 frameworks/base/services/tests/servicestests
- * Install: adb install -r out/target/product/$TARGET_PRODUCT/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
- * Run: adb shell am instrument -w -e class com.android.server.wm.WindowContainerTests com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowContainerTests
  */
 @SmallTest
 @Presubmit
@@ -434,22 +433,30 @@
         final Configuration childOverrideConfig = new Configuration();
         childOverrideConfig.densityDpi = 320;
         child.onOverrideConfigurationChanged(childOverrideConfig);
+        final Configuration mergedOverrideConfig = new Configuration(root.getConfiguration());
+        mergedOverrideConfig.updateFrom(childOverrideConfig);
 
-        // Check configuration update when child is removed from parent.
+        // Check configuration update when child is removed from parent - it should remain same.
         root.removeChild(child);
         assertEquals(childOverrideConfig, child.getOverrideConfiguration());
-        assertEquals(childOverrideConfig, child.getMergedOverrideConfiguration());
-        assertEquals(childOverrideConfig, child.getConfiguration());
+        assertEquals(mergedOverrideConfig, child.getMergedOverrideConfiguration());
+        assertEquals(mergedOverrideConfig, child.getConfiguration());
 
         // It may be paranoia... but let's check if parent's config didn't change after removal.
         assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
         assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
         assertEquals(rootOverrideConfig, root.getConfiguration());
 
-        // Check configuration update when child is added to parent.
-        final Configuration mergedOverrideConfig = new Configuration(root.getConfiguration());
+        // Init different root
+        final TestWindowContainer root2 = builder.setLayer(0).build();
+        final Configuration rootOverrideConfig2 = new Configuration();
+        rootOverrideConfig2.fontScale = 1.1f;
+        root2.onOverrideConfigurationChanged(rootOverrideConfig2);
+
+        // Check configuration update when child is added to different parent.
+        mergedOverrideConfig.setTo(rootOverrideConfig2);
         mergedOverrideConfig.updateFrom(childOverrideConfig);
-        root.addChildWindow(child);
+        root2.addChildWindow(child);
         assertEquals(childOverrideConfig, child.getOverrideConfiguration());
         assertEquals(mergedOverrideConfig, child.getMergedOverrideConfiguration());
         assertEquals(mergedOverrideConfig, child.getConfiguration());
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
new file mode 100644
index 0000000..15cd55f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2016 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.server.wm;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.Gravity;
+import android.view.IWindow;
+import android.view.WindowManager;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
+import static android.view.WindowManager.LayoutParams.FILL_PARENT;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for the {@link WindowState#computeFrameLw} method and other window frame machinery.
+ *
+ * Build/Install/Run: bit FrameworksServicesTests:com.android.server.wm.WindowFrameTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowFrameTests {
+
+    private static WindowManagerService sWm = null;
+    private WindowToken mWindowToken;
+    private final IWindow mIWindow = new TestIWindow();
+
+    class WindowStateWithTask extends WindowState {
+        final Task mTask;
+        WindowStateWithTask(WindowManager.LayoutParams attrs, Task t) {
+            super(sWm, null, mIWindow, mWindowToken, null, 0, 0, attrs, 0, 0);
+            mTask = t;
+        }
+
+        @Override
+        Task getTask() {
+            return mTask;
+        }
+    };
+
+    class TaskWithBounds extends Task {
+        final Rect mBounds;
+        TaskWithBounds(Rect bounds) {
+            super(0, mStubStack, 0, sWm, null, null, false);
+            mBounds = bounds;
+        }
+        @Override
+        void getBounds(Rect outBounds) {
+            outBounds.set(mBounds);
+        }
+        @Override
+        void getTempInsetBounds(Rect outBounds) {
+            outBounds.setEmpty();
+        }
+        @Override
+        boolean isFullscreen() {
+            return true;
+        }
+    }
+
+    TaskStack mStubStack;
+
+    @Before
+    public void setUp() throws Exception {
+        final Context context = InstrumentationRegistry.getTargetContext();
+        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
+        mWindowToken = new WindowToken(sWm, new Binder(), 0, false,
+                sWm.getDefaultDisplayContentLocked());
+        mStubStack = new TaskStack(sWm, 0);
+    }
+
+    public void assertRect(Rect rect, int left, int top, int right, int bottom) {
+        assertEquals(left, rect.left);
+        assertEquals(top, rect.top);
+        assertEquals(right, rect.right);
+        assertEquals(bottom, rect.bottom);
+    }
+
+    @Test
+    public void testLayoutInFullscreenTaskNoInsets() throws Exception {
+        Task task = new TaskWithBounds(null); // fullscreen task doesn't use bounds for computeFrame
+        WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+
+        // With no insets or system decor all the frames incoming from PhoneWindowManager
+        // are identical.
+        final Rect pf = new Rect(0, 0, 1000, 1000);
+
+        // Here the window has FILL_PARENT, FILL_PARENT
+        // so we expect it to fill the entire available frame.
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+        assertRect(w.mFrame, 0, 0, 1000, 1000);
+
+        // It can select various widths and heights within the bounds.
+        // Strangely the window attribute width is ignored for normal windows
+        // and we use mRequestedWidth/mRequestedHeight
+        w.mAttrs.width = 300;
+        w.mAttrs.height = 300;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+        // Explicit width and height without requested width/height
+        // gets us nothing.
+        assertRect(w.mFrame, 0, 0, 0, 0);
+
+        w.mRequestedWidth = 300;
+        w.mRequestedHeight = 300;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+        // With requestedWidth/Height we can freely choose our size within the
+        // parent bounds.
+        assertRect(w.mFrame, 0, 0, 300, 300);
+
+        // With FLAG_SCALED though, requestedWidth/height is used to control
+        // the unscaled surface size, and mAttrs.width/height becomes the
+        // layout controller.
+        w.mAttrs.flags = WindowManager.LayoutParams.FLAG_SCALED;
+        w.mRequestedHeight = -1;
+        w.mRequestedWidth = -1;
+        w.mAttrs.width = 100;
+        w.mAttrs.height = 100;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+        assertRect(w.mFrame, 0, 0, 100, 100);
+        w.mAttrs.flags = 0;
+
+        // But sizes too large will be clipped to the containing frame
+        w.mRequestedWidth = 1200;
+        w.mRequestedHeight = 1200;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+        assertRect(w.mFrame, 0, 0, 1000, 1000);
+
+        // Before they are clipped though windows will be shifted
+        w.mAttrs.x = 300;
+        w.mAttrs.y = 300;
+        w.mRequestedWidth = 1000;
+        w.mRequestedHeight = 1000;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+        assertRect(w.mFrame, 0, 0, 1000, 1000);
+
+        // If there is room to move around in the parent frame the window will be shifted according
+        // to gravity.
+        w.mAttrs.x = 0;
+        w.mAttrs.y = 0;
+        w.mRequestedWidth = 300;
+        w.mRequestedHeight = 300;
+        w.mAttrs.gravity = Gravity.RIGHT | Gravity.TOP;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+        assertRect(w.mFrame, 700, 0, 1000, 300);
+        w.mAttrs.gravity = Gravity.RIGHT | Gravity.BOTTOM;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+        assertRect(w.mFrame, 700, 700, 1000, 1000);
+        // Window specified  x and y are interpreted as offsets in the opposite
+        // direction of gravity
+        w.mAttrs.x = 100;
+        w.mAttrs.y = 100;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
+        assertRect(w.mFrame, 600, 600, 900, 900);
+    }
+
+    private WindowState createWindow(Task task, int width, int height) {
+        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
+        attrs.width = width;
+        attrs.height = height;
+
+        return new WindowStateWithTask(attrs, task);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
index 546c7da..5326a19 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
@@ -41,9 +41,8 @@
 /**
  * Tests for the {@link WindowState} class.
  *
- * Build: mmma -j32 frameworks/base/services/tests/servicestests
- * Install: adb install -r out/target/product/$TARGET_PRODUCT/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
- * Run: adb shell am instrument -w -e class com.android.server.wm.WindowTokenTests com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowTokenTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index e58fe70..8268b40 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -254,8 +254,7 @@
                         && structureEnabled) {
                     mAssistData.clear();
                     final int count = activityToken != null ? 1 : topActivities.size();
-                    // Temp workaround for bug: 28348867  Revert after DP3
-                    for (int i = 0; i < count && i < 1; i++) {
+                    for (int i = 0; i < count; i++) {
                         IBinder topActivity = count == 1 ? activityToken : topActivities.get(i);
                         try {
                             MetricsLogger.count(mContext, "assist_with_context", 1);
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 19388e9..016490c 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -26,6 +26,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.telecom.Logging.Session;
 
 import com.android.internal.os.SomeArgs;
 import com.android.internal.telecom.IConnectionService;
@@ -83,6 +84,32 @@
     // Flag controlling whether PII is emitted into the logs
     private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
 
+    // Session Definitions
+    private static final String SESSION_HANDLER = "H.";
+    private static final String SESSION_ADD_CS_ADAPTER = "CS.aCSA";
+    private static final String SESSION_REMOVE_CS_ADAPTER = "CS.rCSA";
+    private static final String SESSION_CREATE_CONN = "CS.crCo";
+    private static final String SESSION_ABORT = "CS.ab";
+    private static final String SESSION_ANSWER = "CS.an";
+    private static final String SESSION_ANSWER_VIDEO = "CS.anV";
+    private static final String SESSION_REJECT = "CS.r";
+    private static final String SESSION_REJECT_MESSAGE = "CS.rWM";
+    private static final String SESSION_SILENCE = "CS.s";
+    private static final String SESSION_DISCONNECT = "CS.d";
+    private static final String SESSION_HOLD = "CS.h";
+    private static final String SESSION_UNHOLD = "CS.u";
+    private static final String SESSION_CALL_AUDIO_SC = "CS.cASC";
+    private static final String SESSION_PLAY_DTMF = "CS.pDT";
+    private static final String SESSION_STOP_DTMF = "CS.sDT";
+    private static final String SESSION_CONFERENCE = "CS.c";
+    private static final String SESSION_SPLIT_CONFERENCE = "CS.sFC";
+    private static final String SESSION_MERGE_CONFERENCE = "CS.mC";
+    private static final String SESSION_SWAP_CONFERENCE = "CS.sC";
+    private static final String SESSION_POST_DIAL_CONT = "CS.oPDC";
+    private static final String SESSION_PULL_EXTERNAL_CALL = "CS.pEC";
+    private static final String SESSION_SEND_CALL_EVENT = "CS.sCE";
+    private static final String SESSION_EXTRAS_CHANGED = "CS.oEC";
+
     private static final int MSG_ADD_CONNECTION_SERVICE_ADAPTER = 1;
     private static final int MSG_CREATE_CONNECTION = 2;
     private static final int MSG_ABORT = 3;
@@ -125,12 +152,30 @@
 
     private final IBinder mBinder = new IConnectionService.Stub() {
         @Override
-        public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
-            mHandler.obtainMessage(MSG_ADD_CONNECTION_SERVICE_ADAPTER, adapter).sendToTarget();
+        public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter,
+                Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_ADD_CS_ADAPTER);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = adapter;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_ADD_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
-        public void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
-            mHandler.obtainMessage(MSG_REMOVE_CONNECTION_SERVICE_ADAPTER, adapter).sendToTarget();
+        public void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter,
+                Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_REMOVE_CS_ADAPTER);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = adapter;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_REMOVE_CONNECTION_SERVICE_ADAPTER, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
@@ -139,136 +184,292 @@
                 String id,
                 ConnectionRequest request,
                 boolean isIncoming,
-                boolean isUnknown) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = connectionManagerPhoneAccount;
-            args.arg2 = id;
-            args.arg3 = request;
-            args.argi1 = isIncoming ? 1 : 0;
-            args.argi2 = isUnknown ? 1 : 0;
-            mHandler.obtainMessage(MSG_CREATE_CONNECTION, args).sendToTarget();
+                boolean isUnknown,
+                Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_CREATE_CONN);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = connectionManagerPhoneAccount;
+                args.arg2 = id;
+                args.arg3 = request;
+                args.arg4 = Log.createSubsession();
+                args.argi1 = isIncoming ? 1 : 0;
+                args.argi2 = isUnknown ? 1 : 0;
+                mHandler.obtainMessage(MSG_CREATE_CONNECTION, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void abort(String callId) {
-            mHandler.obtainMessage(MSG_ABORT, callId).sendToTarget();
+        public void abort(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_ABORT);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_ABORT, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void answerVideo(String callId, int videoState) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.argi1 = videoState;
-            mHandler.obtainMessage(MSG_ANSWER_VIDEO, args).sendToTarget();
+        public void answerVideo(String callId, int videoState, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_ANSWER_VIDEO);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                args.argi1 = videoState;
+                mHandler.obtainMessage(MSG_ANSWER_VIDEO, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void answer(String callId) {
-            mHandler.obtainMessage(MSG_ANSWER, callId).sendToTarget();
+        public void answer(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_ANSWER);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_ANSWER, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void reject(String callId) {
-            mHandler.obtainMessage(MSG_REJECT, callId).sendToTarget();
+        public void reject(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_REJECT);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_REJECT, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void rejectWithMessage(String callId, String message) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = message;
-            mHandler.obtainMessage(MSG_REJECT_WITH_MESSAGE, args).sendToTarget();
+        public void rejectWithMessage(String callId, String message, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_REJECT_MESSAGE);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = message;
+                args.arg3 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_REJECT_WITH_MESSAGE, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void silence(String callId) {
-            mHandler.obtainMessage(MSG_SILENCE, callId).sendToTarget();
+        public void silence(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_SILENCE);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_SILENCE, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void disconnect(String callId) {
-            mHandler.obtainMessage(MSG_DISCONNECT, callId).sendToTarget();
+        public void disconnect(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_DISCONNECT);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_DISCONNECT, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void hold(String callId) {
-            mHandler.obtainMessage(MSG_HOLD, callId).sendToTarget();
+        public void hold(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_HOLD);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_HOLD, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void unhold(String callId) {
-            mHandler.obtainMessage(MSG_UNHOLD, callId).sendToTarget();
+        public void unhold(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_UNHOLD);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_UNHOLD, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void onCallAudioStateChanged(String callId, CallAudioState callAudioState) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = callAudioState;
-            mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, args).sendToTarget();
+        public void onCallAudioStateChanged(String callId, CallAudioState callAudioState,
+                Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_CALL_AUDIO_SC);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = callAudioState;
+                args.arg3 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void playDtmfTone(String callId, char digit) {
-            mHandler.obtainMessage(MSG_PLAY_DTMF_TONE, digit, 0, callId).sendToTarget();
+        public void playDtmfTone(String callId, char digit, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_PLAY_DTMF);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = digit;
+                args.arg2 = callId;
+                args.arg3 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_PLAY_DTMF_TONE, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void stopDtmfTone(String callId) {
-            mHandler.obtainMessage(MSG_STOP_DTMF_TONE, callId).sendToTarget();
+        public void stopDtmfTone(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_STOP_DTMF);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_STOP_DTMF_TONE, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void conference(String callId1, String callId2) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId1;
-            args.arg2 = callId2;
-            mHandler.obtainMessage(MSG_CONFERENCE, args).sendToTarget();
+        public void conference(String callId1, String callId2, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_CONFERENCE);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId1;
+                args.arg2 = callId2;
+                args.arg3 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_CONFERENCE, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void splitFromConference(String callId) {
-            mHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, callId).sendToTarget();
+        public void splitFromConference(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_SPLIT_CONFERENCE);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void mergeConference(String callId) {
-            mHandler.obtainMessage(MSG_MERGE_CONFERENCE, callId).sendToTarget();
+        public void mergeConference(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_MERGE_CONFERENCE);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_MERGE_CONFERENCE, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void swapConference(String callId) {
-            mHandler.obtainMessage(MSG_SWAP_CONFERENCE, callId).sendToTarget();
+        public void swapConference(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_SWAP_CONFERENCE);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_SWAP_CONFERENCE, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void onPostDialContinue(String callId, boolean proceed) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.argi1 = proceed ? 1 : 0;
-            mHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
+        public void onPostDialContinue(String callId, boolean proceed, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_POST_DIAL_CONT);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                args.argi1 = proceed ? 1 : 0;
+                mHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void pullExternalCall(String callId) {
-            mHandler.obtainMessage(MSG_PULL_EXTERNAL_CALL, callId).sendToTarget();
+        public void pullExternalCall(String callId, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_PULL_EXTERNAL_CALL);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_PULL_EXTERNAL_CALL, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void sendCallEvent(String callId, String event, Bundle extras) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = event;
-            args.arg3 = extras;
-            mHandler.obtainMessage(MSG_SEND_CALL_EVENT, args).sendToTarget();
+        public void sendCallEvent(String callId, String event, Bundle extras,
+                Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_SEND_CALL_EVENT);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = event;
+                args.arg3 = extras;
+                args.arg4 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_SEND_CALL_EVENT, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
 
         @Override
-        public void onExtrasChanged(String callId, Bundle extras) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = extras;
-            mHandler.obtainMessage(MSG_ON_EXTRAS_CHANGED, args).sendToTarget();
+        public void onExtrasChanged(String callId, Bundle extras, Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_EXTRAS_CHANGED);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = extras;
+                args.arg3 = Log.createSubsession();
+                mHandler.obtainMessage(MSG_ON_EXTRAS_CHANGED, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
         }
     };
 
@@ -276,15 +477,35 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case MSG_ADD_CONNECTION_SERVICE_ADAPTER:
-                    mAdapter.addAdapter((IConnectionServiceAdapter) msg.obj);
-                    onAdapterAttached();
+                case MSG_ADD_CONNECTION_SERVICE_ADAPTER: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        IConnectionServiceAdapter adapter = (IConnectionServiceAdapter) args.arg1;
+                        Log.continueSession((Session) args.arg2,
+                                SESSION_HANDLER + SESSION_ADD_CS_ADAPTER);
+                        mAdapter.addAdapter(adapter);
+                        onAdapterAttached();
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
-                case MSG_REMOVE_CONNECTION_SERVICE_ADAPTER:
-                    mAdapter.removeAdapter((IConnectionServiceAdapter) msg.obj);
+                }
+                case MSG_REMOVE_CONNECTION_SERVICE_ADAPTER: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Log.continueSession((Session) args.arg2,
+                                SESSION_HANDLER + SESSION_REMOVE_CS_ADAPTER);
+                        mAdapter.removeAdapter((IConnectionServiceAdapter) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
+                }
                 case MSG_CREATE_CONNECTION: {
                     SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg4, SESSION_HANDLER + SESSION_CREATE_CONN);
                     try {
                         final PhoneAccountHandle connectionManagerPhoneAccount =
                                 (PhoneAccountHandle) args.arg1;
@@ -315,122 +536,253 @@
                         }
                     } finally {
                         args.recycle();
+                        Log.endSession();
                     }
                     break;
                 }
-                case MSG_ABORT:
-                    abort((String) msg.obj);
+                case MSG_ABORT: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ABORT);
+                    try {
+                        abort((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
-                case MSG_ANSWER:
-                    answer((String) msg.obj);
+                }
+                case MSG_ANSWER: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ANSWER);
+                    try {
+                        answer((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
+                }
                 case MSG_ANSWER_VIDEO: {
                     SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg2,
+                            SESSION_HANDLER + SESSION_ANSWER_VIDEO);
                     try {
                         String callId = (String) args.arg1;
                         int videoState = args.argi1;
                         answerVideo(callId, videoState);
                     } finally {
                         args.recycle();
+                        Log.endSession();
                     }
                     break;
                 }
-                case MSG_REJECT:
-                    reject((String) msg.obj);
+                case MSG_REJECT: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
+                    try {
+                        reject((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
+                }
                 case MSG_REJECT_WITH_MESSAGE: {
                     SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg3,
+                            SESSION_HANDLER + SESSION_REJECT_MESSAGE);
                     try {
                         reject((String) args.arg1, (String) args.arg2);
                     } finally {
                         args.recycle();
+                        Log.endSession();
                     }
                     break;
                 }
-                case MSG_DISCONNECT:
-                    disconnect((String) msg.obj);
+                case MSG_DISCONNECT: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_DISCONNECT);
+                    try {
+                        disconnect((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
-                case MSG_SILENCE:
-                    silence((String) msg.obj);
+                }
+                case MSG_SILENCE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_SILENCE);
+                    try {
+                        silence((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
-                case MSG_HOLD:
-                    hold((String) msg.obj);
+                }
+                case MSG_HOLD: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
+                    try {
+                        hold((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
-                case MSG_UNHOLD:
-                    unhold((String) msg.obj);
+                }
+                case MSG_UNHOLD: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_UNHOLD);
+                    try {
+                        unhold((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
+                }
                 case MSG_ON_CALL_AUDIO_STATE_CHANGED: {
                     SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg3,
+                            SESSION_HANDLER + SESSION_CALL_AUDIO_SC);
                     try {
                         String callId = (String) args.arg1;
                         CallAudioState audioState = (CallAudioState) args.arg2;
                         onCallAudioStateChanged(callId, new CallAudioState(audioState));
                     } finally {
                         args.recycle();
+                        Log.endSession();
                     }
                     break;
                 }
-                case MSG_PLAY_DTMF_TONE:
-                    playDtmfTone((String) msg.obj, (char) msg.arg1);
+                case MSG_PLAY_DTMF_TONE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Log.continueSession((Session) args.arg3,
+                                SESSION_HANDLER + SESSION_PLAY_DTMF);
+                        playDtmfTone((String) args.arg2, (char) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
-                case MSG_STOP_DTMF_TONE:
-                    stopDtmfTone((String) msg.obj);
+                }
+                case MSG_STOP_DTMF_TONE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Log.continueSession((Session) args.arg2,
+                                SESSION_HANDLER + SESSION_STOP_DTMF);
+                        stopDtmfTone((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
+                }
                 case MSG_CONFERENCE: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
+                        Log.continueSession((Session) args.arg3,
+                                SESSION_HANDLER + SESSION_CONFERENCE);
                         String callId1 = (String) args.arg1;
                         String callId2 = (String) args.arg2;
                         conference(callId1, callId2);
                     } finally {
                         args.recycle();
+                        Log.endSession();
                     }
                     break;
                 }
-                case MSG_SPLIT_FROM_CONFERENCE:
-                    splitFromConference((String) msg.obj);
+                case MSG_SPLIT_FROM_CONFERENCE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Log.continueSession((Session) args.arg2,
+                                SESSION_HANDLER + SESSION_SPLIT_CONFERENCE);
+                        splitFromConference((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
-                case MSG_MERGE_CONFERENCE:
-                    mergeConference((String) msg.obj);
+                }
+                case MSG_MERGE_CONFERENCE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Log.continueSession((Session) args.arg2,
+                                SESSION_HANDLER + SESSION_MERGE_CONFERENCE);
+                        mergeConference((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
-                case MSG_SWAP_CONFERENCE:
-                    swapConference((String) msg.obj);
+                }
+                case MSG_SWAP_CONFERENCE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Log.continueSession((Session) args.arg2,
+                                SESSION_HANDLER + SESSION_SWAP_CONFERENCE);
+                        swapConference((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
+                }
                 case MSG_ON_POST_DIAL_CONTINUE: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
+                        Log.continueSession((Session) args.arg2,
+                                SESSION_HANDLER + SESSION_POST_DIAL_CONT);
                         String callId = (String) args.arg1;
                         boolean proceed = (args.argi1 == 1);
                         onPostDialContinue(callId, proceed);
                     } finally {
                         args.recycle();
+                        Log.endSession();
                     }
                     break;
                 }
                 case MSG_PULL_EXTERNAL_CALL: {
-                    pullExternalCall((String) msg.obj);
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Log.continueSession((Session) args.arg2,
+                                SESSION_HANDLER + SESSION_PULL_EXTERNAL_CALL);
+                        pullExternalCall((String) args.arg1);
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
                     break;
                 }
                 case MSG_SEND_CALL_EVENT: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
+                        Log.continueSession((Session) args.arg4,
+                                SESSION_HANDLER + SESSION_SEND_CALL_EVENT);
                         String callId = (String) args.arg1;
                         String event = (String) args.arg2;
                         Bundle extras = (Bundle) args.arg3;
                         sendCallEvent(callId, event, extras);
                     } finally {
                         args.recycle();
+                        Log.endSession();
                     }
                     break;
                 }
                 case MSG_ON_EXTRAS_CHANGED: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
+                        Log.continueSession((Session) args.arg3,
+                                SESSION_HANDLER + SESSION_EXTRAS_CHANGED);
                         String callId = (String) args.arg1;
                         Bundle extras = (Bundle) args.arg2;
                         handleExtrasChanged(callId, extras);
                     } finally {
                         args.recycle();
+                        Log.endSession();
                     }
                     break;
                 }
@@ -698,7 +1050,7 @@
                 mAdapter.putExtras(id, extras);
             }
         }
-        
+
         public void onExtrasRemoved(Connection c, List<String> keys) {
             String id = mIdByConnection.get(c);
             if (id != null) {
@@ -1274,15 +1626,11 @@
      * call created using
      * {@code TelecomManager#addNewIncomingCall(PhoneAccountHandle, android.os.Bundle)}.
      *
-     * @param connectionManagerPhoneAccount
-     * @param request
-     * @return
-     *
      * @hide
      */
     public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerPhoneAccount,
             ConnectionRequest request) {
-       return null;
+        return null;
     }
 
     /**
@@ -1509,7 +1857,7 @@
      * @return The call ID.
      */
     private int getNextCallId() {
-        synchronized(mIdSyncRoot) {
+        synchronized (mIdSyncRoot) {
             return ++mId;
         }
     }
diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java
index 249d32b..446bbbb 100644
--- a/telecomm/java/android/telecom/Log.java
+++ b/telecomm/java/android/telecom/Log.java
@@ -184,14 +184,27 @@
         getSessionManager().startSession(shortMethodName, null);
     }
 
+    public static void startSession(Session.Info info, String shortMethodName) {
+        getSessionManager().startSession(info, shortMethodName, null);
+    }
+
     public static void startSession(String shortMethodName, String callerIdentification) {
         getSessionManager().startSession(shortMethodName, callerIdentification);
     }
 
+    public static void startSession(Session.Info info, String shortMethodName,
+            String callerIdentification) {
+        getSessionManager().startSession(info, shortMethodName, callerIdentification);
+    }
+
     public static Session createSubsession() {
         return getSessionManager().createSubsession();
     }
 
+    public static Session.Info getExternalSession() {
+        return getSessionManager().getExternalSession();
+    }
+
     public static void cancelSubsession(Session subsession) {
         getSessionManager().cancelSubsession(subsession);
     }
diff --git a/telecomm/java/android/telecom/Logging/Session.aidl b/telecomm/java/android/telecom/Logging/Session.aidl
new file mode 100644
index 0000000..68961b6
--- /dev/null
+++ b/telecomm/java/android/telecom/Logging/Session.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telecom.Logging;
+
+/**
+ * {@hide}
+ */
+parcelable Session.Info;
\ No newline at end of file
diff --git a/telecomm/java/android/telecom/Logging/Session.java b/telecomm/java/android/telecom/Logging/Session.java
index 510abdd..3a7b8c0 100644
--- a/telecomm/java/android/telecom/Logging/Session.java
+++ b/telecomm/java/android/telecom/Logging/Session.java
@@ -17,6 +17,11 @@
 package android.telecom.Logging;
 
 import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
 
@@ -33,12 +38,58 @@
     public static final String END_SUBSESSION = "END_SUBSESSION";
     public static final String END_SESSION = "END_SESSION";
 
+    public static final String SUBSESSION_SEPARATION_CHAR = "->";
+    public static final String EXTERNAL_INDICATOR = "E-";
+
     /**
      * Initial value of mExecutionEndTimeMs and the final value of {@link #getLocalExecutionTime()}
      * if the Session is canceled.
      */
     public static final int UNDEFINED = -1;
 
+    public static class Info implements Parcelable {
+        public final String sessionId;
+        public final String shortMethodName;
+
+        private Info(String id, String methodName) {
+            sessionId = id;
+            shortMethodName = methodName;
+        }
+
+        public static Info getInfo (Session s) {
+            return new Info(s.getFullSessionId(), s.getShortMethodName());
+        }
+
+        /** Responsible for creating Info objects for deserialized Parcels. */
+        public static final Parcelable.Creator<Info> CREATOR =
+                new Parcelable.Creator<Info> () {
+                    @Override
+                    public Info createFromParcel(Parcel source) {
+                        String id = source.readString();
+                        String methodName = source.readString();
+                        return new Info(id, methodName);
+                    }
+
+                    @Override
+                    public Info[] newArray(int size) {
+                        return new Info[size];
+                    }
+                };
+
+        /** {@inheritDoc} */
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        /** Writes Info object into a Parcel. */
+        @Override
+        public void writeToParcel(Parcel destination, int flags) {
+            destination.writeString(sessionId);
+            destination.writeString(shortMethodName);
+        }
+    }
+
     private String mSessionId;
     private String mShortMethodName;
     private long mExecutionStartTimeMs;
@@ -46,6 +97,7 @@
     private Session mParentSession;
     private ArrayList<Session> mChildSessions;
     private boolean mIsCompleted = false;
+    private boolean mIsExternal = false;
     private int mChildCounter = 0;
     // True if this is a subsession that has been started from the same thread as the parent
     // session. This can happen if Log.startSession(...) is called multiple times on the same
@@ -56,8 +108,11 @@
     // Optionally provided info about the method/class/component that started the session in order
     // to make Logging easier. This info will be provided in parentheses along with the session.
     private String mOwnerInfo;
+    // Cache Full Method path so that recursive population of the full method path only needs to
+    // be calculated once.
+    private String mFullMethodPathCache;
 
-    public Session(String sessionId, String shortMethodName, long startTimeMs, long threadID,
+    public Session(String sessionId, String shortMethodName, long startTimeMs,
             boolean isStartedFromActiveSession, String ownerInfo) {
         setSessionId(sessionId);
         setShortMethodName(shortMethodName);
@@ -86,6 +141,14 @@
         mShortMethodName = shortMethodName;
     }
 
+    public void setIsExternal(boolean isExternal) {
+        mIsExternal = isExternal;
+    }
+
+    public boolean isExternal() {
+        return mIsExternal;
+    }
+
     public void setParentSession(Session parentSession) {
         mParentSession = parentSession;
     }
@@ -126,6 +189,15 @@
         return mIsStartedFromActiveSession;
     }
 
+    public Info getInfo() {
+        return Info.getInfo(this);
+    }
+
+    @VisibleForTesting
+    public String getSessionId() {
+        return mSessionId;
+    }
+
     // Mark this session complete. This will be deleted by Log when all subsessions are complete
     // as well.
     public void markSessionCompleted(long executionEndTimeMs) {
@@ -186,6 +258,46 @@
         }
     }
 
+    // Recursively concatenate mShortMethodName with the parent Sessions to create full method
+    // path. Caches this string so that multiple calls for the path will be quick.
+    public String getFullMethodPath() {
+        StringBuilder sb = new StringBuilder();
+        getFullMethodPath(sb);
+        return sb.toString();
+    }
+
+    private synchronized void getFullMethodPath(StringBuilder sb) {
+        // Don't calculate if we have already figured it out!
+        if (!TextUtils.isEmpty(mFullMethodPathCache)) {
+            sb.append(mFullMethodPathCache);
+            return;
+        }
+        Session parentSession = getParentSession();
+        boolean isSessionStarted = false;
+        if (parentSession != null) {
+            // Check to see if the session has been renamed yet. If it has not, then the session
+            // has not been continued.
+            isSessionStarted = !mShortMethodName.equals(parentSession.mShortMethodName);
+            parentSession.getFullMethodPath(sb);
+            sb.append(SUBSESSION_SEPARATION_CHAR);
+        }
+        // Encapsulate the external session's method name so it is obvious what part of the session
+        // is external.
+        if (isExternal()) {
+            sb.append("(");
+            sb.append(mShortMethodName);
+            sb.append(")");
+        } else {
+            sb.append(mShortMethodName);
+        }
+
+        if(isSessionStarted) {
+            // Cache this value so that we do not have to do this work next time!
+            // We do not cache the value if the session being evaluated hasn't been continued yet.
+            mFullMethodPathCache = sb.toString();
+        }
+    }
+
     @Override
     public int hashCode() {
         int result = mSessionId != null ? mSessionId.hashCode() : 0;
@@ -238,7 +350,7 @@
             return mParentSession.toString();
         } else {
             StringBuilder methodName = new StringBuilder();
-            methodName.append(mShortMethodName);
+            methodName.append(getFullMethodPath());
             if (mOwnerInfo != null && !mOwnerInfo.isEmpty()) {
                 methodName.append("(InCall package: ");
                 methodName.append(mOwnerInfo);
diff --git a/telecomm/java/android/telecom/Logging/SessionManager.java b/telecomm/java/android/telecom/Logging/SessionManager.java
index add1237..8ced7f81 100644
--- a/telecomm/java/android/telecom/Logging/SessionManager.java
+++ b/telecomm/java/android/telecom/Logging/SessionManager.java
@@ -21,6 +21,7 @@
 import android.os.Looper;
 import android.os.Process;
 import android.provider.Settings;
+import android.telecom.Log;
 import android.util.Base64;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -41,12 +42,9 @@
 
     // Currently using 3 letters, So don't exceed 64^3
     private static final long SESSION_ID_ROLLOVER_THRESHOLD = 262144;
-
     // This parameter can be overridden in Telecom's Timeouts class.
-    public static final long DEFAULT_SESSION_TIMEOUT_MS = 30000L; // 30 seconds
-
-    private static String LOGGING_TAG = "Logging";
-
+    private static final long DEFAULT_SESSION_TIMEOUT_MS = 30000L; // 30 seconds
+    private static final String LOGGING_TAG = "Logging";
     private static final String TIMEOUTS_PREFIX = "telecom.";
 
     // Synchronized in all method calls
@@ -56,10 +54,9 @@
     @VisibleForTesting
     public ConcurrentHashMap<Integer, Session> mSessionMapper = new ConcurrentHashMap<>(100);
     @VisibleForTesting
-    public Handler mSessionCleanupHandler = new Handler(Looper.getMainLooper());
-    @VisibleForTesting
     public java.lang.Runnable mCleanStaleSessions = () ->
             cleanupStaleSessions(getSessionCleanupTimeoutMs());
+    private Handler mSessionCleanupHandler = new Handler(Looper.getMainLooper());
 
     // Overridden in LogTest to skip query to ContentProvider
     private interface ISessionCleanupTimeoutMs {
@@ -74,8 +71,7 @@
     @VisibleForTesting
     public ICurrentThreadId mCurrentThreadId = Process::myTid;
 
-    @VisibleForTesting
-    public ISessionCleanupTimeoutMs mSessionCleanupTimeoutMs = () -> {
+    private ISessionCleanupTimeoutMs mSessionCleanupTimeoutMs = () -> {
         // mContext may be null in some cases, such as testing. For these cases, use the
         // default value.
         if (mContext == null) {
@@ -120,6 +116,21 @@
     }
 
     /**
+     * Determines whether or not to start a new session or continue an existing session based on
+     * the {@link Session.Info} info passed into startSession. If info is null, a new Session is
+     * created. This code must be accompanied by endSession() at the end of the Session.
+     */
+    public synchronized void startSession(Session.Info info, String shortMethodName,
+            String callerIdentification) {
+        // Start a new session normally if the
+        if(info == null) {
+            startSession(shortMethodName, callerIdentification);
+        } else {
+            startExternalSession(info, shortMethodName);
+        }
+    }
+
+    /**
      * Call at an entry point to the Telecom code to track the session. This code must be
      * accompanied by a Log.endSession().
      */
@@ -134,14 +145,54 @@
             Session childSession = createSubsession(true);
             continueSession(childSession, shortMethodName);
             return;
+        } else {
+            // Only Log that we are starting the parent session.
+            Log.d(LOGGING_TAG, Session.START_SESSION);
         }
         Session newSession = new Session(getNextSessionID(), shortMethodName,
-                System.currentTimeMillis(), threadId, false, callerIdentification);
+                System.currentTimeMillis(), false, callerIdentification);
         mSessionMapper.put(threadId, newSession);
-
-        android.util.Slog.v(LOGGING_TAG, Session.START_SESSION);
     }
 
+    /**
+     * Registers an external Session with the Manager using that external Session's sessionInfo.
+     * Log.endSession will still need to be called at the end of the session.
+     * @param sessionInfo Describes the external Session's information.
+     * @param shortMethodName The method name of the new session that is being started.
+     */
+    public synchronized void startExternalSession(Session.Info sessionInfo,
+            String shortMethodName) {
+        if(sessionInfo == null) {
+            return;
+        }
+
+        int threadId = getCallingThreadId();
+        Session threadSession = mSessionMapper.get(threadId);
+        if (threadSession != null) {
+            // We should never get into a situation where there is already an active session AND
+            // an external session is added. We are just using that active session.
+            Log.w(LOGGING_TAG, "trying to start an external session with a session " +
+                    "already active.");
+            return;
+        }
+
+        // Create Session from Info and add to the sessionMapper under this ID.
+        Session externalSession = new Session(Session.EXTERNAL_INDICATOR + sessionInfo.sessionId,
+                sessionInfo.shortMethodName, System.currentTimeMillis(),
+                false /*isStartedFromActiveSession*/, null);
+        externalSession.setIsExternal(true);
+        // Mark the external session as already completed, since we have no way of knowing when
+        // the external session actually has completed.
+        externalSession.markSessionCompleted(Session.UNDEFINED);
+        // Track the external session with the SessionMapper so that we can create and continue
+        // an active subsession based on it.
+        mSessionMapper.put(threadId, externalSession);
+        // Create a subsession from this external Session parent node
+        Session childSession = createSubsession();
+        continueSession(childSession, shortMethodName);
+
+        Log.d(LOGGING_TAG, Session.START_SESSION);
+    }
 
     /**
      * Notifies the logging system that a subsession will be run at a later point and
@@ -156,28 +207,45 @@
         int threadId = getCallingThreadId();
         Session threadSession = mSessionMapper.get(threadId);
         if (threadSession == null) {
-            android.util.Slog.d(LOGGING_TAG, "Log.createSubsession was called with no session " +
+            Log.d(LOGGING_TAG, "Log.createSubsession was called with no session " +
                     "active.");
             return null;
         }
         // Start execution time of the session will be overwritten in continueSession(...).
         Session newSubsession = new Session(threadSession.getNextChildId(),
-                threadSession.getShortMethodName(), System.currentTimeMillis(), threadId,
+                threadSession.getShortMethodName(), System.currentTimeMillis(),
                 isStartedFromActiveSession, null);
         threadSession.addChild(newSubsession);
         newSubsession.setParentSession(threadSession);
 
         if (!isStartedFromActiveSession) {
-            android.util.Slog.v(LOGGING_TAG, Session.CREATE_SUBSESSION + " " +
+            Log.v(LOGGING_TAG, Session.CREATE_SUBSESSION + " " +
                     newSubsession.toString());
         } else {
-            android.util.Slog.v(LOGGING_TAG, Session.CREATE_SUBSESSION +
+            Log.v(LOGGING_TAG, Session.CREATE_SUBSESSION +
                     " (Invisible subsession)");
         }
         return newSubsession;
     }
 
     /**
+     * Retrieve the information of the currently active Session. This information is parcelable and
+     * is used to create an external Session ({@link #startExternalSession(Session.Info, String)}).
+     * If there is no Session active, this method will return null.
+     */
+    public synchronized Session.Info getExternalSession() {
+        int threadId = getCallingThreadId();
+        Session threadSession = mSessionMapper.get(threadId);
+        if (threadSession == null) {
+            Log.d(LOGGING_TAG, "Log.getExternalSession was called with no session " +
+                    "active.");
+            return null;
+        }
+
+        return threadSession.getInfo();
+    }
+
+    /**
      * Cancels a subsession that had Log.createSubsession() called on it, but will never have
      * Log.continueSession(...) called on it due to an error. Allows the subsession to be cleaned
      * gracefully instead of being removed by the mSessionCleanupHandler forcefully later.
@@ -201,21 +269,20 @@
             return;
         }
         resetStaleSessionTimer();
-        String callingMethodName = subsession.getShortMethodName();
-        subsession.setShortMethodName(callingMethodName + "->" + shortMethodName);
+        subsession.setShortMethodName(shortMethodName);
         subsession.setExecutionStartTimeMs(System.currentTimeMillis());
         Session parentSession = subsession.getParentSession();
         if (parentSession == null) {
-            android.util.Slog.d(LOGGING_TAG, "Log.continueSession was called with no session " +
+            Log.i(LOGGING_TAG, "Log.continueSession was called with no session " +
                     "active for method " + shortMethodName);
             return;
         }
 
         mSessionMapper.put(getCallingThreadId(), subsession);
         if (!subsession.isStartedFromActiveSession()) {
-            android.util.Slog.v(LOGGING_TAG, Session.CONTINUE_SUBSESSION);
+            Log.v(LOGGING_TAG, Session.CONTINUE_SUBSESSION);
         } else {
-            android.util.Slog.v(LOGGING_TAG, Session.CONTINUE_SUBSESSION +
+            Log.v(LOGGING_TAG, Session.CONTINUE_SUBSESSION +
                     " (Invisible Subsession) with Method " + shortMethodName);
         }
     }
@@ -228,16 +295,16 @@
         int threadId = getCallingThreadId();
         Session completedSession = mSessionMapper.get(threadId);
         if (completedSession == null) {
-            android.util.Slog.w(LOGGING_TAG, "Log.endSession was called with no session active.");
+            Log.w(LOGGING_TAG, "Log.endSession was called with no session active.");
             return;
         }
 
         completedSession.markSessionCompleted(System.currentTimeMillis());
         if (!completedSession.isStartedFromActiveSession()) {
-            android.util.Slog.v(LOGGING_TAG, Session.END_SUBSESSION + " (dur: " +
+            Log.v(LOGGING_TAG, Session.END_SUBSESSION + " (dur: " +
                     completedSession.getLocalExecutionTime() + " mS)");
         } else {
-            android.util.Slog.v(LOGGING_TAG, Session.END_SUBSESSION +
+            Log.v(LOGGING_TAG, Session.END_SUBSESSION +
                     " (Invisible Subsession) (dur: " + completedSession.getLocalExecutionTime() +
                     " ms)");
         }
@@ -260,25 +327,37 @@
         if (!subsession.isSessionCompleted() || subsession.getChildSessions().size() != 0) {
             return;
         }
-
         Session parentSession = subsession.getParentSession();
         if (parentSession != null) {
             subsession.setParentSession(null);
             parentSession.removeChild(subsession);
+            // Report the child session of the external session as being complete to the listeners,
+            // not the external session itself.
+            if (parentSession.isExternal()) {
+                long fullSessionTimeMs =
+                        System.currentTimeMillis() - subsession.getExecutionStartTimeMilliseconds();
+                notifySessionCompleteListeners(subsession.getShortMethodName(), fullSessionTimeMs);
+            }
             endParentSessions(parentSession);
         } else {
             // All of the subsessions have been completed and it is time to report on the full
             // running time of the session.
             long fullSessionTimeMs =
                     System.currentTimeMillis() - subsession.getExecutionStartTimeMilliseconds();
-            android.util.Slog.d(LOGGING_TAG, Session.END_SESSION + " (dur: " + fullSessionTimeMs
+            Log.d(LOGGING_TAG, Session.END_SESSION + " (dur: " + fullSessionTimeMs
                     + " ms): " + subsession.toString());
-            for (ISessionListener l : mSessionListeners) {
-                l.sessionComplete(subsession.getShortMethodName(), fullSessionTimeMs);
+            if (!subsession.isExternal()) {
+                notifySessionCompleteListeners(subsession.getShortMethodName(), fullSessionTimeMs);
             }
         }
     }
 
+    private void notifySessionCompleteListeners(String methodName, long sessionTimeMs) {
+        for (ISessionListener l : mSessionListeners) {
+            l.sessionComplete(methodName, sessionTimeMs);
+        }
+    }
+
     public String getSessionId() {
         Session currentSession = mSessionMapper.get(getCallingThreadId());
         return currentSession != null ? currentSession.toString() : "";
@@ -299,24 +378,22 @@
         return getBase64Encoding(nextId);
     }
 
-    @VisibleForTesting
-    public synchronized void restartSessionCounter() {
+    private synchronized void restartSessionCounter() {
         sCodeEntryCounter = 0;
     }
 
-    @VisibleForTesting
-    public String getBase64Encoding(int number) {
+    private String getBase64Encoding(int number) {
         byte[] idByteArray = ByteBuffer.allocate(4).putInt(number).array();
         idByteArray = Arrays.copyOfRange(idByteArray, 2, 4);
         return Base64.encodeToString(idByteArray, Base64.NO_WRAP | Base64.NO_PADDING);
     }
 
-    public int getCallingThreadId() {
+    private int getCallingThreadId() {
         return mCurrentThreadId.get();
     }
 
     @VisibleForTesting
-    private synchronized void cleanupStaleSessions(long timeoutMs) {
+    public synchronized void cleanupStaleSessions(long timeoutMs) {
         String logMessage = "Stale Sessions Cleaned:\n";
         boolean isSessionsStale = false;
         long currentTimeMs = System.currentTimeMillis();
@@ -335,9 +412,9 @@
             }
         }
         if (isSessionsStale) {
-            android.util.Slog.w(LOGGING_TAG, logMessage);
+            Log.w(LOGGING_TAG, logMessage);
         } else {
-            android.util.Slog.v(LOGGING_TAG, "No stale logging sessions needed to be cleaned...");
+            Log.v(LOGGING_TAG, "No stale logging sessions needed to be cleaned...");
         }
     }
 
diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java
index 0ef9ec1..502b7c0 100644
--- a/telecomm/java/android/telecom/RemoteConference.java
+++ b/telecomm/java/android/telecom/RemoteConference.java
@@ -399,7 +399,7 @@
      */
     public void disconnect() {
         try {
-            mConnectionService.disconnect(mId);
+            mConnectionService.disconnect(mId, null /*Session.Info*/);
         } catch (RemoteException e) {
         }
     }
@@ -414,7 +414,7 @@
     public void separate(RemoteConnection connection) {
         if (mChildConnections.contains(connection)) {
             try {
-                mConnectionService.splitFromConference(connection.getId());
+                mConnectionService.splitFromConference(connection.getId(), null /*Session.Info*/);
             } catch (RemoteException e) {
             }
         }
@@ -432,7 +432,7 @@
      */
     public void merge() {
         try {
-            mConnectionService.mergeConference(mId);
+            mConnectionService.mergeConference(mId, null /*Session.Info*/);
         } catch (RemoteException e) {
         }
     }
@@ -448,7 +448,7 @@
      */
     public void swap() {
         try {
-            mConnectionService.swapConference(mId);
+            mConnectionService.swapConference(mId, null /*Session.Info*/);
         } catch (RemoteException e) {
         }
     }
@@ -458,7 +458,7 @@
      */
     public void hold() {
         try {
-            mConnectionService.hold(mId);
+            mConnectionService.hold(mId, null /*Session.Info*/);
         } catch (RemoteException e) {
         }
     }
@@ -468,7 +468,7 @@
      */
     public void unhold() {
         try {
-            mConnectionService.unhold(mId);
+            mConnectionService.unhold(mId, null /*Session.Info*/);
         } catch (RemoteException e) {
         }
     }
@@ -491,7 +491,7 @@
      */
     public void playDtmfTone(char digit) {
         try {
-            mConnectionService.playDtmfTone(mId, digit);
+            mConnectionService.playDtmfTone(mId, digit, null /*Session.Info*/);
         } catch (RemoteException e) {
         }
     }
@@ -503,7 +503,7 @@
      */
     public void stopDtmfTone() {
         try {
-            mConnectionService.stopDtmfTone(mId);
+            mConnectionService.stopDtmfTone(mId, null /*Session.Info*/);
         } catch (RemoteException e) {
         }
     }
@@ -528,7 +528,7 @@
      */
     public void setCallAudioState(CallAudioState state) {
         try {
-            mConnectionService.onCallAudioStateChanged(mId, state);
+            mConnectionService.onCallAudioStateChanged(mId, state, null /*Session.Info*/);
         } catch (RemoteException e) {
         }
     }
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 37fa374..0e4f53e 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -855,7 +855,7 @@
     public void abort() {
         try {
             if (mConnected) {
-                mConnectionService.abort(mConnectionId);
+                mConnectionService.abort(mConnectionId, null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
@@ -867,7 +867,7 @@
     public void answer() {
         try {
             if (mConnected) {
-                mConnectionService.answer(mConnectionId);
+                mConnectionService.answer(mConnectionId, null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
@@ -881,7 +881,7 @@
     public void answer(int videoState) {
         try {
             if (mConnected) {
-                mConnectionService.answerVideo(mConnectionId, videoState);
+                mConnectionService.answerVideo(mConnectionId, videoState, null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
@@ -893,7 +893,7 @@
     public void reject() {
         try {
             if (mConnected) {
-                mConnectionService.reject(mConnectionId);
+                mConnectionService.reject(mConnectionId, null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
@@ -905,7 +905,7 @@
     public void hold() {
         try {
             if (mConnected) {
-                mConnectionService.hold(mConnectionId);
+                mConnectionService.hold(mConnectionId, null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
@@ -917,7 +917,7 @@
     public void unhold() {
         try {
             if (mConnected) {
-                mConnectionService.unhold(mConnectionId);
+                mConnectionService.unhold(mConnectionId, null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
@@ -929,7 +929,7 @@
     public void disconnect() {
         try {
             if (mConnected) {
-                mConnectionService.disconnect(mConnectionId);
+                mConnectionService.disconnect(mConnectionId, null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
@@ -947,7 +947,7 @@
     public void playDtmfTone(char digit) {
         try {
             if (mConnected) {
-                mConnectionService.playDtmfTone(mConnectionId, digit);
+                mConnectionService.playDtmfTone(mConnectionId, digit, null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
@@ -963,7 +963,7 @@
     public void stopDtmfTone() {
         try {
             if (mConnected) {
-                mConnectionService.stopDtmfTone(mConnectionId);
+                mConnectionService.stopDtmfTone(mConnectionId, null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
@@ -993,7 +993,8 @@
     public void postDialContinue(boolean proceed) {
         try {
             if (mConnected) {
-                mConnectionService.onPostDialContinue(mConnectionId, proceed);
+                mConnectionService.onPostDialContinue(mConnectionId, proceed,
+                        null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
@@ -1007,7 +1008,7 @@
     public void pullExternalCall() {
         try {
             if (mConnected) {
-                mConnectionService.pullExternalCall(mConnectionId);
+                mConnectionService.pullExternalCall(mConnectionId, null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
@@ -1034,7 +1035,8 @@
     public void setCallAudioState(CallAudioState state) {
         try {
             if (mConnected) {
-                mConnectionService.onCallAudioStateChanged(mConnectionId, state);
+                mConnectionService.onCallAudioStateChanged(mConnectionId, state,
+                        null /*Session.Info*/);
             }
         } catch (RemoteException ignored) {
         }
diff --git a/telecomm/java/android/telecom/RemoteConnectionManager.java b/telecomm/java/android/telecom/RemoteConnectionManager.java
index 0366509..0322218 100644
--- a/telecomm/java/android/telecom/RemoteConnectionManager.java
+++ b/telecomm/java/android/telecom/RemoteConnectionManager.java
@@ -76,7 +76,7 @@
     public void conferenceRemoteConnections(RemoteConnection a, RemoteConnection b) {
         if (a.getConnectionService() == b.getConnectionService()) {
             try {
-                a.getConnectionService().conference(a.getId(), b.getId());
+                a.getConnectionService().conference(a.getId(), b.getId(), null /*Session.Info*/);
             } catch (RemoteException e) {
             }
         } else {
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index 1577a0f..3927d81 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -431,7 +431,8 @@
                 request.getVideoState());
         try {
             if (mConnectionById.isEmpty()) {
-                mOutgoingConnectionServiceRpc.addConnectionServiceAdapter(mServant.getStub());
+                mOutgoingConnectionServiceRpc.addConnectionServiceAdapter(mServant.getStub(),
+                        null /*Session.Info*/);
             }
             RemoteConnection connection =
                     new RemoteConnection(id, mOutgoingConnectionServiceRpc, newRequest);
@@ -442,7 +443,8 @@
                     id,
                     newRequest,
                     isIncoming,
-                    false /* isUnknownCall */);
+                    false /* isUnknownCall */,
+                    null /*Session.info*/);
             connection.registerCallback(new RemoteConnection.Callback() {
                 @Override
                 public void onDestroyed(RemoteConnection connection) {
@@ -482,7 +484,8 @@
     private void maybeDisconnectAdapter() {
         if (mConnectionById.isEmpty() && mConferenceById.isEmpty()) {
             try {
-                mOutgoingConnectionServiceRpc.removeConnectionServiceAdapter(mServant.getStub());
+                mOutgoingConnectionServiceRpc.removeConnectionServiceAdapter(mServant.getStub(),
+                        null /*Session.info*/);
             } catch (RemoteException e) {
             }
         }
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
index a4c1798..8a27675 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
@@ -19,6 +19,7 @@
 import android.os.Bundle;
 import android.telecom.CallAudioState;
 import android.telecom.ConnectionRequest;
+import android.telecom.Logging.Session;
 import android.telecom.PhoneAccountHandle;
 
 import com.android.internal.telecom.IConnectionServiceAdapter;
@@ -31,54 +32,58 @@
  * @hide
  */
 oneway interface IConnectionService {
-    void addConnectionServiceAdapter(in IConnectionServiceAdapter adapter);
+    void addConnectionServiceAdapter(in IConnectionServiceAdapter adapter,
+    in Session.Info sessionInfo);
 
-    void removeConnectionServiceAdapter(in IConnectionServiceAdapter adapter);
+    void removeConnectionServiceAdapter(in IConnectionServiceAdapter adapter,
+    in Session.Info sessionInfo);
 
     void createConnection(
             in PhoneAccountHandle connectionManagerPhoneAccount,
             String callId,
             in ConnectionRequest request,
             boolean isIncoming,
-            boolean isUnknown);
+            boolean isUnknown,
+            in Session.Info sessionInfo);
 
-    void abort(String callId);
+    void abort(String callId, in Session.Info sessionInfo);
 
-    void answerVideo(String callId, int videoState);
+    void answerVideo(String callId, int videoState, in Session.Info sessionInfo);
 
-    void answer(String callId);
+    void answer(String callId, in Session.Info sessionInfo);
 
-    void reject(String callId);
+    void reject(String callId, in Session.Info sessionInfo);
 
-    void rejectWithMessage(String callId, String message);
+    void rejectWithMessage(String callId, String message, in Session.Info sessionInfo);
 
-    void disconnect(String callId);
+    void disconnect(String callId, in Session.Info sessionInfo);
 
-    void silence(String callId);
+    void silence(String callId, in Session.Info sessionInfo);
 
-    void hold(String callId);
+    void hold(String callId, in Session.Info sessionInfo);
 
-    void unhold(String callId);
+    void unhold(String callId, in Session.Info sessionInfo);
 
-    void onCallAudioStateChanged(String activeCallId, in CallAudioState callAudioState);
+    void onCallAudioStateChanged(String activeCallId, in CallAudioState callAudioState,
+    in Session.Info sessionInfo);
 
-    void playDtmfTone(String callId, char digit);
+    void playDtmfTone(String callId, char digit, in Session.Info sessionInfo);
 
-    void stopDtmfTone(String callId);
+    void stopDtmfTone(String callId, in Session.Info sessionInfo);
 
-    void conference(String conferenceCallId, String callId);
+    void conference(String conferenceCallId, String callId, in Session.Info sessionInfo);
 
-    void splitFromConference(String callId);
+    void splitFromConference(String callId, in Session.Info sessionInfo);
 
-    void mergeConference(String conferenceCallId);
+    void mergeConference(String conferenceCallId, in Session.Info sessionInfo);
 
-    void swapConference(String conferenceCallId);
+    void swapConference(String conferenceCallId, in Session.Info sessionInfo);
 
-    void onPostDialContinue(String callId, boolean proceed);
+    void onPostDialContinue(String callId, boolean proceed, in Session.Info sessionInfo);
 
-    void pullExternalCall(String callId);
+    void pullExternalCall(String callId, in Session.Info sessionInfo);
 
-    void sendCallEvent(String callId, String event, in Bundle extras);
+    void sendCallEvent(String callId, String event, in Bundle extras, in Session.Info sessionInfo);
 
-    void onExtrasChanged(String callId, in Bundle extras);
+    void onExtrasChanged(String callId, in Bundle extras, in Session.Info sessionInfo);
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 04d680e..7506b10 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1072,6 +1072,18 @@
     public static final String KEY_EDITABLE_WFC_ROAMING_MODE_BOOL =
             "editable_wfc_roaming_mode_bool";
 
+   /**
+     * Determine whether current lpp_mode used for E-911 needs to be kept persistently.
+     * {@code false} - not keeping the lpp_mode means using default configuration of gps.conf
+     *                 when sim is not presented.
+     * {@code true}  - current lpp_profile of carrier will be kepted persistently
+     *                 even after sim is removed.
+     *
+     * @hide
+     */
+    public static final String KEY_PERSIST_LPP_MODE_BOOL = "persist_lpp_mode_bool";
+
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -1266,6 +1278,7 @@
         sDefaults.putStringArray(FILTERED_CNAP_NAMES_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
         sDefaults.putBoolean(KEY_STK_DISABLE_LAUNCH_BROWSER_BOOL, false);
+        sDefaults.putBoolean(KEY_PERSIST_LPP_MODE_BOOL, false);
     }
 
     /**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 5b63199..fe9d41a 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3161,7 +3161,10 @@
      * methods may return true.
      *
      * <p>This method returns valid data for registered cells on devices with
-     * {@link android.content.pm.PackageManager#FEATURE_TELEPHONY}.
+     * {@link android.content.pm.PackageManager#FEATURE_TELEPHONY}. In cases where only
+     * partial information is available for a particular CellInfo entry, unavailable fields
+     * will be reported as Integer.MAX_VALUE. All reported cells will include at least a
+     * valid set of technology-specific identification info and a power level measurement.
      *
      *<p>
      * This method is preferred over using {@link
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasSurfaceViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasSurfaceViewActivity.java
index 086a8f0..2bfe994 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasSurfaceViewActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasSurfaceViewActivity.java
@@ -88,7 +88,7 @@
 
     @Override
     public void surfaceCreated(SurfaceHolder holder) {
-        mThread = new RenderingThread(holder.getSurface());
+        mThread = new RenderingThread(holder);
         mThread.start();
     }
 
@@ -103,11 +103,11 @@
     }
 
     private static class RenderingThread extends Thread {
-        private final Surface mSurface;
+        private final SurfaceHolder mSurface;
         private volatile boolean mRunning = true;
         private int mWidth, mHeight;
 
-        public RenderingThread(Surface surface) {
+        public RenderingThread(SurfaceHolder surface) {
             mSurface = surface;
         }
 
diff --git a/tests/net/Android.mk b/tests/net/Android.mk
new file mode 100644
index 0000000..8aa27a9
--- /dev/null
+++ b/tests/net/Android.mk
@@ -0,0 +1,80 @@
+#########################################################################
+# Build FrameworksNetTests package
+#########################################################################
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, java)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    frameworks-base-testutils \
+    framework-protos \
+    android-support-test \
+    mockito-target-minus-junit4 \
+    platform-test-annotations \
+    services.core \
+    services.net
+
+LOCAL_JAVA_LIBRARIES := \
+    android.test.runner
+
+LOCAL_PACKAGE_NAME := FrameworksNetTests
+
+LOCAL_CERTIFICATE := platform
+
+# These are not normally accessible from apps so they must be explicitly included.
+LOCAL_JNI_SHARED_LIBRARIES := libframeworksnettestsjni \
+    libbacktrace \
+    libbase \
+    libbinder \
+    libc++ \
+    libcutils \
+    liblog \
+    liblzma \
+    libnativehelper \
+    libnetdaidl \
+    libui \
+    libunwind \
+    libutils
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+include $(BUILD_PACKAGE)
+
+#########################################################################
+# Build JNI Shared Library
+#########################################################################
+
+LOCAL_PATH:= $(LOCAL_PATH)/jni
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := -Wall -Wextra -Werror
+
+LOCAL_C_INCLUDES := \
+  libpcap \
+  hardware/google/apf
+
+LOCAL_SRC_FILES := $(call all-cpp-files-under)
+
+LOCAL_SHARED_LIBRARIES := \
+  libbinder \
+  liblog \
+  libcutils \
+  libnativehelper \
+  libnetdaidl
+
+LOCAL_STATIC_LIBRARIES := \
+  libpcap \
+  libapf
+
+LOCAL_MODULE := libframeworksnettestsjni
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/net/AndroidManifest.xml b/tests/net/AndroidManifest.xml
new file mode 100644
index 0000000..e069dd0
--- /dev/null
+++ b/tests/net/AndroidManifest.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.frameworks.tests.net">
+
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
+    <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+    <uses-permission android:name="android.permission.REAL_GET_TASKS" />
+    <uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
+    <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
+    <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
+    <uses-permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
+    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.MANAGE_USERS" />
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
+    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
+    <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
+    <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
+    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.frameworks.tests.net"
+        android:label="Frameworks Networking Tests" />
+</manifest>
diff --git a/services/tests/servicestests/src/android/net/ConnectivityMetricsLoggerTest.java b/tests/net/java/android/net/ConnectivityMetricsLoggerTest.java
similarity index 100%
rename from services/tests/servicestests/src/android/net/ConnectivityMetricsLoggerTest.java
rename to tests/net/java/android/net/ConnectivityMetricsLoggerTest.java
diff --git a/services/tests/servicestests/src/android/net/UidRangeTest.java b/tests/net/java/android/net/UidRangeTest.java
similarity index 98%
rename from services/tests/servicestests/src/android/net/UidRangeTest.java
rename to tests/net/java/android/net/UidRangeTest.java
index 221fe0f..0a56e1b 100644
--- a/services/tests/servicestests/src/android/net/UidRangeTest.java
+++ b/tests/net/java/android/net/UidRangeTest.java
@@ -26,7 +26,7 @@
 public class UidRangeTest extends TestCase {
 
     static {
-        System.loadLibrary("servicestestsjni");
+        System.loadLibrary("frameworksnettestsjni");
     }
 
     private static native byte[] readAndWriteNative(byte[] inParcel);
diff --git a/services/tests/servicestests/src/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java
similarity index 99%
rename from services/tests/servicestests/src/android/net/apf/ApfTest.java
rename to tests/net/java/android/net/apf/ApfTest.java
index 37807b2..b7ec004 100644
--- a/services/tests/servicestests/src/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -35,7 +35,7 @@
 import android.test.suitebuilder.annotation.LargeTest;
 import static android.system.OsConstants.*;
 
-import com.android.frameworks.servicestests.R;
+import com.android.frameworks.tests.net.R;
 import com.android.internal.util.HexDump;
 
 import org.mockito.ArgumentCaptor;
@@ -75,7 +75,7 @@
         super.setUp();
         MockitoAnnotations.initMocks(this);
         // Load up native shared library containing APF interpreter exposed via JNI.
-        System.loadLibrary("servicestestsjni");
+        System.loadLibrary("frameworksnettestsjni");
     }
 
     // Expected return codes from APF interpreter.
diff --git a/services/tests/servicestests/src/android/net/apf/Bpf2Apf.java b/tests/net/java/android/net/apf/Bpf2Apf.java
similarity index 100%
rename from services/tests/servicestests/src/android/net/apf/Bpf2Apf.java
rename to tests/net/java/android/net/apf/Bpf2Apf.java
diff --git a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java b/tests/net/java/android/net/dhcp/DhcpPacketTest.java
similarity index 100%
rename from services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
rename to tests/net/java/android/net/dhcp/DhcpPacketTest.java
diff --git a/services/tests/servicestests/src/android/net/netlink/NetlinkErrorMessageTest.java b/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
similarity index 100%
rename from services/tests/servicestests/src/android/net/netlink/NetlinkErrorMessageTest.java
rename to tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
diff --git a/services/tests/servicestests/src/android/net/netlink/NetlinkSocketTest.java b/tests/net/java/android/net/netlink/NetlinkSocketTest.java
similarity index 100%
rename from services/tests/servicestests/src/android/net/netlink/NetlinkSocketTest.java
rename to tests/net/java/android/net/netlink/NetlinkSocketTest.java
diff --git a/services/tests/servicestests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java b/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
similarity index 100%
rename from services/tests/servicestests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java
rename to tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
diff --git a/services/tests/servicestests/src/android/net/util/IpUtilsTest.java b/tests/net/java/android/net/util/IpUtilsTest.java
similarity index 100%
rename from services/tests/servicestests/src/android/net/util/IpUtilsTest.java
rename to tests/net/java/android/net/util/IpUtilsTest.java
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
similarity index 99%
rename from services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
rename to tests/net/java/com/android/server/ConnectivityServiceTest.java
index a921e8a..885e8a7 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -68,14 +68,16 @@
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.test.AndroidTestCase;
+import android.test.FlakyTest;
 import android.test.mock.MockContentResolver;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 import android.util.LogPrinter;
 
-import com.android.internal.util.FakeSettingsProvider;
 import com.android.internal.util.WakeupMessage;
+import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.connectivity.NetworkAgentInfo;
 import com.android.server.connectivity.NetworkMonitor;
 import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
@@ -215,8 +217,20 @@
             mService.waitForIdle();
             assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength());
         }
+    }
+
+    @FlakyTest(tolerance = 3)
+    public void testNotWaitingForIdleCausesRaceConditions() {
+        // Bring up a network that we can use to send messages to ConnectivityService.
+        ConditionVariable cv = waitForConnectivityBroadcasts(1);
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.connect(false);
+        waitFor(cv);
+        Network n = mWiFiNetworkAgent.getNetwork();
+        assertNotNull(n);
 
         // Ensure that not calling waitForIdle causes a race condition.
+        final int attempts = 50;  // Causes the test to take about 200ms on bullhead-eng.
         for (int i = 0; i < attempts; i++) {
             mWiFiNetworkAgent.setSignalStrength(i);
             if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) {
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
similarity index 94%
rename from services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
rename to tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
index aed3635..6ff0c5a 100644
--- a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
@@ -16,6 +16,17 @@
 
 package com.android.server.connectivity;
 
+import static com.android.server.connectivity.MetricsTestUtil.aBool;
+import static com.android.server.connectivity.MetricsTestUtil.aByteArray;
+import static com.android.server.connectivity.MetricsTestUtil.aLong;
+import static com.android.server.connectivity.MetricsTestUtil.aString;
+import static com.android.server.connectivity.MetricsTestUtil.aType;
+import static com.android.server.connectivity.MetricsTestUtil.anInt;
+import static com.android.server.connectivity.MetricsTestUtil.anIntArray;
+import static com.android.server.connectivity.MetricsTestUtil.b;
+import static com.android.server.connectivity.MetricsTestUtil.describeIpEvent;
+import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityLog;
+
 import android.net.ConnectivityMetricsEvent;
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.ApfStats;
@@ -28,21 +39,10 @@
 import android.net.metrics.NetworkEvent;
 import android.net.metrics.RaEvent;
 import android.net.metrics.ValidationProbeEvent;
-import com.google.protobuf.nano.MessageNano;
-import java.util.Arrays;
+
 import junit.framework.TestCase;
 
-import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityLog;
-import static com.android.server.connectivity.MetricsTestUtil.aBool;
-import static com.android.server.connectivity.MetricsTestUtil.aByteArray;
-import static com.android.server.connectivity.MetricsTestUtil.aLong;
-import static com.android.server.connectivity.MetricsTestUtil.aString;
-import static com.android.server.connectivity.MetricsTestUtil.aType;
-import static com.android.server.connectivity.MetricsTestUtil.anInt;
-import static com.android.server.connectivity.MetricsTestUtil.anIntArray;
-import static com.android.server.connectivity.MetricsTestUtil.b;
-import static com.android.server.connectivity.MetricsTestUtil.describeIpEvent;
-import static com.android.server.connectivity.MetricsTestUtil.ipEv;
+import java.util.Arrays;
 
 public class IpConnectivityEventBuilderTest extends TestCase {
 
@@ -71,7 +71,8 @@
                 "    transport_types: 3",
                 "  >",
                 "  time_ms: 1",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, ev);
     }
@@ -93,7 +94,8 @@
                 "    state_transition: \"SomeState\"",
                 "  >",
                 "  time_ms: 1",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, ev);
     }
@@ -114,7 +116,8 @@
                 "    state_transition: \"\"",
                 "  >",
                 "  time_ms: 1",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, ev);
     }
@@ -160,7 +163,8 @@
                 "    return_codes: 178",
                 "  >",
                 "  time_ms: 1",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, ev);
     }
@@ -181,7 +185,8 @@
                 "    latency_ms: 5678",
                 "  >",
                 "  time_ms: 1",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, ev);
     }
@@ -200,7 +205,8 @@
                 "    if_name: \"wlan0\"",
                 "  >",
                 "  time_ms: 1",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, ev);
     }
@@ -223,7 +229,8 @@
                 "    >",
                 "  >",
                 "  time_ms: 1",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, ev);
     }
@@ -248,7 +255,8 @@
                 "    probe_result: 204",
                 "    probe_type: 1",
                 "  >",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, ev);
     }
@@ -274,7 +282,8 @@
                 "    program_length: 2048",
                 "  >",
                 "  time_ms: 1",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, ev);
     }
@@ -305,7 +314,8 @@
                 "    zero_lifetime_ras: 1",
                 "  >",
                 "  time_ms: 1",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, ev);
     }
@@ -332,7 +342,8 @@
                 "    router_lifetime: 2000",
                 "  >",
                 "  time_ms: 1",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, ev);
     }
@@ -340,8 +351,7 @@
     static void verifySerialization(String want, ConnectivityMetricsEvent... input) {
         try {
             byte[] got = IpConnectivityEventBuilder.serialize(0, Arrays.asList(input));
-            IpConnectivityLog log = new IpConnectivityLog();
-            MessageNano.mergeFrom(log, got);
+            IpConnectivityLog log = IpConnectivityLog.parseFrom(got);
             assertEquals(want, log.toString());
         } catch (Exception e) {
             fail(e.toString());
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
similarity index 90%
rename from services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
rename to tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index 3fc89b9..c7982b1 100644
--- a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -16,9 +16,13 @@
 
 package com.android.server.connectivity;
 
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
 import android.content.Context;
 import android.net.ConnectivityMetricsEvent;
 import android.net.IIpConnectivityMetrics;
+import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.ApfStats;
 import android.net.metrics.DefaultNetworkEvent;
 import android.net.metrics.DhcpClientEvent;
@@ -29,22 +33,21 @@
 import android.net.metrics.ValidationProbeEvent;
 import android.os.Parcelable;
 import android.util.Base64;
+
 import com.android.server.connectivity.metrics.IpConnectivityLogClass;
-import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
-import junit.framework.TestCase;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
 
 public class IpConnectivityMetricsTest extends TestCase {
     static final IpReachabilityEvent FAKE_EV =
@@ -57,7 +60,7 @@
 
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mService = new IpConnectivityMetrics(mCtx);
+        mService = new IpConnectivityMetrics(mCtx, (ctx) -> 2000);
     }
 
     public void testLoggingEvents() throws Exception {
@@ -112,6 +115,27 @@
         assertEquals("", output3);
     }
 
+    public void testRateLimiting() {
+        final IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
+        final ApfProgramEvent ev = new ApfProgramEvent(0, 0, 0, 0, 0);
+        final long fakeTimestamp = 1;
+
+        int attempt = 100; // More than burst quota, but less than buffer size.
+        for (int i = 0; i < attempt; i++) {
+            logger.log(ev);
+        }
+
+        String output1 = getdump("flush");
+        assertFalse("".equals(output1));
+
+        for (int i = 0; i < attempt; i++) {
+            assertFalse("expected event to be dropped", logger.log(fakeTimestamp, ev));
+        }
+
+        String output2 = getdump("flush");
+        assertEquals("", output2);
+    }
+
     public void testEndToEndLogging() {
         IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
 
@@ -204,7 +228,8 @@
                 "    router_lifetime: 2000",
                 "  >",
                 "  time_ms: 700",
-                ">");
+                ">",
+                "version: 2");
 
         verifySerialization(want, getdump("flush"));
     }
@@ -231,8 +256,7 @@
         try {
             byte[] got = Base64.decode(output, Base64.DEFAULT);
             IpConnectivityLogClass.IpConnectivityLog log =
-                    new IpConnectivityLogClass.IpConnectivityLog();
-            MessageNano.mergeFrom(log, got);
+                    IpConnectivityLogClass.IpConnectivityLog.parseFrom(got);
             assertEquals(want, log.toString());
         } catch (Exception e) {
             fail(e.toString());
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
similarity index 100%
rename from services/tests/servicestests/src/com/android/server/connectivity/LingerMonitorTest.java
rename to tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/MetricsLoggerServiceTest.java b/tests/net/java/com/android/server/connectivity/MetricsLoggerServiceTest.java
similarity index 100%
rename from services/tests/servicestests/src/com/android/server/connectivity/MetricsLoggerServiceTest.java
rename to tests/net/java/com/android/server/connectivity/MetricsLoggerServiceTest.java
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/MetricsTestUtil.java b/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java
similarity index 100%
rename from services/tests/servicestests/src/com/android/server/connectivity/MetricsTestUtil.java
rename to tests/net/java/com/android/server/connectivity/MetricsTestUtil.java
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
similarity index 100%
rename from services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java
rename to tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
new file mode 100644
index 0000000..a9f68c8
--- /dev/null
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 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.server.connectivity;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.INetworkPolicyManager;
+import android.net.INetworkStatsService;
+import android.os.INetworkManagementService;
+import android.os.PersistableBundle;
+import android.os.test.TestLooper;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.CarrierConfigManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class TetheringTest {
+    private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
+
+    @Mock private Context mContext;
+    @Mock private INetworkManagementService mNMService;
+    @Mock private INetworkStatsService mStatsService;
+    @Mock private INetworkPolicyManager mPolicyManager;
+    @Mock private MockableSystemProperties mSystemProperties;
+    @Mock private Resources mResources;
+    @Mock private CarrierConfigManager mCarrierConfigManager;
+
+    // Like so many Android system APIs, these cannot be mocked because it is marked final.
+    // We have to use the real versions.
+    private final PersistableBundle mCarrierConfig = new PersistableBundle();
+    private final TestLooper mLooper = new TestLooper();
+
+    private Tethering mTethering;
+
+    @Before public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mResources.getStringArray(com.android.internal.R.array.config_tether_dhcp_range))
+                .thenReturn(new String[0]);
+        when(mResources.getStringArray(com.android.internal.R.array.config_tether_usb_regexs))
+                .thenReturn(new String[0]);
+        when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_regexs))
+                .thenReturn(new String[0]);
+        when(mResources.getStringArray(com.android.internal.R.array.config_tether_bluetooth_regexs))
+                .thenReturn(new String[0]);
+        when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
+                .thenReturn(new int[0]);
+        mTethering = new Tethering(mContext, mNMService, mStatsService, mPolicyManager,
+                                   mLooper.getLooper(), mSystemProperties);
+    }
+
+    private void setupForRequiredProvisioning() {
+        // Produce some acceptable looking provision app setting if requested.
+        when(mResources.getStringArray(
+                com.android.internal.R.array.config_mobile_hotspot_provision_app))
+                .thenReturn(PROVISIONING_APP_NAME);
+        // Don't disable tethering provisioning unless requested.
+        when(mSystemProperties.getBoolean(eq(Tethering.DISABLE_PROVISIONING_SYSPROP_KEY),
+                                          anyBoolean())).thenReturn(false);
+        // Act like the CarrierConfigManager is present and ready unless told otherwise.
+        when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
+                .thenReturn(mCarrierConfigManager);
+        when(mCarrierConfigManager.getConfig()).thenReturn(mCarrierConfig);
+        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
+    }
+
+    @Test
+    public void canRequireProvisioning() {
+        setupForRequiredProvisioning();
+        assertTrue(mTethering.isTetherProvisioningRequired());
+    }
+
+    @Test
+    public void toleratesCarrierConfigManagerMissing() {
+        setupForRequiredProvisioning();
+        when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
+                .thenReturn(null);
+        // Couldn't get the CarrierConfigManager, but still had a declared provisioning app.
+        // We therefore still require provisioning.
+        assertTrue(mTethering.isTetherProvisioningRequired());
+    }
+
+    @Test
+    public void toleratesCarrierConfigMissing() {
+        setupForRequiredProvisioning();
+        when(mCarrierConfigManager.getConfig()).thenReturn(null);
+        // We still have a provisioning app configured, so still require provisioning.
+        assertTrue(mTethering.isTetherProvisioningRequired());
+    }
+
+    @Test
+    public void provisioningNotRequiredWhenAppNotFound() {
+        setupForRequiredProvisioning();
+        when(mResources.getStringArray(
+                com.android.internal.R.array.config_mobile_hotspot_provision_app))
+                .thenReturn(null);
+        assertTrue(!mTethering.isTetherProvisioningRequired());
+        when(mResources.getStringArray(
+                com.android.internal.R.array.config_mobile_hotspot_provision_app))
+                .thenReturn(new String[] {"malformedApp"});
+        assertTrue(!mTethering.isTetherProvisioningRequired());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
similarity index 100%
rename from services/tests/servicestests/src/com/android/server/connectivity/VpnTest.java
rename to tests/net/java/com/android/server/connectivity/VpnTest.java
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
similarity index 100%
rename from services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
rename to tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
diff --git a/services/tests/servicestests/jni/UidRangeTest.cpp b/tests/net/jni/UidRangeTest.cpp
similarity index 100%
rename from services/tests/servicestests/jni/UidRangeTest.cpp
rename to tests/net/jni/UidRangeTest.cpp
diff --git a/services/tests/servicestests/jni/UidRangeTest.h b/tests/net/jni/UidRangeTest.h
similarity index 100%
rename from services/tests/servicestests/jni/UidRangeTest.h
rename to tests/net/jni/UidRangeTest.h
diff --git a/services/tests/servicestests/jni/apf_jni.cpp b/tests/net/jni/apf_jni.cpp
similarity index 100%
rename from services/tests/servicestests/jni/apf_jni.cpp
rename to tests/net/jni/apf_jni.cpp
diff --git a/services/tests/servicestests/res/raw/apf.pcap b/tests/net/res/raw/apf.pcap
similarity index 100%
rename from services/tests/servicestests/res/raw/apf.pcap
rename to tests/net/res/raw/apf.pcap
Binary files differ
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 8424344..f737b24 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -25,6 +25,7 @@
 import junit.framework.TestCase;
 
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.view.Display.DEFAULT_DISPLAY;
 
 /**
  * TODO: Remove this. This is only a placeholder, need to implement this.
@@ -113,7 +114,8 @@
         }
 
         try {
-            mWm.updateOrientationFromAppTokens(new Configuration(), null);
+            mWm.updateOrientationFromAppTokens(new Configuration(),
+                    null /* freezeThisOneIfNeeded */, DEFAULT_DISPLAY);
             fail("IWindowManager.updateOrientationFromAppTokens did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {
diff --git a/tests/utils/testutils/Android.mk b/tests/utils/testutils/Android.mk
index 4bfd234..392d398 100644
--- a/tests/utils/testutils/Android.mk
+++ b/tests/utils/testutils/Android.mk
@@ -27,4 +27,6 @@
     android-support-test \
     mockito-target-minus-junit4
 
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java b/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java
similarity index 93%
rename from services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
rename to tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java
index 6b5be58..2166240 100644
--- a/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
+++ b/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server;
+package com.android.internal.util.test;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -25,13 +25,12 @@
 import android.os.Handler;
 import android.os.UserHandle;
 
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.AbstractFuture;
-
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
@@ -42,9 +41,15 @@
 public class BroadcastInterceptingContext extends ContextWrapper {
     private static final String TAG = "WatchingContext";
 
-    private final List<BroadcastInterceptor> mInterceptors = Lists.newArrayList();
+    private final List<BroadcastInterceptor> mInterceptors = new ArrayList<>();
 
-    abstract class FutureIntent extends AbstractFuture<Intent> {
+    public abstract class FutureIntent extends FutureTask<Intent> {
+        public FutureIntent() {
+            super(
+                () -> { throw new IllegalStateException("Cannot happen"); }
+            );
+        }
+
         public void assertNotReceived()
                 throws InterruptedException, ExecutionException {
             assertNotReceived(5, TimeUnit.SECONDS);
diff --git a/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProvider.java b/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
similarity index 98%
rename from services/tests/servicestests/src/com/android/internal/util/FakeSettingsProvider.java
rename to tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
index 808f4dd..8ca849b 100644
--- a/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProvider.java
+++ b/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.util;
+package com.android.internal.util.test;
 
 import android.net.Uri;
 import android.os.Bundle;
diff --git a/tools/aapt2/.clang-format b/tools/aapt2/.clang-format
index 71c5ef2..545366a 100644
--- a/tools/aapt2/.clang-format
+++ b/tools/aapt2/.clang-format
@@ -1,3 +1,2 @@
 BasedOnStyle: Google
-ColumnLimit: 100
 
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index 6bfedf3..197884dc 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -83,7 +83,7 @@
 
 sources += Format.proto
 
-sourcesJni :=
+sourcesJni := jni/aapt2_jni.cpp
 
 testSources := \
 	compile/IdAssigner_test.cpp \
@@ -158,7 +158,7 @@
 hostLdLibs_linux := -lz
 hostLdLibs_darwin := -lz
 
-cFlags := -Wall -Werror -Wno-unused-parameter -UNDEBUG
+cFlags := -Wall -Werror -Wno-unused-parameter
 cFlags_darwin := -D_DARWIN_UNLIMITED_STREAMS
 cFlags_windows := -Wno-maybe-uninitialized # Incorrectly marking use of Maybe.value() as error.
 cppFlags := -Wno-missing-field-initializers -fno-exceptions -fno-rtti
@@ -194,15 +194,18 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := libaapt2_jni
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-LOCAL_MODULE_HOST_OS := darwin linux windows
+LOCAL_MODULE_HOST_OS := darwin linux
 LOCAL_CFLAGS := $(cFlags)
 LOCAL_CFLAGS_darwin := $(cFlags_darwin)
 LOCAL_CFLAGS_windows := $(cFlags_windows)
 LOCAL_CPPFLAGS := $(cppFlags)
 LOCAL_C_INCLUDES := $(protoIncludes)
-LOCAL_SRC_FILES := $(sourcesJni)
-LOCAL_STATIC_LIBRARIES := libaapt2 $(hostStaticLibs)
+LOCAL_SRC_FILES := $(toolSources) $(sourcesJni)
+LOCAL_STATIC_LIBRARIES := libaapt2 libnativehelper $(hostStaticLibs)
 LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
+LOCAL_LDLIBS := $(hostLdLibs)
+LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
+LOCAL_LDLIBS_linux := $(hostLdLibs_linux)
 include $(BUILD_HOST_SHARED_LIBRARY)
 
 
diff --git a/tools/aapt2/AppInfo.h b/tools/aapt2/AppInfo.h
index 2cbe117..1e488f7 100644
--- a/tools/aapt2/AppInfo.h
+++ b/tools/aapt2/AppInfo.h
@@ -17,10 +17,10 @@
 #ifndef AAPT_APP_INFO_H
 #define AAPT_APP_INFO_H
 
-#include "util/Maybe.h"
-
 #include <string>
 
+#include "util/Maybe.h"
+
 namespace aapt {
 
 /**
@@ -36,17 +36,17 @@
   /**
    * The App's minimum SDK version.
    */
-  Maybe<std::string> minSdkVersion;
+  Maybe<std::string> min_sdk_version;
 
   /**
    * The Version code of the app.
    */
-  Maybe<uint32_t> versionCode;
+  Maybe<uint32_t> version_code;
 
   /**
    * The revision code of the app.
    */
-  Maybe<uint32_t> revisionCode;
+  Maybe<uint32_t> revision_code;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/ConfigDescription.cpp b/tools/aapt2/ConfigDescription.cpp
index 6598d63..289919a3 100644
--- a/tools/aapt2/ConfigDescription.cpp
+++ b/tools/aapt2/ConfigDescription.cpp
@@ -15,22 +15,24 @@
  */
 
 #include "ConfigDescription.h"
+
+#include <string>
+#include <vector>
+
+#include "androidfw/ResourceTypes.h"
+
 #include "Locale.h"
 #include "SdkConstants.h"
 #include "util/StringPiece.h"
 #include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
-#include <string>
-#include <vector>
-
 namespace aapt {
 
 using android::ResTable_config;
 
 static const char* kWildcardName = "any";
 
-const ConfigDescription& ConfigDescription::defaultConfig() {
+const ConfigDescription& ConfigDescription::DefaultConfig() {
   static ConfigDescription config = {};
   return config;
 }
@@ -589,169 +591,169 @@
   return true;
 }
 
-bool ConfigDescription::parse(const StringPiece& str, ConfigDescription* out) {
-  std::vector<std::string> parts = util::splitAndLowercase(str, '-');
+bool ConfigDescription::Parse(const StringPiece& str, ConfigDescription* out) {
+  std::vector<std::string> parts = util::SplitAndLowercase(str, '-');
 
   ConfigDescription config;
-  ssize_t partsConsumed = 0;
+  ssize_t parts_consumed = 0;
   LocaleValue locale;
 
-  const auto partsEnd = parts.end();
-  auto partIter = parts.begin();
+  const auto parts_end = parts.end();
+  auto part_iter = parts.begin();
 
   if (str.size() == 0) {
     goto success;
   }
 
-  if (parseMcc(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseMcc(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseMnc(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseMnc(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
   // Locale spans a few '-' separators, so we let it
   // control the index.
-  partsConsumed = locale.initFromParts(partIter, partsEnd);
-  if (partsConsumed < 0) {
+  parts_consumed = locale.InitFromParts(part_iter, parts_end);
+  if (parts_consumed < 0) {
     return false;
   } else {
-    locale.writeTo(&config);
-    partIter += partsConsumed;
-    if (partIter == partsEnd) {
+    locale.WriteTo(&config);
+    part_iter += parts_consumed;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseLayoutDirection(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseLayoutDirection(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseSmallestScreenWidthDp(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseSmallestScreenWidthDp(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseScreenWidthDp(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseScreenWidthDp(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseScreenHeightDp(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseScreenHeightDp(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseScreenLayoutSize(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseScreenLayoutSize(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseScreenLayoutLong(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseScreenLayoutLong(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseScreenRound(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseScreenRound(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseOrientation(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseOrientation(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseUiModeType(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseUiModeType(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseUiModeNight(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseUiModeNight(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseDensity(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseDensity(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseTouchscreen(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseTouchscreen(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseKeysHidden(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseKeysHidden(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseKeyboard(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseKeyboard(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseNavHidden(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseNavHidden(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseNavigation(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseNavigation(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseScreenSize(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseScreenSize(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
 
-  if (parseVersion(partIter->c_str(), &config)) {
-    ++partIter;
-    if (partIter == partsEnd) {
+  if (parseVersion(part_iter->c_str(), &config)) {
+    ++part_iter;
+    if (part_iter == parts_end) {
       goto success;
     }
   }
@@ -761,57 +763,57 @@
 
 success:
   if (out != NULL) {
-    applyVersionForCompatibility(&config);
+    ApplyVersionForCompatibility(&config);
     *out = config;
   }
   return true;
 }
 
-void ConfigDescription::applyVersionForCompatibility(
+void ConfigDescription::ApplyVersionForCompatibility(
     ConfigDescription* config) {
-  uint16_t minSdk = 0;
+  uint16_t min_sdk = 0;
   if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) {
-    minSdk = SDK_MARSHMALLOW;
+    min_sdk = SDK_MARSHMALLOW;
   } else if (config->density == ResTable_config::DENSITY_ANY) {
-    minSdk = SDK_LOLLIPOP;
+    min_sdk = SDK_LOLLIPOP;
   } else if (config->smallestScreenWidthDp !=
                  ResTable_config::SCREENWIDTH_ANY ||
              config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY ||
              config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
-    minSdk = SDK_HONEYCOMB_MR2;
+    min_sdk = SDK_HONEYCOMB_MR2;
   } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) !=
                  ResTable_config::UI_MODE_TYPE_ANY ||
              (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT) !=
                  ResTable_config::UI_MODE_NIGHT_ANY) {
-    minSdk = SDK_FROYO;
+    min_sdk = SDK_FROYO;
   } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE) !=
                  ResTable_config::SCREENSIZE_ANY ||
              (config->screenLayout & ResTable_config::MASK_SCREENLONG) !=
                  ResTable_config::SCREENLONG_ANY ||
              config->density != ResTable_config::DENSITY_DEFAULT) {
-    minSdk = SDK_DONUT;
+    min_sdk = SDK_DONUT;
   }
 
-  if (minSdk > config->sdkVersion) {
-    config->sdkVersion = minSdk;
+  if (min_sdk > config->sdkVersion) {
+    config->sdkVersion = min_sdk;
   }
 }
 
-ConfigDescription ConfigDescription::copyWithoutSdkVersion() const {
+ConfigDescription ConfigDescription::CopyWithoutSdkVersion() const {
   ConfigDescription copy = *this;
   copy.sdkVersion = 0;
   return copy;
 }
 
-bool ConfigDescription::dominates(const ConfigDescription& o) const {
-  if (*this == defaultConfig() || *this == o) {
+bool ConfigDescription::Dominates(const ConfigDescription& o) const {
+  if (*this == DefaultConfig() || *this == o) {
     return true;
   }
-  return matchWithDensity(o) && !o.matchWithDensity(*this) &&
-         !isMoreSpecificThan(o) && !o.hasHigherPrecedenceThan(*this);
+  return MatchWithDensity(o) && !o.MatchWithDensity(*this) &&
+         !isMoreSpecificThan(o) && !o.HasHigherPrecedenceThan(*this);
 }
 
-bool ConfigDescription::hasHigherPrecedenceThan(
+bool ConfigDescription::HasHigherPrecedenceThan(
     const ConfigDescription& o) const {
   // The order of the following tests defines the importance of one
   // configuration parameter over another. Those tests first are more
@@ -866,7 +868,7 @@
   return *this != o;
 }
 
-bool ConfigDescription::conflictsWith(const ConfigDescription& o) const {
+bool ConfigDescription::ConflictsWith(const ConfigDescription& o) const {
   // This method should be updated as new configuration parameters are
   // introduced (e.g. screenConfig2).
   auto pred = [](const uint32_t a, const uint32_t b) -> bool {
@@ -892,8 +894,8 @@
          !pred(keyboard, o.keyboard) || !pred(navigation, o.navigation);
 }
 
-bool ConfigDescription::isCompatibleWith(const ConfigDescription& o) const {
-  return !conflictsWith(o) && !dominates(o) && !o.dominates(*this);
+bool ConfigDescription::IsCompatibleWith(const ConfigDescription& o) const {
+  return !ConflictsWith(o) && !Dominates(o) && !o.Dominates(*this);
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/ConfigDescription.h b/tools/aapt2/ConfigDescription.h
index bb54886..97d0f38 100644
--- a/tools/aapt2/ConfigDescription.h
+++ b/tools/aapt2/ConfigDescription.h
@@ -17,11 +17,12 @@
 #ifndef AAPT_CONFIG_DESCRIPTION_H
 #define AAPT_CONFIG_DESCRIPTION_H
 
-#include "util/StringPiece.h"
-
-#include <androidfw/ResourceTypes.h>
 #include <ostream>
 
+#include "androidfw/ResourceTypes.h"
+
+#include "util/StringPiece.h"
+
 namespace aapt {
 
 /*
@@ -32,7 +33,7 @@
   /**
    * Returns an immutable default config.
    */
-  static const ConfigDescription& defaultConfig();
+  static const ConfigDescription& DefaultConfig();
 
   /*
    * Parse a string of the form 'fr-sw600dp-land' and fill in the
@@ -41,14 +42,14 @@
    * The resulting configuration has the appropriate sdkVersion defined
    * for backwards compatibility.
    */
-  static bool parse(const StringPiece& str, ConfigDescription* out = nullptr);
+  static bool Parse(const StringPiece& str, ConfigDescription* out = nullptr);
 
   /**
    * If the configuration uses an axis that was added after
    * the original Android release, make sure the SDK version
    * is set accordingly.
    */
-  static void applyVersionForCompatibility(ConfigDescription* config);
+  static void ApplyVersionForCompatibility(ConfigDescription* config);
 
   ConfigDescription();
   ConfigDescription(const android::ResTable_config& o);  // NOLINT(implicit)
@@ -59,7 +60,7 @@
   ConfigDescription& operator=(const ConfigDescription& o);
   ConfigDescription& operator=(ConfigDescription&& o);
 
-  ConfigDescription copyWithoutSdkVersion() const;
+  ConfigDescription CopyWithoutSdkVersion() const;
 
   /**
    * A configuration X dominates another configuration Y, if X has at least the
@@ -70,14 +71,14 @@
    * For example, the configuration 'en-w800dp' dominates 'en-rGB-w1024dp'. It
    * does not dominate 'fr', 'en-w720dp', or 'mcc001-en-w800dp'.
    */
-  bool dominates(const ConfigDescription& o) const;
+  bool Dominates(const ConfigDescription& o) const;
 
   /**
    * Returns true if this configuration defines a more important configuration
    * parameter than o. For example, "en" has higher precedence than "v23",
    * whereas "en" has the same precedence as "en-v23".
    */
-  bool hasHigherPrecedenceThan(const ConfigDescription& o) const;
+  bool HasHigherPrecedenceThan(const ConfigDescription& o) const;
 
   /**
    * A configuration conflicts with another configuration if both
@@ -85,7 +86,7 @@
    * incompatible configuration parameter is a non-range, non-density parameter
    * that is defined in both configurations as a different, non-default value.
    */
-  bool conflictsWith(const ConfigDescription& o) const;
+  bool ConflictsWith(const ConfigDescription& o) const;
 
   /**
    * A configuration is compatible with another configuration if both
@@ -93,9 +94,9 @@
    * unrelated by domination. For example, land-v11 conflicts with port-v21
    * but is compatible with v21 (both land-v11 and v21 would match en-land-v23).
    */
-  bool isCompatibleWith(const ConfigDescription& o) const;
+  bool IsCompatibleWith(const ConfigDescription& o) const;
 
-  bool matchWithDensity(const ConfigDescription& o) const;
+  bool MatchWithDensity(const ConfigDescription& o) const;
 
   bool operator<(const ConfigDescription& o) const;
   bool operator<=(const ConfigDescription& o) const;
@@ -141,7 +142,7 @@
   return *this;
 }
 
-inline bool ConfigDescription::matchWithDensity(
+inline bool ConfigDescription::MatchWithDensity(
     const ConfigDescription& o) const {
   return match(o) && (density == 0 || density == o.density);
 }
diff --git a/tools/aapt2/ConfigDescription_test.cpp b/tools/aapt2/ConfigDescription_test.cpp
index 66b7d47..c331dc0 100644
--- a/tools/aapt2/ConfigDescription_test.cpp
+++ b/tools/aapt2/ConfigDescription_test.cpp
@@ -15,17 +15,18 @@
  */
 
 #include "ConfigDescription.h"
+
+#include <string>
+
 #include "SdkConstants.h"
 #include "test/Test.h"
 #include "util/StringPiece.h"
 
-#include <string>
-
 namespace aapt {
 
 static ::testing::AssertionResult TestParse(
     const StringPiece& input, ConfigDescription* config = nullptr) {
-  if (ConfigDescription::parse(input, config)) {
+  if (ConfigDescription::Parse(input, config)) {
     return ::testing::AssertionSuccess() << input << " was successfully parsed";
   }
   return ::testing::AssertionFailure() << input << " could not be parsed";
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index 965db9e..60b01e3 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -15,10 +15,6 @@
  */
 
 #include "Debug.h"
-#include "ResourceTable.h"
-#include "ResourceValues.h"
-#include "ValueVisitor.h"
-#include "util/Util.h"
 
 #include <algorithm>
 #include <iostream>
@@ -28,18 +24,25 @@
 #include <set>
 #include <vector>
 
+#include "android-base/logging.h"
+
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "ValueVisitor.h"
+#include "util/Util.h"
+
 namespace aapt {
 
 class PrintVisitor : public ValueVisitor {
  public:
-  using ValueVisitor::visit;
+  using ValueVisitor::Visit;
 
-  void visit(Attribute* attr) override {
+  void Visit(Attribute* attr) override {
     std::cout << "(attr) type=";
-    attr->printMask(&std::cout);
+    attr->PrintMask(&std::cout);
     static constexpr uint32_t kMask =
         android::ResTable_map::TYPE_ENUM | android::ResTable_map::TYPE_FLAGS;
-    if (attr->typeMask & kMask) {
+    if (attr->type_mask & kMask) {
       for (const auto& symbol : attr->symbols) {
         std::cout << "\n        " << symbol.symbol.name.value().entry;
         if (symbol.symbol.id) {
@@ -50,20 +53,20 @@
     }
   }
 
-  void visit(Style* style) override {
+  void Visit(Style* style) override {
     std::cout << "(style)";
     if (style->parent) {
-      const Reference& parentRef = style->parent.value();
+      const Reference& parent_ref = style->parent.value();
       std::cout << " parent=";
-      if (parentRef.name) {
-        if (parentRef.privateReference) {
+      if (parent_ref.name) {
+        if (parent_ref.private_reference) {
           std::cout << "*";
         }
-        std::cout << parentRef.name.value() << " ";
+        std::cout << parent_ref.name.value() << " ";
       }
 
-      if (parentRef.id) {
-        std::cout << parentRef.id.value();
+      if (parent_ref.id) {
+        std::cout << parent_ref.id.value();
       }
     }
 
@@ -85,11 +88,11 @@
     }
   }
 
-  void visit(Array* array) override { array->print(&std::cout); }
+  void Visit(Array* array) override { array->Print(&std::cout); }
 
-  void visit(Plural* plural) override { plural->print(&std::cout); }
+  void Visit(Plural* plural) override { plural->Print(&std::cout); }
 
-  void visit(Styleable* styleable) override {
+  void Visit(Styleable* styleable) override {
     std::cout << "(styleable)";
     for (const auto& attr : styleable->entries) {
       std::cout << "\n        ";
@@ -107,10 +110,10 @@
     }
   }
 
-  void visitItem(Item* item) override { item->print(&std::cout); }
+  void VisitItem(Item* item) override { item->Print(&std::cout); }
 };
 
-void Debug::printTable(ResourceTable* table,
+void Debug::PrintTable(ResourceTable* table,
                        const DebugPrintTableOptions& options) {
   PrintVisitor visitor;
 
@@ -128,10 +131,10 @@
       }
       std::cout << " entryCount=" << type->entries.size() << std::endl;
 
-      std::vector<const ResourceEntry*> sortedEntries;
+      std::vector<const ResourceEntry*> sorted_entries;
       for (const auto& entry : type->entries) {
         auto iter = std::lower_bound(
-            sortedEntries.begin(), sortedEntries.end(), entry.get(),
+            sorted_entries.begin(), sorted_entries.end(), entry.get(),
             [](const ResourceEntry* a, const ResourceEntry* b) -> bool {
               if (a->id && b->id) {
                 return a->id.value() < b->id.value();
@@ -141,17 +144,17 @@
                 return false;
               }
             });
-        sortedEntries.insert(iter, entry.get());
+        sorted_entries.insert(iter, entry.get());
       }
 
-      for (const ResourceEntry* entry : sortedEntries) {
+      for (const ResourceEntry* entry : sorted_entries) {
         ResourceId id(package->id ? package->id.value() : uint8_t(0),
                       type->id ? type->id.value() : uint8_t(0),
                       entry->id ? entry->id.value() : uint16_t(0));
         ResourceName name(package->name, type->type, entry->name);
 
         std::cout << "    spec resource " << id << " " << name;
-        switch (entry->symbolStatus.state) {
+        switch (entry->symbol_status.state) {
           case SymbolState::kPublic:
             std::cout << " PUBLIC";
             break;
@@ -166,9 +169,9 @@
 
         for (const auto& value : entry->values) {
           std::cout << "      (" << value->config << ") ";
-          value->value->accept(&visitor);
-          if (options.showSources && !value->value->getSource().path.empty()) {
-            std::cout << " src=" << value->value->getSource();
+          value->value->Accept(&visitor);
+          if (options.show_sources && !value->value->GetSource().path.empty()) {
+            std::cout << " src=" << value->value->GetSource();
           }
           std::cout << std::endl;
         }
@@ -177,35 +180,36 @@
   }
 }
 
-static size_t getNodeIndex(const std::vector<ResourceName>& names,
+static size_t GetNodeIndex(const std::vector<ResourceName>& names,
                            const ResourceName& name) {
   auto iter = std::lower_bound(names.begin(), names.end(), name);
-  assert(iter != names.end() && *iter == name);
+  CHECK(iter != names.end());
+  CHECK(*iter == name);
   return std::distance(names.begin(), iter);
 }
 
-void Debug::printStyleGraph(ResourceTable* table,
-                            const ResourceName& targetStyle) {
+void Debug::PrintStyleGraph(ResourceTable* table,
+                            const ResourceName& target_style) {
   std::map<ResourceName, std::set<ResourceName>> graph;
 
-  std::queue<ResourceName> stylesToVisit;
-  stylesToVisit.push(targetStyle);
-  for (; !stylesToVisit.empty(); stylesToVisit.pop()) {
-    const ResourceName& styleName = stylesToVisit.front();
-    std::set<ResourceName>& parents = graph[styleName];
+  std::queue<ResourceName> styles_to_visit;
+  styles_to_visit.push(target_style);
+  for (; !styles_to_visit.empty(); styles_to_visit.pop()) {
+    const ResourceName& style_name = styles_to_visit.front();
+    std::set<ResourceName>& parents = graph[style_name];
     if (!parents.empty()) {
       // We've already visited this style.
       continue;
     }
 
-    Maybe<ResourceTable::SearchResult> result = table->findResource(styleName);
+    Maybe<ResourceTable::SearchResult> result = table->FindResource(style_name);
     if (result) {
       ResourceEntry* entry = result.value().entry;
       for (const auto& value : entry->values) {
-        if (Style* style = valueCast<Style>(value->value.get())) {
+        if (Style* style = ValueCast<Style>(value->value.get())) {
           if (style->parent && style->parent.value().name) {
             parents.insert(style->parent.value().name.value());
-            stylesToVisit.push(style->parent.value().name.value());
+            styles_to_visit.push(style->parent.value().name.value());
           }
         }
       }
@@ -219,24 +223,24 @@
 
   std::cout << "digraph styles {\n";
   for (const auto& name : names) {
-    std::cout << "  node_" << getNodeIndex(names, name) << " [label=\"" << name
+    std::cout << "  node_" << GetNodeIndex(names, name) << " [label=\"" << name
               << "\"];\n";
   }
 
   for (const auto& entry : graph) {
-    const ResourceName& styleName = entry.first;
-    size_t styleNodeIndex = getNodeIndex(names, styleName);
+    const ResourceName& style_name = entry.first;
+    size_t style_node_index = GetNodeIndex(names, style_name);
 
-    for (const auto& parentName : entry.second) {
-      std::cout << "  node_" << styleNodeIndex << " -> "
-                << "node_" << getNodeIndex(names, parentName) << ";\n";
+    for (const auto& parent_name : entry.second) {
+      std::cout << "  node_" << style_node_index << " -> "
+                << "node_" << GetNodeIndex(names, parent_name) << ";\n";
     }
   }
 
   std::cout << "}" << std::endl;
 }
 
-void Debug::dumpHex(const void* data, size_t len) {
+void Debug::DumpHex(const void* data, size_t len) {
   const uint8_t* d = (const uint8_t*)data;
   for (size_t i = 0; i < len; i++) {
     std::cerr << std::hex << std::setfill('0') << std::setw(2) << (uint32_t)d[i]
@@ -255,55 +259,55 @@
 
 class XmlPrinter : public xml::Visitor {
  public:
-  using xml::Visitor::visit;
+  using xml::Visitor::Visit;
 
-  void visit(xml::Element* el) override {
-    std::cerr << mPrefix;
+  void Visit(xml::Element* el) override {
+    std::cerr << prefix_;
     std::cerr << "E: ";
-    if (!el->namespaceUri.empty()) {
-      std::cerr << el->namespaceUri << ":";
+    if (!el->namespace_uri.empty()) {
+      std::cerr << el->namespace_uri << ":";
     }
-    std::cerr << el->name << " (line=" << el->lineNumber << ")\n";
+    std::cerr << el->name << " (line=" << el->line_number << ")\n";
 
     for (const xml::Attribute& attr : el->attributes) {
-      std::cerr << mPrefix << "  A: ";
-      if (!attr.namespaceUri.empty()) {
-        std::cerr << attr.namespaceUri << ":";
+      std::cerr << prefix_ << "  A: ";
+      if (!attr.namespace_uri.empty()) {
+        std::cerr << attr.namespace_uri << ":";
       }
       std::cerr << attr.name << "=" << attr.value << "\n";
     }
 
-    const size_t previousSize = mPrefix.size();
-    mPrefix += "  ";
-    xml::Visitor::visit(el);
-    mPrefix.resize(previousSize);
+    const size_t previous_size = prefix_.size();
+    prefix_ += "  ";
+    xml::Visitor::Visit(el);
+    prefix_.resize(previous_size);
   }
 
-  void visit(xml::Namespace* ns) override {
-    std::cerr << mPrefix;
-    std::cerr << "N: " << ns->namespacePrefix << "=" << ns->namespaceUri
-              << " (line=" << ns->lineNumber << ")\n";
+  void Visit(xml::Namespace* ns) override {
+    std::cerr << prefix_;
+    std::cerr << "N: " << ns->namespace_prefix << "=" << ns->namespace_uri
+              << " (line=" << ns->line_number << ")\n";
 
-    const size_t previousSize = mPrefix.size();
-    mPrefix += "  ";
-    xml::Visitor::visit(ns);
-    mPrefix.resize(previousSize);
+    const size_t previous_size = prefix_.size();
+    prefix_ += "  ";
+    xml::Visitor::Visit(ns);
+    prefix_.resize(previous_size);
   }
 
-  void visit(xml::Text* text) override {
-    std::cerr << mPrefix;
+  void Visit(xml::Text* text) override {
+    std::cerr << prefix_;
     std::cerr << "T: '" << text->text << "'\n";
   }
 
  private:
-  std::string mPrefix;
+  std::string prefix_;
 };
 
 }  // namespace
 
-void Debug::dumpXml(xml::XmlResource* doc) {
+void Debug::DumpXml(xml::XmlResource* doc) {
   XmlPrinter printer;
-  doc->root->accept(&printer);
+  doc->root->Accept(&printer);
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/Debug.h b/tools/aapt2/Debug.h
index bd92ec1..56e2e95 100644
--- a/tools/aapt2/Debug.h
+++ b/tools/aapt2/Debug.h
@@ -17,26 +17,26 @@
 #ifndef AAPT_DEBUG_H
 #define AAPT_DEBUG_H
 
+// Include for printf-like debugging.
+#include <iostream>
+
 #include "Resource.h"
 #include "ResourceTable.h"
 #include "xml/XmlDom.h"
 
-// Include for printf-like debugging.
-#include <iostream>
-
 namespace aapt {
 
 struct DebugPrintTableOptions {
-  bool showSources = false;
+  bool show_sources = false;
 };
 
 struct Debug {
-  static void printTable(ResourceTable* table,
+  static void PrintTable(ResourceTable* table,
                          const DebugPrintTableOptions& options = {});
-  static void printStyleGraph(ResourceTable* table,
-                              const ResourceName& targetStyle);
-  static void dumpHex(const void* data, size_t len);
-  static void dumpXml(xml::XmlResource* doc);
+  static void PrintStyleGraph(ResourceTable* table,
+                              const ResourceName& target_style);
+  static void DumpHex(const void* data, size_t len);
+  static void DumpXml(xml::XmlResource* doc);
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/Diagnostics.h b/tools/aapt2/Diagnostics.h
index d39cf4c..5bc86a9 100644
--- a/tools/aapt2/Diagnostics.h
+++ b/tools/aapt2/Diagnostics.h
@@ -17,15 +17,16 @@
 #ifndef AAPT_DIAGNOSTICS_H
 #define AAPT_DIAGNOSTICS_H
 
-#include "Source.h"
-#include "util/StringPiece.h"
-#include "util/Util.h"
-
-#include <android-base/macros.h>
 #include <iostream>
 #include <sstream>
 #include <string>
 
+#include "android-base/macros.h"
+
+#include "Source.h"
+#include "util/StringPiece.h"
+#include "util/Util.h"
+
 namespace aapt {
 
 struct DiagMessageActual {
@@ -34,28 +35,28 @@
 };
 
 struct DiagMessage {
- private:
-  Source mSource;
-  std::stringstream mMessage;
-
  public:
   DiagMessage() = default;
 
-  explicit DiagMessage(const StringPiece& src) : mSource(src) {}
+  explicit DiagMessage(const StringPiece& src) : source_(src) {}
 
-  explicit DiagMessage(const Source& src) : mSource(src) {}
+  explicit DiagMessage(const Source& src) : source_(src) {}
 
-  explicit DiagMessage(size_t line) : mSource(Source().withLine(line)) {}
+  explicit DiagMessage(size_t line) : source_(Source().WithLine(line)) {}
 
   template <typename T>
   DiagMessage& operator<<(const T& value) {
-    mMessage << value;
+    message_ << value;
     return *this;
   }
 
-  DiagMessageActual build() const {
-    return DiagMessageActual{mSource, mMessage.str()};
+  DiagMessageActual Build() const {
+    return DiagMessageActual{source_, message_.str()};
   }
+
+ private:
+  Source source_;
+  std::stringstream message_;
 };
 
 struct IDiagnostics {
@@ -63,21 +64,21 @@
 
   enum class Level { Note, Warn, Error };
 
-  virtual void log(Level level, DiagMessageActual& actualMsg) = 0;
+  virtual void Log(Level level, DiagMessageActual& actualMsg) = 0;
 
-  virtual void error(const DiagMessage& message) {
-    DiagMessageActual actual = message.build();
-    log(Level::Error, actual);
+  virtual void Error(const DiagMessage& message) {
+    DiagMessageActual actual = message.Build();
+    Log(Level::Error, actual);
   }
 
-  virtual void warn(const DiagMessage& message) {
-    DiagMessageActual actual = message.build();
-    log(Level::Warn, actual);
+  virtual void Warn(const DiagMessage& message) {
+    DiagMessageActual actual = message.Build();
+    Log(Level::Warn, actual);
   }
 
-  virtual void note(const DiagMessage& message) {
-    DiagMessageActual actual = message.build();
-    log(Level::Note, actual);
+  virtual void Note(const DiagMessage& message) {
+    DiagMessageActual actual = message.Build();
+    Log(Level::Note, actual);
   }
 };
 
@@ -85,13 +86,13 @@
  public:
   StdErrDiagnostics() = default;
 
-  void log(Level level, DiagMessageActual& actualMsg) override {
+  void Log(Level level, DiagMessageActual& actual_msg) override {
     const char* tag;
 
     switch (level) {
       case Level::Error:
-        mNumErrors++;
-        if (mNumErrors > 20) {
+        num_errors_++;
+        if (num_errors_ > 20) {
           return;
         }
         tag = "error";
@@ -106,14 +107,14 @@
         break;
     }
 
-    if (!actualMsg.source.path.empty()) {
-      std::cerr << actualMsg.source << ": ";
+    if (!actual_msg.source.path.empty()) {
+      std::cerr << actual_msg.source << ": ";
     }
-    std::cerr << tag << ": " << actualMsg.message << "." << std::endl;
+    std::cerr << tag << ": " << actual_msg.message << "." << std::endl;
   }
 
  private:
-  size_t mNumErrors = 0;
+  size_t num_errors_ = 0;
 
   DISALLOW_COPY_AND_ASSIGN(StdErrDiagnostics);
 };
@@ -121,16 +122,16 @@
 class SourcePathDiagnostics : public IDiagnostics {
  public:
   SourcePathDiagnostics(const Source& src, IDiagnostics* diag)
-      : mSource(src), mDiag(diag) {}
+      : source_(src), diag_(diag) {}
 
-  void log(Level level, DiagMessageActual& actualMsg) override {
-    actualMsg.source.path = mSource.path;
-    mDiag->log(level, actualMsg);
+  void Log(Level level, DiagMessageActual& actual_msg) override {
+    actual_msg.source.path = source_.path;
+    diag_->Log(level, actual_msg);
   }
 
  private:
-  Source mSource;
-  IDiagnostics* mDiag;
+  Source source_;
+  IDiagnostics* diag_;
 
   DISALLOW_COPY_AND_ASSIGN(SourcePathDiagnostics);
 };
diff --git a/tools/aapt2/DominatorTree.cpp b/tools/aapt2/DominatorTree.cpp
index 8f6f783..118a385 100644
--- a/tools/aapt2/DominatorTree.cpp
+++ b/tools/aapt2/DominatorTree.cpp
@@ -15,77 +15,80 @@
  */
 
 #include "DominatorTree.h"
-#include "ConfigDescription.h"
 
 #include <algorithm>
 
+#include "android-base/logging.h"
+
+#include "ConfigDescription.h"
+
 namespace aapt {
 
 DominatorTree::DominatorTree(
     const std::vector<std::unique_ptr<ResourceConfigValue>>& configs) {
   for (const auto& config : configs) {
-    mProductRoots[config->product].tryAddChild(
+    product_roots_[config->product].TryAddChild(
         util::make_unique<Node>(config.get(), nullptr));
   }
 }
 
-void DominatorTree::accept(Visitor* visitor) {
-  for (auto& entry : mProductRoots) {
-    visitor->visitTree(entry.first, &entry.second);
+void DominatorTree::Accept(Visitor* visitor) {
+  for (auto& entry : product_roots_) {
+    visitor->VisitTree(entry.first, &entry.second);
   }
 }
 
-bool DominatorTree::Node::tryAddChild(std::unique_ptr<Node> newChild) {
-  assert(newChild->mValue && "cannot add a root or empty node as a child");
-  if (mValue && !dominates(newChild.get())) {
+bool DominatorTree::Node::TryAddChild(std::unique_ptr<Node> new_child) {
+  CHECK(new_child->value_) << "cannot add a root or empty node as a child";
+  if (value_ && !Dominates(new_child.get())) {
     // This is not the root and the child dominates us.
     return false;
   }
-  return addChild(std::move(newChild));
+  return AddChild(std::move(new_child));
 }
 
-bool DominatorTree::Node::addChild(std::unique_ptr<Node> newChild) {
-  bool hasDominatedChildren = false;
+bool DominatorTree::Node::AddChild(std::unique_ptr<Node> new_child) {
+  bool has_dominated_children = false;
   // Demote children dominated by the new config.
-  for (auto& child : mChildren) {
-    if (newChild->dominates(child.get())) {
-      child->mParent = newChild.get();
-      newChild->mChildren.push_back(std::move(child));
+  for (auto& child : children_) {
+    if (new_child->Dominates(child.get())) {
+      child->parent_ = new_child.get();
+      new_child->children_.push_back(std::move(child));
       child = {};
-      hasDominatedChildren = true;
+      has_dominated_children = true;
     }
   }
   // Remove dominated children.
-  if (hasDominatedChildren) {
-    mChildren.erase(
-        std::remove_if(mChildren.begin(), mChildren.end(),
+  if (has_dominated_children) {
+    children_.erase(
+        std::remove_if(children_.begin(), children_.end(),
                        [](const std::unique_ptr<Node>& child) -> bool {
                          return child == nullptr;
                        }),
-        mChildren.end());
+        children_.end());
   }
   // Add the new config to a child if a child dominates the new config.
-  for (auto& child : mChildren) {
-    if (child->dominates(newChild.get())) {
-      child->addChild(std::move(newChild));
+  for (auto& child : children_) {
+    if (child->Dominates(new_child.get())) {
+      child->AddChild(std::move(new_child));
       return true;
     }
   }
   // The new config is not dominated by a child, so add it here.
-  newChild->mParent = this;
-  mChildren.push_back(std::move(newChild));
+  new_child->parent_ = this;
+  children_.push_back(std::move(new_child));
   return true;
 }
 
-bool DominatorTree::Node::dominates(const Node* other) const {
+bool DominatorTree::Node::Dominates(const Node* other) const {
   // Check root node dominations.
-  if (other->isRootNode()) {
-    return isRootNode();
-  } else if (isRootNode()) {
+  if (other->is_root_node()) {
+    return is_root_node();
+  } else if (is_root_node()) {
     return true;
   }
   // Neither node is a root node; compare the configurations.
-  return mValue->config.dominates(other->mValue->config);
+  return value_->config.Dominates(other->value_->config);
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/DominatorTree.h b/tools/aapt2/DominatorTree.h
index 6d45b5d..7d50935 100644
--- a/tools/aapt2/DominatorTree.h
+++ b/tools/aapt2/DominatorTree.h
@@ -17,13 +17,13 @@
 #ifndef AAPT_DOMINATOR_TREE_H
 #define AAPT_DOMINATOR_TREE_H
 
-#include "ResourceTable.h"
-
 #include <map>
 #include <memory>
 #include <string>
 #include <vector>
 
+#include "ResourceTable.h"
+
 namespace aapt {
 
 /**
@@ -53,67 +53,67 @@
   class Node {
    public:
     explicit Node(ResourceConfigValue* value = nullptr, Node* parent = nullptr)
-        : mValue(value), mParent(parent) {}
+        : value_(value), parent_(parent) {}
 
-    inline ResourceConfigValue* value() const { return mValue; }
+    inline ResourceConfigValue* value() const { return value_; }
 
-    inline Node* parent() const { return mParent; }
+    inline Node* parent() const { return parent_; }
 
-    inline bool isRootNode() const { return !mValue; }
+    inline bool is_root_node() const { return !value_; }
 
     inline const std::vector<std::unique_ptr<Node>>& children() const {
-      return mChildren;
+      return children_;
     }
 
-    bool tryAddChild(std::unique_ptr<Node> newChild);
+    bool TryAddChild(std::unique_ptr<Node> new_child);
 
    private:
-    bool addChild(std::unique_ptr<Node> newChild);
-    bool dominates(const Node* other) const;
+    bool AddChild(std::unique_ptr<Node> new_child);
+    bool Dominates(const Node* other) const;
 
-    ResourceConfigValue* mValue;
-    Node* mParent;
-    std::vector<std::unique_ptr<Node>> mChildren;
+    ResourceConfigValue* value_;
+    Node* parent_;
+    std::vector<std::unique_ptr<Node>> children_;
 
     DISALLOW_COPY_AND_ASSIGN(Node);
   };
 
   struct Visitor {
     virtual ~Visitor() = default;
-    virtual void visitTree(const std::string& product, Node* root) = 0;
+    virtual void VisitTree(const std::string& product, Node* root) = 0;
   };
 
   class BottomUpVisitor : public Visitor {
    public:
     virtual ~BottomUpVisitor() = default;
 
-    void visitTree(const std::string& product, Node* root) override {
+    void VisitTree(const std::string& product, Node* root) override {
       for (auto& child : root->children()) {
-        visitNode(child.get());
+        VisitNode(child.get());
       }
     }
 
-    virtual void visitConfig(Node* node) = 0;
+    virtual void VisitConfig(Node* node) = 0;
 
    private:
-    void visitNode(Node* node) {
+    void VisitNode(Node* node) {
       for (auto& child : node->children()) {
-        visitNode(child.get());
+        VisitNode(child.get());
       }
-      visitConfig(node);
+      VisitConfig(node);
     }
   };
 
-  void accept(Visitor* visitor);
+  void Accept(Visitor* visitor);
 
-  inline const std::map<std::string, Node>& getProductRoots() const {
-    return mProductRoots;
+  inline const std::map<std::string, Node>& product_roots() const {
+    return product_roots_;
   }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(DominatorTree);
 
-  std::map<std::string, Node> mProductRoots;
+  std::map<std::string, Node> product_roots_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/DominatorTree_test.cpp b/tools/aapt2/DominatorTree_test.cpp
index a42d2f7..e89c6be 100644
--- a/tools/aapt2/DominatorTree_test.cpp
+++ b/tools/aapt2/DominatorTree_test.cpp
@@ -15,67 +15,68 @@
  */
 
 #include "DominatorTree.h"
-#include "test/Test.h"
-#include "util/Util.h"
 
 #include <sstream>
 #include <string>
 #include <vector>
 
+#include "test/Test.h"
+#include "util/Util.h"
+
 namespace aapt {
 
 namespace {
 
 class PrettyPrinter : public DominatorTree::Visitor {
  public:
-  explicit PrettyPrinter(const int indent = 2) : mIndent(indent) {}
+  explicit PrettyPrinter(const int indent = 2) : indent_(indent) {}
 
-  void visitTree(const std::string& product,
+  void VisitTree(const std::string& product,
                  DominatorTree::Node* root) override {
     for (auto& child : root->children()) {
-      visitNode(child.get(), 0);
+      VisitNode(child.get(), 0);
     }
   }
 
-  std::string toString(DominatorTree* tree) {
-    mBuffer.str("");
-    mBuffer.clear();
-    tree->accept(this);
-    return mBuffer.str();
+  std::string ToString(DominatorTree* tree) {
+    buffer_.str("");
+    buffer_.clear();
+    tree->Accept(this);
+    return buffer_.str();
   }
 
  private:
-  void visitConfig(const DominatorTree::Node* node, const int indent) {
-    auto configString = node->value()->config.toString();
-    mBuffer << std::string(indent, ' ')
-            << (configString.isEmpty() ? "<default>" : configString)
+  void VisitConfig(const DominatorTree::Node* node, const int indent) {
+    auto config_string = node->value()->config.toString();
+    buffer_ << std::string(indent, ' ')
+            << (config_string.isEmpty() ? "<default>" : config_string)
             << std::endl;
   }
 
-  void visitNode(const DominatorTree::Node* node, const int indent) {
-    visitConfig(node, indent);
+  void VisitNode(const DominatorTree::Node* node, const int indent) {
+    VisitConfig(node, indent);
     for (const auto& child : node->children()) {
-      visitNode(child.get(), indent + mIndent);
+      VisitNode(child.get(), indent + indent_);
     }
   }
 
-  std::stringstream mBuffer;
-  const int mIndent = 2;
+  std::stringstream buffer_;
+  const int indent_ = 2;
 };
 
 }  // namespace
 
 TEST(DominatorTreeTest, DefaultDominatesEverything) {
-  const ConfigDescription defaultConfig = {};
-  const ConfigDescription landConfig = test::parseConfigOrDie("land");
-  const ConfigDescription sw600dpLandConfig =
-      test::parseConfigOrDie("sw600dp-land-v13");
+  const ConfigDescription default_config = {};
+  const ConfigDescription land_config = test::ParseConfigOrDie("land");
+  const ConfigDescription sw600dp_land_config =
+      test::ParseConfigOrDie("sw600dp-land-v13");
 
   std::vector<std::unique_ptr<ResourceConfigValue>> configs;
-  configs.push_back(util::make_unique<ResourceConfigValue>(defaultConfig, ""));
-  configs.push_back(util::make_unique<ResourceConfigValue>(landConfig, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
   configs.push_back(
-      util::make_unique<ResourceConfigValue>(sw600dpLandConfig, ""));
+      util::make_unique<ResourceConfigValue>(sw600dp_land_config, ""));
 
   DominatorTree tree(configs);
   PrettyPrinter printer;
@@ -84,22 +85,22 @@
       "<default>\n"
       "  land\n"
       "  sw600dp-land-v13\n";
-  EXPECT_EQ(expected, printer.toString(&tree));
+  EXPECT_EQ(expected, printer.ToString(&tree));
 }
 
 TEST(DominatorTreeTest, ProductsAreDominatedSeparately) {
-  const ConfigDescription defaultConfig = {};
-  const ConfigDescription landConfig = test::parseConfigOrDie("land");
-  const ConfigDescription sw600dpLandConfig =
-      test::parseConfigOrDie("sw600dp-land-v13");
+  const ConfigDescription default_config = {};
+  const ConfigDescription land_config = test::ParseConfigOrDie("land");
+  const ConfigDescription sw600dp_land_config =
+      test::ParseConfigOrDie("sw600dp-land-v13");
 
   std::vector<std::unique_ptr<ResourceConfigValue>> configs;
-  configs.push_back(util::make_unique<ResourceConfigValue>(defaultConfig, ""));
-  configs.push_back(util::make_unique<ResourceConfigValue>(landConfig, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
   configs.push_back(
-      util::make_unique<ResourceConfigValue>(defaultConfig, "phablet"));
+      util::make_unique<ResourceConfigValue>(default_config, "phablet"));
   configs.push_back(
-      util::make_unique<ResourceConfigValue>(sw600dpLandConfig, "phablet"));
+      util::make_unique<ResourceConfigValue>(sw600dp_land_config, "phablet"));
 
   DominatorTree tree(configs);
   PrettyPrinter printer;
@@ -109,34 +110,38 @@
       "  land\n"
       "<default>\n"
       "  sw600dp-land-v13\n";
-  EXPECT_EQ(expected, printer.toString(&tree));
+  EXPECT_EQ(expected, printer.ToString(&tree));
 }
 
 TEST(DominatorTreeTest, MoreSpecificConfigurationsAreDominated) {
-  const ConfigDescription defaultConfig = {};
-  const ConfigDescription enConfig = test::parseConfigOrDie("en");
-  const ConfigDescription enV21Config = test::parseConfigOrDie("en-v21");
-  const ConfigDescription ldrtlConfig = test::parseConfigOrDie("ldrtl-v4");
-  const ConfigDescription ldrtlXhdpiConfig =
-      test::parseConfigOrDie("ldrtl-xhdpi-v4");
-  const ConfigDescription sw300dpConfig = test::parseConfigOrDie("sw300dp-v13");
-  const ConfigDescription sw540dpConfig = test::parseConfigOrDie("sw540dp-v14");
-  const ConfigDescription sw600dpConfig = test::parseConfigOrDie("sw600dp-v14");
-  const ConfigDescription sw720dpConfig = test::parseConfigOrDie("sw720dp-v13");
-  const ConfigDescription v20Config = test::parseConfigOrDie("v20");
+  const ConfigDescription default_config = {};
+  const ConfigDescription en_config = test::ParseConfigOrDie("en");
+  const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
+  const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl-v4");
+  const ConfigDescription ldrtl_xhdpi_config =
+      test::ParseConfigOrDie("ldrtl-xhdpi-v4");
+  const ConfigDescription sw300dp_config =
+      test::ParseConfigOrDie("sw300dp-v13");
+  const ConfigDescription sw540dp_config =
+      test::ParseConfigOrDie("sw540dp-v14");
+  const ConfigDescription sw600dp_config =
+      test::ParseConfigOrDie("sw600dp-v14");
+  const ConfigDescription sw720dp_config =
+      test::ParseConfigOrDie("sw720dp-v13");
+  const ConfigDescription v20_config = test::ParseConfigOrDie("v20");
 
   std::vector<std::unique_ptr<ResourceConfigValue>> configs;
-  configs.push_back(util::make_unique<ResourceConfigValue>(defaultConfig, ""));
-  configs.push_back(util::make_unique<ResourceConfigValue>(enConfig, ""));
-  configs.push_back(util::make_unique<ResourceConfigValue>(enV21Config, ""));
-  configs.push_back(util::make_unique<ResourceConfigValue>(ldrtlConfig, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(en_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(en_v21_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_config, ""));
   configs.push_back(
-      util::make_unique<ResourceConfigValue>(ldrtlXhdpiConfig, ""));
-  configs.push_back(util::make_unique<ResourceConfigValue>(sw300dpConfig, ""));
-  configs.push_back(util::make_unique<ResourceConfigValue>(sw540dpConfig, ""));
-  configs.push_back(util::make_unique<ResourceConfigValue>(sw600dpConfig, ""));
-  configs.push_back(util::make_unique<ResourceConfigValue>(sw720dpConfig, ""));
-  configs.push_back(util::make_unique<ResourceConfigValue>(v20Config, ""));
+      util::make_unique<ResourceConfigValue>(ldrtl_xhdpi_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(sw300dp_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(sw540dp_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(sw720dp_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(v20_config, ""));
 
   DominatorTree tree(configs);
   PrettyPrinter printer;
@@ -152,7 +157,7 @@
       "      sw600dp-v14\n"
       "    sw720dp-v13\n"
       "  v20\n";
-  EXPECT_EQ(expected, printer.toString(&tree));
+  EXPECT_EQ(expected, printer.ToString(&tree));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/Flags.cpp b/tools/aapt2/Flags.cpp
index cb16196..c98cd37 100644
--- a/tools/aapt2/Flags.cpp
+++ b/tools/aapt2/Flags.cpp
@@ -15,97 +15,98 @@
  */
 
 #include "Flags.h"
-#include "util/StringPiece.h"
-#include "util/Util.h"
 
 #include <iomanip>
 #include <iostream>
 #include <string>
 #include <vector>
 
+#include "util/StringPiece.h"
+#include "util/Util.h"
+
 namespace aapt {
 
-Flags& Flags::requiredFlag(const StringPiece& name,
+Flags& Flags::RequiredFlag(const StringPiece& name,
                            const StringPiece& description, std::string* value) {
   auto func = [value](const StringPiece& arg) -> bool {
-    *value = arg.toString();
+    *value = arg.ToString();
     return true;
   };
 
-  mFlags.push_back(
-      Flag{name.toString(), description.toString(), func, true, 1, false});
+  flags_.push_back(
+      Flag{name.ToString(), description.ToString(), func, true, 1, false});
   return *this;
 }
 
-Flags& Flags::requiredFlagList(const StringPiece& name,
+Flags& Flags::RequiredFlagList(const StringPiece& name,
                                const StringPiece& description,
                                std::vector<std::string>* value) {
   auto func = [value](const StringPiece& arg) -> bool {
-    value->push_back(arg.toString());
+    value->push_back(arg.ToString());
     return true;
   };
 
-  mFlags.push_back(
-      Flag{name.toString(), description.toString(), func, true, 1, false});
+  flags_.push_back(
+      Flag{name.ToString(), description.ToString(), func, true, 1, false});
   return *this;
 }
 
-Flags& Flags::optionalFlag(const StringPiece& name,
+Flags& Flags::OptionalFlag(const StringPiece& name,
                            const StringPiece& description,
                            Maybe<std::string>* value) {
   auto func = [value](const StringPiece& arg) -> bool {
-    *value = arg.toString();
+    *value = arg.ToString();
     return true;
   };
 
-  mFlags.push_back(
-      Flag{name.toString(), description.toString(), func, false, 1, false});
+  flags_.push_back(
+      Flag{name.ToString(), description.ToString(), func, false, 1, false});
   return *this;
 }
 
-Flags& Flags::optionalFlagList(const StringPiece& name,
+Flags& Flags::OptionalFlagList(const StringPiece& name,
                                const StringPiece& description,
                                std::vector<std::string>* value) {
   auto func = [value](const StringPiece& arg) -> bool {
-    value->push_back(arg.toString());
+    value->push_back(arg.ToString());
     return true;
   };
 
-  mFlags.push_back(
-      Flag{name.toString(), description.toString(), func, false, 1, false});
+  flags_.push_back(
+      Flag{name.ToString(), description.ToString(), func, false, 1, false});
   return *this;
 }
 
-Flags& Flags::optionalFlagList(const StringPiece& name,
+Flags& Flags::OptionalFlagList(const StringPiece& name,
                                const StringPiece& description,
                                std::unordered_set<std::string>* value) {
   auto func = [value](const StringPiece& arg) -> bool {
-    value->insert(arg.toString());
+    value->insert(arg.ToString());
     return true;
   };
 
-  mFlags.push_back(
-      Flag{name.toString(), description.toString(), func, false, 1, false});
+  flags_.push_back(
+      Flag{name.ToString(), description.ToString(), func, false, 1, false});
   return *this;
 }
 
-Flags& Flags::optionalSwitch(const StringPiece& name,
+Flags& Flags::OptionalSwitch(const StringPiece& name,
                              const StringPiece& description, bool* value) {
   auto func = [value](const StringPiece& arg) -> bool {
     *value = true;
     return true;
   };
 
-  mFlags.push_back(
-      Flag{name.toString(), description.toString(), func, false, 0, false});
+  flags_.push_back(
+      Flag{name.ToString(), description.ToString(), func, false, 0, false});
   return *this;
 }
 
-void Flags::usage(const StringPiece& command, std::ostream* out) {
+void Flags::Usage(const StringPiece& command, std::ostream* out) {
   constexpr size_t kWidth = 50;
 
   *out << command << " [options]";
-  for (const Flag& flag : mFlags) {
+  for (const Flag& flag : flags_) {
     if (flag.required) {
       *out << " " << flag.name << " arg";
     }
@@ -113,10 +114,10 @@
 
   *out << " files...\n\nOptions:\n";
 
-  for (const Flag& flag : mFlags) {
-    std::string argLine = flag.name;
-    if (flag.numArgs > 0) {
-      argLine += " arg";
+  for (const Flag& flag : flags_) {
+    std::string argline = flag.name;
+    if (flag.num_args > 0) {
+      argline += " arg";
     }
 
     // Split the description by newlines and write out the argument (which is
@@ -124,9 +125,9 @@
     // the first line) followed by the description line. This will make sure
     // that multiline
     // descriptions are still right justified and aligned.
-    for (StringPiece line : util::tokenize(flag.description, '\n')) {
-      *out << " " << std::setw(kWidth) << std::left << argLine << line << "\n";
-      argLine = " ";
+    for (StringPiece line : util::Tokenize(flag.description, '\n')) {
+      *out << " " << std::setw(kWidth) << std::left << argline << line << "\n";
+      argline = " ";
     }
   }
   *out << " " << std::setw(kWidth) << std::left << "-h"
@@ -134,29 +135,29 @@
   out->flush();
 }
 
-bool Flags::parse(const StringPiece& command,
+bool Flags::Parse(const StringPiece& command,
                   const std::vector<StringPiece>& args,
-                  std::ostream* outError) {
+                  std::ostream* out_error) {
   for (size_t i = 0; i < args.size(); i++) {
     StringPiece arg = args[i];
     if (*(arg.data()) != '-') {
-      mArgs.push_back(arg.toString());
+      args_.push_back(arg.ToString());
       continue;
     }
 
     if (arg == "-h" || arg == "--help") {
-      usage(command, outError);
+      Usage(command, out_error);
       return false;
     }
 
     bool match = false;
-    for (Flag& flag : mFlags) {
+    for (Flag& flag : flags_) {
       if (arg == flag.name) {
-        if (flag.numArgs > 0) {
+        if (flag.num_args > 0) {
           i++;
           if (i >= args.size()) {
-            *outError << flag.name << " missing argument.\n\n";
-            usage(command, outError);
+            *out_error << flag.name << " missing argument.\n\n";
+            Usage(command, out_error);
             return false;
           }
           flag.action(args[i]);
@@ -170,22 +171,22 @@
     }
 
     if (!match) {
-      *outError << "unknown option '" << arg << "'.\n\n";
-      usage(command, outError);
+      *out_error << "unknown option '" << arg << "'.\n\n";
+      Usage(command, out_error);
       return false;
     }
   }
 
-  for (const Flag& flag : mFlags) {
+  for (const Flag& flag : flags_) {
     if (flag.required && !flag.parsed) {
-      *outError << "missing required flag " << flag.name << "\n\n";
-      usage(command, outError);
+      *out_error << "missing required flag " << flag.name << "\n\n";
+      Usage(command, out_error);
       return false;
     }
   }
   return true;
 }
 
-const std::vector<std::string>& Flags::getArgs() { return mArgs; }
+const std::vector<std::string>& Flags::GetArgs() { return args_; }
 
 }  // namespace aapt
diff --git a/tools/aapt2/Flags.h b/tools/aapt2/Flags.h
index 4a0efdb..9feff6b 100644
--- a/tools/aapt2/Flags.h
+++ b/tools/aapt2/Flags.h
@@ -17,41 +17,41 @@
 #ifndef AAPT_FLAGS_H
 #define AAPT_FLAGS_H
 
-#include "util/Maybe.h"
-#include "util/StringPiece.h"
-
 #include <functional>
 #include <ostream>
 #include <string>
 #include <unordered_set>
 #include <vector>
 
+#include "util/Maybe.h"
+#include "util/StringPiece.h"
+
 namespace aapt {
 
 class Flags {
  public:
-  Flags& requiredFlag(const StringPiece& name, const StringPiece& description,
+  Flags& RequiredFlag(const StringPiece& name, const StringPiece& description,
                       std::string* value);
-  Flags& requiredFlagList(const StringPiece& name,
+  Flags& RequiredFlagList(const StringPiece& name,
                           const StringPiece& description,
                           std::vector<std::string>* value);
-  Flags& optionalFlag(const StringPiece& name, const StringPiece& description,
+  Flags& OptionalFlag(const StringPiece& name, const StringPiece& description,
                       Maybe<std::string>* value);
-  Flags& optionalFlagList(const StringPiece& name,
+  Flags& OptionalFlagList(const StringPiece& name,
                           const StringPiece& description,
                           std::vector<std::string>* value);
-  Flags& optionalFlagList(const StringPiece& name,
+  Flags& OptionalFlagList(const StringPiece& name,
                           const StringPiece& description,
                           std::unordered_set<std::string>* value);
-  Flags& optionalSwitch(const StringPiece& name, const StringPiece& description,
+  Flags& OptionalSwitch(const StringPiece& name, const StringPiece& description,
                         bool* value);
 
-  void usage(const StringPiece& command, std::ostream* out);
+  void Usage(const StringPiece& command, std::ostream* out);
 
-  bool parse(const StringPiece& command, const std::vector<StringPiece>& args,
+  bool Parse(const StringPiece& command, const std::vector<StringPiece>& args,
              std::ostream* outError);
 
-  const std::vector<std::string>& getArgs();
+  const std::vector<std::string>& GetArgs();
 
  private:
   struct Flag {
@@ -59,13 +59,13 @@
     std::string description;
     std::function<bool(const StringPiece& value)> action;
     bool required;
-    size_t numArgs;
+    size_t num_args;
 
     bool parsed;
   };
 
-  std::vector<Flag> mFlags;
-  std::vector<std::string> mArgs;
+  std::vector<Flag> flags_;
+  std::vector<std::string> args_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/Locale.cpp b/tools/aapt2/Locale.cpp
index a0f7641..78f56c7a 100644
--- a/tools/aapt2/Locale.cpp
+++ b/tools/aapt2/Locale.cpp
@@ -15,174 +15,176 @@
  */
 
 #include "Locale.h"
-#include "util/Util.h"
 
 #include <ctype.h>
+
 #include <algorithm>
 #include <string>
 #include <vector>
 
+#include "util/Util.h"
+
 namespace aapt {
 
 using android::ResTable_config;
 
-void LocaleValue::setLanguage(const char* languageChars) {
+void LocaleValue::set_language(const char* language_chars) {
   size_t i = 0;
-  while ((*languageChars) != '\0') {
-    language[i++] = ::tolower(*languageChars);
-    languageChars++;
+  while ((*language_chars) != '\0') {
+    language[i++] = ::tolower(*language_chars);
+    language_chars++;
   }
 }
 
-void LocaleValue::setRegion(const char* regionChars) {
+void LocaleValue::set_region(const char* region_chars) {
   size_t i = 0;
-  while ((*regionChars) != '\0') {
-    region[i++] = ::toupper(*regionChars);
-    regionChars++;
+  while ((*region_chars) != '\0') {
+    region[i++] = ::toupper(*region_chars);
+    region_chars++;
   }
 }
 
-void LocaleValue::setScript(const char* scriptChars) {
+void LocaleValue::set_script(const char* script_chars) {
   size_t i = 0;
-  while ((*scriptChars) != '\0') {
+  while ((*script_chars) != '\0') {
     if (i == 0) {
-      script[i++] = ::toupper(*scriptChars);
+      script[i++] = ::toupper(*script_chars);
     } else {
-      script[i++] = ::tolower(*scriptChars);
+      script[i++] = ::tolower(*script_chars);
     }
-    scriptChars++;
+    script_chars++;
   }
 }
 
-void LocaleValue::setVariant(const char* variantChars) {
+void LocaleValue::set_variant(const char* variant_chars) {
   size_t i = 0;
-  while ((*variantChars) != '\0') {
-    variant[i++] = *variantChars;
-    variantChars++;
+  while ((*variant_chars) != '\0') {
+    variant[i++] = *variant_chars;
+    variant_chars++;
   }
 }
 
-static inline bool isAlpha(const std::string& str) {
+static inline bool is_alpha(const std::string& str) {
   return std::all_of(std::begin(str), std::end(str), ::isalpha);
 }
 
-static inline bool isNumber(const std::string& str) {
+static inline bool is_number(const std::string& str) {
   return std::all_of(std::begin(str), std::end(str), ::isdigit);
 }
 
-bool LocaleValue::initFromFilterString(const StringPiece& str) {
+bool LocaleValue::InitFromFilterString(const StringPiece& str) {
   // A locale (as specified in the filter) is an underscore separated name such
   // as "en_US", "en_Latn_US", or "en_US_POSIX".
-  std::vector<std::string> parts = util::splitAndLowercase(str, '_');
+  std::vector<std::string> parts = util::SplitAndLowercase(str, '_');
 
-  const int numTags = parts.size();
+  const int num_tags = parts.size();
   bool valid = false;
-  if (numTags >= 1) {
+  if (num_tags >= 1) {
     const std::string& lang = parts[0];
-    if (isAlpha(lang) && (lang.length() == 2 || lang.length() == 3)) {
-      setLanguage(lang.c_str());
+    if (is_alpha(lang) && (lang.length() == 2 || lang.length() == 3)) {
+      set_language(lang.c_str());
       valid = true;
     }
   }
 
-  if (!valid || numTags == 1) {
+  if (!valid || num_tags == 1) {
     return valid;
   }
 
   // At this point, valid == true && numTags > 1.
   const std::string& part2 = parts[1];
-  if ((part2.length() == 2 && isAlpha(part2)) ||
-      (part2.length() == 3 && isNumber(part2))) {
-    setRegion(part2.c_str());
-  } else if (part2.length() == 4 && isAlpha(part2)) {
-    setScript(part2.c_str());
+  if ((part2.length() == 2 && is_alpha(part2)) ||
+      (part2.length() == 3 && is_number(part2))) {
+    set_region(part2.c_str());
+  } else if (part2.length() == 4 && is_alpha(part2)) {
+    set_script(part2.c_str());
   } else if (part2.length() >= 4 && part2.length() <= 8) {
-    setVariant(part2.c_str());
+    set_variant(part2.c_str());
   } else {
     valid = false;
   }
 
-  if (!valid || numTags == 2) {
+  if (!valid || num_tags == 2) {
     return valid;
   }
 
   // At this point, valid == true && numTags > 1.
   const std::string& part3 = parts[2];
-  if (((part3.length() == 2 && isAlpha(part3)) ||
-       (part3.length() == 3 && isNumber(part3))) &&
+  if (((part3.length() == 2 && is_alpha(part3)) ||
+       (part3.length() == 3 && is_number(part3))) &&
       script[0]) {
-    setRegion(part3.c_str());
+    set_region(part3.c_str());
   } else if (part3.length() >= 4 && part3.length() <= 8) {
-    setVariant(part3.c_str());
+    set_variant(part3.c_str());
   } else {
     valid = false;
   }
 
-  if (!valid || numTags == 3) {
+  if (!valid || num_tags == 3) {
     return valid;
   }
 
   const std::string& part4 = parts[3];
   if (part4.length() >= 4 && part4.length() <= 8) {
-    setVariant(part4.c_str());
+    set_variant(part4.c_str());
   } else {
     valid = false;
   }
 
-  if (!valid || numTags > 4) {
+  if (!valid || num_tags > 4) {
     return false;
   }
 
   return true;
 }
 
-ssize_t LocaleValue::initFromParts(std::vector<std::string>::iterator iter,
+ssize_t LocaleValue::InitFromParts(std::vector<std::string>::iterator iter,
                                    std::vector<std::string>::iterator end) {
-  const std::vector<std::string>::iterator startIter = iter;
+  const std::vector<std::string>::iterator start_iter = iter;
 
   std::string& part = *iter;
   if (part[0] == 'b' && part[1] == '+') {
     // This is a "modified" BCP 47 language tag. Same semantics as BCP 47 tags,
     // except that the separator is "+" and not "-".
-    std::vector<std::string> subtags = util::splitAndLowercase(part, '+');
+    std::vector<std::string> subtags = util::SplitAndLowercase(part, '+');
     subtags.erase(subtags.begin());
     if (subtags.size() == 1) {
-      setLanguage(subtags[0].c_str());
+      set_language(subtags[0].c_str());
     } else if (subtags.size() == 2) {
-      setLanguage(subtags[0].c_str());
+      set_language(subtags[0].c_str());
 
       // The second tag can either be a region, a variant or a script.
       switch (subtags[1].size()) {
         case 2:
         case 3:
-          setRegion(subtags[1].c_str());
+          set_region(subtags[1].c_str());
           break;
         case 4:
           if ('0' <= subtags[1][0] && subtags[1][0] <= '9') {
             // This is a variant: fall through
           } else {
-            setScript(subtags[1].c_str());
+            set_script(subtags[1].c_str());
             break;
           }
         case 5:
         case 6:
         case 7:
         case 8:
-          setVariant(subtags[1].c_str());
+          set_variant(subtags[1].c_str());
           break;
         default:
           return -1;
       }
     } else if (subtags.size() == 3) {
       // The language is always the first subtag.
-      setLanguage(subtags[0].c_str());
+      set_language(subtags[0].c_str());
 
       // The second subtag can either be a script or a region code.
       // If its size is 4, it's a script code, else it's a region code.
       if (subtags[1].size() == 4) {
-        setScript(subtags[1].c_str());
+        set_script(subtags[1].c_str());
       } else if (subtags[1].size() == 2 || subtags[1].size() == 3) {
-        setRegion(subtags[1].c_str());
+        set_region(subtags[1].c_str());
       } else {
         return -1;
       }
@@ -190,15 +192,15 @@
       // The third tag can either be a region code (if the second tag was
       // a script), else a variant code.
       if (subtags[2].size() >= 4) {
-        setVariant(subtags[2].c_str());
+        set_variant(subtags[2].c_str());
       } else {
-        setRegion(subtags[2].c_str());
+        set_region(subtags[2].c_str());
       }
     } else if (subtags.size() == 4) {
-      setLanguage(subtags[0].c_str());
-      setScript(subtags[1].c_str());
-      setRegion(subtags[2].c_str());
-      setVariant(subtags[3].c_str());
+      set_language(subtags[0].c_str());
+      set_script(subtags[1].c_str());
+      set_region(subtags[2].c_str());
+      set_variant(subtags[3].c_str());
     } else {
       return -1;
     }
@@ -206,25 +208,25 @@
     ++iter;
 
   } else {
-    if ((part.length() == 2 || part.length() == 3) && isAlpha(part) &&
+    if ((part.length() == 2 || part.length() == 3) && is_alpha(part) &&
         part != "car") {
-      setLanguage(part.c_str());
+      set_language(part.c_str());
       ++iter;
 
       if (iter != end) {
-        const std::string& regionPart = *iter;
-        if (regionPart.c_str()[0] == 'r' && regionPart.length() == 3) {
-          setRegion(regionPart.c_str() + 1);
+        const std::string& region_part = *iter;
+        if (region_part.c_str()[0] == 'r' && region_part.length() == 3) {
+          set_region(region_part.c_str() + 1);
           ++iter;
         }
       }
     }
   }
 
-  return static_cast<ssize_t>(iter - startIter);
+  return static_cast<ssize_t>(iter - start_iter);
 }
 
-void LocaleValue::initFromResTable(const ResTable_config& config) {
+void LocaleValue::InitFromResTable(const ResTable_config& config) {
   config.unpackLanguage(language);
   config.unpackRegion(region);
   if (config.localeScript[0] && !config.localeScriptWasComputed) {
@@ -236,7 +238,7 @@
   }
 }
 
-void LocaleValue::writeTo(ResTable_config* out) const {
+void LocaleValue::WriteTo(ResTable_config* out) const {
   out->packLanguage(language);
   out->packRegion(region);
 
diff --git a/tools/aapt2/Locale.h b/tools/aapt2/Locale.h
index 0f75850..fc6c448 100644
--- a/tools/aapt2/Locale.h
+++ b/tools/aapt2/Locale.h
@@ -17,12 +17,13 @@
 #ifndef AAPT_LOCALE_VALUE_H
 #define AAPT_LOCALE_VALUE_H
 
-#include "util/StringPiece.h"
-
-#include <androidfw/ResourceTypes.h>
 #include <string>
 #include <vector>
 
+#include "androidfw/ResourceTypes.h"
+
+#include "util/StringPiece.h"
+
 namespace aapt {
 
 /**
@@ -39,23 +40,23 @@
   /**
    * Initialize this LocaleValue from a config string.
    */
-  bool initFromFilterString(const StringPiece& config);
+  bool InitFromFilterString(const StringPiece& config);
 
   /**
    * Initialize this LocaleValue from parts of a vector.
    */
-  ssize_t initFromParts(std::vector<std::string>::iterator iter,
+  ssize_t InitFromParts(std::vector<std::string>::iterator iter,
                         std::vector<std::string>::iterator end);
 
   /**
    * Initialize this LocaleValue from a ResTable_config.
    */
-  void initFromResTable(const android::ResTable_config& config);
+  void InitFromResTable(const android::ResTable_config& config);
 
   /**
    * Set the locale in a ResTable_config from this LocaleValue.
    */
-  void writeTo(android::ResTable_config* out) const;
+  void WriteTo(android::ResTable_config* out) const;
 
   inline int compare(const LocaleValue& other) const;
 
@@ -67,10 +68,10 @@
   inline bool operator>(const LocaleValue& o) const;
 
  private:
-  void setLanguage(const char* language);
-  void setRegion(const char* language);
-  void setScript(const char* script);
-  void setVariant(const char* variant);
+  void set_language(const char* language);
+  void set_region(const char* language);
+  void set_script(const char* script);
+  void set_variant(const char* variant);
 };
 
 //
diff --git a/tools/aapt2/Locale_test.cpp b/tools/aapt2/Locale_test.cpp
index b82d2b9..68b4cae 100644
--- a/tools/aapt2/Locale_test.cpp
+++ b/tools/aapt2/Locale_test.cpp
@@ -15,18 +15,20 @@
  */
 
 #include "Locale.h"
-#include "util/Util.h"
 
-#include <gtest/gtest.h>
 #include <string>
 
+#include "gtest/gtest.h"
+
+#include "util/Util.h"
+
 namespace aapt {
 
 static ::testing::AssertionResult TestLanguage(const char* input,
                                                const char* lang) {
-  std::vector<std::string> parts = util::splitAndLowercase(input, '-');
+  std::vector<std::string> parts = util::SplitAndLowercase(input, '-');
   LocaleValue lv;
-  ssize_t count = lv.initFromParts(std::begin(parts), std::end(parts));
+  ssize_t count = lv.InitFromParts(std::begin(parts), std::end(parts));
   if (count < 0) {
     return ::testing::AssertionFailure() << " failed to parse '" << input
                                          << "'.";
@@ -51,9 +53,9 @@
 static ::testing::AssertionResult TestLanguageRegion(const char* input,
                                                      const char* lang,
                                                      const char* region) {
-  std::vector<std::string> parts = util::splitAndLowercase(input, '-');
+  std::vector<std::string> parts = util::SplitAndLowercase(input, '-');
   LocaleValue lv;
-  ssize_t count = lv.initFromParts(std::begin(parts), std::end(parts));
+  ssize_t count = lv.InitFromParts(std::begin(parts), std::end(parts));
   if (count < 0) {
     return ::testing::AssertionFailure() << " failed to parse '" << input
                                          << "'.";
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 8aedd44..8dd176d 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-#include "util/StringPiece.h"
-
 #include <iostream>
 #include <vector>
 
+#include "util/StringPiece.h"
+
 namespace aapt {
 
 // DO NOT UPDATE, this is more of a marketing version.
@@ -27,16 +27,16 @@
 // Update minor version whenever a feature or flag is added.
 static const char* sMinorVersion = "2";
 
-int printVersion() {
+int PrintVersion() {
   std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "."
             << sMinorVersion << std::endl;
   return 0;
 }
 
-extern int compile(const std::vector<StringPiece>& args);
-extern int link(const std::vector<StringPiece>& args);
-extern int dump(const std::vector<StringPiece>& args);
-extern int diff(const std::vector<StringPiece>& args);
+extern int Compile(const std::vector<StringPiece>& args);
+extern int Link(const std::vector<StringPiece>& args);
+extern int Dump(const std::vector<StringPiece>& args);
+extern int Diff(const std::vector<StringPiece>& args);
 
 }  // namespace aapt
 
@@ -52,15 +52,15 @@
 
     aapt::StringPiece command(argv[0]);
     if (command == "compile" || command == "c") {
-      return aapt::compile(args);
+      return aapt::Compile(args);
     } else if (command == "link" || command == "l") {
-      return aapt::link(args);
+      return aapt::Link(args);
     } else if (command == "dump" || command == "d") {
-      return aapt::dump(args);
+      return aapt::Dump(args);
     } else if (command == "diff") {
-      return aapt::diff(args);
+      return aapt::Diff(args);
     } else if (command == "version") {
-      return aapt::printVersion();
+      return aapt::PrintVersion();
     }
     std::cerr << "unknown command '" << command << "'\n";
   } else {
diff --git a/tools/aapt2/NameMangler.h b/tools/aapt2/NameMangler.h
index 6d244aa..dba2d09 100644
--- a/tools/aapt2/NameMangler.h
+++ b/tools/aapt2/NameMangler.h
@@ -17,12 +17,12 @@
 #ifndef AAPT_NAME_MANGLER_H
 #define AAPT_NAME_MANGLER_H
 
-#include "Resource.h"
-#include "util/Maybe.h"
-
 #include <set>
 #include <string>
 
+#include "Resource.h"
+#include "util/Maybe.h"
+
 namespace aapt {
 
 struct NameManglerPolicy {
@@ -31,37 +31,35 @@
    * to this package are not mangled, and mangled references inherit this
    * package name.
    */
-  std::string targetPackageName;
+  std::string target_package_name;
 
   /**
    * We must know which references to mangle, and which to keep (android vs.
    * com.android.support).
    */
-  std::set<std::string> packagesToMangle;
+  std::set<std::string> packages_to_mangle;
 };
 
 class NameMangler {
- private:
-  NameManglerPolicy mPolicy;
-
  public:
-  explicit NameMangler(NameManglerPolicy policy) : mPolicy(policy) {}
+  explicit NameMangler(NameManglerPolicy policy) : policy_(policy) {}
 
-  Maybe<ResourceName> mangleName(const ResourceName& name) {
-    if (mPolicy.targetPackageName == name.package ||
-        mPolicy.packagesToMangle.count(name.package) == 0) {
+  Maybe<ResourceName> MangleName(const ResourceName& name) {
+    if (policy_.target_package_name == name.package ||
+        policy_.packages_to_mangle.count(name.package) == 0) {
       return {};
     }
 
-    std::string mangledEntryName = mangleEntry(name.package, name.entry);
-    return ResourceName(mPolicy.targetPackageName, name.type, mangledEntryName);
+    std::string mangled_entry_name = MangleEntry(name.package, name.entry);
+    return ResourceName(policy_.target_package_name, name.type,
+                        mangled_entry_name);
   }
 
-  bool shouldMangle(const std::string& package) const {
-    if (package.empty() || mPolicy.targetPackageName == package) {
+  bool ShouldMangle(const std::string& package) const {
+    if (package.empty() || policy_.target_package_name == package) {
       return false;
     }
-    return mPolicy.packagesToMangle.count(package) != 0;
+    return policy_.packages_to_mangle.count(package) != 0;
   }
 
   /**
@@ -69,7 +67,7 @@
    * The mangled name should contain symbols that are illegal to define in XML,
    * so that there will never be name mangling collisions.
    */
-  static std::string mangleEntry(const std::string& package,
+  static std::string MangleEntry(const std::string& package,
                                  const std::string& name) {
     return package + "$" + name;
   }
@@ -79,16 +77,20 @@
    * and the package in `outPackage`. Returns true if the name was unmangled or
    * false if the name was never mangled to begin with.
    */
-  static bool unmangle(std::string* outName, std::string* outPackage) {
-    size_t pivot = outName->find('$');
+  static bool Unmangle(std::string* out_name, std::string* out_package) {
+    size_t pivot = out_name->find('$');
     if (pivot == std::string::npos) {
       return false;
     }
 
-    outPackage->assign(outName->data(), pivot);
-    outName->assign(outName->data() + pivot + 1, outName->size() - (pivot + 1));
+    out_package->assign(out_name->data(), pivot);
+    out_name->assign(out_name->data() + pivot + 1,
+                     out_name->size() - (pivot + 1));
     return true;
   }
+
+ private:
+  NameManglerPolicy policy_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/NameMangler_test.cpp b/tools/aapt2/NameMangler_test.cpp
index b02986d..bc89b5c 100644
--- a/tools/aapt2/NameMangler_test.cpp
+++ b/tools/aapt2/NameMangler_test.cpp
@@ -15,31 +15,32 @@
  */
 
 #include "NameMangler.h"
-#include "test/Test.h"
 
 #include <string>
 
+#include "test/Test.h"
+
 namespace aapt {
 
 TEST(NameManglerTest, MangleName) {
   std::string package = "android.appcompat";
   std::string name = "Platform.AppCompat";
 
-  std::string mangledName = NameMangler::mangleEntry(package, name);
-  EXPECT_EQ(mangledName, "android.appcompat$Platform.AppCompat");
+  std::string mangled_name = NameMangler::MangleEntry(package, name);
+  EXPECT_EQ(mangled_name, "android.appcompat$Platform.AppCompat");
 
-  std::string unmangledPackage;
-  std::string unmangledName = mangledName;
-  ASSERT_TRUE(NameMangler::unmangle(&unmangledName, &unmangledPackage));
-  EXPECT_EQ(unmangledName, "Platform.AppCompat");
-  EXPECT_EQ(unmangledPackage, "android.appcompat");
+  std::string unmangled_package;
+  std::string unmangled_name = mangled_name;
+  ASSERT_TRUE(NameMangler::Unmangle(&unmangled_name, &unmangled_package));
+  EXPECT_EQ(unmangled_name, "Platform.AppCompat");
+  EXPECT_EQ(unmangled_package, "android.appcompat");
 }
 
 TEST(NameManglerTest, IgnoreUnmangledName) {
   std::string package;
   std::string name = "foo_bar";
 
-  EXPECT_FALSE(NameMangler::unmangle(&name, &package));
+  EXPECT_FALSE(NameMangler::Unmangle(&name, &package));
   EXPECT_EQ(name, "foo_bar");
 }
 
diff --git a/tools/aapt2/Resource.cpp b/tools/aapt2/Resource.cpp
index 6805631..1d414743 100644
--- a/tools/aapt2/Resource.cpp
+++ b/tools/aapt2/Resource.cpp
@@ -15,14 +15,13 @@
  */
 
 #include "Resource.h"
-#include "util/StringPiece.h"
 
 #include <map>
 #include <string>
 
 namespace aapt {
 
-StringPiece toString(ResourceType type) {
+StringPiece ToString(ResourceType type) {
   switch (type) {
     case ResourceType::kAnim:
       return "anim";
@@ -100,7 +99,7 @@
     {"xml", ResourceType::kXml},
 };
 
-const ResourceType* parseResourceType(const StringPiece& str) {
+const ResourceType* ParseResourceType(const StringPiece& str) {
   auto iter = sResourceTypeMap.find(str);
   if (iter == std::end(sResourceTypeMap)) {
     return nullptr;
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
index 30739db..78acb70 100644
--- a/tools/aapt2/Resource.h
+++ b/tools/aapt2/Resource.h
@@ -17,12 +17,6 @@
 #ifndef AAPT_RESOURCE_H
 #define AAPT_RESOURCE_H
 
-#include "ConfigDescription.h"
-#include "Source.h"
-#include "util/StringPiece.h"
-
-#include <utils/JenkinsHash.h>
-
 #include <iomanip>
 #include <limits>
 #include <sstream>
@@ -30,6 +24,12 @@
 #include <tuple>
 #include <vector>
 
+#include "utils/JenkinsHash.h"
+
+#include "ConfigDescription.h"
+#include "Source.h"
+#include "util/StringPiece.h"
+
 namespace aapt {
 
 /**
@@ -62,13 +62,13 @@
   kXml,
 };
 
-StringPiece toString(ResourceType type);
+StringPiece ToString(ResourceType type);
 
 /**
  * Returns a pointer to a valid ResourceType, or nullptr if
  * the string was invalid.
  */
-const ResourceType* parseResourceType(const StringPiece& str);
+const ResourceType* ParseResourceType(const StringPiece& str);
 
 /**
  * A resource's name. This can uniquely identify
@@ -76,16 +76,16 @@
  */
 struct ResourceName {
   std::string package;
-  ResourceType type;
+  ResourceType type = ResourceType::kRaw;
   std::string entry;
 
-  ResourceName() : type(ResourceType::kRaw) {}
+  ResourceName() = default;
   ResourceName(const StringPiece& p, ResourceType t, const StringPiece& e);
 
   int compare(const ResourceName& other) const;
 
-  bool isValid() const;
-  std::string toString() const;
+  bool is_valid() const;
+  std::string ToString() const;
 };
 
 /**
@@ -96,7 +96,7 @@
  */
 struct ResourceNameRef {
   StringPiece package;
-  ResourceType type;
+  ResourceType type = ResourceType::kRaw;
   StringPiece entry;
 
   ResourceNameRef() = default;
@@ -108,8 +108,8 @@
   ResourceNameRef& operator=(ResourceNameRef&& rhs) = default;
   ResourceNameRef& operator=(const ResourceName& rhs);
 
-  ResourceName toResourceName() const;
-  bool isValid() const;
+  ResourceName ToResourceName() const;
+  bool is_valid() const;
 };
 
 /**
@@ -128,13 +128,13 @@
 
   ResourceId();
   ResourceId(const ResourceId& rhs);
-  ResourceId(uint32_t resId);  // NOLINT(implicit)
+  ResourceId(uint32_t res_id);  // NOLINT(implicit)
   ResourceId(uint8_t p, uint8_t t, uint16_t e);
 
-  bool isValid() const;
-  uint8_t packageId() const;
-  uint8_t typeId() const;
-  uint16_t entryId() const;
+  bool is_valid() const;
+  uint8_t package_id() const;
+  uint8_t type_id() const;
+  uint16_t entry_id() const;
 };
 
 struct SourcedResourceName {
@@ -153,7 +153,7 @@
   Source source;
 
   // Exported symbols
-  std::vector<SourcedResourceName> exportedSymbols;
+  std::vector<SourcedResourceName> exported_symbols;
 };
 
 /**
@@ -196,24 +196,24 @@
 
 inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {}
 
-inline ResourceId::ResourceId(uint32_t resId) : id(resId) {}
+inline ResourceId::ResourceId(uint32_t res_id) : id(res_id) {}
 
 inline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e)
     : id((p << 24) | (t << 16) | e) {}
 
-inline bool ResourceId::isValid() const {
+inline bool ResourceId::is_valid() const {
   return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
 }
 
-inline uint8_t ResourceId::packageId() const {
+inline uint8_t ResourceId::package_id() const {
   return static_cast<uint8_t>(id >> 24);
 }
 
-inline uint8_t ResourceId::typeId() const {
+inline uint8_t ResourceId::type_id() const {
   return static_cast<uint8_t>(id >> 16);
 }
 
-inline uint16_t ResourceId::entryId() const {
+inline uint16_t ResourceId::entry_id() const {
   return static_cast<uint16_t>(id);
 }
 
@@ -234,13 +234,13 @@
 }
 
 inline ::std::ostream& operator<<(::std::ostream& out,
-                                  const ResourceId& resId) {
-  std::ios_base::fmtflags oldFlags = out.flags();
-  char oldFill = out.fill();
+                                  const ResourceId& res_id) {
+  std::ios_base::fmtflags old_flags = out.flags();
+  char old_fill = out.fill();
   out << "0x" << std::internal << std::setfill('0') << std::setw(8) << std::hex
-      << resId.id;
-  out.flags(oldFlags);
-  out.fill(oldFill);
+      << res_id.id;
+  out.flags(old_flags);
+  out.fill(old_fill);
   return out;
 }
 
@@ -250,7 +250,7 @@
 
 inline ::std::ostream& operator<<(::std::ostream& out,
                                   const ResourceType& val) {
-  return out << toString(val);
+  return out << ToString(val);
 }
 
 //
@@ -259,7 +259,7 @@
 
 inline ResourceName::ResourceName(const StringPiece& p, ResourceType t,
                                   const StringPiece& e)
-    : package(p.toString()), type(t), entry(e.toString()) {}
+    : package(p.ToString()), type(t), entry(e.ToString()) {}
 
 inline int ResourceName::compare(const ResourceName& other) const {
   int cmp = package.compare(other.package);
@@ -270,7 +270,7 @@
   return cmp;
 }
 
-inline bool ResourceName::isValid() const {
+inline bool ResourceName::is_valid() const {
   return !package.empty() && !entry.empty();
 }
 
@@ -297,7 +297,7 @@
   return out << name.type << "/" << name.entry;
 }
 
-inline std::string ResourceName::toString() const {
+inline std::string ResourceName::ToString() const {
   std::stringstream stream;
   stream << *this;
   return stream.str();
@@ -321,11 +321,11 @@
   return *this;
 }
 
-inline ResourceName ResourceNameRef::toResourceName() const {
+inline ResourceName ResourceNameRef::ToResourceName() const {
   return ResourceName(package, type, entry);
 }
 
-inline bool ResourceNameRef::isValid() const {
+inline bool ResourceNameRef::is_valid() const {
   return !package.empty() && !entry.empty();
 }
 
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 51aed13..b16def4 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -15,6 +15,12 @@
  */
 
 #include "ResourceParser.h"
+
+#include <functional>
+#include <sstream>
+
+#include "android-base/logging.h"
+
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
@@ -23,9 +29,6 @@
 #include "util/Util.h"
 #include "xml/XmlPullParser.h"
 
-#include <functional>
-#include <sstream>
-
 namespace aapt {
 
 constexpr const char* sXliffNamespaceUri =
@@ -35,12 +38,12 @@
  * Returns true if the element is <skip> or <eat-comment> and can be safely
  * ignored.
  */
-static bool shouldIgnoreElement(const StringPiece& ns,
+static bool ShouldIgnoreElement(const StringPiece& ns,
                                 const StringPiece& name) {
   return ns.empty() && (name == "skip" || name == "eat-comment");
 }
 
-static uint32_t parseFormatType(const StringPiece& piece) {
+static uint32_t ParseFormatType(const StringPiece& piece) {
   if (piece == "reference")
     return android::ResTable_map::TYPE_REFERENCE;
   else if (piece == "string")
@@ -64,11 +67,11 @@
   return 0;
 }
 
-static uint32_t parseFormatAttribute(const StringPiece& str) {
+static uint32_t ParseFormatAttribute(const StringPiece& str) {
   uint32_t mask = 0;
-  for (StringPiece part : util::tokenize(str, '|')) {
-    StringPiece trimmedPart = util::trimWhitespace(part);
-    uint32_t type = parseFormatType(trimmedPart);
+  for (StringPiece part : util::Tokenize(str, '|')) {
+    StringPiece trimmed_part = util::TrimWhitespace(part);
+    uint32_t type = ParseFormatType(trimmed_part);
     if (type == 0) {
       return 0;
     }
@@ -86,45 +89,45 @@
   std::string product;
   Source source;
   ResourceId id;
-  Maybe<SymbolState> symbolState;
+  Maybe<SymbolState> symbol_state;
   std::string comment;
   std::unique_ptr<Value> value;
-  std::list<ParsedResource> childResources;
+  std::list<ParsedResource> child_resources;
 };
 
 // Recursively adds resources to the ResourceTable.
-static bool addResourcesToTable(ResourceTable* table, IDiagnostics* diag,
+static bool AddResourcesToTable(ResourceTable* table, IDiagnostics* diag,
                                 ParsedResource* res) {
-  StringPiece trimmedComment = util::trimWhitespace(res->comment);
-  if (trimmedComment.size() != res->comment.size()) {
+  StringPiece trimmed_comment = util::TrimWhitespace(res->comment);
+  if (trimmed_comment.size() != res->comment.size()) {
     // Only if there was a change do we re-assign.
-    res->comment = trimmedComment.toString();
+    res->comment = trimmed_comment.ToString();
   }
 
-  if (res->symbolState) {
+  if (res->symbol_state) {
     Symbol symbol;
-    symbol.state = res->symbolState.value();
+    symbol.state = res->symbol_state.value();
     symbol.source = res->source;
     symbol.comment = res->comment;
-    if (!table->setSymbolState(res->name, res->id, symbol, diag)) {
+    if (!table->SetSymbolState(res->name, res->id, symbol, diag)) {
       return false;
     }
   }
 
   if (res->value) {
     // Attach the comment, source and config to the value.
-    res->value->setComment(std::move(res->comment));
-    res->value->setSource(std::move(res->source));
+    res->value->SetComment(std::move(res->comment));
+    res->value->SetSource(std::move(res->source));
 
-    if (!table->addResource(res->name, res->id, res->config, res->product,
+    if (!table->AddResource(res->name, res->id, res->config, res->product,
                             std::move(res->value), diag)) {
       return false;
     }
   }
 
   bool error = false;
-  for (ParsedResource& child : res->childResources) {
-    error |= !addResourcesToTable(table, diag, &child);
+  for (ParsedResource& child : res->child_resources) {
+    error |= !AddResourcesToTable(table, diag, &child);
   }
   return !error;
 }
@@ -136,29 +139,29 @@
                                const Source& source,
                                const ConfigDescription& config,
                                const ResourceParserOptions& options)
-    : mDiag(diag),
-      mTable(table),
-      mSource(source),
-      mConfig(config),
-      mOptions(options) {}
+    : diag_(diag),
+      table_(table),
+      source_(source),
+      config_(config),
+      options_(options) {}
 
 /**
  * Build a string from XML that converts nested elements into Span objects.
  */
-bool ResourceParser::flattenXmlSubtree(xml::XmlPullParser* parser,
-                                       std::string* outRawString,
-                                       StyleString* outStyleString) {
-  std::vector<Span> spanStack;
+bool ResourceParser::FlattenXmlSubtree(xml::XmlPullParser* parser,
+                                       std::string* out_raw_string,
+                                       StyleString* out_style_string) {
+  std::vector<Span> span_stack;
 
   bool error = false;
-  outRawString->clear();
-  outStyleString->spans.clear();
+  out_raw_string->clear();
+  out_style_string->spans.clear();
   util::StringBuilder builder;
   size_t depth = 1;
-  while (xml::XmlPullParser::isGoodEvent(parser->next())) {
-    const xml::XmlPullParser::Event event = parser->getEvent();
+  while (xml::XmlPullParser::IsGoodEvent(parser->Next())) {
+    const xml::XmlPullParser::Event event = parser->event();
     if (event == xml::XmlPullParser::Event::kEndElement) {
-      if (!parser->getElementNamespace().empty()) {
+      if (!parser->element_namespace().empty()) {
         // We already warned and skipped the start element, so just skip here
         // too
         continue;
@@ -169,150 +172,151 @@
         break;
       }
 
-      spanStack.back().lastChar = builder.utf16Len() - 1;
-      outStyleString->spans.push_back(spanStack.back());
-      spanStack.pop_back();
+      span_stack.back().last_char = builder.Utf16Len() - 1;
+      out_style_string->spans.push_back(span_stack.back());
+      span_stack.pop_back();
 
     } else if (event == xml::XmlPullParser::Event::kText) {
-      outRawString->append(parser->getText());
-      builder.append(parser->getText());
+      out_raw_string->append(parser->text());
+      builder.Append(parser->text());
 
     } else if (event == xml::XmlPullParser::Event::kStartElement) {
-      if (!parser->getElementNamespace().empty()) {
-        if (parser->getElementNamespace() != sXliffNamespaceUri) {
+      if (!parser->element_namespace().empty()) {
+        if (parser->element_namespace() != sXliffNamespaceUri) {
           // Only warn if this isn't an xliff namespace.
-          mDiag->warn(DiagMessage(mSource.withLine(parser->getLineNumber()))
-                      << "skipping element '" << parser->getElementName()
+          diag_->Warn(DiagMessage(source_.WithLine(parser->line_number()))
+                      << "skipping element '" << parser->element_name()
                       << "' with unknown namespace '"
-                      << parser->getElementNamespace() << "'");
+                      << parser->element_namespace() << "'");
         }
         continue;
       }
       depth++;
 
       // Build a span object out of the nested element.
-      std::string spanName = parser->getElementName();
-      const auto endAttrIter = parser->endAttributes();
-      for (auto attrIter = parser->beginAttributes(); attrIter != endAttrIter;
-           ++attrIter) {
-        spanName += ";";
-        spanName += attrIter->name;
-        spanName += "=";
-        spanName += attrIter->value;
+      std::string span_name = parser->element_name();
+      const auto end_attr_iter = parser->end_attributes();
+      for (auto attr_iter = parser->begin_attributes();
+           attr_iter != end_attr_iter; ++attr_iter) {
+        span_name += ";";
+        span_name += attr_iter->name;
+        span_name += "=";
+        span_name += attr_iter->value;
       }
 
-      if (builder.utf16Len() > std::numeric_limits<uint32_t>::max()) {
-        mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
-                     << "style string '" << builder.str() << "' is too long");
+      if (builder.Utf16Len() > std::numeric_limits<uint32_t>::max()) {
+        diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
+                     << "style string '" << builder.ToString()
+                     << "' is too long");
         error = true;
       } else {
-        spanStack.push_back(
-            Span{spanName, static_cast<uint32_t>(builder.utf16Len())});
+        span_stack.push_back(
+            Span{span_name, static_cast<uint32_t>(builder.Utf16Len())});
       }
 
     } else if (event == xml::XmlPullParser::Event::kComment) {
       // Skip
     } else {
-      assert(false);
+      LOG(FATAL) << "unhandled XML event";
     }
   }
-  assert(spanStack.empty() && "spans haven't been fully processed");
+  CHECK(span_stack.empty()) << "spans haven't been fully processed";
 
-  outStyleString->str = builder.str();
+  out_style_string->str = builder.ToString();
   return !error;
 }
 
-bool ResourceParser::parse(xml::XmlPullParser* parser) {
+bool ResourceParser::Parse(xml::XmlPullParser* parser) {
   bool error = false;
-  const size_t depth = parser->getDepth();
-  while (xml::XmlPullParser::nextChildNode(parser, depth)) {
-    if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) {
+  const size_t depth = parser->depth();
+  while (xml::XmlPullParser::NextChildNode(parser, depth)) {
+    if (parser->event() != xml::XmlPullParser::Event::kStartElement) {
       // Skip comments and text.
       continue;
     }
 
-    if (!parser->getElementNamespace().empty() ||
-        parser->getElementName() != "resources") {
-      mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
+    if (!parser->element_namespace().empty() ||
+        parser->element_name() != "resources") {
+      diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
                    << "root element must be <resources>");
       return false;
     }
 
-    error |= !parseResources(parser);
+    error |= !ParseResources(parser);
     break;
   };
 
-  if (parser->getEvent() == xml::XmlPullParser::Event::kBadDocument) {
-    mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
-                 << "xml parser error: " << parser->getLastError());
+  if (parser->event() == xml::XmlPullParser::Event::kBadDocument) {
+    diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
+                 << "xml parser error: " << parser->error());
     return false;
   }
   return !error;
 }
 
-bool ResourceParser::parseResources(xml::XmlPullParser* parser) {
-  std::set<ResourceName> strippedResources;
+bool ResourceParser::ParseResources(xml::XmlPullParser* parser) {
+  std::set<ResourceName> stripped_resources;
 
   bool error = false;
   std::string comment;
-  const size_t depth = parser->getDepth();
-  while (xml::XmlPullParser::nextChildNode(parser, depth)) {
-    const xml::XmlPullParser::Event event = parser->getEvent();
+  const size_t depth = parser->depth();
+  while (xml::XmlPullParser::NextChildNode(parser, depth)) {
+    const xml::XmlPullParser::Event event = parser->event();
     if (event == xml::XmlPullParser::Event::kComment) {
-      comment = parser->getComment();
+      comment = parser->comment();
       continue;
     }
 
     if (event == xml::XmlPullParser::Event::kText) {
-      if (!util::trimWhitespace(parser->getText()).empty()) {
-        mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
+      if (!util::TrimWhitespace(parser->text()).empty()) {
+        diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
                      << "plain text not allowed here");
         error = true;
       }
       continue;
     }
 
-    assert(event == xml::XmlPullParser::Event::kStartElement);
+    CHECK(event == xml::XmlPullParser::Event::kStartElement);
 
-    if (!parser->getElementNamespace().empty()) {
+    if (!parser->element_namespace().empty()) {
       // Skip unknown namespace.
       continue;
     }
 
-    std::string elementName = parser->getElementName();
-    if (elementName == "skip" || elementName == "eat-comment") {
+    std::string element_name = parser->element_name();
+    if (element_name == "skip" || element_name == "eat-comment") {
       comment = "";
       continue;
     }
 
-    ParsedResource parsedResource;
-    parsedResource.config = mConfig;
-    parsedResource.source = mSource.withLine(parser->getLineNumber());
-    parsedResource.comment = std::move(comment);
+    ParsedResource parsed_resource;
+    parsed_resource.config = config_;
+    parsed_resource.source = source_.WithLine(parser->line_number());
+    parsed_resource.comment = std::move(comment);
 
     // Extract the product name if it exists.
-    if (Maybe<StringPiece> maybeProduct =
-            xml::findNonEmptyAttribute(parser, "product")) {
-      parsedResource.product = maybeProduct.value().toString();
+    if (Maybe<StringPiece> maybe_product =
+            xml::FindNonEmptyAttribute(parser, "product")) {
+      parsed_resource.product = maybe_product.value().ToString();
     }
 
     // Parse the resource regardless of product.
-    if (!parseResource(parser, &parsedResource)) {
+    if (!ParseResource(parser, &parsed_resource)) {
       error = true;
       continue;
     }
 
-    if (!addResourcesToTable(mTable, mDiag, &parsedResource)) {
+    if (!AddResourcesToTable(table_, diag_, &parsed_resource)) {
       error = true;
     }
   }
 
   // Check that we included at least one variant of each stripped resource.
-  for (const ResourceName& strippedResource : strippedResources) {
-    if (!mTable->findResource(strippedResource)) {
+  for (const ResourceName& stripped_resource : stripped_resources) {
+    if (!table_->FindResource(stripped_resource)) {
       // Failed to find the resource.
-      mDiag->error(DiagMessage(mSource)
-                   << "resource '" << strippedResource
+      diag_->Error(DiagMessage(source_)
+                   << "resource '" << stripped_resource
                    << "' "
                       "was filtered out but no product variant remains");
       error = true;
@@ -322,8 +326,8 @@
   return !error;
 }
 
-bool ResourceParser::parseResource(xml::XmlPullParser* parser,
-                                   ParsedResource* outResource) {
+bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
+                                   ParsedResource* out_resource) {
   struct ItemTypeFormat {
     ResourceType type;
     uint32_t format;
@@ -333,7 +337,7 @@
                                           ParsedResource*)>;
 
   static const auto elToItemMap =
-      ImmutableMap<std::string, ItemTypeFormat>::createPreSorted({
+      ImmutableMap<std::string, ItemTypeFormat>::CreatePreSorted({
           {"bool", {ResourceType::kBool, android::ResTable_map::TYPE_BOOLEAN}},
           {"color", {ResourceType::kColor, android::ResTable_map::TYPE_COLOR}},
           {"dimen",
@@ -354,48 +358,49 @@
       });
 
   static const auto elToBagMap =
-      ImmutableMap<std::string, BagParseFunc>::createPreSorted({
-          {"add-resource", std::mem_fn(&ResourceParser::parseAddResource)},
-          {"array", std::mem_fn(&ResourceParser::parseArray)},
-          {"attr", std::mem_fn(&ResourceParser::parseAttr)},
+      ImmutableMap<std::string, BagParseFunc>::CreatePreSorted({
+          {"add-resource", std::mem_fn(&ResourceParser::ParseAddResource)},
+          {"array", std::mem_fn(&ResourceParser::ParseArray)},
+          {"attr", std::mem_fn(&ResourceParser::ParseAttr)},
           {"declare-styleable",
-           std::mem_fn(&ResourceParser::parseDeclareStyleable)},
-          {"integer-array", std::mem_fn(&ResourceParser::parseIntegerArray)},
-          {"java-symbol", std::mem_fn(&ResourceParser::parseSymbol)},
-          {"plurals", std::mem_fn(&ResourceParser::parsePlural)},
-          {"public", std::mem_fn(&ResourceParser::parsePublic)},
-          {"public-group", std::mem_fn(&ResourceParser::parsePublicGroup)},
-          {"string-array", std::mem_fn(&ResourceParser::parseStringArray)},
-          {"style", std::mem_fn(&ResourceParser::parseStyle)},
-          {"symbol", std::mem_fn(&ResourceParser::parseSymbol)},
+           std::mem_fn(&ResourceParser::ParseDeclareStyleable)},
+          {"integer-array", std::mem_fn(&ResourceParser::ParseIntegerArray)},
+          {"java-symbol", std::mem_fn(&ResourceParser::ParseSymbol)},
+          {"plurals", std::mem_fn(&ResourceParser::ParsePlural)},
+          {"public", std::mem_fn(&ResourceParser::ParsePublic)},
+          {"public-group", std::mem_fn(&ResourceParser::ParsePublicGroup)},
+          {"string-array", std::mem_fn(&ResourceParser::ParseStringArray)},
+          {"style", std::mem_fn(&ResourceParser::ParseStyle)},
+          {"symbol", std::mem_fn(&ResourceParser::ParseSymbol)},
       });
 
-  std::string resourceType = parser->getElementName();
+  std::string resource_type = parser->element_name();
 
   // The value format accepted for this resource.
-  uint32_t resourceFormat = 0u;
+  uint32_t resource_format = 0u;
 
-  if (resourceType == "item") {
+  if (resource_type == "item") {
     // Items have their type encoded in the type attribute.
-    if (Maybe<StringPiece> maybeType =
-            xml::findNonEmptyAttribute(parser, "type")) {
-      resourceType = maybeType.value().toString();
+    if (Maybe<StringPiece> maybe_type =
+            xml::FindNonEmptyAttribute(parser, "type")) {
+      resource_type = maybe_type.value().ToString();
     } else {
-      mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
+      diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
                    << "<item> must have a 'type' attribute");
       return false;
     }
 
-    if (Maybe<StringPiece> maybeFormat =
-            xml::findNonEmptyAttribute(parser, "format")) {
+    if (Maybe<StringPiece> maybe_format =
+            xml::FindNonEmptyAttribute(parser, "format")) {
       // An explicit format for this resource was specified. The resource will
       // retain
       // its type in its name, but the accepted value for this type is
       // overridden.
-      resourceFormat = parseFormatType(maybeFormat.value());
-      if (!resourceFormat) {
-        mDiag->error(DiagMessage(outResource->source)
-                     << "'" << maybeFormat.value() << "' is an invalid format");
+      resource_format = ParseFormatType(maybe_format.value());
+      if (!resource_format) {
+        diag_->Error(DiagMessage(out_resource->source)
+                     << "'" << maybe_format.value()
+                     << "' is an invalid format");
         return false;
       }
     }
@@ -403,65 +408,65 @@
 
   // Get the name of the resource. This will be checked later, because not all
   // XML elements require a name.
-  Maybe<StringPiece> maybeName = xml::findNonEmptyAttribute(parser, "name");
+  Maybe<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name");
 
-  if (resourceType == "id") {
-    if (!maybeName) {
-      mDiag->error(DiagMessage(outResource->source)
-                   << "<" << parser->getElementName()
+  if (resource_type == "id") {
+    if (!maybe_name) {
+      diag_->Error(DiagMessage(out_resource->source)
+                   << "<" << parser->element_name()
                    << "> missing 'name' attribute");
       return false;
     }
 
-    outResource->name.type = ResourceType::kId;
-    outResource->name.entry = maybeName.value().toString();
-    outResource->value = util::make_unique<Id>();
+    out_resource->name.type = ResourceType::kId;
+    out_resource->name.entry = maybe_name.value().ToString();
+    out_resource->value = util::make_unique<Id>();
     return true;
   }
 
-  const auto itemIter = elToItemMap.find(resourceType);
-  if (itemIter != elToItemMap.end()) {
+  const auto item_iter = elToItemMap.find(resource_type);
+  if (item_iter != elToItemMap.end()) {
     // This is an item, record its type and format and start parsing.
 
-    if (!maybeName) {
-      mDiag->error(DiagMessage(outResource->source)
-                   << "<" << parser->getElementName()
+    if (!maybe_name) {
+      diag_->Error(DiagMessage(out_resource->source)
+                   << "<" << parser->element_name()
                    << "> missing 'name' attribute");
       return false;
     }
 
-    outResource->name.type = itemIter->second.type;
-    outResource->name.entry = maybeName.value().toString();
+    out_resource->name.type = item_iter->second.type;
+    out_resource->name.entry = maybe_name.value().ToString();
 
     // Only use the implicit format for this type if it wasn't overridden.
-    if (!resourceFormat) {
-      resourceFormat = itemIter->second.format;
+    if (!resource_format) {
+      resource_format = item_iter->second.format;
     }
 
-    if (!parseItem(parser, outResource, resourceFormat)) {
+    if (!ParseItem(parser, out_resource, resource_format)) {
       return false;
     }
     return true;
   }
 
   // This might be a bag or something.
-  const auto bagIter = elToBagMap.find(resourceType);
-  if (bagIter != elToBagMap.end()) {
+  const auto bag_iter = elToBagMap.find(resource_type);
+  if (bag_iter != elToBagMap.end()) {
     // Ensure we have a name (unless this is a <public-group>).
-    if (resourceType != "public-group") {
-      if (!maybeName) {
-        mDiag->error(DiagMessage(outResource->source)
-                     << "<" << parser->getElementName()
+    if (resource_type != "public-group") {
+      if (!maybe_name) {
+        diag_->Error(DiagMessage(out_resource->source)
+                     << "<" << parser->element_name()
                      << "> missing 'name' attribute");
         return false;
       }
 
-      outResource->name.entry = maybeName.value().toString();
+      out_resource->name.entry = maybe_name.value().ToString();
     }
 
     // Call the associated parse method. The type will be filled in by the
     // parse func.
-    if (!bagIter->second(this, parser, outResource)) {
+    if (!bag_iter->second(this, parser, out_resource)) {
       return false;
     }
     return true;
@@ -469,44 +474,44 @@
 
   // Try parsing the elementName (or type) as a resource. These shall only be
   // resources like 'layout' or 'xml' and they can only be references.
-  const ResourceType* parsedType = parseResourceType(resourceType);
-  if (parsedType) {
-    if (!maybeName) {
-      mDiag->error(DiagMessage(outResource->source)
-                   << "<" << parser->getElementName()
+  const ResourceType* parsed_type = ParseResourceType(resource_type);
+  if (parsed_type) {
+    if (!maybe_name) {
+      diag_->Error(DiagMessage(out_resource->source)
+                   << "<" << parser->element_name()
                    << "> missing 'name' attribute");
       return false;
     }
 
-    outResource->name.type = *parsedType;
-    outResource->name.entry = maybeName.value().toString();
-    outResource->value =
-        parseXml(parser, android::ResTable_map::TYPE_REFERENCE, kNoRawString);
-    if (!outResource->value) {
-      mDiag->error(DiagMessage(outResource->source)
-                   << "invalid value for type '" << *parsedType
+    out_resource->name.type = *parsed_type;
+    out_resource->name.entry = maybe_name.value().ToString();
+    out_resource->value =
+        ParseXml(parser, android::ResTable_map::TYPE_REFERENCE, kNoRawString);
+    if (!out_resource->value) {
+      diag_->Error(DiagMessage(out_resource->source)
+                   << "invalid value for type '" << *parsed_type
                    << "'. Expected a reference");
       return false;
     }
     return true;
   }
 
-  mDiag->warn(DiagMessage(outResource->source)
-              << "unknown resource type '" << parser->getElementName() << "'");
+  diag_->Warn(DiagMessage(out_resource->source)
+              << "unknown resource type '" << parser->element_name() << "'");
   return false;
 }
 
-bool ResourceParser::parseItem(xml::XmlPullParser* parser,
-                               ParsedResource* outResource,
+bool ResourceParser::ParseItem(xml::XmlPullParser* parser,
+                               ParsedResource* out_resource,
                                const uint32_t format) {
   if (format == android::ResTable_map::TYPE_STRING) {
-    return parseString(parser, outResource);
+    return ParseString(parser, out_resource);
   }
 
-  outResource->value = parseXml(parser, format, kNoRawString);
-  if (!outResource->value) {
-    mDiag->error(DiagMessage(outResource->source) << "invalid "
-                                                  << outResource->name.type);
+  out_resource->value = ParseXml(parser, format, kNoRawString);
+  if (!out_resource->value) {
+    diag_->Error(DiagMessage(out_resource->source) << "invalid "
+                                                   << out_resource->name.type);
     return false;
   }
   return true;
@@ -519,361 +524,364 @@
  * an Item. If allowRawValue is false, nullptr is returned in this
  * case.
  */
-std::unique_ptr<Item> ResourceParser::parseXml(xml::XmlPullParser* parser,
-                                               const uint32_t typeMask,
-                                               const bool allowRawValue) {
-  const size_t beginXmlLine = parser->getLineNumber();
+std::unique_ptr<Item> ResourceParser::ParseXml(xml::XmlPullParser* parser,
+                                               const uint32_t type_mask,
+                                               const bool allow_raw_value) {
+  const size_t begin_xml_line = parser->line_number();
 
-  std::string rawValue;
-  StyleString styleString;
-  if (!flattenXmlSubtree(parser, &rawValue, &styleString)) {
+  std::string raw_value;
+  StyleString style_string;
+  if (!FlattenXmlSubtree(parser, &raw_value, &style_string)) {
     return {};
   }
 
-  if (!styleString.spans.empty()) {
+  if (!style_string.spans.empty()) {
     // This can only be a StyledString.
-    return util::make_unique<StyledString>(mTable->stringPool.makeRef(
-        styleString, StringPool::Context{1, mConfig}));
+    return util::make_unique<StyledString>(table_->string_pool.MakeRef(
+        style_string,
+        StringPool::Context(StringPool::Context::kStylePriority, config_)));
   }
 
-  auto onCreateReference = [&](const ResourceName& name) {
+  auto on_create_reference = [&](const ResourceName& name) {
     // name.package can be empty here, as it will assume the package name of the
     // table.
     std::unique_ptr<Id> id = util::make_unique<Id>();
-    id->setSource(mSource.withLine(beginXmlLine));
-    mTable->addResource(name, {}, {}, std::move(id), mDiag);
+    id->SetSource(source_.WithLine(begin_xml_line));
+    table_->AddResource(name, {}, {}, std::move(id), diag_);
   };
 
   // Process the raw value.
-  std::unique_ptr<Item> processedItem = ResourceUtils::tryParseItemForAttribute(
-      rawValue, typeMask, onCreateReference);
-  if (processedItem) {
+  std::unique_ptr<Item> processed_item =
+      ResourceUtils::TryParseItemForAttribute(raw_value, type_mask,
+                                              on_create_reference);
+  if (processed_item) {
     // Fix up the reference.
-    if (Reference* ref = valueCast<Reference>(processedItem.get())) {
-      transformReferenceFromNamespace(parser, "", ref);
+    if (Reference* ref = ValueCast<Reference>(processed_item.get())) {
+      TransformReferenceFromNamespace(parser, "", ref);
     }
-    return processedItem;
+    return processed_item;
   }
 
   // Try making a regular string.
-  if (typeMask & android::ResTable_map::TYPE_STRING) {
+  if (type_mask & android::ResTable_map::TYPE_STRING) {
     // Use the trimmed, escaped string.
-    return util::make_unique<String>(mTable->stringPool.makeRef(
-        styleString.str, StringPool::Context{1, mConfig}));
+    return util::make_unique<String>(table_->string_pool.MakeRef(
+        style_string.str, StringPool::Context(config_)));
   }
 
-  if (allowRawValue) {
+  if (allow_raw_value) {
     // We can't parse this so return a RawString if we are allowed.
     return util::make_unique<RawString>(
-        mTable->stringPool.makeRef(rawValue, StringPool::Context{1, mConfig}));
+        table_->string_pool.MakeRef(raw_value, StringPool::Context(config_)));
   }
   return {};
 }
 
-bool ResourceParser::parseString(xml::XmlPullParser* parser,
-                                 ParsedResource* outResource) {
+bool ResourceParser::ParseString(xml::XmlPullParser* parser,
+                                 ParsedResource* out_resource) {
   bool formatted = true;
-  if (Maybe<StringPiece> formattedAttr =
-          xml::findAttribute(parser, "formatted")) {
-    Maybe<bool> maybeFormatted =
-        ResourceUtils::parseBool(formattedAttr.value());
-    if (!maybeFormatted) {
-      mDiag->error(DiagMessage(outResource->source)
+  if (Maybe<StringPiece> formatted_attr =
+          xml::FindAttribute(parser, "formatted")) {
+    Maybe<bool> maybe_formatted =
+        ResourceUtils::ParseBool(formatted_attr.value());
+    if (!maybe_formatted) {
+      diag_->Error(DiagMessage(out_resource->source)
                    << "invalid value for 'formatted'. Must be a boolean");
       return false;
     }
-    formatted = maybeFormatted.value();
+    formatted = maybe_formatted.value();
   }
 
-  bool translateable = mOptions.translatable;
-  if (Maybe<StringPiece> translateableAttr =
-          xml::findAttribute(parser, "translatable")) {
-    Maybe<bool> maybeTranslateable =
-        ResourceUtils::parseBool(translateableAttr.value());
-    if (!maybeTranslateable) {
-      mDiag->error(DiagMessage(outResource->source)
+  bool translateable = options_.translatable;
+  if (Maybe<StringPiece> translateable_attr =
+          xml::FindAttribute(parser, "translatable")) {
+    Maybe<bool> maybe_translateable =
+        ResourceUtils::ParseBool(translateable_attr.value());
+    if (!maybe_translateable) {
+      diag_->Error(DiagMessage(out_resource->source)
                    << "invalid value for 'translatable'. Must be a boolean");
       return false;
     }
-    translateable = maybeTranslateable.value();
+    translateable = maybe_translateable.value();
   }
 
-  outResource->value =
-      parseXml(parser, android::ResTable_map::TYPE_STRING, kNoRawString);
-  if (!outResource->value) {
-    mDiag->error(DiagMessage(outResource->source) << "not a valid string");
+  out_resource->value =
+      ParseXml(parser, android::ResTable_map::TYPE_STRING, kNoRawString);
+  if (!out_resource->value) {
+    diag_->Error(DiagMessage(out_resource->source) << "not a valid string");
     return false;
   }
 
-  if (String* stringValue = valueCast<String>(outResource->value.get())) {
-    stringValue->setTranslateable(translateable);
+  if (String* string_value = ValueCast<String>(out_resource->value.get())) {
+    string_value->SetTranslateable(translateable);
 
     if (formatted && translateable) {
-      if (!util::verifyJavaStringFormat(*stringValue->value)) {
-        DiagMessage msg(outResource->source);
+      if (!util::VerifyJavaStringFormat(*string_value->value)) {
+        DiagMessage msg(out_resource->source);
         msg << "multiple substitutions specified in non-positional format; "
                "did you mean to add the formatted=\"false\" attribute?";
-        if (mOptions.errorOnPositionalArguments) {
-          mDiag->error(msg);
+        if (options_.error_on_positional_arguments) {
+          diag_->Error(msg);
           return false;
         }
 
-        mDiag->warn(msg);
+        diag_->Warn(msg);
       }
     }
 
-  } else if (StyledString* stringValue =
-                 valueCast<StyledString>(outResource->value.get())) {
-    stringValue->setTranslateable(translateable);
+  } else if (StyledString* string_value =
+                 ValueCast<StyledString>(out_resource->value.get())) {
+    string_value->SetTranslateable(translateable);
   }
   return true;
 }
 
-bool ResourceParser::parsePublic(xml::XmlPullParser* parser,
-                                 ParsedResource* outResource) {
-  Maybe<StringPiece> maybeType = xml::findNonEmptyAttribute(parser, "type");
-  if (!maybeType) {
-    mDiag->error(DiagMessage(outResource->source)
+bool ResourceParser::ParsePublic(xml::XmlPullParser* parser,
+                                 ParsedResource* out_resource) {
+  Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type");
+  if (!maybe_type) {
+    diag_->Error(DiagMessage(out_resource->source)
                  << "<public> must have a 'type' attribute");
     return false;
   }
 
-  const ResourceType* parsedType = parseResourceType(maybeType.value());
-  if (!parsedType) {
-    mDiag->error(DiagMessage(outResource->source) << "invalid resource type '"
-                                                  << maybeType.value()
-                                                  << "' in <public>");
+  const ResourceType* parsed_type = ParseResourceType(maybe_type.value());
+  if (!parsed_type) {
+    diag_->Error(DiagMessage(out_resource->source) << "invalid resource type '"
+                                                   << maybe_type.value()
+                                                   << "' in <public>");
     return false;
   }
 
-  outResource->name.type = *parsedType;
+  out_resource->name.type = *parsed_type;
 
-  if (Maybe<StringPiece> maybeIdStr =
-          xml::findNonEmptyAttribute(parser, "id")) {
-    Maybe<ResourceId> maybeId =
-        ResourceUtils::parseResourceId(maybeIdStr.value());
-    if (!maybeId) {
-      mDiag->error(DiagMessage(outResource->source) << "invalid resource ID '"
-                                                    << maybeId.value()
-                                                    << "' in <public>");
+  if (Maybe<StringPiece> maybe_id_str =
+          xml::FindNonEmptyAttribute(parser, "id")) {
+    Maybe<ResourceId> maybe_id =
+        ResourceUtils::ParseResourceId(maybe_id_str.value());
+    if (!maybe_id) {
+      diag_->Error(DiagMessage(out_resource->source) << "invalid resource ID '"
+                                                     << maybe_id.value()
+                                                     << "' in <public>");
       return false;
     }
-    outResource->id = maybeId.value();
+    out_resource->id = maybe_id.value();
   }
 
-  if (*parsedType == ResourceType::kId) {
+  if (*parsed_type == ResourceType::kId) {
     // An ID marked as public is also the definition of an ID.
-    outResource->value = util::make_unique<Id>();
+    out_resource->value = util::make_unique<Id>();
   }
 
-  outResource->symbolState = SymbolState::kPublic;
+  out_resource->symbol_state = SymbolState::kPublic;
   return true;
 }
 
-bool ResourceParser::parsePublicGroup(xml::XmlPullParser* parser,
-                                      ParsedResource* outResource) {
-  Maybe<StringPiece> maybeType = xml::findNonEmptyAttribute(parser, "type");
-  if (!maybeType) {
-    mDiag->error(DiagMessage(outResource->source)
+bool ResourceParser::ParsePublicGroup(xml::XmlPullParser* parser,
+                                      ParsedResource* out_resource) {
+  Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type");
+  if (!maybe_type) {
+    diag_->Error(DiagMessage(out_resource->source)
                  << "<public-group> must have a 'type' attribute");
     return false;
   }
 
-  const ResourceType* parsedType = parseResourceType(maybeType.value());
-  if (!parsedType) {
-    mDiag->error(DiagMessage(outResource->source) << "invalid resource type '"
-                                                  << maybeType.value()
-                                                  << "' in <public-group>");
+  const ResourceType* parsed_type = ParseResourceType(maybe_type.value());
+  if (!parsed_type) {
+    diag_->Error(DiagMessage(out_resource->source) << "invalid resource type '"
+                                                   << maybe_type.value()
+                                                   << "' in <public-group>");
     return false;
   }
 
-  Maybe<StringPiece> maybeIdStr =
-      xml::findNonEmptyAttribute(parser, "first-id");
-  if (!maybeIdStr) {
-    mDiag->error(DiagMessage(outResource->source)
+  Maybe<StringPiece> maybe_id_str =
+      xml::FindNonEmptyAttribute(parser, "first-id");
+  if (!maybe_id_str) {
+    diag_->Error(DiagMessage(out_resource->source)
                  << "<public-group> must have a 'first-id' attribute");
     return false;
   }
 
-  Maybe<ResourceId> maybeId =
-      ResourceUtils::parseResourceId(maybeIdStr.value());
-  if (!maybeId) {
-    mDiag->error(DiagMessage(outResource->source) << "invalid resource ID '"
-                                                  << maybeIdStr.value()
-                                                  << "' in <public-group>");
+  Maybe<ResourceId> maybe_id =
+      ResourceUtils::ParseResourceId(maybe_id_str.value());
+  if (!maybe_id) {
+    diag_->Error(DiagMessage(out_resource->source) << "invalid resource ID '"
+                                                   << maybe_id_str.value()
+                                                   << "' in <public-group>");
     return false;
   }
 
-  ResourceId nextId = maybeId.value();
+  ResourceId next_id = maybe_id.value();
 
   std::string comment;
   bool error = false;
-  const size_t depth = parser->getDepth();
-  while (xml::XmlPullParser::nextChildNode(parser, depth)) {
-    if (parser->getEvent() == xml::XmlPullParser::Event::kComment) {
-      comment = util::trimWhitespace(parser->getComment()).toString();
+  const size_t depth = parser->depth();
+  while (xml::XmlPullParser::NextChildNode(parser, depth)) {
+    if (parser->event() == xml::XmlPullParser::Event::kComment) {
+      comment = util::TrimWhitespace(parser->comment()).ToString();
       continue;
-    } else if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) {
+    } else if (parser->event() != xml::XmlPullParser::Event::kStartElement) {
       // Skip text.
       continue;
     }
 
-    const Source itemSource = mSource.withLine(parser->getLineNumber());
-    const std::string& elementNamespace = parser->getElementNamespace();
-    const std::string& elementName = parser->getElementName();
-    if (elementNamespace.empty() && elementName == "public") {
-      Maybe<StringPiece> maybeName = xml::findNonEmptyAttribute(parser, "name");
-      if (!maybeName) {
-        mDiag->error(DiagMessage(itemSource)
+    const Source item_source = source_.WithLine(parser->line_number());
+    const std::string& element_namespace = parser->element_namespace();
+    const std::string& element_name = parser->element_name();
+    if (element_namespace.empty() && element_name == "public") {
+      Maybe<StringPiece> maybe_name =
+          xml::FindNonEmptyAttribute(parser, "name");
+      if (!maybe_name) {
+        diag_->Error(DiagMessage(item_source)
                      << "<public> must have a 'name' attribute");
         error = true;
         continue;
       }
 
-      if (xml::findNonEmptyAttribute(parser, "id")) {
-        mDiag->error(DiagMessage(itemSource)
+      if (xml::FindNonEmptyAttribute(parser, "id")) {
+        diag_->Error(DiagMessage(item_source)
                      << "'id' is ignored within <public-group>");
         error = true;
         continue;
       }
 
-      if (xml::findNonEmptyAttribute(parser, "type")) {
-        mDiag->error(DiagMessage(itemSource)
+      if (xml::FindNonEmptyAttribute(parser, "type")) {
+        diag_->Error(DiagMessage(item_source)
                      << "'type' is ignored within <public-group>");
         error = true;
         continue;
       }
 
-      ParsedResource childResource;
-      childResource.name.type = *parsedType;
-      childResource.name.entry = maybeName.value().toString();
-      childResource.id = nextId;
-      childResource.comment = std::move(comment);
-      childResource.source = itemSource;
-      childResource.symbolState = SymbolState::kPublic;
-      outResource->childResources.push_back(std::move(childResource));
+      ParsedResource child_resource;
+      child_resource.name.type = *parsed_type;
+      child_resource.name.entry = maybe_name.value().ToString();
+      child_resource.id = next_id;
+      child_resource.comment = std::move(comment);
+      child_resource.source = item_source;
+      child_resource.symbol_state = SymbolState::kPublic;
+      out_resource->child_resources.push_back(std::move(child_resource));
 
-      nextId.id += 1;
+      next_id.id += 1;
 
-    } else if (!shouldIgnoreElement(elementNamespace, elementName)) {
-      mDiag->error(DiagMessage(itemSource) << ":" << elementName << ">");
+    } else if (!ShouldIgnoreElement(element_namespace, element_name)) {
+      diag_->Error(DiagMessage(item_source) << ":" << element_name << ">");
       error = true;
     }
   }
   return !error;
 }
 
-bool ResourceParser::parseSymbolImpl(xml::XmlPullParser* parser,
-                                     ParsedResource* outResource) {
-  Maybe<StringPiece> maybeType = xml::findNonEmptyAttribute(parser, "type");
-  if (!maybeType) {
-    mDiag->error(DiagMessage(outResource->source)
-                 << "<" << parser->getElementName()
+bool ResourceParser::ParseSymbolImpl(xml::XmlPullParser* parser,
+                                     ParsedResource* out_resource) {
+  Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type");
+  if (!maybe_type) {
+    diag_->Error(DiagMessage(out_resource->source)
+                 << "<" << parser->element_name()
                  << "> must have a 'type' attribute");
     return false;
   }
 
-  const ResourceType* parsedType = parseResourceType(maybeType.value());
-  if (!parsedType) {
-    mDiag->error(DiagMessage(outResource->source)
-                 << "invalid resource type '" << maybeType.value() << "' in <"
-                 << parser->getElementName() << ">");
+  const ResourceType* parsed_type = ParseResourceType(maybe_type.value());
+  if (!parsed_type) {
+    diag_->Error(DiagMessage(out_resource->source)
+                 << "invalid resource type '" << maybe_type.value() << "' in <"
+                 << parser->element_name() << ">");
     return false;
   }
 
-  outResource->name.type = *parsedType;
+  out_resource->name.type = *parsed_type;
   return true;
 }
 
-bool ResourceParser::parseSymbol(xml::XmlPullParser* parser,
-                                 ParsedResource* outResource) {
-  if (parseSymbolImpl(parser, outResource)) {
-    outResource->symbolState = SymbolState::kPrivate;
+bool ResourceParser::ParseSymbol(xml::XmlPullParser* parser,
+                                 ParsedResource* out_resource) {
+  if (ParseSymbolImpl(parser, out_resource)) {
+    out_resource->symbol_state = SymbolState::kPrivate;
     return true;
   }
   return false;
 }
 
-bool ResourceParser::parseAddResource(xml::XmlPullParser* parser,
-                                      ParsedResource* outResource) {
-  if (parseSymbolImpl(parser, outResource)) {
-    outResource->symbolState = SymbolState::kUndefined;
+bool ResourceParser::ParseAddResource(xml::XmlPullParser* parser,
+                                      ParsedResource* out_resource) {
+  if (ParseSymbolImpl(parser, out_resource)) {
+    out_resource->symbol_state = SymbolState::kUndefined;
     return true;
   }
   return false;
 }
 
-bool ResourceParser::parseAttr(xml::XmlPullParser* parser,
-                               ParsedResource* outResource) {
-  return parseAttrImpl(parser, outResource, false);
+bool ResourceParser::ParseAttr(xml::XmlPullParser* parser,
+                               ParsedResource* out_resource) {
+  return ParseAttrImpl(parser, out_resource, false);
 }
 
-bool ResourceParser::parseAttrImpl(xml::XmlPullParser* parser,
-                                   ParsedResource* outResource, bool weak) {
-  outResource->name.type = ResourceType::kAttr;
+bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
+                                   ParsedResource* out_resource, bool weak) {
+  out_resource->name.type = ResourceType::kAttr;
 
   // Attributes only end up in default configuration.
-  if (outResource->config != ConfigDescription::defaultConfig()) {
-    mDiag->warn(DiagMessage(outResource->source)
-                << "ignoring configuration '" << outResource->config
-                << "' for attribute " << outResource->name);
-    outResource->config = ConfigDescription::defaultConfig();
+  if (out_resource->config != ConfigDescription::DefaultConfig()) {
+    diag_->Warn(DiagMessage(out_resource->source)
+                << "ignoring configuration '" << out_resource->config
+                << "' for attribute " << out_resource->name);
+    out_resource->config = ConfigDescription::DefaultConfig();
   }
 
-  uint32_t typeMask = 0;
+  uint32_t type_mask = 0;
 
-  Maybe<StringPiece> maybeFormat = xml::findAttribute(parser, "format");
-  if (maybeFormat) {
-    typeMask = parseFormatAttribute(maybeFormat.value());
-    if (typeMask == 0) {
-      mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
-                   << "invalid attribute format '" << maybeFormat.value()
+  Maybe<StringPiece> maybe_format = xml::FindAttribute(parser, "format");
+  if (maybe_format) {
+    type_mask = ParseFormatAttribute(maybe_format.value());
+    if (type_mask == 0) {
+      diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
+                   << "invalid attribute format '" << maybe_format.value()
                    << "'");
       return false;
     }
   }
 
-  Maybe<int32_t> maybeMin, maybeMax;
+  Maybe<int32_t> maybe_min, maybe_max;
 
-  if (Maybe<StringPiece> maybeMinStr = xml::findAttribute(parser, "min")) {
-    StringPiece minStr = util::trimWhitespace(maybeMinStr.value());
-    if (!minStr.empty()) {
-      std::u16string minStr16 = util::utf8ToUtf16(minStr);
+  if (Maybe<StringPiece> maybe_min_str = xml::FindAttribute(parser, "min")) {
+    StringPiece min_str = util::TrimWhitespace(maybe_min_str.value());
+    if (!min_str.empty()) {
+      std::u16string min_str16 = util::Utf8ToUtf16(min_str);
       android::Res_value value;
-      if (android::ResTable::stringToInt(minStr16.data(), minStr16.size(),
+      if (android::ResTable::stringToInt(min_str16.data(), min_str16.size(),
                                          &value)) {
-        maybeMin = static_cast<int32_t>(value.data);
+        maybe_min = static_cast<int32_t>(value.data);
       }
     }
 
-    if (!maybeMin) {
-      mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
-                   << "invalid 'min' value '" << minStr << "'");
+    if (!maybe_min) {
+      diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
+                   << "invalid 'min' value '" << min_str << "'");
       return false;
     }
   }
 
-  if (Maybe<StringPiece> maybeMaxStr = xml::findAttribute(parser, "max")) {
-    StringPiece maxStr = util::trimWhitespace(maybeMaxStr.value());
-    if (!maxStr.empty()) {
-      std::u16string maxStr16 = util::utf8ToUtf16(maxStr);
+  if (Maybe<StringPiece> maybe_max_str = xml::FindAttribute(parser, "max")) {
+    StringPiece max_str = util::TrimWhitespace(maybe_max_str.value());
+    if (!max_str.empty()) {
+      std::u16string max_str16 = util::Utf8ToUtf16(max_str);
       android::Res_value value;
-      if (android::ResTable::stringToInt(maxStr16.data(), maxStr16.size(),
+      if (android::ResTable::stringToInt(max_str16.data(), max_str16.size(),
                                          &value)) {
-        maybeMax = static_cast<int32_t>(value.data);
+        maybe_max = static_cast<int32_t>(value.data);
       }
     }
 
-    if (!maybeMax) {
-      mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
-                   << "invalid 'max' value '" << maxStr << "'");
+    if (!maybe_max) {
+      diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
+                   << "invalid 'max' value '" << max_str << "'");
       return false;
     }
   }
 
-  if ((maybeMin || maybeMax) &&
-      (typeMask & android::ResTable_map::TYPE_INTEGER) == 0) {
-    mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
+  if ((maybe_min || maybe_max) &&
+      (type_mask & android::ResTable_map::TYPE_INTEGER) == 0) {
+    diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
                  << "'min' and 'max' can only be used when format='integer'");
     return false;
   }
@@ -888,68 +896,68 @@
 
   std::string comment;
   bool error = false;
-  const size_t depth = parser->getDepth();
-  while (xml::XmlPullParser::nextChildNode(parser, depth)) {
-    if (parser->getEvent() == xml::XmlPullParser::Event::kComment) {
-      comment = util::trimWhitespace(parser->getComment()).toString();
+  const size_t depth = parser->depth();
+  while (xml::XmlPullParser::NextChildNode(parser, depth)) {
+    if (parser->event() == xml::XmlPullParser::Event::kComment) {
+      comment = util::TrimWhitespace(parser->comment()).ToString();
       continue;
-    } else if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) {
+    } else if (parser->event() != xml::XmlPullParser::Event::kStartElement) {
       // Skip text.
       continue;
     }
 
-    const Source itemSource = mSource.withLine(parser->getLineNumber());
-    const std::string& elementNamespace = parser->getElementNamespace();
-    const std::string& elementName = parser->getElementName();
-    if (elementNamespace.empty() &&
-        (elementName == "flag" || elementName == "enum")) {
-      if (elementName == "enum") {
-        if (typeMask & android::ResTable_map::TYPE_FLAGS) {
-          mDiag->error(DiagMessage(itemSource)
+    const Source item_source = source_.WithLine(parser->line_number());
+    const std::string& element_namespace = parser->element_namespace();
+    const std::string& element_name = parser->element_name();
+    if (element_namespace.empty() &&
+        (element_name == "flag" || element_name == "enum")) {
+      if (element_name == "enum") {
+        if (type_mask & android::ResTable_map::TYPE_FLAGS) {
+          diag_->Error(DiagMessage(item_source)
                        << "can not define an <enum>; already defined a <flag>");
           error = true;
           continue;
         }
-        typeMask |= android::ResTable_map::TYPE_ENUM;
+        type_mask |= android::ResTable_map::TYPE_ENUM;
 
-      } else if (elementName == "flag") {
-        if (typeMask & android::ResTable_map::TYPE_ENUM) {
-          mDiag->error(DiagMessage(itemSource)
+      } else if (element_name == "flag") {
+        if (type_mask & android::ResTable_map::TYPE_ENUM) {
+          diag_->Error(DiagMessage(item_source)
                        << "can not define a <flag>; already defined an <enum>");
           error = true;
           continue;
         }
-        typeMask |= android::ResTable_map::TYPE_FLAGS;
+        type_mask |= android::ResTable_map::TYPE_FLAGS;
       }
 
       if (Maybe<Attribute::Symbol> s =
-              parseEnumOrFlagItem(parser, elementName)) {
+              ParseEnumOrFlagItem(parser, element_name)) {
         Attribute::Symbol& symbol = s.value();
-        ParsedResource childResource;
-        childResource.name = symbol.symbol.name.value();
-        childResource.source = itemSource;
-        childResource.value = util::make_unique<Id>();
-        outResource->childResources.push_back(std::move(childResource));
+        ParsedResource child_resource;
+        child_resource.name = symbol.symbol.name.value();
+        child_resource.source = item_source;
+        child_resource.value = util::make_unique<Id>();
+        out_resource->child_resources.push_back(std::move(child_resource));
 
-        symbol.symbol.setComment(std::move(comment));
-        symbol.symbol.setSource(itemSource);
+        symbol.symbol.SetComment(std::move(comment));
+        symbol.symbol.SetSource(item_source);
 
-        auto insertResult = items.insert(std::move(symbol));
-        if (!insertResult.second) {
-          const Attribute::Symbol& existingSymbol = *insertResult.first;
-          mDiag->error(DiagMessage(itemSource)
+        auto insert_result = items.insert(std::move(symbol));
+        if (!insert_result.second) {
+          const Attribute::Symbol& existing_symbol = *insert_result.first;
+          diag_->Error(DiagMessage(item_source)
                        << "duplicate symbol '"
-                       << existingSymbol.symbol.name.value().entry << "'");
+                       << existing_symbol.symbol.name.value().entry << "'");
 
-          mDiag->note(DiagMessage(existingSymbol.symbol.getSource())
+          diag_->Note(DiagMessage(existing_symbol.symbol.GetSource())
                       << "first defined here");
           error = true;
         }
       } else {
         error = true;
       }
-    } else if (!shouldIgnoreElement(elementNamespace, elementName)) {
-      mDiag->error(DiagMessage(itemSource) << ":" << elementName << ">");
+    } else if (!ShouldIgnoreElement(element_namespace, element_name)) {
+      diag_->Error(DiagMessage(item_source) << ":" << element_name << ">");
       error = true;
     }
 
@@ -962,134 +970,134 @@
 
   std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(weak);
   attr->symbols = std::vector<Attribute::Symbol>(items.begin(), items.end());
-  attr->typeMask =
-      typeMask ? typeMask : uint32_t(android::ResTable_map::TYPE_ANY);
-  if (maybeMin) {
-    attr->minInt = maybeMin.value();
+  attr->type_mask =
+      type_mask ? type_mask : uint32_t(android::ResTable_map::TYPE_ANY);
+  if (maybe_min) {
+    attr->min_int = maybe_min.value();
   }
 
-  if (maybeMax) {
-    attr->maxInt = maybeMax.value();
+  if (maybe_max) {
+    attr->max_int = maybe_max.value();
   }
-  outResource->value = std::move(attr);
+  out_resource->value = std::move(attr);
   return true;
 }
 
-Maybe<Attribute::Symbol> ResourceParser::parseEnumOrFlagItem(
+Maybe<Attribute::Symbol> ResourceParser::ParseEnumOrFlagItem(
     xml::XmlPullParser* parser, const StringPiece& tag) {
-  const Source source = mSource.withLine(parser->getLineNumber());
+  const Source source = source_.WithLine(parser->line_number());
 
-  Maybe<StringPiece> maybeName = xml::findNonEmptyAttribute(parser, "name");
-  if (!maybeName) {
-    mDiag->error(DiagMessage(source) << "no attribute 'name' found for tag <"
+  Maybe<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name");
+  if (!maybe_name) {
+    diag_->Error(DiagMessage(source) << "no attribute 'name' found for tag <"
                                      << tag << ">");
     return {};
   }
 
-  Maybe<StringPiece> maybeValue = xml::findNonEmptyAttribute(parser, "value");
-  if (!maybeValue) {
-    mDiag->error(DiagMessage(source) << "no attribute 'value' found for tag <"
+  Maybe<StringPiece> maybe_value = xml::FindNonEmptyAttribute(parser, "value");
+  if (!maybe_value) {
+    diag_->Error(DiagMessage(source) << "no attribute 'value' found for tag <"
                                      << tag << ">");
     return {};
   }
 
-  std::u16string value16 = util::utf8ToUtf16(maybeValue.value());
+  std::u16string value16 = util::Utf8ToUtf16(maybe_value.value());
   android::Res_value val;
   if (!android::ResTable::stringToInt(value16.data(), value16.size(), &val)) {
-    mDiag->error(DiagMessage(source) << "invalid value '" << maybeValue.value()
+    diag_->Error(DiagMessage(source) << "invalid value '" << maybe_value.value()
                                      << "' for <" << tag
                                      << ">; must be an integer");
     return {};
   }
 
   return Attribute::Symbol{
-      Reference(ResourceNameRef({}, ResourceType::kId, maybeName.value())),
+      Reference(ResourceNameRef({}, ResourceType::kId, maybe_name.value())),
       val.data};
 }
 
-bool ResourceParser::parseStyleItem(xml::XmlPullParser* parser, Style* style) {
-  const Source source = mSource.withLine(parser->getLineNumber());
+bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) {
+  const Source source = source_.WithLine(parser->line_number());
 
-  Maybe<StringPiece> maybeName = xml::findNonEmptyAttribute(parser, "name");
-  if (!maybeName) {
-    mDiag->error(DiagMessage(source) << "<item> must have a 'name' attribute");
+  Maybe<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name");
+  if (!maybe_name) {
+    diag_->Error(DiagMessage(source) << "<item> must have a 'name' attribute");
     return false;
   }
 
-  Maybe<Reference> maybeKey =
-      ResourceUtils::parseXmlAttributeName(maybeName.value());
-  if (!maybeKey) {
-    mDiag->error(DiagMessage(source) << "invalid attribute name '"
-                                     << maybeName.value() << "'");
+  Maybe<Reference> maybe_key =
+      ResourceUtils::ParseXmlAttributeName(maybe_name.value());
+  if (!maybe_key) {
+    diag_->Error(DiagMessage(source) << "invalid attribute name '"
+                                     << maybe_name.value() << "'");
     return false;
   }
 
-  transformReferenceFromNamespace(parser, "", &maybeKey.value());
-  maybeKey.value().setSource(source);
+  TransformReferenceFromNamespace(parser, "", &maybe_key.value());
+  maybe_key.value().SetSource(source);
 
-  std::unique_ptr<Item> value = parseXml(parser, 0, kAllowRawString);
+  std::unique_ptr<Item> value = ParseXml(parser, 0, kAllowRawString);
   if (!value) {
-    mDiag->error(DiagMessage(source) << "could not parse style item");
+    diag_->Error(DiagMessage(source) << "could not parse style item");
     return false;
   }
 
   style->entries.push_back(
-      Style::Entry{std::move(maybeKey.value()), std::move(value)});
+      Style::Entry{std::move(maybe_key.value()), std::move(value)});
   return true;
 }
 
-bool ResourceParser::parseStyle(xml::XmlPullParser* parser,
-                                ParsedResource* outResource) {
-  outResource->name.type = ResourceType::kStyle;
+bool ResourceParser::ParseStyle(xml::XmlPullParser* parser,
+                                ParsedResource* out_resource) {
+  out_resource->name.type = ResourceType::kStyle;
 
   std::unique_ptr<Style> style = util::make_unique<Style>();
 
-  Maybe<StringPiece> maybeParent = xml::findAttribute(parser, "parent");
-  if (maybeParent) {
+  Maybe<StringPiece> maybe_parent = xml::FindAttribute(parser, "parent");
+  if (maybe_parent) {
     // If the parent is empty, we don't have a parent, but we also don't infer
     // either.
-    if (!maybeParent.value().empty()) {
-      std::string errStr;
-      style->parent = ResourceUtils::parseStyleParentReference(
-          maybeParent.value(), &errStr);
+    if (!maybe_parent.value().empty()) {
+      std::string err_str;
+      style->parent = ResourceUtils::ParseStyleParentReference(
+          maybe_parent.value(), &err_str);
       if (!style->parent) {
-        mDiag->error(DiagMessage(outResource->source) << errStr);
+        diag_->Error(DiagMessage(out_resource->source) << err_str);
         return false;
       }
 
       // Transform the namespace prefix to the actual package name, and mark the
       // reference as
       // private if appropriate.
-      transformReferenceFromNamespace(parser, "", &style->parent.value());
+      TransformReferenceFromNamespace(parser, "", &style->parent.value());
     }
 
   } else {
     // No parent was specified, so try inferring it from the style name.
-    std::string styleName = outResource->name.entry;
-    size_t pos = styleName.find_last_of(u'.');
+    std::string style_name = out_resource->name.entry;
+    size_t pos = style_name.find_last_of(u'.');
     if (pos != std::string::npos) {
-      style->parentInferred = true;
+      style->parent_inferred = true;
       style->parent = Reference(
-          ResourceName({}, ResourceType::kStyle, styleName.substr(0, pos)));
+          ResourceName({}, ResourceType::kStyle, style_name.substr(0, pos)));
     }
   }
 
   bool error = false;
-  const size_t depth = parser->getDepth();
-  while (xml::XmlPullParser::nextChildNode(parser, depth)) {
-    if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) {
+  const size_t depth = parser->depth();
+  while (xml::XmlPullParser::NextChildNode(parser, depth)) {
+    if (parser->event() != xml::XmlPullParser::Event::kStartElement) {
       // Skip text and comments.
       continue;
     }
 
-    const std::string& elementNamespace = parser->getElementNamespace();
-    const std::string& elementName = parser->getElementName();
-    if (elementNamespace == "" && elementName == "item") {
-      error |= !parseStyleItem(parser, style.get());
+    const std::string& element_namespace = parser->element_namespace();
+    const std::string& element_name = parser->element_name();
+    if (element_namespace == "" && element_name == "item") {
+      error |= !ParseStyleItem(parser, style.get());
 
-    } else if (!shouldIgnoreElement(elementNamespace, elementName)) {
-      mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
-                   << ":" << elementName << ">");
+    } else if (!ShouldIgnoreElement(element_namespace, element_name)) {
+      diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
+                   << ":" << element_name << ">");
       error = true;
     }
   }
@@ -1098,73 +1106,73 @@
     return false;
   }
 
-  outResource->value = std::move(style);
+  out_resource->value = std::move(style);
   return true;
 }
 
-bool ResourceParser::parseArray(xml::XmlPullParser* parser,
-                                ParsedResource* outResource) {
-  return parseArrayImpl(parser, outResource, android::ResTable_map::TYPE_ANY);
+bool ResourceParser::ParseArray(xml::XmlPullParser* parser,
+                                ParsedResource* out_resource) {
+  return ParseArrayImpl(parser, out_resource, android::ResTable_map::TYPE_ANY);
 }
 
-bool ResourceParser::parseIntegerArray(xml::XmlPullParser* parser,
-                                       ParsedResource* outResource) {
-  return parseArrayImpl(parser, outResource,
+bool ResourceParser::ParseIntegerArray(xml::XmlPullParser* parser,
+                                       ParsedResource* out_resource) {
+  return ParseArrayImpl(parser, out_resource,
                         android::ResTable_map::TYPE_INTEGER);
 }
 
-bool ResourceParser::parseStringArray(xml::XmlPullParser* parser,
-                                      ParsedResource* outResource) {
-  return parseArrayImpl(parser, outResource,
+bool ResourceParser::ParseStringArray(xml::XmlPullParser* parser,
+                                      ParsedResource* out_resource) {
+  return ParseArrayImpl(parser, out_resource,
                         android::ResTable_map::TYPE_STRING);
 }
 
-bool ResourceParser::parseArrayImpl(xml::XmlPullParser* parser,
-                                    ParsedResource* outResource,
+bool ResourceParser::ParseArrayImpl(xml::XmlPullParser* parser,
+                                    ParsedResource* out_resource,
                                     const uint32_t typeMask) {
-  outResource->name.type = ResourceType::kArray;
+  out_resource->name.type = ResourceType::kArray;
 
   std::unique_ptr<Array> array = util::make_unique<Array>();
 
-  bool translateable = mOptions.translatable;
-  if (Maybe<StringPiece> translateableAttr =
-          xml::findAttribute(parser, "translatable")) {
-    Maybe<bool> maybeTranslateable =
-        ResourceUtils::parseBool(translateableAttr.value());
-    if (!maybeTranslateable) {
-      mDiag->error(DiagMessage(outResource->source)
+  bool translateable = options_.translatable;
+  if (Maybe<StringPiece> translateable_attr =
+          xml::FindAttribute(parser, "translatable")) {
+    Maybe<bool> maybe_translateable =
+        ResourceUtils::ParseBool(translateable_attr.value());
+    if (!maybe_translateable) {
+      diag_->Error(DiagMessage(out_resource->source)
                    << "invalid value for 'translatable'. Must be a boolean");
       return false;
     }
-    translateable = maybeTranslateable.value();
+    translateable = maybe_translateable.value();
   }
-  array->setTranslateable(translateable);
+  array->SetTranslateable(translateable);
 
   bool error = false;
-  const size_t depth = parser->getDepth();
-  while (xml::XmlPullParser::nextChildNode(parser, depth)) {
-    if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) {
+  const size_t depth = parser->depth();
+  while (xml::XmlPullParser::NextChildNode(parser, depth)) {
+    if (parser->event() != xml::XmlPullParser::Event::kStartElement) {
       // Skip text and comments.
       continue;
     }
 
-    const Source itemSource = mSource.withLine(parser->getLineNumber());
-    const std::string& elementNamespace = parser->getElementNamespace();
-    const std::string& elementName = parser->getElementName();
-    if (elementNamespace.empty() && elementName == "item") {
-      std::unique_ptr<Item> item = parseXml(parser, typeMask, kNoRawString);
+    const Source item_source = source_.WithLine(parser->line_number());
+    const std::string& element_namespace = parser->element_namespace();
+    const std::string& element_name = parser->element_name();
+    if (element_namespace.empty() && element_name == "item") {
+      std::unique_ptr<Item> item = ParseXml(parser, typeMask, kNoRawString);
       if (!item) {
-        mDiag->error(DiagMessage(itemSource) << "could not parse array item");
+        diag_->Error(DiagMessage(item_source) << "could not parse array item");
         error = true;
         continue;
       }
-      item->setSource(itemSource);
+      item->SetSource(item_source);
       array->items.emplace_back(std::move(item));
 
-    } else if (!shouldIgnoreElement(elementNamespace, elementName)) {
-      mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
-                   << "unknown tag <" << elementNamespace << ":" << elementName
-                   << ">");
+    } else if (!ShouldIgnoreElement(element_namespace, element_name)) {
+      diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
+                   << "unknown tag <" << element_namespace << ":"
+                   << element_name << ">");
       error = true;
     }
   }
@@ -1173,77 +1181,78 @@
     return false;
   }
 
-  outResource->value = std::move(array);
+  out_resource->value = std::move(array);
   return true;
 }
 
-bool ResourceParser::parsePlural(xml::XmlPullParser* parser,
-                                 ParsedResource* outResource) {
-  outResource->name.type = ResourceType::kPlurals;
+bool ResourceParser::ParsePlural(xml::XmlPullParser* parser,
+                                 ParsedResource* out_resource) {
+  out_resource->name.type = ResourceType::kPlurals;
 
   std::unique_ptr<Plural> plural = util::make_unique<Plural>();
 
   bool error = false;
-  const size_t depth = parser->getDepth();
-  while (xml::XmlPullParser::nextChildNode(parser, depth)) {
-    if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) {
+  const size_t depth = parser->depth();
+  while (xml::XmlPullParser::NextChildNode(parser, depth)) {
+    if (parser->event() != xml::XmlPullParser::Event::kStartElement) {
       // Skip text and comments.
       continue;
     }
 
-    const Source itemSource = mSource.withLine(parser->getLineNumber());
-    const std::string& elementNamespace = parser->getElementNamespace();
-    const std::string& elementName = parser->getElementName();
-    if (elementNamespace.empty() && elementName == "item") {
-      Maybe<StringPiece> maybeQuantity =
-          xml::findNonEmptyAttribute(parser, "quantity");
-      if (!maybeQuantity) {
-        mDiag->error(DiagMessage(itemSource)
+    const Source item_source = source_.WithLine(parser->line_number());
+    const std::string& element_namespace = parser->element_namespace();
+    const std::string& element_name = parser->element_name();
+    if (element_namespace.empty() && element_name == "item") {
+      Maybe<StringPiece> maybe_quantity =
+          xml::FindNonEmptyAttribute(parser, "quantity");
+      if (!maybe_quantity) {
+        diag_->Error(DiagMessage(item_source)
                      << "<item> in <plurals> requires attribute "
                      << "'quantity'");
         error = true;
         continue;
       }
 
-      StringPiece trimmedQuantity = util::trimWhitespace(maybeQuantity.value());
+      StringPiece trimmed_quantity =
+          util::TrimWhitespace(maybe_quantity.value());
       size_t index = 0;
-      if (trimmedQuantity == "zero") {
+      if (trimmed_quantity == "zero") {
         index = Plural::Zero;
-      } else if (trimmedQuantity == "one") {
+      } else if (trimmed_quantity == "one") {
         index = Plural::One;
-      } else if (trimmedQuantity == "two") {
+      } else if (trimmed_quantity == "two") {
         index = Plural::Two;
-      } else if (trimmedQuantity == "few") {
+      } else if (trimmed_quantity == "few") {
         index = Plural::Few;
-      } else if (trimmedQuantity == "many") {
+      } else if (trimmed_quantity == "many") {
         index = Plural::Many;
-      } else if (trimmedQuantity == "other") {
+      } else if (trimmed_quantity == "other") {
         index = Plural::Other;
       } else {
-        mDiag->error(DiagMessage(itemSource)
+        diag_->Error(DiagMessage(item_source)
                      << "<item> in <plural> has invalid value '"
-                     << trimmedQuantity << "' for attribute 'quantity'");
+                     << trimmed_quantity << "' for attribute 'quantity'");
         error = true;
         continue;
       }
 
       if (plural->values[index]) {
-        mDiag->error(DiagMessage(itemSource) << "duplicate quantity '"
-                                             << trimmedQuantity << "'");
+        diag_->Error(DiagMessage(item_source) << "duplicate quantity '"
+                                              << trimmed_quantity << "'");
         error = true;
         continue;
       }
 
-      if (!(plural->values[index] = parseXml(
+      if (!(plural->values[index] = ParseXml(
                 parser, android::ResTable_map::TYPE_STRING, kNoRawString))) {
         error = true;
       }
-      plural->values[index]->setSource(itemSource);
+      plural->values[index]->SetSource(item_source);
 
-    } else if (!shouldIgnoreElement(elementNamespace, elementName)) {
-      mDiag->error(DiagMessage(itemSource)
-                   << "unknown tag <" << elementNamespace << ":" << elementName
-                   << ">");
+    } else if (!ShouldIgnoreElement(element_namespace, element_name)) {
+      diag_->Error(DiagMessage(item_source) << "unknown tag <"
+                                            << element_namespace << ":"
+                                            << element_name << ">");
       error = true;
     }
   }
@@ -1252,47 +1261,48 @@
     return false;
   }
 
-  outResource->value = std::move(plural);
+  out_resource->value = std::move(plural);
   return true;
 }
 
-bool ResourceParser::parseDeclareStyleable(xml::XmlPullParser* parser,
-                                           ParsedResource* outResource) {
-  outResource->name.type = ResourceType::kStyleable;
+bool ResourceParser::ParseDeclareStyleable(xml::XmlPullParser* parser,
+                                           ParsedResource* out_resource) {
+  out_resource->name.type = ResourceType::kStyleable;
 
   // Declare-styleable is kPrivate by default, because it technically only
   // exists in R.java.
-  outResource->symbolState = SymbolState::kPublic;
+  out_resource->symbol_state = SymbolState::kPublic;
 
   // Declare-styleable only ends up in default config;
-  if (outResource->config != ConfigDescription::defaultConfig()) {
-    mDiag->warn(DiagMessage(outResource->source)
-                << "ignoring configuration '" << outResource->config
-                << "' for styleable " << outResource->name.entry);
-    outResource->config = ConfigDescription::defaultConfig();
+  if (out_resource->config != ConfigDescription::DefaultConfig()) {
+    diag_->Warn(DiagMessage(out_resource->source)
+                << "ignoring configuration '" << out_resource->config
+                << "' for styleable " << out_resource->name.entry);
+    out_resource->config = ConfigDescription::DefaultConfig();
   }
 
   std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
 
   std::string comment;
   bool error = false;
-  const size_t depth = parser->getDepth();
-  while (xml::XmlPullParser::nextChildNode(parser, depth)) {
-    if (parser->getEvent() == xml::XmlPullParser::Event::kComment) {
-      comment = util::trimWhitespace(parser->getComment()).toString();
+  const size_t depth = parser->depth();
+  while (xml::XmlPullParser::NextChildNode(parser, depth)) {
+    if (parser->event() == xml::XmlPullParser::Event::kComment) {
+      comment = util::TrimWhitespace(parser->comment()).ToString();
       continue;
-    } else if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) {
+    } else if (parser->event() != xml::XmlPullParser::Event::kStartElement) {
       // Ignore text.
       continue;
     }
 
-    const Source itemSource = mSource.withLine(parser->getLineNumber());
-    const std::string& elementNamespace = parser->getElementNamespace();
-    const std::string& elementName = parser->getElementName();
-    if (elementNamespace.empty() && elementName == "attr") {
-      Maybe<StringPiece> maybeName = xml::findNonEmptyAttribute(parser, "name");
-      if (!maybeName) {
-        mDiag->error(DiagMessage(itemSource)
+    const Source item_source = source_.WithLine(parser->line_number());
+    const std::string& element_namespace = parser->element_namespace();
+    const std::string& element_name = parser->element_name();
+    if (element_namespace.empty() && element_name == "attr") {
+      Maybe<StringPiece> maybe_name =
+          xml::FindNonEmptyAttribute(parser, "name");
+      if (!maybe_name) {
+        diag_->Error(DiagMessage(item_source)
                      << "<attr> tag must have a 'name' attribute");
         error = true;
         continue;
@@ -1301,40 +1311,40 @@
       // If this is a declaration, the package name may be in the name. Separate
       // these out.
       // Eg. <attr name="android:text" />
-      Maybe<Reference> maybeRef =
-          ResourceUtils::parseXmlAttributeName(maybeName.value());
-      if (!maybeRef) {
-        mDiag->error(DiagMessage(itemSource) << "<attr> tag has invalid name '"
-                                             << maybeName.value() << "'");
+      Maybe<Reference> maybe_ref =
+          ResourceUtils::ParseXmlAttributeName(maybe_name.value());
+      if (!maybe_ref) {
+        diag_->Error(DiagMessage(item_source) << "<attr> tag has invalid name '"
+                                              << maybe_name.value() << "'");
         error = true;
         continue;
       }
 
-      Reference& childRef = maybeRef.value();
-      xml::transformReferenceFromNamespace(parser, "", &childRef);
+      Reference& child_ref = maybe_ref.value();
+      xml::TransformReferenceFromNamespace(parser, "", &child_ref);
 
       // Create the ParsedResource that will add the attribute to the table.
-      ParsedResource childResource;
-      childResource.name = childRef.name.value();
-      childResource.source = itemSource;
-      childResource.comment = std::move(comment);
+      ParsedResource child_resource;
+      child_resource.name = child_ref.name.value();
+      child_resource.source = item_source;
+      child_resource.comment = std::move(comment);
 
-      if (!parseAttrImpl(parser, &childResource, true)) {
+      if (!ParseAttrImpl(parser, &child_resource, true)) {
         error = true;
         continue;
       }
 
       // Create the reference to this attribute.
-      childRef.setComment(childResource.comment);
-      childRef.setSource(itemSource);
-      styleable->entries.push_back(std::move(childRef));
+      child_ref.SetComment(child_resource.comment);
+      child_ref.SetSource(item_source);
+      styleable->entries.push_back(std::move(child_ref));
 
-      outResource->childResources.push_back(std::move(childResource));
+      out_resource->child_resources.push_back(std::move(child_resource));
 
-    } else if (!shouldIgnoreElement(elementNamespace, elementName)) {
-      mDiag->error(DiagMessage(itemSource)
-                   << "unknown tag <" << elementNamespace << ":" << elementName
-                   << ">");
+    } else if (!ShouldIgnoreElement(element_namespace, element_name)) {
+      diag_->Error(DiagMessage(item_source) << "unknown tag <"
+                                            << element_namespace << ":"
+                                            << element_name << ">");
       error = true;
     }
 
@@ -1345,7 +1355,7 @@
     return false;
   }
 
-  outResource->value = std::move(styleable);
+  out_resource->value = std::move(styleable);
   return true;
 }
 
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
index 644ed49..11b1e5b 100644
--- a/tools/aapt2/ResourceParser.h
+++ b/tools/aapt2/ResourceParser.h
@@ -17,6 +17,10 @@
 #ifndef AAPT_RESOURCE_PARSER_H
 #define AAPT_RESOURCE_PARSER_H
 
+#include <memory>
+
+#include "android-base/macros.h"
+
 #include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "ResourceTable.h"
@@ -26,8 +30,6 @@
 #include "util/StringPiece.h"
 #include "xml/XmlPullParser.h"
 
-#include <memory>
-
 namespace aapt {
 
 struct ParsedResource;
@@ -42,7 +44,7 @@
    * Whether positional arguments in formatted strings are treated as errors or
    * warnings.
    */
-  bool errorOnPositionalArguments = true;
+  bool error_on_positional_arguments = true;
 };
 
 /*
@@ -53,70 +55,71 @@
   ResourceParser(IDiagnostics* diag, ResourceTable* table, const Source& source,
                  const ConfigDescription& config,
                  const ResourceParserOptions& options = {});
-
-  ResourceParser(const ResourceParser&) = delete;  // No copy.
-
-  bool parse(xml::XmlPullParser* parser);
+  bool Parse(xml::XmlPullParser* parser);
 
  private:
+  DISALLOW_COPY_AND_ASSIGN(ResourceParser);
+
   /*
    * Parses the XML subtree as a StyleString (flattened XML representation for
    * strings
-   * with formatting). If successful, `outStyleString`
-   * contains the escaped and whitespace trimmed text, while `outRawString`
+   * with formatting). If successful, `out_style_string`
+   * contains the escaped and whitespace trimmed text, while `out_raw_string`
    * contains the unescaped text. Returns true on success.
    */
-  bool flattenXmlSubtree(xml::XmlPullParser* parser, std::string* outRawString,
-                         StyleString* outStyleString);
+  bool FlattenXmlSubtree(xml::XmlPullParser* parser,
+                         std::string* out_raw_string,
+                         StyleString* out_style_string);
 
   /*
    * Parses the XML subtree and returns an Item.
-   * The type of Item that can be parsed is denoted by the `typeMask`.
-   * If `allowRawValue` is true and the subtree can not be parsed as a regular
+   * The type of Item that can be parsed is denoted by the `type_mask`.
+   * If `allow_raw_value` is true and the subtree can not be parsed as a regular
    * Item, then a
    * RawString is returned. Otherwise this returns false;
    */
-  std::unique_ptr<Item> parseXml(xml::XmlPullParser* parser,
-                                 const uint32_t typeMask,
-                                 const bool allowRawValue);
+  std::unique_ptr<Item> ParseXml(xml::XmlPullParser* parser,
+                                 const uint32_t type_mask,
+                                 const bool allow_raw_value);
 
-  bool parseResources(xml::XmlPullParser* parser);
-  bool parseResource(xml::XmlPullParser* parser, ParsedResource* outResource);
+  bool ParseResources(xml::XmlPullParser* parser);
+  bool ParseResource(xml::XmlPullParser* parser, ParsedResource* out_resource);
 
-  bool parseItem(xml::XmlPullParser* parser, ParsedResource* outResource,
+  bool ParseItem(xml::XmlPullParser* parser, ParsedResource* out_resource,
                  uint32_t format);
-  bool parseString(xml::XmlPullParser* parser, ParsedResource* outResource);
+  bool ParseString(xml::XmlPullParser* parser, ParsedResource* out_resource);
 
-  bool parsePublic(xml::XmlPullParser* parser, ParsedResource* outResource);
-  bool parsePublicGroup(xml::XmlPullParser* parser,
-                        ParsedResource* outResource);
-  bool parseSymbolImpl(xml::XmlPullParser* parser, ParsedResource* outResource);
-  bool parseSymbol(xml::XmlPullParser* parser, ParsedResource* outResource);
-  bool parseAddResource(xml::XmlPullParser* parser,
-                        ParsedResource* outResource);
-  bool parseAttr(xml::XmlPullParser* parser, ParsedResource* outResource);
-  bool parseAttrImpl(xml::XmlPullParser* parser, ParsedResource* outResource,
+  bool ParsePublic(xml::XmlPullParser* parser, ParsedResource* out_resource);
+  bool ParsePublicGroup(xml::XmlPullParser* parser,
+                        ParsedResource* out_resource);
+  bool ParseSymbolImpl(xml::XmlPullParser* parser,
+                       ParsedResource* out_resource);
+  bool ParseSymbol(xml::XmlPullParser* parser, ParsedResource* out_resource);
+  bool ParseAddResource(xml::XmlPullParser* parser,
+                        ParsedResource* out_resource);
+  bool ParseAttr(xml::XmlPullParser* parser, ParsedResource* out_resource);
+  bool ParseAttrImpl(xml::XmlPullParser* parser, ParsedResource* out_resource,
                      bool weak);
-  Maybe<Attribute::Symbol> parseEnumOrFlagItem(xml::XmlPullParser* parser,
+  Maybe<Attribute::Symbol> ParseEnumOrFlagItem(xml::XmlPullParser* parser,
                                                const StringPiece& tag);
-  bool parseStyle(xml::XmlPullParser* parser, ParsedResource* outResource);
-  bool parseStyleItem(xml::XmlPullParser* parser, Style* style);
-  bool parseDeclareStyleable(xml::XmlPullParser* parser,
-                             ParsedResource* outResource);
-  bool parseArray(xml::XmlPullParser* parser, ParsedResource* outResource);
-  bool parseIntegerArray(xml::XmlPullParser* parser,
-                         ParsedResource* outResource);
-  bool parseStringArray(xml::XmlPullParser* parser,
-                        ParsedResource* outResource);
-  bool parseArrayImpl(xml::XmlPullParser* parser, ParsedResource* outResource,
+  bool ParseStyle(xml::XmlPullParser* parser, ParsedResource* out_resource);
+  bool ParseStyleItem(xml::XmlPullParser* parser, Style* style);
+  bool ParseDeclareStyleable(xml::XmlPullParser* parser,
+                             ParsedResource* out_resource);
+  bool ParseArray(xml::XmlPullParser* parser, ParsedResource* out_resource);
+  bool ParseIntegerArray(xml::XmlPullParser* parser,
+                         ParsedResource* out_resource);
+  bool ParseStringArray(xml::XmlPullParser* parser,
+                        ParsedResource* out_resource);
+  bool ParseArrayImpl(xml::XmlPullParser* parser, ParsedResource* out_resource,
                       uint32_t typeMask);
-  bool parsePlural(xml::XmlPullParser* parser, ParsedResource* outResource);
+  bool ParsePlural(xml::XmlPullParser* parser, ParsedResource* out_resource);
 
-  IDiagnostics* mDiag;
-  ResourceTable* mTable;
-  Source mSource;
-  ConfigDescription mConfig;
-  ResourceParserOptions mOptions;
+  IDiagnostics* diag_;
+  ResourceTable* table_;
+  Source source_;
+  ConfigDescription config_;
+  ResourceParserOptions options_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index b6d57c0..2463911 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -15,79 +15,82 @@
  */
 
 #include "ResourceParser.h"
+
+#include <sstream>
+#include <string>
+
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
 #include "test/Test.h"
 #include "xml/XmlPullParser.h"
 
-#include <sstream>
-#include <string>
-
 namespace aapt {
 
 constexpr const char* kXmlPreamble =
     "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
 
 TEST(ResourceParserSingleTest, FailToParseWithNoRootResourcesElement) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   std::stringstream input(kXmlPreamble);
   input << "<attr name=\"foo\"/>" << std::endl;
   ResourceTable table;
-  ResourceParser parser(context->getDiagnostics(), &table, Source{"test"}, {});
-  xml::XmlPullParser xmlParser(input);
-  ASSERT_FALSE(parser.parse(&xmlParser));
+  ResourceParser parser(context->GetDiagnostics(), &table, Source{"test"}, {});
+  xml::XmlPullParser xml_parser(input);
+  ASSERT_FALSE(parser.Parse(&xml_parser));
 }
 
-struct ResourceParserTest : public ::testing::Test {
-  ResourceTable mTable;
-  std::unique_ptr<IAaptContext> mContext;
+class ResourceParserTest : public ::testing::Test {
+ public:
+  void SetUp() override { context_ = test::ContextBuilder().Build(); }
 
-  void SetUp() override { mContext = test::ContextBuilder().build(); }
-
-  ::testing::AssertionResult testParse(const StringPiece& str) {
-    return testParse(str, ConfigDescription{});
+  ::testing::AssertionResult TestParse(const StringPiece& str) {
+    return TestParse(str, ConfigDescription{});
   }
 
-  ::testing::AssertionResult testParse(const StringPiece& str,
+  ::testing::AssertionResult TestParse(const StringPiece& str,
                                        const ConfigDescription& config) {
     std::stringstream input(kXmlPreamble);
     input << "<resources>\n" << str << "\n</resources>" << std::endl;
     ResourceParserOptions parserOptions;
-    ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{"test"},
+    ResourceParser parser(context_->GetDiagnostics(), &table_, Source{"test"},
                           config, parserOptions);
     xml::XmlPullParser xmlParser(input);
-    if (parser.parse(&xmlParser)) {
+    if (parser.Parse(&xmlParser)) {
       return ::testing::AssertionSuccess();
     }
     return ::testing::AssertionFailure();
   }
+
+ protected:
+  ResourceTable table_;
+  std::unique_ptr<IAaptContext> context_;
 };
 
 TEST_F(ResourceParserTest, ParseQuotedString) {
   std::string input = "<string name=\"foo\">   \"  hey there \" </string>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  String* str = test::getValue<String>(&mTable, "string/foo");
+  String* str = test::GetValue<String>(&table_, "string/foo");
   ASSERT_NE(nullptr, str);
   EXPECT_EQ(std::string("  hey there "), *str->value);
 }
 
 TEST_F(ResourceParserTest, ParseEscapedString) {
   std::string input = "<string name=\"foo\">\\?123</string>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  String* str = test::getValue<String>(&mTable, "string/foo");
+  String* str = test::GetValue<String>(&table_, "string/foo");
   ASSERT_NE(nullptr, str);
   EXPECT_EQ(std::string("?123"), *str->value);
 }
 
 TEST_F(ResourceParserTest, ParseFormattedString) {
   std::string input = "<string name=\"foo\">%d %s</string>";
-  ASSERT_FALSE(testParse(input));
+  ASSERT_FALSE(TestParse(input));
 
   input = "<string name=\"foo\">%1$d %2$s</string>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 }
 
 TEST_F(ResourceParserTest, ParseStyledString) {
@@ -96,32 +99,32 @@
   // use UTF-16 length and not UTF-18 length.
   std::string input =
       "<string name=\"foo\">This is my aunt\u2019s <b>string</b></string>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  StyledString* str = test::getValue<StyledString>(&mTable, "string/foo");
+  StyledString* str = test::GetValue<StyledString>(&table_, "string/foo");
   ASSERT_NE(nullptr, str);
 
-  const std::string expectedStr = "This is my aunt\u2019s string";
-  EXPECT_EQ(expectedStr, *str->value->str);
+  const std::string expected_str = "This is my aunt\u2019s string";
+  EXPECT_EQ(expected_str, *str->value->str);
   EXPECT_EQ(1u, str->value->spans.size());
 
   EXPECT_EQ(std::string("b"), *str->value->spans[0].name);
-  EXPECT_EQ(17u, str->value->spans[0].firstChar);
-  EXPECT_EQ(23u, str->value->spans[0].lastChar);
+  EXPECT_EQ(17u, str->value->spans[0].first_char);
+  EXPECT_EQ(23u, str->value->spans[0].last_char);
 }
 
 TEST_F(ResourceParserTest, ParseStringWithWhitespace) {
   std::string input = "<string name=\"foo\">  This is what  I think  </string>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  String* str = test::getValue<String>(&mTable, "string/foo");
+  String* str = test::GetValue<String>(&table_, "string/foo");
   ASSERT_NE(nullptr, str);
   EXPECT_EQ(std::string("This is what I think"), *str->value);
 
   input = "<string name=\"foo2\">\"  This is what  I think  \"</string>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  str = test::getValue<String>(&mTable, "string/foo2");
+  str = test::GetValue<String>(&table_, "string/foo2");
   ASSERT_NE(nullptr, str);
   EXPECT_EQ(std::string("  This is what  I think  "), *str->value);
 }
@@ -131,16 +134,16 @@
       "<string name=\"foo\" \n"
       "        xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n"
       "  There are <xliff:g id=\"count\">%1$d</xliff:g> apples</string>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  String* str = test::getValue<String>(&mTable, "string/foo");
+  String* str = test::GetValue<String>(&table_, "string/foo");
   ASSERT_NE(nullptr, str);
   EXPECT_EQ(StringPiece("There are %1$d apples"), StringPiece(*str->value));
 }
 
 TEST_F(ResourceParserTest, ParseNull) {
   std::string input = "<integer name=\"foo\">@null</integer>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
   // The Android runtime treats a value of android::Res_value::TYPE_NULL as
   // a non-existing value, and this causes problems in styles when trying to
@@ -149,7 +152,7 @@
   // android::Res_value::TYPE_REFERENCE
   // with a data value of 0.
   BinaryPrimitive* integer =
-      test::getValue<BinaryPrimitive>(&mTable, "integer/foo");
+      test::GetValue<BinaryPrimitive>(&table_, "integer/foo");
   ASSERT_NE(nullptr, integer);
   EXPECT_EQ(uint16_t(android::Res_value::TYPE_REFERENCE),
             integer->value.dataType);
@@ -158,10 +161,10 @@
 
 TEST_F(ResourceParserTest, ParseEmpty) {
   std::string input = "<integer name=\"foo\">@empty</integer>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
   BinaryPrimitive* integer =
-      test::getValue<BinaryPrimitive>(&mTable, "integer/foo");
+      test::GetValue<BinaryPrimitive>(&table_, "integer/foo");
   ASSERT_NE(nullptr, integer);
   EXPECT_EQ(uint16_t(android::Res_value::TYPE_NULL), integer->value.dataType);
   EXPECT_EQ(uint32_t(android::Res_value::DATA_NULL_EMPTY), integer->value.data);
@@ -171,15 +174,15 @@
   std::string input =
       "<attr name=\"foo\" format=\"string\"/>\n"
       "<attr name=\"bar\"/>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Attribute* attr = test::getValue<Attribute>(&mTable, "attr/foo");
+  Attribute* attr = test::GetValue<Attribute>(&table_, "attr/foo");
   ASSERT_NE(nullptr, attr);
-  EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask);
+  EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->type_mask);
 
-  attr = test::getValue<Attribute>(&mTable, "attr/bar");
+  attr = test::GetValue<Attribute>(&table_, "attr/bar");
   ASSERT_NE(nullptr, attr);
-  EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_ANY), attr->typeMask);
+  EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_ANY), attr->type_mask);
 }
 
 // Old AAPT allowed attributes to be defined under different configurations, but
@@ -188,42 +191,42 @@
 // behavior.
 TEST_F(ResourceParserTest,
        ParseAttrAndDeclareStyleableUnderConfigButRecordAsNoConfig) {
-  const ConfigDescription watchConfig = test::parseConfigOrDie("watch");
+  const ConfigDescription watch_config = test::ParseConfigOrDie("watch");
   std::string input = R"EOF(
         <attr name="foo" />
         <declare-styleable name="bar">
           <attr name="baz" />
         </declare-styleable>)EOF";
-  ASSERT_TRUE(testParse(input, watchConfig));
+  ASSERT_TRUE(TestParse(input, watch_config));
 
-  EXPECT_EQ(nullptr, test::getValueForConfig<Attribute>(&mTable, "attr/foo",
-                                                        watchConfig));
-  EXPECT_EQ(nullptr, test::getValueForConfig<Attribute>(&mTable, "attr/baz",
-                                                        watchConfig));
-  EXPECT_EQ(nullptr, test::getValueForConfig<Styleable>(
-                         &mTable, "styleable/bar", watchConfig));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<Attribute>(&table_, "attr/foo",
+                                                        watch_config));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<Attribute>(&table_, "attr/baz",
+                                                        watch_config));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<Styleable>(
+                         &table_, "styleable/bar", watch_config));
 
-  EXPECT_NE(nullptr, test::getValue<Attribute>(&mTable, "attr/foo"));
-  EXPECT_NE(nullptr, test::getValue<Attribute>(&mTable, "attr/baz"));
-  EXPECT_NE(nullptr, test::getValue<Styleable>(&mTable, "styleable/bar"));
+  EXPECT_NE(nullptr, test::GetValue<Attribute>(&table_, "attr/foo"));
+  EXPECT_NE(nullptr, test::GetValue<Attribute>(&table_, "attr/baz"));
+  EXPECT_NE(nullptr, test::GetValue<Styleable>(&table_, "styleable/bar"));
 }
 
 TEST_F(ResourceParserTest, ParseAttrWithMinMax) {
   std::string input =
       "<attr name=\"foo\" min=\"10\" max=\"23\" format=\"integer\"/>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Attribute* attr = test::getValue<Attribute>(&mTable, "attr/foo");
+  Attribute* attr = test::GetValue<Attribute>(&table_, "attr/foo");
   ASSERT_NE(nullptr, attr);
-  EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_INTEGER), attr->typeMask);
-  EXPECT_EQ(10, attr->minInt);
-  EXPECT_EQ(23, attr->maxInt);
+  EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_INTEGER), attr->type_mask);
+  EXPECT_EQ(10, attr->min_int);
+  EXPECT_EQ(23, attr->max_int);
 }
 
 TEST_F(ResourceParserTest, FailParseAttrWithMinMaxButNotInteger) {
   std::string input =
       "<attr name=\"foo\" min=\"10\" max=\"23\" format=\"string\"/>";
-  ASSERT_FALSE(testParse(input));
+  ASSERT_FALSE(TestParse(input));
 }
 
 TEST_F(ResourceParserTest, ParseUseAndDeclOfAttr) {
@@ -232,11 +235,11 @@
       "  <attr name=\"foo\" />\n"
       "</declare-styleable>\n"
       "<attr name=\"foo\" format=\"string\"/>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Attribute* attr = test::getValue<Attribute>(&mTable, "attr/foo");
+  Attribute* attr = test::GetValue<Attribute>(&table_, "attr/foo");
   ASSERT_NE(nullptr, attr);
-  EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask);
+  EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->type_mask);
 }
 
 TEST_F(ResourceParserTest, ParseDoubleUseOfAttr) {
@@ -247,11 +250,11 @@
       "<declare-styleable name=\"Window\">\n"
       "  <attr name=\"foo\" format=\"boolean\"/>\n"
       "</declare-styleable>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Attribute* attr = test::getValue<Attribute>(&mTable, "attr/foo");
+  Attribute* attr = test::GetValue<Attribute>(&table_, "attr/foo");
   ASSERT_NE(nullptr, attr);
-  EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_BOOLEAN), attr->typeMask);
+  EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_BOOLEAN), attr->type_mask);
 }
 
 TEST_F(ResourceParserTest, ParseEnumAttr) {
@@ -261,24 +264,24 @@
       "  <enum name=\"bat\" value=\"1\"/>\n"
       "  <enum name=\"baz\" value=\"2\"/>\n"
       "</attr>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Attribute* enumAttr = test::getValue<Attribute>(&mTable, "attr/foo");
-  ASSERT_NE(enumAttr, nullptr);
-  EXPECT_EQ(enumAttr->typeMask, android::ResTable_map::TYPE_ENUM);
-  ASSERT_EQ(enumAttr->symbols.size(), 3u);
+  Attribute* enum_attr = test::GetValue<Attribute>(&table_, "attr/foo");
+  ASSERT_NE(enum_attr, nullptr);
+  EXPECT_EQ(enum_attr->type_mask, android::ResTable_map::TYPE_ENUM);
+  ASSERT_EQ(enum_attr->symbols.size(), 3u);
 
-  AAPT_ASSERT_TRUE(enumAttr->symbols[0].symbol.name);
-  EXPECT_EQ(enumAttr->symbols[0].symbol.name.value().entry, "bar");
-  EXPECT_EQ(enumAttr->symbols[0].value, 0u);
+  AAPT_ASSERT_TRUE(enum_attr->symbols[0].symbol.name);
+  EXPECT_EQ(enum_attr->symbols[0].symbol.name.value().entry, "bar");
+  EXPECT_EQ(enum_attr->symbols[0].value, 0u);
 
-  AAPT_ASSERT_TRUE(enumAttr->symbols[1].symbol.name);
-  EXPECT_EQ(enumAttr->symbols[1].symbol.name.value().entry, "bat");
-  EXPECT_EQ(enumAttr->symbols[1].value, 1u);
+  AAPT_ASSERT_TRUE(enum_attr->symbols[1].symbol.name);
+  EXPECT_EQ(enum_attr->symbols[1].symbol.name.value().entry, "bat");
+  EXPECT_EQ(enum_attr->symbols[1].value, 1u);
 
-  AAPT_ASSERT_TRUE(enumAttr->symbols[2].symbol.name);
-  EXPECT_EQ(enumAttr->symbols[2].symbol.name.value().entry, "baz");
-  EXPECT_EQ(enumAttr->symbols[2].value, 2u);
+  AAPT_ASSERT_TRUE(enum_attr->symbols[2].symbol.name);
+  EXPECT_EQ(enum_attr->symbols[2].symbol.name.value().entry, "baz");
+  EXPECT_EQ(enum_attr->symbols[2].value, 2u);
 }
 
 TEST_F(ResourceParserTest, ParseFlagAttr) {
@@ -288,29 +291,29 @@
       "  <flag name=\"bat\" value=\"1\"/>\n"
       "  <flag name=\"baz\" value=\"2\"/>\n"
       "</attr>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Attribute* flagAttr = test::getValue<Attribute>(&mTable, "attr/foo");
-  ASSERT_NE(nullptr, flagAttr);
-  EXPECT_EQ(flagAttr->typeMask, android::ResTable_map::TYPE_FLAGS);
-  ASSERT_EQ(flagAttr->symbols.size(), 3u);
+  Attribute* flag_attr = test::GetValue<Attribute>(&table_, "attr/foo");
+  ASSERT_NE(nullptr, flag_attr);
+  EXPECT_EQ(flag_attr->type_mask, android::ResTable_map::TYPE_FLAGS);
+  ASSERT_EQ(flag_attr->symbols.size(), 3u);
 
-  AAPT_ASSERT_TRUE(flagAttr->symbols[0].symbol.name);
-  EXPECT_EQ(flagAttr->symbols[0].symbol.name.value().entry, "bar");
-  EXPECT_EQ(flagAttr->symbols[0].value, 0u);
+  AAPT_ASSERT_TRUE(flag_attr->symbols[0].symbol.name);
+  EXPECT_EQ(flag_attr->symbols[0].symbol.name.value().entry, "bar");
+  EXPECT_EQ(flag_attr->symbols[0].value, 0u);
 
-  AAPT_ASSERT_TRUE(flagAttr->symbols[1].symbol.name);
-  EXPECT_EQ(flagAttr->symbols[1].symbol.name.value().entry, "bat");
-  EXPECT_EQ(flagAttr->symbols[1].value, 1u);
+  AAPT_ASSERT_TRUE(flag_attr->symbols[1].symbol.name);
+  EXPECT_EQ(flag_attr->symbols[1].symbol.name.value().entry, "bat");
+  EXPECT_EQ(flag_attr->symbols[1].value, 1u);
 
-  AAPT_ASSERT_TRUE(flagAttr->symbols[2].symbol.name);
-  EXPECT_EQ(flagAttr->symbols[2].symbol.name.value().entry, "baz");
-  EXPECT_EQ(flagAttr->symbols[2].value, 2u);
+  AAPT_ASSERT_TRUE(flag_attr->symbols[2].symbol.name);
+  EXPECT_EQ(flag_attr->symbols[2].symbol.name.value().entry, "baz");
+  EXPECT_EQ(flag_attr->symbols[2].value, 2u);
 
-  std::unique_ptr<BinaryPrimitive> flagValue =
-      ResourceUtils::tryParseFlagSymbol(flagAttr, "baz|bat");
-  ASSERT_NE(nullptr, flagValue);
-  EXPECT_EQ(flagValue->value.data, 1u | 2u);
+  std::unique_ptr<BinaryPrimitive> flag_value =
+      ResourceUtils::TryParseFlagSymbol(flag_attr, "baz|bat");
+  ASSERT_NE(nullptr, flag_value);
+  EXPECT_EQ(flag_value->value.data, 1u | 2u);
 }
 
 TEST_F(ResourceParserTest, FailToParseEnumAttrWithNonUniqueKeys) {
@@ -320,7 +323,7 @@
       "  <enum name=\"bat\" value=\"1\"/>\n"
       "  <enum name=\"bat\" value=\"2\"/>\n"
       "</attr>";
-  ASSERT_FALSE(testParse(input));
+  ASSERT_FALSE(TestParse(input));
 }
 
 TEST_F(ResourceParserTest, ParseStyle) {
@@ -330,38 +333,38 @@
       "  <item name=\"bat\">@string/hey</item>\n"
       "  <item name=\"baz\"><b>hey</b></item>\n"
       "</style>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Style* style = test::getValue<Style>(&mTable, "style/foo");
+  Style* style = test::GetValue<Style>(&table_, "style/foo");
   ASSERT_NE(nullptr, style);
   AAPT_ASSERT_TRUE(style->parent);
   AAPT_ASSERT_TRUE(style->parent.value().name);
-  EXPECT_EQ(test::parseNameOrDie("style/fu"),
+  EXPECT_EQ(test::ParseNameOrDie("style/fu"),
             style->parent.value().name.value());
   ASSERT_EQ(3u, style->entries.size());
 
   AAPT_ASSERT_TRUE(style->entries[0].key.name);
-  EXPECT_EQ(test::parseNameOrDie("attr/bar"),
+  EXPECT_EQ(test::ParseNameOrDie("attr/bar"),
             style->entries[0].key.name.value());
 
   AAPT_ASSERT_TRUE(style->entries[1].key.name);
-  EXPECT_EQ(test::parseNameOrDie("attr/bat"),
+  EXPECT_EQ(test::ParseNameOrDie("attr/bat"),
             style->entries[1].key.name.value());
 
   AAPT_ASSERT_TRUE(style->entries[2].key.name);
-  EXPECT_EQ(test::parseNameOrDie("attr/baz"),
+  EXPECT_EQ(test::ParseNameOrDie("attr/baz"),
             style->entries[2].key.name.value());
 }
 
 TEST_F(ResourceParserTest, ParseStyleWithShorthandParent) {
   std::string input = "<style name=\"foo\" parent=\"com.app:Theme\"/>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Style* style = test::getValue<Style>(&mTable, "style/foo");
+  Style* style = test::GetValue<Style>(&table_, "style/foo");
   ASSERT_NE(nullptr, style);
   AAPT_ASSERT_TRUE(style->parent);
   AAPT_ASSERT_TRUE(style->parent.value().name);
-  EXPECT_EQ(test::parseNameOrDie("com.app:style/Theme"),
+  EXPECT_EQ(test::ParseNameOrDie("com.app:style/Theme"),
             style->parent.value().name.value());
 }
 
@@ -369,13 +372,13 @@
   std::string input =
       "<style xmlns:app=\"http://schemas.android.com/apk/res/android\"\n"
       "       name=\"foo\" parent=\"app:Theme\"/>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Style* style = test::getValue<Style>(&mTable, "style/foo");
+  Style* style = test::GetValue<Style>(&table_, "style/foo");
   ASSERT_NE(nullptr, style);
   AAPT_ASSERT_TRUE(style->parent);
   AAPT_ASSERT_TRUE(style->parent.value().name);
-  EXPECT_EQ(test::parseNameOrDie("android:style/Theme"),
+  EXPECT_EQ(test::ParseNameOrDie("android:style/Theme"),
             style->parent.value().name.value());
 }
 
@@ -385,55 +388,55 @@
       "name=\"foo\">\n"
       "  <item name=\"app:bar\">0</item>\n"
       "</style>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Style* style = test::getValue<Style>(&mTable, "style/foo");
+  Style* style = test::GetValue<Style>(&table_, "style/foo");
   ASSERT_NE(nullptr, style);
   ASSERT_EQ(1u, style->entries.size());
-  EXPECT_EQ(test::parseNameOrDie("android:attr/bar"),
+  EXPECT_EQ(test::ParseNameOrDie("android:attr/bar"),
             style->entries[0].key.name.value());
 }
 
 TEST_F(ResourceParserTest, ParseStyleWithInferredParent) {
   std::string input = "<style name=\"foo.bar\"/>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Style* style = test::getValue<Style>(&mTable, "style/foo.bar");
+  Style* style = test::GetValue<Style>(&table_, "style/foo.bar");
   ASSERT_NE(nullptr, style);
   AAPT_ASSERT_TRUE(style->parent);
   AAPT_ASSERT_TRUE(style->parent.value().name);
   EXPECT_EQ(style->parent.value().name.value(),
-            test::parseNameOrDie("style/foo"));
-  EXPECT_TRUE(style->parentInferred);
+            test::ParseNameOrDie("style/foo"));
+  EXPECT_TRUE(style->parent_inferred);
 }
 
 TEST_F(ResourceParserTest,
        ParseStyleWithInferredParentOverridenByEmptyParentAttribute) {
   std::string input = "<style name=\"foo.bar\" parent=\"\"/>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Style* style = test::getValue<Style>(&mTable, "style/foo.bar");
+  Style* style = test::GetValue<Style>(&table_, "style/foo.bar");
   ASSERT_NE(nullptr, style);
   AAPT_EXPECT_FALSE(style->parent);
-  EXPECT_FALSE(style->parentInferred);
+  EXPECT_FALSE(style->parent_inferred);
 }
 
 TEST_F(ResourceParserTest, ParseStyleWithPrivateParentReference) {
   std::string input =
       R"EOF(<style name="foo" parent="*android:style/bar" />)EOF";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Style* style = test::getValue<Style>(&mTable, "style/foo");
+  Style* style = test::GetValue<Style>(&table_, "style/foo");
   ASSERT_NE(nullptr, style);
   AAPT_ASSERT_TRUE(style->parent);
-  EXPECT_TRUE(style->parent.value().privateReference);
+  EXPECT_TRUE(style->parent.value().private_reference);
 }
 
 TEST_F(ResourceParserTest, ParseAutoGeneratedIdReference) {
   std::string input = "<string name=\"foo\">@+id/bar</string>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Id* id = test::getValue<Id>(&mTable, "id/bar");
+  Id* id = test::GetValue<Id>(&table_, "id/bar");
   ASSERT_NE(id, nullptr);
 }
 
@@ -446,35 +449,35 @@
       "    <enum name=\"foo\" value=\"1\"/>\n"
       "  </attr>\n"
       "</declare-styleable>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
   Maybe<ResourceTable::SearchResult> result =
-      mTable.findResource(test::parseNameOrDie("styleable/foo"));
+      table_.FindResource(test::ParseNameOrDie("styleable/foo"));
   AAPT_ASSERT_TRUE(result);
-  EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbolStatus.state);
+  EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbol_status.state);
 
-  Attribute* attr = test::getValue<Attribute>(&mTable, "attr/bar");
+  Attribute* attr = test::GetValue<Attribute>(&table_, "attr/bar");
   ASSERT_NE(attr, nullptr);
-  EXPECT_TRUE(attr->isWeak());
+  EXPECT_TRUE(attr->IsWeak());
 
-  attr = test::getValue<Attribute>(&mTable, "attr/bat");
+  attr = test::GetValue<Attribute>(&table_, "attr/bat");
   ASSERT_NE(attr, nullptr);
-  EXPECT_TRUE(attr->isWeak());
+  EXPECT_TRUE(attr->IsWeak());
 
-  attr = test::getValue<Attribute>(&mTable, "attr/baz");
+  attr = test::GetValue<Attribute>(&table_, "attr/baz");
   ASSERT_NE(attr, nullptr);
-  EXPECT_TRUE(attr->isWeak());
+  EXPECT_TRUE(attr->IsWeak());
   EXPECT_EQ(1u, attr->symbols.size());
 
-  EXPECT_NE(nullptr, test::getValue<Id>(&mTable, "id/foo"));
+  EXPECT_NE(nullptr, test::GetValue<Id>(&table_, "id/foo"));
 
-  Styleable* styleable = test::getValue<Styleable>(&mTable, "styleable/foo");
+  Styleable* styleable = test::GetValue<Styleable>(&table_, "styleable/foo");
   ASSERT_NE(styleable, nullptr);
   ASSERT_EQ(3u, styleable->entries.size());
 
-  EXPECT_EQ(test::parseNameOrDie("attr/bar"),
+  EXPECT_EQ(test::ParseNameOrDie("attr/bar"),
             styleable->entries[0].name.value());
-  EXPECT_EQ(test::parseNameOrDie("attr/bat"),
+  EXPECT_EQ(test::ParseNameOrDie("attr/bat"),
             styleable->entries[1].name.value());
 }
 
@@ -485,16 +488,16 @@
       "  <attr name=\"*android:bar\" />\n"
       "  <attr name=\"privAndroid:bat\" />\n"
       "</declare-styleable>";
-  ASSERT_TRUE(testParse(input));
-  Styleable* styleable = test::getValue<Styleable>(&mTable, "styleable/foo");
+  ASSERT_TRUE(TestParse(input));
+  Styleable* styleable = test::GetValue<Styleable>(&table_, "styleable/foo");
   ASSERT_NE(nullptr, styleable);
   ASSERT_EQ(2u, styleable->entries.size());
 
-  EXPECT_TRUE(styleable->entries[0].privateReference);
+  EXPECT_TRUE(styleable->entries[0].private_reference);
   AAPT_ASSERT_TRUE(styleable->entries[0].name);
   EXPECT_EQ(std::string("android"), styleable->entries[0].name.value().package);
 
-  EXPECT_TRUE(styleable->entries[1].privateReference);
+  EXPECT_TRUE(styleable->entries[1].private_reference);
   AAPT_ASSERT_TRUE(styleable->entries[1].name);
   EXPECT_EQ(std::string("android"), styleable->entries[1].name.value().package);
 }
@@ -506,15 +509,15 @@
       "  <item>hey</item>\n"
       "  <item>23</item>\n"
       "</array>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Array* array = test::getValue<Array>(&mTable, "array/foo");
+  Array* array = test::GetValue<Array>(&table_, "array/foo");
   ASSERT_NE(array, nullptr);
   ASSERT_EQ(3u, array->items.size());
 
-  EXPECT_NE(nullptr, valueCast<Reference>(array->items[0].get()));
-  EXPECT_NE(nullptr, valueCast<String>(array->items[1].get()));
-  EXPECT_NE(nullptr, valueCast<BinaryPrimitive>(array->items[2].get()));
+  EXPECT_NE(nullptr, ValueCast<Reference>(array->items[0].get()));
+  EXPECT_NE(nullptr, ValueCast<String>(array->items[1].get()));
+  EXPECT_NE(nullptr, ValueCast<BinaryPrimitive>(array->items[2].get()));
 }
 
 TEST_F(ResourceParserTest, ParseStringArray) {
@@ -522,8 +525,8 @@
       "<string-array name=\"foo\">\n"
       "  <item>\"Werk\"</item>\n"
       "</string-array>\n";
-  ASSERT_TRUE(testParse(input));
-  EXPECT_NE(nullptr, test::getValue<Array>(&mTable, "array/foo"));
+  ASSERT_TRUE(TestParse(input));
+  EXPECT_NE(nullptr, test::GetValue<Array>(&table_, "array/foo"));
 }
 
 TEST_F(ResourceParserTest, ParsePlural) {
@@ -532,18 +535,18 @@
       "  <item quantity=\"other\">apples</item>\n"
       "  <item quantity=\"one\">apple</item>\n"
       "</plurals>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 }
 
 TEST_F(ResourceParserTest, ParseCommentsWithResource) {
   std::string input =
       "<!--This is a comment-->\n"
       "<string name=\"foo\">Hi</string>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  String* value = test::getValue<String>(&mTable, "string/foo");
+  String* value = test::GetValue<String>(&table_, "string/foo");
   ASSERT_NE(nullptr, value);
-  EXPECT_EQ(value->getComment(), "This is a comment");
+  EXPECT_EQ(value->GetComment(), "This is a comment");
 }
 
 TEST_F(ResourceParserTest, DoNotCombineMultipleComments) {
@@ -552,11 +555,11 @@
       "<!--Two-->\n"
       "<string name=\"foo\">Hi</string>";
 
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  String* value = test::getValue<String>(&mTable, "string/foo");
+  String* value = test::GetValue<String>(&table_, "string/foo");
   ASSERT_NE(nullptr, value);
-  EXPECT_EQ(value->getComment(), "Two");
+  EXPECT_EQ(value->GetComment(), "Two");
 }
 
 TEST_F(ResourceParserTest, IgnoreCommentBeforeEndTag) {
@@ -567,11 +570,11 @@
       "<!--Two-->\n"
       "</string>";
 
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  String* value = test::getValue<String>(&mTable, "string/foo");
+  String* value = test::GetValue<String>(&table_, "string/foo");
   ASSERT_NE(nullptr, value);
-  EXPECT_EQ(value->getComment(), "One");
+  EXPECT_EQ(value->GetComment(), "One");
 }
 
 TEST_F(ResourceParserTest, ParseNestedComments) {
@@ -588,21 +591,21 @@
           <!-- The very first -->
           <enum name="one" value="1" />
         </attr>)EOF";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Styleable* styleable = test::getValue<Styleable>(&mTable, "styleable/foo");
+  Styleable* styleable = test::GetValue<Styleable>(&table_, "styleable/foo");
   ASSERT_NE(nullptr, styleable);
   ASSERT_EQ(1u, styleable->entries.size());
 
   EXPECT_EQ(StringPiece("The name of the bar"),
-            styleable->entries.front().getComment());
+            styleable->entries.front().GetComment());
 
-  Attribute* attr = test::getValue<Attribute>(&mTable, "attr/foo");
+  Attribute* attr = test::GetValue<Attribute>(&table_, "attr/foo");
   ASSERT_NE(nullptr, attr);
   ASSERT_EQ(1u, attr->symbols.size());
 
   EXPECT_EQ(StringPiece("The very first"),
-            attr->symbols.front().symbol.getComment());
+            attr->symbols.front().symbol.GetComment());
 }
 
 /*
@@ -611,9 +614,9 @@
  */
 TEST_F(ResourceParserTest, ParsePublicIdAsDefinition) {
   std::string input = "<public type=\"id\" name=\"foo\"/>";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  Id* id = test::getValue<Id>(&mTable, "id/foo");
+  Id* id = test::GetValue<Id>(&table_, "id/foo");
   ASSERT_NE(nullptr, id);
 }
 
@@ -626,26 +629,26 @@
         <string name="bit" product="phablet">hoot</string>
         <string name="bot" product="default">yes</string>
     )EOF";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
-  EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>(
-                         &mTable, "string/foo",
-                         ConfigDescription::defaultConfig(), "phone"));
-  EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>(
-                         &mTable, "string/foo",
-                         ConfigDescription::defaultConfig(), "no-sdcard"));
+  EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<String>(
+                         &table_, "string/foo",
+                         ConfigDescription::DefaultConfig(), "phone"));
+  EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<String>(
+                         &table_, "string/foo",
+                         ConfigDescription::DefaultConfig(), "no-sdcard"));
   EXPECT_NE(nullptr,
-            test::getValueForConfigAndProduct<String>(
-                &mTable, "string/bar", ConfigDescription::defaultConfig(), ""));
+            test::GetValueForConfigAndProduct<String>(
+                &table_, "string/bar", ConfigDescription::DefaultConfig(), ""));
   EXPECT_NE(nullptr,
-            test::getValueForConfigAndProduct<String>(
-                &mTable, "string/baz", ConfigDescription::defaultConfig(), ""));
-  EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>(
-                         &mTable, "string/bit",
-                         ConfigDescription::defaultConfig(), "phablet"));
-  EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>(
-                         &mTable, "string/bot",
-                         ConfigDescription::defaultConfig(), "default"));
+            test::GetValueForConfigAndProduct<String>(
+                &table_, "string/baz", ConfigDescription::DefaultConfig(), ""));
+  EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<String>(
+                         &table_, "string/bit",
+                         ConfigDescription::DefaultConfig(), "phablet"));
+  EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<String>(
+                         &table_, "string/bot",
+                         ConfigDescription::DefaultConfig(), "default"));
 }
 
 TEST_F(ResourceParserTest, AutoIncrementIdsInPublicGroup) {
@@ -654,61 +657,61 @@
       <public name="foo" />
       <public name="bar" />
     </public-group>)EOF";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
   Maybe<ResourceTable::SearchResult> result =
-      mTable.findResource(test::parseNameOrDie("attr/foo"));
+      table_.FindResource(test::ParseNameOrDie("attr/foo"));
   AAPT_ASSERT_TRUE(result);
 
   AAPT_ASSERT_TRUE(result.value().package->id);
   AAPT_ASSERT_TRUE(result.value().type->id);
   AAPT_ASSERT_TRUE(result.value().entry->id);
-  ResourceId actualId(result.value().package->id.value(),
-                      result.value().type->id.value(),
-                      result.value().entry->id.value());
-  EXPECT_EQ(ResourceId(0x01010040), actualId);
+  ResourceId actual_id(result.value().package->id.value(),
+                       result.value().type->id.value(),
+                       result.value().entry->id.value());
+  EXPECT_EQ(ResourceId(0x01010040), actual_id);
 
-  result = mTable.findResource(test::parseNameOrDie("attr/bar"));
+  result = table_.FindResource(test::ParseNameOrDie("attr/bar"));
   AAPT_ASSERT_TRUE(result);
 
   AAPT_ASSERT_TRUE(result.value().package->id);
   AAPT_ASSERT_TRUE(result.value().type->id);
   AAPT_ASSERT_TRUE(result.value().entry->id);
-  actualId = ResourceId(result.value().package->id.value(),
-                        result.value().type->id.value(),
-                        result.value().entry->id.value());
-  EXPECT_EQ(ResourceId(0x01010041), actualId);
+  actual_id = ResourceId(result.value().package->id.value(),
+                         result.value().type->id.value(),
+                         result.value().entry->id.value());
+  EXPECT_EQ(ResourceId(0x01010041), actual_id);
 }
 
 TEST_F(ResourceParserTest, ExternalTypesShouldOnlyBeReferences) {
   std::string input =
       R"EOF(<item type="layout" name="foo">@layout/bar</item>)EOF";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
   input = R"EOF(<item type="layout" name="bar">"this is a string"</item>)EOF";
-  ASSERT_FALSE(testParse(input));
+  ASSERT_FALSE(TestParse(input));
 }
 
 TEST_F(ResourceParserTest,
        AddResourcesElementShouldAddEntryWithUndefinedSymbol) {
   std::string input = R"EOF(<add-resource name="bar" type="string" />)EOF";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
   Maybe<ResourceTable::SearchResult> result =
-      mTable.findResource(test::parseNameOrDie("string/bar"));
+      table_.FindResource(test::ParseNameOrDie("string/bar"));
   AAPT_ASSERT_TRUE(result);
   const ResourceEntry* entry = result.value().entry;
   ASSERT_NE(nullptr, entry);
-  EXPECT_EQ(SymbolState::kUndefined, entry->symbolStatus.state);
+  EXPECT_EQ(SymbolState::kUndefined, entry->symbol_status.state);
 }
 
 TEST_F(ResourceParserTest, ParseItemElementWithFormat) {
   std::string input =
       R"EOF(<item name="foo" type="integer" format="float">0.3</item>)EOF";
-  ASSERT_TRUE(testParse(input));
+  ASSERT_TRUE(TestParse(input));
 
   BinaryPrimitive* val =
-      test::getValue<BinaryPrimitive>(&mTable, "integer/foo");
+      test::GetValue<BinaryPrimitive>(&table_, "integer/foo");
   ASSERT_NE(nullptr, val);
 
   EXPECT_EQ(uint32_t(android::Res_value::TYPE_FLOAT), val->value.dataType);
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index c52c91c..4e6a50a 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -21,6 +21,7 @@
 #include "ValueVisitor.h"
 #include "util/Util.h"
 
+#include <android-base/logging.h>
 #include <androidfw/ResourceTypes.h>
 #include <algorithm>
 #include <memory>
@@ -29,28 +30,29 @@
 
 namespace aapt {
 
-static bool lessThanType(const std::unique_ptr<ResourceTableType>& lhs,
-                         ResourceType rhs) {
+static bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs,
+                           ResourceType rhs) {
   return lhs->type < rhs;
 }
 
 template <typename T>
-static bool lessThanStructWithName(const std::unique_ptr<T>& lhs,
-                                   const StringPiece& rhs) {
+static bool less_than_struct_with_name(const std::unique_ptr<T>& lhs,
+                                       const StringPiece& rhs) {
   return lhs->name.compare(0, lhs->name.size(), rhs.data(), rhs.size()) < 0;
 }
 
-ResourceTablePackage* ResourceTable::findPackage(const StringPiece& name) {
+ResourceTablePackage* ResourceTable::FindPackage(const StringPiece& name) {
   const auto last = packages.end();
-  auto iter = std::lower_bound(packages.begin(), last, name,
-                               lessThanStructWithName<ResourceTablePackage>);
+  auto iter =
+      std::lower_bound(packages.begin(), last, name,
+                       less_than_struct_with_name<ResourceTablePackage>);
   if (iter != last && name == (*iter)->name) {
     return iter->get();
   }
   return nullptr;
 }
 
-ResourceTablePackage* ResourceTable::findPackageById(uint8_t id) {
+ResourceTablePackage* ResourceTable::FindPackageById(uint8_t id) {
   for (auto& package : packages) {
     if (package->id && package->id.value() == id) {
       return package.get();
@@ -59,9 +61,9 @@
   return nullptr;
 }
 
-ResourceTablePackage* ResourceTable::createPackage(const StringPiece& name,
+ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name,
                                                    Maybe<uint8_t> id) {
-  ResourceTablePackage* package = findOrCreatePackage(name);
+  ResourceTablePackage* package = FindOrCreatePackage(name);
   if (id && !package->id) {
     package->id = id;
     return package;
@@ -73,61 +75,62 @@
   return package;
 }
 
-ResourceTablePackage* ResourceTable::findOrCreatePackage(
+ResourceTablePackage* ResourceTable::FindOrCreatePackage(
     const StringPiece& name) {
   const auto last = packages.end();
-  auto iter = std::lower_bound(packages.begin(), last, name,
-                               lessThanStructWithName<ResourceTablePackage>);
+  auto iter =
+      std::lower_bound(packages.begin(), last, name,
+                       less_than_struct_with_name<ResourceTablePackage>);
   if (iter != last && name == (*iter)->name) {
     return iter->get();
   }
 
-  std::unique_ptr<ResourceTablePackage> newPackage =
+  std::unique_ptr<ResourceTablePackage> new_package =
       util::make_unique<ResourceTablePackage>();
-  newPackage->name = name.toString();
-  return packages.emplace(iter, std::move(newPackage))->get();
+  new_package->name = name.ToString();
+  return packages.emplace(iter, std::move(new_package))->get();
 }
 
-ResourceTableType* ResourceTablePackage::findType(ResourceType type) {
+ResourceTableType* ResourceTablePackage::FindType(ResourceType type) {
   const auto last = types.end();
-  auto iter = std::lower_bound(types.begin(), last, type, lessThanType);
+  auto iter = std::lower_bound(types.begin(), last, type, less_than_type);
   if (iter != last && (*iter)->type == type) {
     return iter->get();
   }
   return nullptr;
 }
 
-ResourceTableType* ResourceTablePackage::findOrCreateType(ResourceType type) {
+ResourceTableType* ResourceTablePackage::FindOrCreateType(ResourceType type) {
   const auto last = types.end();
-  auto iter = std::lower_bound(types.begin(), last, type, lessThanType);
+  auto iter = std::lower_bound(types.begin(), last, type, less_than_type);
   if (iter != last && (*iter)->type == type) {
     return iter->get();
   }
   return types.emplace(iter, new ResourceTableType(type))->get();
 }
 
-ResourceEntry* ResourceTableType::findEntry(const StringPiece& name) {
+ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name) {
   const auto last = entries.end();
   auto iter = std::lower_bound(entries.begin(), last, name,
-                               lessThanStructWithName<ResourceEntry>);
+                               less_than_struct_with_name<ResourceEntry>);
   if (iter != last && name == (*iter)->name) {
     return iter->get();
   }
   return nullptr;
 }
 
-ResourceEntry* ResourceTableType::findOrCreateEntry(const StringPiece& name) {
+ResourceEntry* ResourceTableType::FindOrCreateEntry(const StringPiece& name) {
   auto last = entries.end();
   auto iter = std::lower_bound(entries.begin(), last, name,
-                               lessThanStructWithName<ResourceEntry>);
+                               less_than_struct_with_name<ResourceEntry>);
   if (iter != last && name == (*iter)->name) {
     return iter->get();
   }
   return entries.emplace(iter, new ResourceEntry(name))->get();
 }
 
-ResourceConfigValue* ResourceEntry::findValue(const ConfigDescription& config) {
-  return findValue(config, StringPiece());
+ResourceConfigValue* ResourceEntry::FindValue(const ConfigDescription& config) {
+  return FindValue(config, StringPiece());
 }
 
 struct ConfigKey {
@@ -144,7 +147,7 @@
   return cmp < 0;
 }
 
-ResourceConfigValue* ResourceEntry::findValue(const ConfigDescription& config,
+ResourceConfigValue* ResourceEntry::FindValue(const ConfigDescription& config,
                                               const StringPiece& product) {
   auto iter = std::lower_bound(values.begin(), values.end(),
                                ConfigKey{&config, product}, ltConfigKeyRef);
@@ -157,7 +160,7 @@
   return nullptr;
 }
 
-ResourceConfigValue* ResourceEntry::findOrCreateValue(
+ResourceConfigValue* ResourceEntry::FindOrCreateValue(
     const ConfigDescription& config, const StringPiece& product) {
   auto iter = std::lower_bound(values.begin(), values.end(),
                                ConfigKey{&config, product}, ltConfigKeyRef);
@@ -197,7 +200,7 @@
   return results;
 }
 
-std::vector<ResourceConfigValue*> ResourceEntry::findValuesIf(
+std::vector<ResourceConfigValue*> ResourceEntry::FindValuesIf(
     const std::function<bool(ResourceConfigValue*)>& f) {
   std::vector<ResourceConfigValue*> results;
   for (auto& configValue : values) {
@@ -232,16 +235,16 @@
  * format for there to be
  * no error.
  */
-ResourceTable::CollisionResult ResourceTable::resolveValueCollision(
+ResourceTable::CollisionResult ResourceTable::ResolveValueCollision(
     Value* existing, Value* incoming) {
-  Attribute* existingAttr = valueCast<Attribute>(existing);
-  Attribute* incomingAttr = valueCast<Attribute>(incoming);
-  if (!incomingAttr) {
-    if (incoming->isWeak()) {
+  Attribute* existing_attr = ValueCast<Attribute>(existing);
+  Attribute* incoming_attr = ValueCast<Attribute>(incoming);
+  if (!incoming_attr) {
+    if (incoming->IsWeak()) {
       // We're trying to add a weak resource but a resource
       // already exists. Keep the existing.
       return CollisionResult::kKeepOriginal;
-    } else if (existing->isWeak()) {
+    } else if (existing->IsWeak()) {
       // Override the weak resource with the new strong resource.
       return CollisionResult::kTakeNew;
     }
@@ -250,8 +253,8 @@
     return CollisionResult::kConflict;
   }
 
-  if (!existingAttr) {
-    if (existing->isWeak()) {
+  if (!existing_attr) {
+    if (existing->IsWeak()) {
       // The existing value is not an attribute and it is weak,
       // so take the incoming attribute value.
       return CollisionResult::kTakeNew;
@@ -261,7 +264,7 @@
     return CollisionResult::kConflict;
   }
 
-  assert(incomingAttr && existingAttr);
+  CHECK(incoming_attr != nullptr && existing_attr != nullptr);
 
   //
   // Attribute specific handling. At this point we know both
@@ -269,22 +272,22 @@
   // attributes all-over, we do special handling to see
   // which definition sticks.
   //
-  if (existingAttr->typeMask == incomingAttr->typeMask) {
+  if (existing_attr->type_mask == incoming_attr->type_mask) {
     // The two attributes are both DECLs, but they are plain attributes
     // with the same formats.
     // Keep the strongest one.
-    return existingAttr->isWeak() ? CollisionResult::kTakeNew
-                                  : CollisionResult::kKeepOriginal;
+    return existing_attr->IsWeak() ? CollisionResult::kTakeNew
+                                   : CollisionResult::kKeepOriginal;
   }
 
-  if (existingAttr->isWeak() &&
-      existingAttr->typeMask == android::ResTable_map::TYPE_ANY) {
+  if (existing_attr->IsWeak() &&
+      existing_attr->type_mask == android::ResTable_map::TYPE_ANY) {
     // Any incoming attribute is better than this.
     return CollisionResult::kTakeNew;
   }
 
-  if (incomingAttr->isWeak() &&
-      incomingAttr->typeMask == android::ResTable_map::TYPE_ANY) {
+  if (incoming_attr->IsWeak() &&
+      incoming_attr->type_mask == android::ResTable_map::TYPE_ANY) {
     // The incoming attribute may be a USE instead of a DECL.
     // Keep the existing attribute.
     return CollisionResult::kKeepOriginal;
@@ -295,138 +298,139 @@
 static constexpr const char* kValidNameChars = "._-";
 static constexpr const char* kValidNameMangledChars = "._-$";
 
-bool ResourceTable::addResource(const ResourceNameRef& name,
+bool ResourceTable::AddResource(const ResourceNameRef& name,
                                 const ConfigDescription& config,
                                 const StringPiece& product,
                                 std::unique_ptr<Value> value,
                                 IDiagnostics* diag) {
-  return addResourceImpl(name, {}, config, product, std::move(value),
-                         kValidNameChars, resolveValueCollision, diag);
+  return AddResourceImpl(name, {}, config, product, std::move(value),
+                         kValidNameChars, ResolveValueCollision, diag);
 }
 
-bool ResourceTable::addResource(const ResourceNameRef& name,
-                                const ResourceId& resId,
+bool ResourceTable::AddResource(const ResourceNameRef& name,
+                                const ResourceId& res_id,
                                 const ConfigDescription& config,
                                 const StringPiece& product,
                                 std::unique_ptr<Value> value,
                                 IDiagnostics* diag) {
-  return addResourceImpl(name, resId, config, product, std::move(value),
-                         kValidNameChars, resolveValueCollision, diag);
+  return AddResourceImpl(name, res_id, config, product, std::move(value),
+                         kValidNameChars, ResolveValueCollision, diag);
 }
 
-bool ResourceTable::addFileReference(const ResourceNameRef& name,
+bool ResourceTable::AddFileReference(const ResourceNameRef& name,
                                      const ConfigDescription& config,
                                      const Source& source,
                                      const StringPiece& path,
                                      IDiagnostics* diag) {
-  return addFileReferenceImpl(name, config, source, path, nullptr,
+  return AddFileReferenceImpl(name, config, source, path, nullptr,
                               kValidNameChars, diag);
 }
 
-bool ResourceTable::addFileReferenceAllowMangled(
+bool ResourceTable::AddFileReferenceAllowMangled(
     const ResourceNameRef& name, const ConfigDescription& config,
     const Source& source, const StringPiece& path, io::IFile* file,
     IDiagnostics* diag) {
-  return addFileReferenceImpl(name, config, source, path, file,
+  return AddFileReferenceImpl(name, config, source, path, file,
                               kValidNameMangledChars, diag);
 }
 
-bool ResourceTable::addFileReferenceImpl(
+bool ResourceTable::AddFileReferenceImpl(
     const ResourceNameRef& name, const ConfigDescription& config,
     const Source& source, const StringPiece& path, io::IFile* file,
-    const char* validChars, IDiagnostics* diag) {
+    const char* valid_chars, IDiagnostics* diag) {
   std::unique_ptr<FileReference> fileRef =
-      util::make_unique<FileReference>(stringPool.makeRef(path));
-  fileRef->setSource(source);
+      util::make_unique<FileReference>(string_pool.MakeRef(path));
+  fileRef->SetSource(source);
   fileRef->file = file;
-  return addResourceImpl(name, ResourceId{}, config, StringPiece{},
-                         std::move(fileRef), validChars, resolveValueCollision,
+  return AddResourceImpl(name, ResourceId{}, config, StringPiece{},
+                         std::move(fileRef), valid_chars, ResolveValueCollision,
                          diag);
 }
 
-bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name,
+bool ResourceTable::AddResourceAllowMangled(const ResourceNameRef& name,
                                             const ConfigDescription& config,
                                             const StringPiece& product,
                                             std::unique_ptr<Value> value,
                                             IDiagnostics* diag) {
-  return addResourceImpl(name, ResourceId{}, config, product, std::move(value),
-                         kValidNameMangledChars, resolveValueCollision, diag);
+  return AddResourceImpl(name, ResourceId{}, config, product, std::move(value),
+                         kValidNameMangledChars, ResolveValueCollision, diag);
 }
 
-bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name,
+bool ResourceTable::AddResourceAllowMangled(const ResourceNameRef& name,
                                             const ResourceId& id,
                                             const ConfigDescription& config,
                                             const StringPiece& product,
                                             std::unique_ptr<Value> value,
                                             IDiagnostics* diag) {
-  return addResourceImpl(name, id, config, product, std::move(value),
-                         kValidNameMangledChars, resolveValueCollision, diag);
+  return AddResourceImpl(name, id, config, product, std::move(value),
+                         kValidNameMangledChars, ResolveValueCollision, diag);
 }
 
-bool ResourceTable::addResourceImpl(
-    const ResourceNameRef& name, const ResourceId& resId,
+bool ResourceTable::AddResourceImpl(
+    const ResourceNameRef& name, const ResourceId& res_id,
     const ConfigDescription& config, const StringPiece& product,
-    std::unique_ptr<Value> value, const char* validChars,
+    std::unique_ptr<Value> value, const char* valid_chars,
     const CollisionResolverFunc& conflictResolver, IDiagnostics* diag) {
-  assert(value && "value can't be nullptr");
-  assert(diag && "diagnostics can't be nullptr");
+  CHECK(value != nullptr);
+  CHECK(diag != nullptr);
 
-  auto badCharIter =
-      util::findNonAlphaNumericAndNotInSet(name.entry, validChars);
-  if (badCharIter != name.entry.end()) {
-    diag->error(DiagMessage(value->getSource())
+  auto bad_char_iter =
+      util::FindNonAlphaNumericAndNotInSet(name.entry, valid_chars);
+  if (bad_char_iter != name.entry.end()) {
+    diag->Error(DiagMessage(value->GetSource())
                 << "resource '" << name << "' has invalid entry name '"
                 << name.entry << "'. Invalid character '"
-                << StringPiece(badCharIter, 1) << "'");
+                << StringPiece(bad_char_iter, 1) << "'");
     return false;
   }
 
-  ResourceTablePackage* package = findOrCreatePackage(name.package);
-  if (resId.isValid() && package->id &&
-      package->id.value() != resId.packageId()) {
-    diag->error(DiagMessage(value->getSource())
-                << "trying to add resource '" << name << "' with ID " << resId
+  ResourceTablePackage* package = FindOrCreatePackage(name.package);
+  if (res_id.is_valid() && package->id &&
+      package->id.value() != res_id.package_id()) {
+    diag->Error(DiagMessage(value->GetSource())
+                << "trying to add resource '" << name << "' with ID " << res_id
                 << " but package '" << package->name << "' already has ID "
                 << std::hex << (int)package->id.value() << std::dec);
     return false;
   }
 
-  ResourceTableType* type = package->findOrCreateType(name.type);
-  if (resId.isValid() && type->id && type->id.value() != resId.typeId()) {
-    diag->error(DiagMessage(value->getSource())
-                << "trying to add resource '" << name << "' with ID " << resId
+  ResourceTableType* type = package->FindOrCreateType(name.type);
+  if (res_id.is_valid() && type->id && type->id.value() != res_id.type_id()) {
+    diag->Error(DiagMessage(value->GetSource())
+                << "trying to add resource '" << name << "' with ID " << res_id
                 << " but type '" << type->type << "' already has ID "
                 << std::hex << (int)type->id.value() << std::dec);
     return false;
   }
 
-  ResourceEntry* entry = type->findOrCreateEntry(name.entry);
-  if (resId.isValid() && entry->id && entry->id.value() != resId.entryId()) {
-    diag->error(DiagMessage(value->getSource())
-                << "trying to add resource '" << name << "' with ID " << resId
+  ResourceEntry* entry = type->FindOrCreateEntry(name.entry);
+  if (res_id.is_valid() && entry->id &&
+      entry->id.value() != res_id.entry_id()) {
+    diag->Error(DiagMessage(value->GetSource())
+                << "trying to add resource '" << name << "' with ID " << res_id
                 << " but resource already has ID "
                 << ResourceId(package->id.value(), type->id.value(),
                               entry->id.value()));
     return false;
   }
 
-  ResourceConfigValue* configValue = entry->findOrCreateValue(config, product);
-  if (!configValue->value) {
+  ResourceConfigValue* config_value = entry->FindOrCreateValue(config, product);
+  if (!config_value->value) {
     // Resource does not exist, add it now.
-    configValue->value = std::move(value);
+    config_value->value = std::move(value);
 
   } else {
-    switch (conflictResolver(configValue->value.get(), value.get())) {
+    switch (conflictResolver(config_value->value.get(), value.get())) {
       case CollisionResult::kTakeNew:
         // Take the incoming value.
-        configValue->value = std::move(value);
+        config_value->value = std::move(value);
         break;
 
       case CollisionResult::kConflict:
-        diag->error(DiagMessage(value->getSource())
+        diag->Error(DiagMessage(value->GetSource())
                     << "duplicate value for resource '" << name << "' "
                     << "with config '" << config << "'");
-        diag->error(DiagMessage(configValue->value->getSource())
+        diag->Error(DiagMessage(config_value->value->GetSource())
                     << "resource previously defined here");
         return false;
 
@@ -435,113 +439,114 @@
     }
   }
 
-  if (resId.isValid()) {
-    package->id = resId.packageId();
-    type->id = resId.typeId();
-    entry->id = resId.entryId();
+  if (res_id.is_valid()) {
+    package->id = res_id.package_id();
+    type->id = res_id.type_id();
+    entry->id = res_id.entry_id();
   }
   return true;
 }
 
-bool ResourceTable::setSymbolState(const ResourceNameRef& name,
-                                   const ResourceId& resId,
+bool ResourceTable::SetSymbolState(const ResourceNameRef& name,
+                                   const ResourceId& res_id,
                                    const Symbol& symbol, IDiagnostics* diag) {
-  return setSymbolStateImpl(name, resId, symbol, kValidNameChars, diag);
+  return SetSymbolStateImpl(name, res_id, symbol, kValidNameChars, diag);
 }
 
-bool ResourceTable::setSymbolStateAllowMangled(const ResourceNameRef& name,
-                                               const ResourceId& resId,
+bool ResourceTable::SetSymbolStateAllowMangled(const ResourceNameRef& name,
+                                               const ResourceId& res_id,
                                                const Symbol& symbol,
                                                IDiagnostics* diag) {
-  return setSymbolStateImpl(name, resId, symbol, kValidNameMangledChars, diag);
+  return SetSymbolStateImpl(name, res_id, symbol, kValidNameMangledChars, diag);
 }
 
-bool ResourceTable::setSymbolStateImpl(const ResourceNameRef& name,
-                                       const ResourceId& resId,
+bool ResourceTable::SetSymbolStateImpl(const ResourceNameRef& name,
+                                       const ResourceId& res_id,
                                        const Symbol& symbol,
-                                       const char* validChars,
+                                       const char* valid_chars,
                                        IDiagnostics* diag) {
-  assert(diag && "diagnostics can't be nullptr");
+  CHECK(diag != nullptr);
 
-  auto badCharIter =
-      util::findNonAlphaNumericAndNotInSet(name.entry, validChars);
-  if (badCharIter != name.entry.end()) {
-    diag->error(DiagMessage(symbol.source)
+  auto bad_char_iter =
+      util::FindNonAlphaNumericAndNotInSet(name.entry, valid_chars);
+  if (bad_char_iter != name.entry.end()) {
+    diag->Error(DiagMessage(symbol.source)
                 << "resource '" << name << "' has invalid entry name '"
                 << name.entry << "'. Invalid character '"
-                << StringPiece(badCharIter, 1) << "'");
+                << StringPiece(bad_char_iter, 1) << "'");
     return false;
   }
 
-  ResourceTablePackage* package = findOrCreatePackage(name.package);
-  if (resId.isValid() && package->id &&
-      package->id.value() != resId.packageId()) {
-    diag->error(DiagMessage(symbol.source)
-                << "trying to add resource '" << name << "' with ID " << resId
+  ResourceTablePackage* package = FindOrCreatePackage(name.package);
+  if (res_id.is_valid() && package->id &&
+      package->id.value() != res_id.package_id()) {
+    diag->Error(DiagMessage(symbol.source)
+                << "trying to add resource '" << name << "' with ID " << res_id
                 << " but package '" << package->name << "' already has ID "
                 << std::hex << (int)package->id.value() << std::dec);
     return false;
   }
 
-  ResourceTableType* type = package->findOrCreateType(name.type);
-  if (resId.isValid() && type->id && type->id.value() != resId.typeId()) {
-    diag->error(DiagMessage(symbol.source)
-                << "trying to add resource '" << name << "' with ID " << resId
+  ResourceTableType* type = package->FindOrCreateType(name.type);
+  if (res_id.is_valid() && type->id && type->id.value() != res_id.type_id()) {
+    diag->Error(DiagMessage(symbol.source)
+                << "trying to add resource '" << name << "' with ID " << res_id
                 << " but type '" << type->type << "' already has ID "
                 << std::hex << (int)type->id.value() << std::dec);
     return false;
   }
 
-  ResourceEntry* entry = type->findOrCreateEntry(name.entry);
-  if (resId.isValid() && entry->id && entry->id.value() != resId.entryId()) {
-    diag->error(DiagMessage(symbol.source)
-                << "trying to add resource '" << name << "' with ID " << resId
+  ResourceEntry* entry = type->FindOrCreateEntry(name.entry);
+  if (res_id.is_valid() && entry->id &&
+      entry->id.value() != res_id.entry_id()) {
+    diag->Error(DiagMessage(symbol.source)
+                << "trying to add resource '" << name << "' with ID " << res_id
                 << " but resource already has ID "
                 << ResourceId(package->id.value(), type->id.value(),
                               entry->id.value()));
     return false;
   }
 
-  if (resId.isValid()) {
-    package->id = resId.packageId();
-    type->id = resId.typeId();
-    entry->id = resId.entryId();
+  if (res_id.is_valid()) {
+    package->id = res_id.package_id();
+    type->id = res_id.type_id();
+    entry->id = res_id.entry_id();
   }
 
   // Only mark the type state as public, it doesn't care about being private.
   if (symbol.state == SymbolState::kPublic) {
-    type->symbolStatus.state = SymbolState::kPublic;
+    type->symbol_status.state = SymbolState::kPublic;
   }
 
   if (symbol.state == SymbolState::kUndefined &&
-      entry->symbolStatus.state != SymbolState::kUndefined) {
+      entry->symbol_status.state != SymbolState::kUndefined) {
     // We can't undefine a symbol (remove its visibility). Ignore.
     return true;
   }
 
   if (symbol.state == SymbolState::kPrivate &&
-      entry->symbolStatus.state == SymbolState::kPublic) {
+      entry->symbol_status.state == SymbolState::kPublic) {
     // We can't downgrade public to private. Ignore.
     return true;
   }
 
-  entry->symbolStatus = std::move(symbol);
+  entry->symbol_status = std::move(symbol);
   return true;
 }
 
-Maybe<ResourceTable::SearchResult> ResourceTable::findResource(
+Maybe<ResourceTable::SearchResult> ResourceTable::FindResource(
     const ResourceNameRef& name) {
-  ResourceTablePackage* package = findPackage(name.package);
+  ResourceTablePackage* package = FindPackage(name.package);
   if (!package) {
     return {};
   }
 
-  ResourceTableType* type = package->findType(name.type);
+  ResourceTableType* type = package->FindType(name.type);
   if (!type) {
     return {};
   }
 
-  ResourceEntry* entry = type->findEntry(name.entry);
+  ResourceEntry* entry = type->FindEntry(name.entry);
   if (!entry) {
     return {};
   }
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index ebaad41..a0c3217 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -70,7 +70,7 @@
 
   ResourceConfigValue(const ConfigDescription& config,
                       const StringPiece& product)
-      : config(config), product(product.toString()) {}
+      : config(config), product(product.ToString()) {}
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ResourceConfigValue);
@@ -98,23 +98,23 @@
    * Whether this resource is public (and must maintain the same entry ID across
    * builds).
    */
-  Symbol symbolStatus;
+  Symbol symbol_status;
 
   /**
    * The resource's values for each configuration.
    */
   std::vector<std::unique_ptr<ResourceConfigValue>> values;
 
-  explicit ResourceEntry(const StringPiece& name) : name(name.toString()) {}
+  explicit ResourceEntry(const StringPiece& name) : name(name.ToString()) {}
 
-  ResourceConfigValue* findValue(const ConfigDescription& config);
-  ResourceConfigValue* findValue(const ConfigDescription& config,
+  ResourceConfigValue* FindValue(const ConfigDescription& config);
+  ResourceConfigValue* FindValue(const ConfigDescription& config,
                                  const StringPiece& product);
-  ResourceConfigValue* findOrCreateValue(const ConfigDescription& config,
+  ResourceConfigValue* FindOrCreateValue(const ConfigDescription& config,
                                          const StringPiece& product);
   std::vector<ResourceConfigValue*> findAllValues(
       const ConfigDescription& config);
-  std::vector<ResourceConfigValue*> findValuesIf(
+  std::vector<ResourceConfigValue*> FindValuesIf(
       const std::function<bool(ResourceConfigValue*)>& f);
 
  private:
@@ -141,7 +141,7 @@
    * Whether this type is public (and must maintain the same
    * type ID across builds).
    */
-  Symbol symbolStatus;
+  Symbol symbol_status;
 
   /**
    * List of resources for this type.
@@ -150,8 +150,8 @@
 
   explicit ResourceTableType(const ResourceType type) : type(type) {}
 
-  ResourceEntry* findEntry(const StringPiece& name);
-  ResourceEntry* findOrCreateEntry(const StringPiece& name);
+  ResourceEntry* FindEntry(const StringPiece& name);
+  ResourceEntry* FindOrCreateEntry(const StringPiece& name);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
@@ -168,8 +168,8 @@
   std::vector<std::unique_ptr<ResourceTableType>> types;
 
   ResourceTablePackage() = default;
-  ResourceTableType* findType(ResourceType type);
-  ResourceTableType* findOrCreateType(const ResourceType type);
+  ResourceTableType* FindType(ResourceType type);
+  ResourceTableType* FindOrCreateType(const ResourceType type);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
@@ -191,53 +191,53 @@
    * When a collision of resources occurs, this method decides which value to
    * keep.
    */
-  static CollisionResult resolveValueCollision(Value* existing,
+  static CollisionResult ResolveValueCollision(Value* existing,
                                                Value* incoming);
 
-  bool addResource(const ResourceNameRef& name, const ConfigDescription& config,
+  bool AddResource(const ResourceNameRef& name, const ConfigDescription& config,
                    const StringPiece& product, std::unique_ptr<Value> value,
                    IDiagnostics* diag);
 
-  bool addResource(const ResourceNameRef& name, const ResourceId& resId,
+  bool AddResource(const ResourceNameRef& name, const ResourceId& res_id,
                    const ConfigDescription& config, const StringPiece& product,
                    std::unique_ptr<Value> value, IDiagnostics* diag);
 
-  bool addFileReference(const ResourceNameRef& name,
+  bool AddFileReference(const ResourceNameRef& name,
                         const ConfigDescription& config, const Source& source,
                         const StringPiece& path, IDiagnostics* diag);
 
-  bool addFileReferenceAllowMangled(const ResourceNameRef& name,
+  bool AddFileReferenceAllowMangled(const ResourceNameRef& name,
                                     const ConfigDescription& config,
                                     const Source& source,
                                     const StringPiece& path, io::IFile* file,
                                     IDiagnostics* diag);
 
   /**
-   * Same as addResource, but doesn't verify the validity of the name. This is
+   * Same as AddResource, but doesn't verify the validity of the name. This is
    * used
    * when loading resources from an existing binary resource table that may have
    * mangled
    * names.
    */
-  bool addResourceAllowMangled(const ResourceNameRef& name,
+  bool AddResourceAllowMangled(const ResourceNameRef& name,
                                const ConfigDescription& config,
                                const StringPiece& product,
                                std::unique_ptr<Value> value,
                                IDiagnostics* diag);
 
-  bool addResourceAllowMangled(const ResourceNameRef& name,
+  bool AddResourceAllowMangled(const ResourceNameRef& name,
                                const ResourceId& id,
                                const ConfigDescription& config,
                                const StringPiece& product,
                                std::unique_ptr<Value> value,
                                IDiagnostics* diag);
 
-  bool setSymbolState(const ResourceNameRef& name, const ResourceId& resId,
+  bool SetSymbolState(const ResourceNameRef& name, const ResourceId& res_id,
                       const Symbol& symbol, IDiagnostics* diag);
 
-  bool setSymbolStateAllowMangled(const ResourceNameRef& name,
-                                  const ResourceId& resId, const Symbol& symbol,
-                                  IDiagnostics* diag);
+  bool SetSymbolStateAllowMangled(const ResourceNameRef& name,
+                                  const ResourceId& res_id,
+                                  const Symbol& symbol, IDiagnostics* diag);
 
   struct SearchResult {
     ResourceTablePackage* package;
@@ -245,21 +245,21 @@
     ResourceEntry* entry;
   };
 
-  Maybe<SearchResult> findResource(const ResourceNameRef& name);
+  Maybe<SearchResult> FindResource(const ResourceNameRef& name);
 
   /**
    * The string pool used by this resource table. Values that reference strings
    * must use
    * this pool to create their strings.
    *
-   * NOTE: `stringPool` must come before `packages` so that it is destroyed
+   * NOTE: `string_pool` must come before `packages` so that it is destroyed
    * after.
-   * When `string pool` references are destroyed (as they will be when
+   * When `string_pool` references are destroyed (as they will be when
    * `packages`
    * is destroyed), they decrement a refCount, which would cause invalid
    * memory access if the pool was already destroyed.
    */
-  StringPool stringPool;
+  StringPool string_pool;
 
   /**
    * The list of packages in this table, sorted alphabetically by package name.
@@ -273,31 +273,31 @@
    * represent the
    * 'current' package before it is known to the ResourceTable.
    */
-  ResourceTablePackage* findPackage(const StringPiece& name);
+  ResourceTablePackage* FindPackage(const StringPiece& name);
 
-  ResourceTablePackage* findPackageById(uint8_t id);
+  ResourceTablePackage* FindPackageById(uint8_t id);
 
-  ResourceTablePackage* createPackage(const StringPiece& name,
+  ResourceTablePackage* CreatePackage(const StringPiece& name,
                                       Maybe<uint8_t> id = {});
 
  private:
-  ResourceTablePackage* findOrCreatePackage(const StringPiece& name);
+  ResourceTablePackage* FindOrCreatePackage(const StringPiece& name);
 
-  bool addResourceImpl(const ResourceNameRef& name, const ResourceId& resId,
+  bool AddResourceImpl(const ResourceNameRef& name, const ResourceId& res_id,
                        const ConfigDescription& config,
                        const StringPiece& product, std::unique_ptr<Value> value,
-                       const char* validChars,
-                       const CollisionResolverFunc& conflictResolver,
+                       const char* valid_chars,
+                       const CollisionResolverFunc& conflict_resolver,
                        IDiagnostics* diag);
 
-  bool addFileReferenceImpl(const ResourceNameRef& name,
+  bool AddFileReferenceImpl(const ResourceNameRef& name,
                             const ConfigDescription& config,
                             const Source& source, const StringPiece& path,
-                            io::IFile* file, const char* validChars,
+                            io::IFile* file, const char* valid_chars,
                             IDiagnostics* diag);
 
-  bool setSymbolStateImpl(const ResourceNameRef& name, const ResourceId& resId,
-                          const Symbol& symbol, const char* validChars,
+  bool SetSymbolStateImpl(const ResourceNameRef& name, const ResourceId& res_id,
+                          const Symbol& symbol, const char* valid_chars,
                           IDiagnostics* diag);
 
   DISALLOW_COPY_AND_ASSIGN(ResourceTable);
diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp
index a64ad3e..cb3699a0 100644
--- a/tools/aapt2/ResourceTable_test.cpp
+++ b/tools/aapt2/ResourceTable_test.cpp
@@ -29,108 +29,108 @@
 TEST(ResourceTableTest, FailToAddResourceWithBadName) {
   ResourceTable table;
 
-  EXPECT_FALSE(table.addResource(
-      test::parseNameOrDie("android:id/hey,there"), ConfigDescription{}, "",
-      test::ValueBuilder<Id>().setSource("test.xml", 21u).build(),
-      test::getDiagnostics()));
+  EXPECT_FALSE(table.AddResource(
+      test::ParseNameOrDie("android:id/hey,there"), ConfigDescription{}, "",
+      test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(),
+      test::GetDiagnostics()));
 
-  EXPECT_FALSE(table.addResource(
-      test::parseNameOrDie("android:id/hey:there"), ConfigDescription{}, "",
-      test::ValueBuilder<Id>().setSource("test.xml", 21u).build(),
-      test::getDiagnostics()));
+  EXPECT_FALSE(table.AddResource(
+      test::ParseNameOrDie("android:id/hey:there"), ConfigDescription{}, "",
+      test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(),
+      test::GetDiagnostics()));
 }
 
 TEST(ResourceTableTest, AddOneResource) {
   ResourceTable table;
 
-  EXPECT_TRUE(table.addResource(
-      test::parseNameOrDie("android:attr/id"), ConfigDescription{}, "",
-      test::ValueBuilder<Id>().setSource("test/path/file.xml", 23u).build(),
-      test::getDiagnostics()));
+  EXPECT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:attr/id"), ConfigDescription{}, "",
+      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 23u).Build(),
+      test::GetDiagnostics()));
 
-  ASSERT_NE(nullptr, test::getValue<Id>(&table, "android:attr/id"));
+  ASSERT_NE(nullptr, test::GetValue<Id>(&table, "android:attr/id"));
 }
 
 TEST(ResourceTableTest, AddMultipleResources) {
   ResourceTable table;
 
   ConfigDescription config;
-  ConfigDescription languageConfig;
-  memcpy(languageConfig.language, "pl", sizeof(languageConfig.language));
+  ConfigDescription language_config;
+  memcpy(language_config.language, "pl", sizeof(language_config.language));
 
-  EXPECT_TRUE(table.addResource(
-      test::parseNameOrDie("android:attr/layout_width"), config, "",
-      test::ValueBuilder<Id>().setSource("test/path/file.xml", 10u).build(),
-      test::getDiagnostics()));
+  EXPECT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:attr/layout_width"), config, "",
+      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 10u).Build(),
+      test::GetDiagnostics()));
 
-  EXPECT_TRUE(table.addResource(
-      test::parseNameOrDie("android:attr/id"), config, "",
-      test::ValueBuilder<Id>().setSource("test/path/file.xml", 12u).build(),
-      test::getDiagnostics()));
+  EXPECT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:attr/id"), config, "",
+      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 12u).Build(),
+      test::GetDiagnostics()));
 
-  EXPECT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/ok"), config, "",
-      test::ValueBuilder<Id>().setSource("test/path/file.xml", 14u).build(),
-      test::getDiagnostics()));
+  EXPECT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/ok"), config, "",
+      test::ValueBuilder<Id>().SetSource("test/path/file.xml", 14u).Build(),
+      test::GetDiagnostics()));
 
-  EXPECT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/ok"), languageConfig, "",
+  EXPECT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/ok"), language_config, "",
       test::ValueBuilder<BinaryPrimitive>(android::Res_value{})
-          .setSource("test/path/file.xml", 20u)
-          .build(),
-      test::getDiagnostics()));
+          .SetSource("test/path/file.xml", 20u)
+          .Build(),
+      test::GetDiagnostics()));
 
-  ASSERT_NE(nullptr, test::getValue<Id>(&table, "android:attr/layout_width"));
-  ASSERT_NE(nullptr, test::getValue<Id>(&table, "android:attr/id"));
-  ASSERT_NE(nullptr, test::getValue<Id>(&table, "android:string/ok"));
-  ASSERT_NE(nullptr, test::getValueForConfig<BinaryPrimitive>(
-                         &table, "android:string/ok", languageConfig));
+  ASSERT_NE(nullptr, test::GetValue<Id>(&table, "android:attr/layout_width"));
+  ASSERT_NE(nullptr, test::GetValue<Id>(&table, "android:attr/id"));
+  ASSERT_NE(nullptr, test::GetValue<Id>(&table, "android:string/ok"));
+  ASSERT_NE(nullptr, test::GetValueForConfig<BinaryPrimitive>(
+                         &table, "android:string/ok", language_config));
 }
 
 TEST(ResourceTableTest, OverrideWeakResourceValue) {
   ResourceTable table;
 
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
-      util::make_unique<Attribute>(true), test::getDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
+      util::make_unique<Attribute>(true), test::GetDiagnostics()));
 
-  Attribute* attr = test::getValue<Attribute>(&table, "android:attr/foo");
+  Attribute* attr = test::GetValue<Attribute>(&table, "android:attr/foo");
   ASSERT_NE(nullptr, attr);
-  EXPECT_TRUE(attr->isWeak());
+  EXPECT_TRUE(attr->IsWeak());
 
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
-      util::make_unique<Attribute>(false), test::getDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
+      util::make_unique<Attribute>(false), test::GetDiagnostics()));
 
-  attr = test::getValue<Attribute>(&table, "android:attr/foo");
+  attr = test::GetValue<Attribute>(&table, "android:attr/foo");
   ASSERT_NE(nullptr, attr);
-  EXPECT_FALSE(attr->isWeak());
+  EXPECT_FALSE(attr->IsWeak());
 }
 
 TEST(ResourceTableTest, ProductVaryingValues) {
   ResourceTable table;
 
-  EXPECT_TRUE(table.addResource(test::parseNameOrDie("android:string/foo"),
-                                test::parseConfigOrDie("land"), "tablet",
+  EXPECT_TRUE(table.AddResource(test::ParseNameOrDie("android:string/foo"),
+                                test::ParseConfigOrDie("land"), "tablet",
                                 util::make_unique<Id>(),
-                                test::getDiagnostics()));
-  EXPECT_TRUE(table.addResource(test::parseNameOrDie("android:string/foo"),
-                                test::parseConfigOrDie("land"), "phone",
+                                test::GetDiagnostics()));
+  EXPECT_TRUE(table.AddResource(test::ParseNameOrDie("android:string/foo"),
+                                test::ParseConfigOrDie("land"), "phone",
                                 util::make_unique<Id>(),
-                                test::getDiagnostics()));
+                                test::GetDiagnostics()));
 
-  EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(
+  EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<Id>(
                          &table, "android:string/foo",
-                         test::parseConfigOrDie("land"), "tablet"));
-  EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(
+                         test::ParseConfigOrDie("land"), "tablet"));
+  EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<Id>(
                          &table, "android:string/foo",
-                         test::parseConfigOrDie("land"), "phone"));
+                         test::ParseConfigOrDie("land"), "phone"));
 
   Maybe<ResourceTable::SearchResult> sr =
-      table.findResource(test::parseNameOrDie("android:string/foo"));
+      table.FindResource(test::ParseNameOrDie("android:string/foo"));
   AAPT_ASSERT_TRUE(sr);
   std::vector<ResourceConfigValue*> values =
-      sr.value().entry->findAllValues(test::parseConfigOrDie("land"));
+      sr.value().entry->findAllValues(test::ParseConfigOrDie("land"));
   ASSERT_EQ(2u, values.size());
   EXPECT_EQ(std::string("phone"), values[0]->product);
   EXPECT_EQ(std::string("tablet"), values[1]->product);
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index b41be4b..fce9b33 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -15,34 +15,36 @@
  */
 
 #include "ResourceUtils.h"
+
+#include <sstream>
+
+#include "androidfw/ResourceTypes.h"
+
 #include "NameMangler.h"
 #include "SdkConstants.h"
 #include "flatten/ResourceTypeExtensions.h"
 #include "util/Files.h"
 #include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
-#include <sstream>
-
 namespace aapt {
 namespace ResourceUtils {
 
-Maybe<ResourceName> toResourceName(
-    const android::ResTable::resource_name& nameIn) {
-  ResourceName nameOut;
-  if (!nameIn.package) {
+Maybe<ResourceName> ToResourceName(
+    const android::ResTable::resource_name& name_in) {
+  ResourceName name_out;
+  if (!name_in.package) {
     return {};
   }
 
-  nameOut.package =
-      util::utf16ToUtf8(StringPiece16(nameIn.package, nameIn.packageLen));
+  name_out.package =
+      util::Utf16ToUtf8(StringPiece16(name_in.package, name_in.packageLen));
 
   const ResourceType* type;
-  if (nameIn.type) {
-    type = parseResourceType(
-        util::utf16ToUtf8(StringPiece16(nameIn.type, nameIn.typeLen)));
-  } else if (nameIn.type8) {
-    type = parseResourceType(StringPiece(nameIn.type8, nameIn.typeLen));
+  if (name_in.type) {
+    type = ParseResourceType(
+        util::Utf16ToUtf8(StringPiece16(name_in.type, name_in.typeLen)));
+  } else if (name_in.type8) {
+    type = ParseResourceType(StringPiece(name_in.type8, name_in.typeLen));
   } else {
     return {};
   }
@@ -51,46 +53,46 @@
     return {};
   }
 
-  nameOut.type = *type;
+  name_out.type = *type;
 
-  if (nameIn.name) {
-    nameOut.entry =
-        util::utf16ToUtf8(StringPiece16(nameIn.name, nameIn.nameLen));
-  } else if (nameIn.name8) {
-    nameOut.entry = StringPiece(nameIn.name8, nameIn.nameLen).toString();
+  if (name_in.name) {
+    name_out.entry =
+        util::Utf16ToUtf8(StringPiece16(name_in.name, name_in.nameLen));
+  } else if (name_in.name8) {
+    name_out.entry = StringPiece(name_in.name8, name_in.nameLen).ToString();
   } else {
     return {};
   }
-  return nameOut;
+  return name_out;
 }
 
-bool extractResourceName(const StringPiece& str, StringPiece* outPackage,
-                         StringPiece* outType, StringPiece* outEntry) {
-  bool hasPackageSeparator = false;
-  bool hasTypeSeparator = false;
+bool ExtractResourceName(const StringPiece& str, StringPiece* out_package,
+                         StringPiece* out_type, StringPiece* out_entry) {
+  bool has_package_separator = false;
+  bool has_type_separator = false;
   const char* start = str.data();
   const char* end = start + str.size();
   const char* current = start;
   while (current != end) {
-    if (outType->size() == 0 && *current == '/') {
-      hasTypeSeparator = true;
-      outType->assign(start, current - start);
+    if (out_type->size() == 0 && *current == '/') {
+      has_type_separator = true;
+      out_type->assign(start, current - start);
       start = current + 1;
-    } else if (outPackage->size() == 0 && *current == ':') {
-      hasPackageSeparator = true;
-      outPackage->assign(start, current - start);
+    } else if (out_package->size() == 0 && *current == ':') {
+      has_package_separator = true;
+      out_package->assign(start, current - start);
       start = current + 1;
     }
     current++;
   }
-  outEntry->assign(start, end - start);
+  out_entry->assign(start, end - start);
 
-  return !(hasPackageSeparator && outPackage->empty()) &&
-         !(hasTypeSeparator && outType->empty());
+  return !(has_package_separator && out_package->empty()) &&
+         !(has_type_separator && out_type->empty());
 }
 
-bool parseResourceName(const StringPiece& str, ResourceNameRef* outRef,
-                       bool* outPrivate) {
+bool ParseResourceName(const StringPiece& str, ResourceNameRef* out_ref,
+                       bool* out_private) {
   if (str.empty()) {
     return false;
   }
@@ -105,13 +107,13 @@
   StringPiece package;
   StringPiece type;
   StringPiece entry;
-  if (!extractResourceName(str.substr(offset, str.size() - offset), &package,
+  if (!ExtractResourceName(str.substr(offset, str.size() - offset), &package,
                            &type, &entry)) {
     return false;
   }
 
-  const ResourceType* parsedType = parseResourceType(type);
-  if (!parsedType) {
+  const ResourceType* parsed_type = ParseResourceType(type);
+  if (!parsed_type) {
     return false;
   }
 
@@ -119,37 +121,37 @@
     return false;
   }
 
-  if (outRef) {
-    outRef->package = package;
-    outRef->type = *parsedType;
-    outRef->entry = entry;
+  if (out_ref) {
+    out_ref->package = package;
+    out_ref->type = *parsed_type;
+    out_ref->entry = entry;
   }
 
-  if (outPrivate) {
-    *outPrivate = priv;
+  if (out_private) {
+    *out_private = priv;
   }
   return true;
 }
 
-bool parseReference(const StringPiece& str, ResourceNameRef* outRef,
-                    bool* outCreate, bool* outPrivate) {
-  StringPiece trimmedStr(util::trimWhitespace(str));
-  if (trimmedStr.empty()) {
+bool ParseReference(const StringPiece& str, ResourceNameRef* out_ref,
+                    bool* out_create, bool* out_private) {
+  StringPiece trimmed_str(util::TrimWhitespace(str));
+  if (trimmed_str.empty()) {
     return false;
   }
 
   bool create = false;
   bool priv = false;
-  if (trimmedStr.data()[0] == '@') {
+  if (trimmed_str.data()[0] == '@') {
     size_t offset = 1;
-    if (trimmedStr.data()[1] == '+') {
+    if (trimmed_str.data()[1] == '+') {
       create = true;
       offset += 1;
     }
 
     ResourceNameRef name;
-    if (!parseResourceName(
-            trimmedStr.substr(offset, trimmedStr.size() - offset), &name,
+    if (!ParseResourceName(
+            trimmed_str.substr(offset, trimmed_str.size() - offset), &name,
             &priv)) {
       return false;
     }
@@ -162,37 +164,37 @@
       return false;
     }
 
-    if (outRef) {
-      *outRef = name;
+    if (out_ref) {
+      *out_ref = name;
     }
 
-    if (outCreate) {
-      *outCreate = create;
+    if (out_create) {
+      *out_create = create;
     }
 
-    if (outPrivate) {
-      *outPrivate = priv;
+    if (out_private) {
+      *out_private = priv;
     }
     return true;
   }
   return false;
 }
 
-bool isReference(const StringPiece& str) {
-  return parseReference(str, nullptr, nullptr, nullptr);
+bool IsReference(const StringPiece& str) {
+  return ParseReference(str, nullptr, nullptr, nullptr);
 }
 
-bool parseAttributeReference(const StringPiece& str, ResourceNameRef* outRef) {
-  StringPiece trimmedStr(util::trimWhitespace(str));
-  if (trimmedStr.empty()) {
+bool ParseAttributeReference(const StringPiece& str, ResourceNameRef* out_ref) {
+  StringPiece trimmed_str(util::TrimWhitespace(str));
+  if (trimmed_str.empty()) {
     return false;
   }
 
-  if (*trimmedStr.data() == '?') {
+  if (*trimmed_str.data() == '?') {
     StringPiece package;
     StringPiece type;
     StringPiece entry;
-    if (!extractResourceName(trimmedStr.substr(1, trimmedStr.size() - 1),
+    if (!ExtractResourceName(trimmed_str.substr(1, trimmed_str.size() - 1),
                              &package, &type, &entry)) {
       return false;
     }
@@ -205,18 +207,18 @@
       return false;
     }
 
-    if (outRef) {
-      outRef->package = package;
-      outRef->type = ResourceType::kAttr;
-      outRef->entry = entry;
+    if (out_ref) {
+      out_ref->package = package;
+      out_ref->type = ResourceType::kAttr;
+      out_ref->entry = entry;
     }
     return true;
   }
   return false;
 }
 
-bool isAttributeReference(const StringPiece& str) {
-  return parseAttributeReference(str, nullptr);
+bool IsAttributeReference(const StringPiece& str) {
+  return ParseAttributeReference(str, nullptr);
 }
 
 /*
@@ -227,65 +229,65 @@
  * <[*]package>:[style/]<entry>
  * [[*]package:style/]<entry>
  */
-Maybe<Reference> parseStyleParentReference(const StringPiece& str,
-                                           std::string* outError) {
+Maybe<Reference> ParseStyleParentReference(const StringPiece& str,
+                                           std::string* out_error) {
   if (str.empty()) {
     return {};
   }
 
   StringPiece name = str;
 
-  bool hasLeadingIdentifiers = false;
-  bool privateRef = false;
+  bool has_leading_identifiers = false;
+  bool private_ref = false;
 
   // Skip over these identifiers. A style's parent is a normal reference.
   if (name.data()[0] == '@' || name.data()[0] == '?') {
-    hasLeadingIdentifiers = true;
+    has_leading_identifiers = true;
     name = name.substr(1, name.size() - 1);
   }
 
   if (name.data()[0] == '*') {
-    privateRef = true;
+    private_ref = true;
     name = name.substr(1, name.size() - 1);
   }
 
   ResourceNameRef ref;
   ref.type = ResourceType::kStyle;
 
-  StringPiece typeStr;
-  extractResourceName(name, &ref.package, &typeStr, &ref.entry);
-  if (!typeStr.empty()) {
+  StringPiece type_str;
+  ExtractResourceName(name, &ref.package, &type_str, &ref.entry);
+  if (!type_str.empty()) {
     // If we have a type, make sure it is a Style.
-    const ResourceType* parsedType = parseResourceType(typeStr);
-    if (!parsedType || *parsedType != ResourceType::kStyle) {
+    const ResourceType* parsed_type = ParseResourceType(type_str);
+    if (!parsed_type || *parsed_type != ResourceType::kStyle) {
       std::stringstream err;
-      err << "invalid resource type '" << typeStr << "' for parent of style";
-      *outError = err.str();
+      err << "invalid resource type '" << type_str << "' for parent of style";
+      *out_error = err.str();
       return {};
     }
   }
 
-  if (!hasLeadingIdentifiers && ref.package.empty() && !typeStr.empty()) {
+  if (!has_leading_identifiers && ref.package.empty() && !type_str.empty()) {
     std::stringstream err;
     err << "invalid parent reference '" << str << "'";
-    *outError = err.str();
+    *out_error = err.str();
     return {};
   }
 
   Reference result(ref);
-  result.privateReference = privateRef;
+  result.private_reference = private_ref;
   return result;
 }
 
-Maybe<Reference> parseXmlAttributeName(const StringPiece& str) {
-  StringPiece trimmedStr = util::trimWhitespace(str);
-  const char* start = trimmedStr.data();
-  const char* const end = start + trimmedStr.size();
+Maybe<Reference> ParseXmlAttributeName(const StringPiece& str) {
+  StringPiece trimmed_str = util::TrimWhitespace(str);
+  const char* start = trimmed_str.data();
+  const char* const end = start + trimmed_str.size();
   const char* p = start;
 
   Reference ref;
   if (p != end && *p == '*') {
-    ref.privateReference = true;
+    ref.private_reference = true;
     start++;
     p++;
   }
@@ -302,38 +304,38 @@
   }
 
   ref.name =
-      ResourceName(package.toString(), ResourceType::kAttr,
-                   name.empty() ? trimmedStr.toString() : name.toString());
+      ResourceName(package.ToString(), ResourceType::kAttr,
+                   name.empty() ? trimmed_str.ToString() : name.ToString());
   return Maybe<Reference>(std::move(ref));
 }
 
-std::unique_ptr<Reference> tryParseReference(const StringPiece& str,
-                                             bool* outCreate) {
+std::unique_ptr<Reference> TryParseReference(const StringPiece& str,
+                                             bool* out_create) {
   ResourceNameRef ref;
-  bool privateRef = false;
-  if (parseReference(str, &ref, outCreate, &privateRef)) {
+  bool private_ref = false;
+  if (ParseReference(str, &ref, out_create, &private_ref)) {
     std::unique_ptr<Reference> value = util::make_unique<Reference>(ref);
-    value->privateReference = privateRef;
+    value->private_reference = private_ref;
     return value;
   }
 
-  if (parseAttributeReference(str, &ref)) {
-    if (outCreate) {
-      *outCreate = false;
+  if (ParseAttributeReference(str, &ref)) {
+    if (out_create) {
+      *out_create = false;
     }
     return util::make_unique<Reference>(ref, Reference::Type::kAttribute);
   }
   return {};
 }
 
-std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece& str) {
-  StringPiece trimmedStr(util::trimWhitespace(str));
+std::unique_ptr<BinaryPrimitive> TryParseNullOrEmpty(const StringPiece& str) {
+  StringPiece trimmed_str(util::TrimWhitespace(str));
   android::Res_value value = {};
-  if (trimmedStr == "@null") {
+  if (trimmed_str == "@null") {
     // TYPE_NULL with data set to 0 is interpreted by the runtime as an error.
     // Instead we set the data type to TYPE_REFERENCE with a value of 0.
     value.dataType = android::Res_value::TYPE_REFERENCE;
-  } else if (trimmedStr == "@empty") {
+  } else if (trimmed_str == "@empty") {
     // TYPE_NULL with value of DATA_NULL_EMPTY is handled fine by the runtime.
     value.dataType = android::Res_value::TYPE_NULL;
     value.data = android::Res_value::DATA_NULL_EMPTY;
@@ -343,14 +345,14 @@
   return util::make_unique<BinaryPrimitive>(value);
 }
 
-std::unique_ptr<BinaryPrimitive> tryParseEnumSymbol(const Attribute* enumAttr,
+std::unique_ptr<BinaryPrimitive> TryParseEnumSymbol(const Attribute* enum_attr,
                                                     const StringPiece& str) {
-  StringPiece trimmedStr(util::trimWhitespace(str));
-  for (const Attribute::Symbol& symbol : enumAttr->symbols) {
+  StringPiece trimmed_str(util::TrimWhitespace(str));
+  for (const Attribute::Symbol& symbol : enum_attr->symbols) {
     // Enum symbols are stored as @package:id/symbol resources,
     // so we need to match against the 'entry' part of the identifier.
-    const ResourceName& enumSymbolResourceName = symbol.symbol.name.value();
-    if (trimmedStr == enumSymbolResourceName.entry) {
+    const ResourceName& enum_symbol_resource_name = symbol.symbol.name.value();
+    if (trimmed_str == enum_symbol_resource_name.entry) {
       android::Res_value value = {};
       value.dataType = android::Res_value::TYPE_INT_DEC;
       value.data = symbol.value;
@@ -360,40 +362,41 @@
   return {};
 }
 
-std::unique_ptr<BinaryPrimitive> tryParseFlagSymbol(const Attribute* flagAttr,
+std::unique_ptr<BinaryPrimitive> TryParseFlagSymbol(const Attribute* flag_attr,
                                                     const StringPiece& str) {
   android::Res_value flags = {};
   flags.dataType = android::Res_value::TYPE_INT_HEX;
   flags.data = 0u;
 
-  if (util::trimWhitespace(str).empty()) {
+  if (util::TrimWhitespace(str).empty()) {
     // Empty string is a valid flag (0).
     return util::make_unique<BinaryPrimitive>(flags);
   }
 
-  for (StringPiece part : util::tokenize(str, '|')) {
-    StringPiece trimmedPart = util::trimWhitespace(part);
+  for (StringPiece part : util::Tokenize(str, '|')) {
+    StringPiece trimmed_part = util::TrimWhitespace(part);
 
-    bool flagSet = false;
-    for (const Attribute::Symbol& symbol : flagAttr->symbols) {
+    bool flag_set = false;
+    for (const Attribute::Symbol& symbol : flag_attr->symbols) {
       // Flag symbols are stored as @package:id/symbol resources,
       // so we need to match against the 'entry' part of the identifier.
-      const ResourceName& flagSymbolResourceName = symbol.symbol.name.value();
-      if (trimmedPart == flagSymbolResourceName.entry) {
+      const ResourceName& flag_symbol_resource_name =
+          symbol.symbol.name.value();
+      if (trimmed_part == flag_symbol_resource_name.entry) {
         flags.data |= symbol.value;
-        flagSet = true;
+        flag_set = true;
         break;
       }
     }
 
-    if (!flagSet) {
+    if (!flag_set) {
       return {};
     }
   }
   return util::make_unique<BinaryPrimitive>(flags);
 }
 
-static uint32_t parseHex(char c, bool* outError) {
+static uint32_t ParseHex(char c, bool* out_error) {
   if (c >= '0' && c <= '9') {
     return c - '0';
   } else if (c >= 'a' && c <= 'f') {
@@ -401,15 +404,15 @@
   } else if (c >= 'A' && c <= 'F') {
     return c - 'A' + 0xa;
   } else {
-    *outError = true;
+    *out_error = true;
     return 0xffffffffu;
   }
 }
 
-std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece& str) {
-  StringPiece colorStr(util::trimWhitespace(str));
-  const char* start = colorStr.data();
-  const size_t len = colorStr.size();
+std::unique_ptr<BinaryPrimitive> TryParseColor(const StringPiece& str) {
+  StringPiece color_str(util::TrimWhitespace(str));
+  const char* start = color_str.data();
+  const size_t len = color_str.size();
   if (len == 0 || start[0] != '#') {
     return {};
   }
@@ -419,41 +422,41 @@
   if (len == 4) {
     value.dataType = android::Res_value::TYPE_INT_COLOR_RGB4;
     value.data = 0xff000000u;
-    value.data |= parseHex(start[1], &error) << 20;
-    value.data |= parseHex(start[1], &error) << 16;
-    value.data |= parseHex(start[2], &error) << 12;
-    value.data |= parseHex(start[2], &error) << 8;
-    value.data |= parseHex(start[3], &error) << 4;
-    value.data |= parseHex(start[3], &error);
+    value.data |= ParseHex(start[1], &error) << 20;
+    value.data |= ParseHex(start[1], &error) << 16;
+    value.data |= ParseHex(start[2], &error) << 12;
+    value.data |= ParseHex(start[2], &error) << 8;
+    value.data |= ParseHex(start[3], &error) << 4;
+    value.data |= ParseHex(start[3], &error);
   } else if (len == 5) {
     value.dataType = android::Res_value::TYPE_INT_COLOR_ARGB4;
-    value.data |= parseHex(start[1], &error) << 28;
-    value.data |= parseHex(start[1], &error) << 24;
-    value.data |= parseHex(start[2], &error) << 20;
-    value.data |= parseHex(start[2], &error) << 16;
-    value.data |= parseHex(start[3], &error) << 12;
-    value.data |= parseHex(start[3], &error) << 8;
-    value.data |= parseHex(start[4], &error) << 4;
-    value.data |= parseHex(start[4], &error);
+    value.data |= ParseHex(start[1], &error) << 28;
+    value.data |= ParseHex(start[1], &error) << 24;
+    value.data |= ParseHex(start[2], &error) << 20;
+    value.data |= ParseHex(start[2], &error) << 16;
+    value.data |= ParseHex(start[3], &error) << 12;
+    value.data |= ParseHex(start[3], &error) << 8;
+    value.data |= ParseHex(start[4], &error) << 4;
+    value.data |= ParseHex(start[4], &error);
   } else if (len == 7) {
     value.dataType = android::Res_value::TYPE_INT_COLOR_RGB8;
     value.data = 0xff000000u;
-    value.data |= parseHex(start[1], &error) << 20;
-    value.data |= parseHex(start[2], &error) << 16;
-    value.data |= parseHex(start[3], &error) << 12;
-    value.data |= parseHex(start[4], &error) << 8;
-    value.data |= parseHex(start[5], &error) << 4;
-    value.data |= parseHex(start[6], &error);
+    value.data |= ParseHex(start[1], &error) << 20;
+    value.data |= ParseHex(start[2], &error) << 16;
+    value.data |= ParseHex(start[3], &error) << 12;
+    value.data |= ParseHex(start[4], &error) << 8;
+    value.data |= ParseHex(start[5], &error) << 4;
+    value.data |= ParseHex(start[6], &error);
   } else if (len == 9) {
     value.dataType = android::Res_value::TYPE_INT_COLOR_ARGB8;
-    value.data |= parseHex(start[1], &error) << 28;
-    value.data |= parseHex(start[2], &error) << 24;
-    value.data |= parseHex(start[3], &error) << 20;
-    value.data |= parseHex(start[4], &error) << 16;
-    value.data |= parseHex(start[5], &error) << 12;
-    value.data |= parseHex(start[6], &error) << 8;
-    value.data |= parseHex(start[7], &error) << 4;
-    value.data |= parseHex(start[8], &error);
+    value.data |= ParseHex(start[1], &error) << 28;
+    value.data |= ParseHex(start[2], &error) << 24;
+    value.data |= ParseHex(start[3], &error) << 20;
+    value.data |= ParseHex(start[4], &error) << 16;
+    value.data |= ParseHex(start[5], &error) << 12;
+    value.data |= ParseHex(start[6], &error) << 8;
+    value.data |= ParseHex(start[7], &error) << 4;
+    value.data |= ParseHex(start[8], &error);
   } else {
     return {};
   }
@@ -461,19 +464,19 @@
                : util::make_unique<BinaryPrimitive>(value);
 }
 
-Maybe<bool> parseBool(const StringPiece& str) {
-  StringPiece trimmedStr(util::trimWhitespace(str));
-  if (trimmedStr == "true" || trimmedStr == "TRUE" || trimmedStr == "True") {
+Maybe<bool> ParseBool(const StringPiece& str) {
+  StringPiece trimmed_str(util::TrimWhitespace(str));
+  if (trimmed_str == "true" || trimmed_str == "TRUE" || trimmed_str == "True") {
     return Maybe<bool>(true);
-  } else if (trimmedStr == "false" || trimmedStr == "FALSE" ||
-             trimmedStr == "False") {
+  } else if (trimmed_str == "false" || trimmed_str == "FALSE" ||
+             trimmed_str == "False") {
     return Maybe<bool>(false);
   }
   return {};
 }
 
-Maybe<uint32_t> parseInt(const StringPiece& str) {
-  std::u16string str16 = util::utf8ToUtf16(str);
+Maybe<uint32_t> ParseInt(const StringPiece& str) {
+  std::u16string str16 = util::Utf8ToUtf16(str);
   android::Res_value value;
   if (android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
     return value.data;
@@ -481,15 +484,15 @@
   return {};
 }
 
-Maybe<ResourceId> parseResourceId(const StringPiece& str) {
-  StringPiece trimmedStr(util::trimWhitespace(str));
+Maybe<ResourceId> ParseResourceId(const StringPiece& str) {
+  StringPiece trimmed_str(util::TrimWhitespace(str));
 
-  std::u16string str16 = util::utf8ToUtf16(trimmedStr);
+  std::u16string str16 = util::Utf8ToUtf16(trimmed_str);
   android::Res_value value;
   if (android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
     if (value.dataType == android::Res_value::TYPE_INT_HEX) {
       ResourceId id(value.data);
-      if (id.isValid()) {
+      if (id.is_valid()) {
         return id;
       }
     }
@@ -497,29 +500,29 @@
   return {};
 }
 
-Maybe<int> parseSdkVersion(const StringPiece& str) {
-  StringPiece trimmedStr(util::trimWhitespace(str));
+Maybe<int> ParseSdkVersion(const StringPiece& str) {
+  StringPiece trimmed_str(util::TrimWhitespace(str));
 
-  std::u16string str16 = util::utf8ToUtf16(trimmedStr);
+  std::u16string str16 = util::Utf8ToUtf16(trimmed_str);
   android::Res_value value;
   if (android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
     return static_cast<int>(value.data);
   }
 
   // Try parsing the code name.
-  std::pair<StringPiece, int> entry = getDevelopmentSdkCodeNameAndVersion();
-  if (entry.first == trimmedStr) {
+  std::pair<StringPiece, int> entry = GetDevelopmentSdkCodeNameAndVersion();
+  if (entry.first == trimmed_str) {
     return entry.second;
   }
   return {};
 }
 
-std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece& str) {
-  if (Maybe<bool> maybeResult = parseBool(str)) {
+std::unique_ptr<BinaryPrimitive> TryParseBool(const StringPiece& str) {
+  if (Maybe<bool> maybe_result = ParseBool(str)) {
     android::Res_value value = {};
     value.dataType = android::Res_value::TYPE_INT_BOOLEAN;
 
-    if (maybeResult.value()) {
+    if (maybe_result.value()) {
       value.data = 0xffffffffu;
     } else {
       value.data = 0;
@@ -529,8 +532,8 @@
   return {};
 }
 
-std::unique_ptr<BinaryPrimitive> tryParseInt(const StringPiece& str) {
-  std::u16string str16 = util::utf8ToUtf16(str);
+std::unique_ptr<BinaryPrimitive> TryParseInt(const StringPiece& str) {
+  std::u16string str16 = util::Utf8ToUtf16(str);
   android::Res_value value;
   if (!android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
     return {};
@@ -538,8 +541,8 @@
   return util::make_unique<BinaryPrimitive>(value);
 }
 
-std::unique_ptr<BinaryPrimitive> tryParseFloat(const StringPiece& str) {
-  std::u16string str16 = util::utf8ToUtf16(str);
+std::unique_ptr<BinaryPrimitive> TryParseFloat(const StringPiece& str) {
+  std::u16string str16 = util::Utf8ToUtf16(str);
   android::Res_value value;
   if (!android::ResTable::stringToFloat(str16.data(), str16.size(), &value)) {
     return {};
@@ -547,7 +550,7 @@
   return util::make_unique<BinaryPrimitive>(value);
 }
 
-uint32_t androidTypeToAttributeTypeMask(uint16_t type) {
+uint32_t AndroidTypeToAttributeTypeMask(uint16_t type) {
   switch (type) {
     case android::Res_value::TYPE_NULL:
     case android::Res_value::TYPE_REFERENCE:
@@ -587,57 +590,57 @@
   };
 }
 
-std::unique_ptr<Item> tryParseItemForAttribute(
-    const StringPiece& value, uint32_t typeMask,
-    const std::function<void(const ResourceName&)>& onCreateReference) {
-  std::unique_ptr<BinaryPrimitive> nullOrEmpty = tryParseNullOrEmpty(value);
-  if (nullOrEmpty) {
-    return std::move(nullOrEmpty);
+std::unique_ptr<Item> TryParseItemForAttribute(
+    const StringPiece& value, uint32_t type_mask,
+    const std::function<void(const ResourceName&)>& on_create_reference) {
+  std::unique_ptr<BinaryPrimitive> null_or_empty = TryParseNullOrEmpty(value);
+  if (null_or_empty) {
+    return std::move(null_or_empty);
   }
 
   bool create = false;
-  std::unique_ptr<Reference> reference = tryParseReference(value, &create);
+  std::unique_ptr<Reference> reference = TryParseReference(value, &create);
   if (reference) {
-    if (create && onCreateReference) {
-      onCreateReference(reference->name.value());
+    if (create && on_create_reference) {
+      on_create_reference(reference->name.value());
     }
     return std::move(reference);
   }
 
-  if (typeMask & android::ResTable_map::TYPE_COLOR) {
+  if (type_mask & android::ResTable_map::TYPE_COLOR) {
     // Try parsing this as a color.
-    std::unique_ptr<BinaryPrimitive> color = tryParseColor(value);
+    std::unique_ptr<BinaryPrimitive> color = TryParseColor(value);
     if (color) {
       return std::move(color);
     }
   }
 
-  if (typeMask & android::ResTable_map::TYPE_BOOLEAN) {
+  if (type_mask & android::ResTable_map::TYPE_BOOLEAN) {
     // Try parsing this as a boolean.
-    std::unique_ptr<BinaryPrimitive> boolean = tryParseBool(value);
+    std::unique_ptr<BinaryPrimitive> boolean = TryParseBool(value);
     if (boolean) {
       return std::move(boolean);
     }
   }
 
-  if (typeMask & android::ResTable_map::TYPE_INTEGER) {
+  if (type_mask & android::ResTable_map::TYPE_INTEGER) {
     // Try parsing this as an integer.
-    std::unique_ptr<BinaryPrimitive> integer = tryParseInt(value);
+    std::unique_ptr<BinaryPrimitive> integer = TryParseInt(value);
     if (integer) {
       return std::move(integer);
     }
   }
 
-  const uint32_t floatMask = android::ResTable_map::TYPE_FLOAT |
-                             android::ResTable_map::TYPE_DIMENSION |
-                             android::ResTable_map::TYPE_FRACTION;
-  if (typeMask & floatMask) {
+  const uint32_t float_mask = android::ResTable_map::TYPE_FLOAT |
+                              android::ResTable_map::TYPE_DIMENSION |
+                              android::ResTable_map::TYPE_FRACTION;
+  if (type_mask & float_mask) {
     // Try parsing this as a float.
-    std::unique_ptr<BinaryPrimitive> floatingPoint = tryParseFloat(value);
-    if (floatingPoint) {
-      if (typeMask &
-          androidTypeToAttributeTypeMask(floatingPoint->value.dataType)) {
-        return std::move(floatingPoint);
+    std::unique_ptr<BinaryPrimitive> floating_point = TryParseFloat(value);
+    if (floating_point) {
+      if (type_mask &
+          AndroidTypeToAttributeTypeMask(floating_point->value.dataType)) {
+        return std::move(floating_point);
       }
     }
   }
@@ -648,49 +651,49 @@
  * We successively try to parse the string as a resource type that the Attribute
  * allows.
  */
-std::unique_ptr<Item> tryParseItemForAttribute(
+std::unique_ptr<Item> TryParseItemForAttribute(
     const StringPiece& str, const Attribute* attr,
-    const std::function<void(const ResourceName&)>& onCreateReference) {
-  const uint32_t typeMask = attr->typeMask;
+    const std::function<void(const ResourceName&)>& on_create_reference) {
+  const uint32_t type_mask = attr->type_mask;
   std::unique_ptr<Item> value =
-      tryParseItemForAttribute(str, typeMask, onCreateReference);
+      TryParseItemForAttribute(str, type_mask, on_create_reference);
   if (value) {
     return value;
   }
 
-  if (typeMask & android::ResTable_map::TYPE_ENUM) {
+  if (type_mask & android::ResTable_map::TYPE_ENUM) {
     // Try parsing this as an enum.
-    std::unique_ptr<BinaryPrimitive> enumValue = tryParseEnumSymbol(attr, str);
-    if (enumValue) {
-      return std::move(enumValue);
+    std::unique_ptr<BinaryPrimitive> enum_value = TryParseEnumSymbol(attr, str);
+    if (enum_value) {
+      return std::move(enum_value);
     }
   }
 
-  if (typeMask & android::ResTable_map::TYPE_FLAGS) {
+  if (type_mask & android::ResTable_map::TYPE_FLAGS) {
     // Try parsing this as a flag.
-    std::unique_ptr<BinaryPrimitive> flagValue = tryParseFlagSymbol(attr, str);
-    if (flagValue) {
-      return std::move(flagValue);
+    std::unique_ptr<BinaryPrimitive> flag_value = TryParseFlagSymbol(attr, str);
+    if (flag_value) {
+      return std::move(flag_value);
     }
   }
   return {};
 }
 
-std::string buildResourceFileName(const ResourceFile& resFile,
+std::string BuildResourceFileName(const ResourceFile& res_file,
                                   const NameMangler* mangler) {
   std::stringstream out;
-  out << "res/" << resFile.name.type;
-  if (resFile.config != ConfigDescription{}) {
-    out << "-" << resFile.config;
+  out << "res/" << res_file.name.type;
+  if (res_file.config != ConfigDescription{}) {
+    out << "-" << res_file.config;
   }
   out << "/";
 
-  if (mangler && mangler->shouldMangle(resFile.name.package)) {
-    out << NameMangler::mangleEntry(resFile.name.package, resFile.name.entry);
+  if (mangler && mangler->ShouldMangle(res_file.name.package)) {
+    out << NameMangler::MangleEntry(res_file.name.package, res_file.name.entry);
   } else {
-    out << resFile.name.entry;
+    out << res_file.name.entry;
   }
-  out << file::getExtension(resFile.source.path);
+  out << file::GetExtension(res_file.source.path);
   return out.str();
 }
 
diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h
index cebe47c..9766f6a 100644
--- a/tools/aapt2/ResourceUtils.h
+++ b/tools/aapt2/ResourceUtils.h
@@ -17,14 +17,14 @@
 #ifndef AAPT_RESOURCEUTILS_H
 #define AAPT_RESOURCEUTILS_H
 
+#include <functional>
+#include <memory>
+
 #include "NameMangler.h"
 #include "Resource.h"
 #include "ResourceValues.h"
 #include "util/StringPiece.h"
 
-#include <functional>
-#include <memory>
-
 namespace aapt {
 namespace ResourceUtils {
 
@@ -37,76 +37,75 @@
  * individual extracted piece to verify that the pieces are valid.
  * Returns false if there was no package but a ':' was present.
  */
-bool extractResourceName(const StringPiece& str, StringPiece* outPackage,
-                         StringPiece* outType, StringPiece* outEntry);
+bool ExtractResourceName(const StringPiece& str, StringPiece* out_package,
+                         StringPiece* out_type, StringPiece* out_entry);
 
 /**
  * Returns true if the string was parsed as a resource name
  * ([*][package:]type/name), with
- * `outResource` set to the parsed resource name and `outPrivate` set to true if
- * a '*' prefix
- * was present.
+ * `out_resource` set to the parsed resource name and `out_private` set to true
+ * if a '*' prefix was present.
  */
-bool parseResourceName(const StringPiece& str, ResourceNameRef* outResource,
-                       bool* outPrivate = nullptr);
+bool ParseResourceName(const StringPiece& str, ResourceNameRef* out_resource,
+                       bool* out_private = nullptr);
 
 /*
  * Returns true if the string was parsed as a reference
  * (@[+][package:]type/name), with
- * `outReference` set to the parsed reference.
+ * `out_reference` set to the parsed reference.
  *
- * If '+' was present in the reference, `outCreate` is set to true.
- * If '*' was present in the reference, `outPrivate` is set to true.
+ * If '+' was present in the reference, `out_create` is set to true.
+ * If '*' was present in the reference, `out_private` is set to true.
  */
-bool parseReference(const StringPiece& str, ResourceNameRef* outReference,
-                    bool* outCreate = nullptr, bool* outPrivate = nullptr);
+bool ParseReference(const StringPiece& str, ResourceNameRef* out_reference,
+                    bool* out_create = nullptr, bool* out_private = nullptr);
 
 /*
  * Returns true if the string is in the form of a resource reference
  * (@[+][package:]type/name).
  */
-bool isReference(const StringPiece& str);
+bool IsReference(const StringPiece& str);
 
 /*
  * Returns true if the string was parsed as an attribute reference
  * (?[package:][type/]name),
- * with `outReference` set to the parsed reference.
+ * with `out_reference` set to the parsed reference.
  */
-bool parseAttributeReference(const StringPiece& str,
-                             ResourceNameRef* outReference);
+bool ParseAttributeReference(const StringPiece& str,
+                             ResourceNameRef* out_reference);
 
 /**
  * Returns true if the string is in the form of an attribute
  * reference(?[package:][type/]name).
  */
-bool isAttributeReference(const StringPiece& str);
+bool IsAttributeReference(const StringPiece& str);
 
 /**
  * Convert an android::ResTable::resource_name to an aapt::ResourceName struct.
  */
-Maybe<ResourceName> toResourceName(
+Maybe<ResourceName> ToResourceName(
     const android::ResTable::resource_name& name);
 
 /**
  * Returns a boolean value if the string is equal to TRUE, true, True, FALSE,
  * false, or False.
  */
-Maybe<bool> parseBool(const StringPiece& str);
+Maybe<bool> ParseBool(const StringPiece& str);
 
 /**
  * Returns a uint32_t if the string is an integer.
  */
-Maybe<uint32_t> parseInt(const StringPiece& str);
+Maybe<uint32_t> ParseInt(const StringPiece& str);
 
 /**
  * Returns an ID if it the string represented a valid ID.
  */
-Maybe<ResourceId> parseResourceId(const StringPiece& str);
+Maybe<ResourceId> ParseResourceId(const StringPiece& str);
 
 /**
  * Parses an SDK version, which can be an integer, or a letter from A-Z.
  */
-Maybe<int> parseSdkVersion(const StringPiece& str);
+Maybe<int> ParseSdkVersion(const StringPiece& str);
 
 /*
  * Returns a Reference, or None Maybe instance if the string `str` was parsed as
@@ -119,8 +118,8 @@
  * ?[package:]style/<entry> or
  * <package>:[style/]<entry>
  */
-Maybe<Reference> parseStyleParentReference(const StringPiece& str,
-                                           std::string* outError);
+Maybe<Reference> ParseStyleParentReference(const StringPiece& str,
+                                           std::string* out_error);
 
 /*
  * Returns a Reference if the string `str` was parsed as a valid XML attribute
@@ -129,7 +128,7 @@
  *
  * package:entry
  */
-Maybe<Reference> parseXmlAttributeName(const StringPiece& str);
+Maybe<Reference> ParseXmlAttributeName(const StringPiece& str);
 
 /*
  * Returns a Reference object if the string was parsed as a resource or
@@ -138,73 +137,68 @@
  * if
  * the '+' was present in the string.
  */
-std::unique_ptr<Reference> tryParseReference(const StringPiece& str,
-                                             bool* outCreate = nullptr);
+std::unique_ptr<Reference> TryParseReference(const StringPiece& str,
+                                             bool* out_create = nullptr);
 
 /*
  * Returns a BinaryPrimitve object representing @null or @empty if the string
- * was parsed
- * as one.
+ * was parsed as one.
  */
-std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece& str);
+std::unique_ptr<BinaryPrimitive> TryParseNullOrEmpty(const StringPiece& str);
 
 /*
  * Returns a BinaryPrimitve object representing a color if the string was parsed
  * as one.
  */
-std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece& str);
+std::unique_ptr<BinaryPrimitive> TryParseColor(const StringPiece& str);
 
 /*
  * Returns a BinaryPrimitve object representing a boolean if the string was
- * parsed
- * as one.
+ * parsed as one.
  */
-std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece& str);
+std::unique_ptr<BinaryPrimitive> TryParseBool(const StringPiece& str);
 
 /*
  * Returns a BinaryPrimitve object representing an integer if the string was
- * parsed
- * as one.
+ * parsed as one.
  */
-std::unique_ptr<BinaryPrimitive> tryParseInt(const StringPiece& str);
+std::unique_ptr<BinaryPrimitive> TryParseInt(const StringPiece& str);
 
 /*
  * Returns a BinaryPrimitve object representing a floating point number
  * (float, dimension, etc) if the string was parsed as one.
  */
-std::unique_ptr<BinaryPrimitive> tryParseFloat(const StringPiece& str);
+std::unique_ptr<BinaryPrimitive> TryParseFloat(const StringPiece& str);
 
 /*
  * Returns a BinaryPrimitve object representing an enum symbol if the string was
- * parsed
- * as one.
+ * parsed as one.
  */
-std::unique_ptr<BinaryPrimitive> tryParseEnumSymbol(const Attribute* enumAttr,
+std::unique_ptr<BinaryPrimitive> TryParseEnumSymbol(const Attribute* enum_attr,
                                                     const StringPiece& str);
 
 /*
  * Returns a BinaryPrimitve object representing a flag symbol if the string was
- * parsed
- * as one.
+ * parsed as one.
  */
-std::unique_ptr<BinaryPrimitive> tryParseFlagSymbol(const Attribute* enumAttr,
+std::unique_ptr<BinaryPrimitive> TryParseFlagSymbol(const Attribute* enum_attr,
                                                     const StringPiece& str);
 /*
  * Try to convert a string to an Item for the given attribute. The attribute
  * will
  * restrict what values the string can be converted to.
- * The callback function onCreateReference is called when the parsed item is a
+ * The callback function on_create_reference is called when the parsed item is a
  * reference to an ID that must be created (@+id/foo).
  */
-std::unique_ptr<Item> tryParseItemForAttribute(
+std::unique_ptr<Item> TryParseItemForAttribute(
     const StringPiece& value, const Attribute* attr,
-    const std::function<void(const ResourceName&)>& onCreateReference = {});
+    const std::function<void(const ResourceName&)>& on_create_reference = {});
 
-std::unique_ptr<Item> tryParseItemForAttribute(
-    const StringPiece& value, uint32_t typeMask,
-    const std::function<void(const ResourceName&)>& onCreateReference = {});
+std::unique_ptr<Item> TryParseItemForAttribute(
+    const StringPiece& value, uint32_t type_mask,
+    const std::function<void(const ResourceName&)>& on_create_reference = {});
 
-uint32_t androidTypeToAttributeTypeMask(uint16_t type);
+uint32_t AndroidTypeToAttributeTypeMask(uint16_t type);
 
 /**
  * Returns a string path suitable for use within an APK. The path will look
@@ -216,8 +210,8 @@
  * the package
  * requires mangling.
  */
-std::string buildResourceFileName(const ResourceFile& resFile,
-                                  const NameMangler* mangler);
+std::string BuildResourceFileName(const ResourceFile& res_file,
+                                  const NameMangler* mangler = nullptr);
 
 }  // namespace ResourceUtils
 }  // namespace aapt
diff --git a/tools/aapt2/ResourceUtils_test.cpp b/tools/aapt2/ResourceUtils_test.cpp
index eb62b1b..f9c500b 100644
--- a/tools/aapt2/ResourceUtils_test.cpp
+++ b/tools/aapt2/ResourceUtils_test.cpp
@@ -15,128 +15,129 @@
  */
 
 #include "ResourceUtils.h"
+
 #include "Resource.h"
 #include "test/Test.h"
 
 namespace aapt {
 
 TEST(ResourceUtilsTest, ParseBool) {
-  EXPECT_EQ(Maybe<bool>(true), ResourceUtils::parseBool("true"));
-  EXPECT_EQ(Maybe<bool>(true), ResourceUtils::parseBool("TRUE"));
-  EXPECT_EQ(Maybe<bool>(true), ResourceUtils::parseBool("True"));
-  EXPECT_EQ(Maybe<bool>(false), ResourceUtils::parseBool("false"));
-  EXPECT_EQ(Maybe<bool>(false), ResourceUtils::parseBool("FALSE"));
-  EXPECT_EQ(Maybe<bool>(false), ResourceUtils::parseBool("False"));
+  EXPECT_EQ(Maybe<bool>(true), ResourceUtils::ParseBool("true"));
+  EXPECT_EQ(Maybe<bool>(true), ResourceUtils::ParseBool("TRUE"));
+  EXPECT_EQ(Maybe<bool>(true), ResourceUtils::ParseBool("True"));
+  EXPECT_EQ(Maybe<bool>(false), ResourceUtils::ParseBool("false"));
+  EXPECT_EQ(Maybe<bool>(false), ResourceUtils::ParseBool("FALSE"));
+  EXPECT_EQ(Maybe<bool>(false), ResourceUtils::ParseBool("False"));
 }
 
 TEST(ResourceUtilsTest, ParseResourceName) {
   ResourceNameRef actual;
-  bool actualPriv = false;
-  EXPECT_TRUE(ResourceUtils::parseResourceName("android:color/foo", &actual,
-                                               &actualPriv));
+  bool actual_priv = false;
+  EXPECT_TRUE(ResourceUtils::ParseResourceName("android:color/foo", &actual,
+                                               &actual_priv));
   EXPECT_EQ(ResourceNameRef("android", ResourceType::kColor, "foo"), actual);
-  EXPECT_FALSE(actualPriv);
+  EXPECT_FALSE(actual_priv);
 
   EXPECT_TRUE(
-      ResourceUtils::parseResourceName("color/foo", &actual, &actualPriv));
+      ResourceUtils::ParseResourceName("color/foo", &actual, &actual_priv));
   EXPECT_EQ(ResourceNameRef({}, ResourceType::kColor, "foo"), actual);
-  EXPECT_FALSE(actualPriv);
+  EXPECT_FALSE(actual_priv);
 
-  EXPECT_TRUE(ResourceUtils::parseResourceName("*android:color/foo", &actual,
-                                               &actualPriv));
+  EXPECT_TRUE(ResourceUtils::ParseResourceName("*android:color/foo", &actual,
+                                               &actual_priv));
   EXPECT_EQ(ResourceNameRef("android", ResourceType::kColor, "foo"), actual);
-  EXPECT_TRUE(actualPriv);
+  EXPECT_TRUE(actual_priv);
 
   EXPECT_FALSE(
-      ResourceUtils::parseResourceName(StringPiece(), &actual, &actualPriv));
+      ResourceUtils::ParseResourceName(StringPiece(), &actual, &actual_priv));
 }
 
 TEST(ResourceUtilsTest, ParseReferenceWithNoPackage) {
   ResourceNameRef expected({}, ResourceType::kColor, "foo");
   ResourceNameRef actual;
   bool create = false;
-  bool privateRef = false;
-  EXPECT_TRUE(ResourceUtils::parseReference("@color/foo", &actual, &create,
-                                            &privateRef));
+  bool private_ref = false;
+  EXPECT_TRUE(ResourceUtils::ParseReference("@color/foo", &actual, &create,
+                                            &private_ref));
   EXPECT_EQ(expected, actual);
   EXPECT_FALSE(create);
-  EXPECT_FALSE(privateRef);
+  EXPECT_FALSE(private_ref);
 }
 
 TEST(ResourceUtilsTest, ParseReferenceWithPackage) {
   ResourceNameRef expected("android", ResourceType::kColor, "foo");
   ResourceNameRef actual;
   bool create = false;
-  bool privateRef = false;
-  EXPECT_TRUE(ResourceUtils::parseReference("@android:color/foo", &actual,
-                                            &create, &privateRef));
+  bool private_ref = false;
+  EXPECT_TRUE(ResourceUtils::ParseReference("@android:color/foo", &actual,
+                                            &create, &private_ref));
   EXPECT_EQ(expected, actual);
   EXPECT_FALSE(create);
-  EXPECT_FALSE(privateRef);
+  EXPECT_FALSE(private_ref);
 }
 
 TEST(ResourceUtilsTest, ParseReferenceWithSurroundingWhitespace) {
   ResourceNameRef expected("android", ResourceType::kColor, "foo");
   ResourceNameRef actual;
   bool create = false;
-  bool privateRef = false;
-  EXPECT_TRUE(ResourceUtils::parseReference("\t @android:color/foo\n \n\t",
-                                            &actual, &create, &privateRef));
+  bool private_ref = false;
+  EXPECT_TRUE(ResourceUtils::ParseReference("\t @android:color/foo\n \n\t",
+                                            &actual, &create, &private_ref));
   EXPECT_EQ(expected, actual);
   EXPECT_FALSE(create);
-  EXPECT_FALSE(privateRef);
+  EXPECT_FALSE(private_ref);
 }
 
 TEST(ResourceUtilsTest, ParseAutoCreateIdReference) {
   ResourceNameRef expected("android", ResourceType::kId, "foo");
   ResourceNameRef actual;
   bool create = false;
-  bool privateRef = false;
-  EXPECT_TRUE(ResourceUtils::parseReference("@+android:id/foo", &actual,
-                                            &create, &privateRef));
+  bool private_ref = false;
+  EXPECT_TRUE(ResourceUtils::ParseReference("@+android:id/foo", &actual,
+                                            &create, &private_ref));
   EXPECT_EQ(expected, actual);
   EXPECT_TRUE(create);
-  EXPECT_FALSE(privateRef);
+  EXPECT_FALSE(private_ref);
 }
 
 TEST(ResourceUtilsTest, ParsePrivateReference) {
   ResourceNameRef expected("android", ResourceType::kId, "foo");
   ResourceNameRef actual;
   bool create = false;
-  bool privateRef = false;
-  EXPECT_TRUE(ResourceUtils::parseReference("@*android:id/foo", &actual,
-                                            &create, &privateRef));
+  bool private_ref = false;
+  EXPECT_TRUE(ResourceUtils::ParseReference("@*android:id/foo", &actual,
+                                            &create, &private_ref));
   EXPECT_EQ(expected, actual);
   EXPECT_FALSE(create);
-  EXPECT_TRUE(privateRef);
+  EXPECT_TRUE(private_ref);
 }
 
 TEST(ResourceUtilsTest, FailToParseAutoCreateNonIdReference) {
   bool create = false;
-  bool privateRef = false;
+  bool private_ref = false;
   ResourceNameRef actual;
-  EXPECT_FALSE(ResourceUtils::parseReference("@+android:color/foo", &actual,
-                                             &create, &privateRef));
+  EXPECT_FALSE(ResourceUtils::ParseReference("@+android:color/foo", &actual,
+                                             &create, &private_ref));
 }
 
 TEST(ResourceUtilsTest, ParseAttributeReferences) {
-  EXPECT_TRUE(ResourceUtils::isAttributeReference("?android"));
-  EXPECT_TRUE(ResourceUtils::isAttributeReference("?android:foo"));
-  EXPECT_TRUE(ResourceUtils::isAttributeReference("?attr/foo"));
-  EXPECT_TRUE(ResourceUtils::isAttributeReference("?android:attr/foo"));
+  EXPECT_TRUE(ResourceUtils::IsAttributeReference("?android"));
+  EXPECT_TRUE(ResourceUtils::IsAttributeReference("?android:foo"));
+  EXPECT_TRUE(ResourceUtils::IsAttributeReference("?attr/foo"));
+  EXPECT_TRUE(ResourceUtils::IsAttributeReference("?android:attr/foo"));
 }
 
 TEST(ResourceUtilsTest, FailParseIncompleteReference) {
-  EXPECT_FALSE(ResourceUtils::isAttributeReference("?style/foo"));
-  EXPECT_FALSE(ResourceUtils::isAttributeReference("?android:style/foo"));
-  EXPECT_FALSE(ResourceUtils::isAttributeReference("?android:"));
-  EXPECT_FALSE(ResourceUtils::isAttributeReference("?android:attr/"));
-  EXPECT_FALSE(ResourceUtils::isAttributeReference("?:attr/"));
-  EXPECT_FALSE(ResourceUtils::isAttributeReference("?:attr/foo"));
-  EXPECT_FALSE(ResourceUtils::isAttributeReference("?:/"));
-  EXPECT_FALSE(ResourceUtils::isAttributeReference("?:/foo"));
-  EXPECT_FALSE(ResourceUtils::isAttributeReference("?attr/"));
-  EXPECT_FALSE(ResourceUtils::isAttributeReference("?/foo"));
+  EXPECT_FALSE(ResourceUtils::IsAttributeReference("?style/foo"));
+  EXPECT_FALSE(ResourceUtils::IsAttributeReference("?android:style/foo"));
+  EXPECT_FALSE(ResourceUtils::IsAttributeReference("?android:"));
+  EXPECT_FALSE(ResourceUtils::IsAttributeReference("?android:attr/"));
+  EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:attr/"));
+  EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:attr/foo"));
+  EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:/"));
+  EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:/foo"));
+  EXPECT_FALSE(ResourceUtils::IsAttributeReference("?attr/"));
+  EXPECT_FALSE(ResourceUtils::IsAttributeReference("?/foo"));
 }
 
 TEST(ResourceUtilsTest, ParseStyleParentReference) {
@@ -144,56 +145,58 @@
                                           "foo");
   const ResourceName kStyleFooName({}, ResourceType::kStyle, "foo");
 
-  std::string errStr;
+  std::string err_str;
   Maybe<Reference> ref =
-      ResourceUtils::parseStyleParentReference("@android:style/foo", &errStr);
+      ResourceUtils::ParseStyleParentReference("@android:style/foo", &err_str);
   AAPT_ASSERT_TRUE(ref);
   EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName);
 
-  ref = ResourceUtils::parseStyleParentReference("@style/foo", &errStr);
+  ref = ResourceUtils::ParseStyleParentReference("@style/foo", &err_str);
   AAPT_ASSERT_TRUE(ref);
   EXPECT_EQ(ref.value().name.value(), kStyleFooName);
 
-  ref = ResourceUtils::parseStyleParentReference("?android:style/foo", &errStr);
+  ref =
+      ResourceUtils::ParseStyleParentReference("?android:style/foo", &err_str);
   AAPT_ASSERT_TRUE(ref);
   EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName);
 
-  ref = ResourceUtils::parseStyleParentReference("?style/foo", &errStr);
+  ref = ResourceUtils::ParseStyleParentReference("?style/foo", &err_str);
   AAPT_ASSERT_TRUE(ref);
   EXPECT_EQ(ref.value().name.value(), kStyleFooName);
 
-  ref = ResourceUtils::parseStyleParentReference("android:style/foo", &errStr);
+  ref = ResourceUtils::ParseStyleParentReference("android:style/foo", &err_str);
   AAPT_ASSERT_TRUE(ref);
   EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName);
 
-  ref = ResourceUtils::parseStyleParentReference("android:foo", &errStr);
+  ref = ResourceUtils::ParseStyleParentReference("android:foo", &err_str);
   AAPT_ASSERT_TRUE(ref);
   EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName);
 
-  ref = ResourceUtils::parseStyleParentReference("@android:foo", &errStr);
+  ref = ResourceUtils::ParseStyleParentReference("@android:foo", &err_str);
   AAPT_ASSERT_TRUE(ref);
   EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName);
 
-  ref = ResourceUtils::parseStyleParentReference("foo", &errStr);
+  ref = ResourceUtils::ParseStyleParentReference("foo", &err_str);
   AAPT_ASSERT_TRUE(ref);
   EXPECT_EQ(ref.value().name.value(), kStyleFooName);
 
-  ref = ResourceUtils::parseStyleParentReference("*android:style/foo", &errStr);
+  ref =
+      ResourceUtils::ParseStyleParentReference("*android:style/foo", &err_str);
   AAPT_ASSERT_TRUE(ref);
   EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName);
-  EXPECT_TRUE(ref.value().privateReference);
+  EXPECT_TRUE(ref.value().private_reference);
 }
 
 TEST(ResourceUtilsTest, ParseEmptyFlag) {
   std::unique_ptr<Attribute> attr =
       test::AttributeBuilder(false)
-          .setTypeMask(android::ResTable_map::TYPE_FLAGS)
-          .addItem("one", 0x01)
-          .addItem("two", 0x02)
-          .build();
+          .SetTypeMask(android::ResTable_map::TYPE_FLAGS)
+          .AddItem("one", 0x01)
+          .AddItem("two", 0x02)
+          .Build();
 
   std::unique_ptr<BinaryPrimitive> result =
-      ResourceUtils::tryParseFlagSymbol(attr.get(), "");
+      ResourceUtils::TryParseFlagSymbol(attr.get(), "");
   ASSERT_NE(nullptr, result);
   EXPECT_EQ(0u, result->value.data);
 }
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
index 60590b6..7956ad8 100644
--- a/tools/aapt2/ResourceValues.cpp
+++ b/tools/aapt2/ResourceValues.cpp
@@ -15,94 +15,95 @@
  */
 
 #include "ResourceValues.h"
+
+#include <algorithm>
+#include <limits>
+#include <set>
+
+#include "androidfw/ResourceTypes.h"
+
 #include "Resource.h"
 #include "ResourceUtils.h"
 #include "ValueVisitor.h"
 #include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
-#include <algorithm>
-#include <limits>
-#include <set>
-
 namespace aapt {
 
 template <typename Derived>
-void BaseValue<Derived>::accept(RawValueVisitor* visitor) {
-  visitor->visit(static_cast<Derived*>(this));
+void BaseValue<Derived>::Accept(RawValueVisitor* visitor) {
+  visitor->Visit(static_cast<Derived*>(this));
 }
 
 template <typename Derived>
-void BaseItem<Derived>::accept(RawValueVisitor* visitor) {
-  visitor->visit(static_cast<Derived*>(this));
+void BaseItem<Derived>::Accept(RawValueVisitor* visitor) {
+  visitor->Visit(static_cast<Derived*>(this));
 }
 
 RawString::RawString(const StringPool::Ref& ref) : value(ref) {}
 
-bool RawString::equals(const Value* value) const {
-  const RawString* other = valueCast<RawString>(value);
+bool RawString::Equals(const Value* value) const {
+  const RawString* other = ValueCast<RawString>(value);
   if (!other) {
     return false;
   }
   return *this->value == *other->value;
 }
 
-RawString* RawString::clone(StringPool* newPool) const {
-  RawString* rs = new RawString(newPool->makeRef(*value));
-  rs->mComment = mComment;
-  rs->mSource = mSource;
+RawString* RawString::Clone(StringPool* new_pool) const {
+  RawString* rs = new RawString(new_pool->MakeRef(*value));
+  rs->comment_ = comment_;
+  rs->source_ = source_;
   return rs;
 }
 
-bool RawString::flatten(android::Res_value* outValue) const {
-  outValue->dataType = android::Res_value::TYPE_STRING;
-  outValue->data =
-      util::hostToDevice32(static_cast<uint32_t>(value.getIndex()));
+bool RawString::Flatten(android::Res_value* out_value) const {
+  out_value->dataType = android::Res_value::TYPE_STRING;
+  out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
   return true;
 }
 
-void RawString::print(std::ostream* out) const {
+void RawString::Print(std::ostream* out) const {
   *out << "(raw string) " << *value;
 }
 
-Reference::Reference() : referenceType(Type::kResource) {}
+Reference::Reference() : reference_type(Type::kResource) {}
 
 Reference::Reference(const ResourceNameRef& n, Type t)
-    : name(n.toResourceName()), referenceType(t) {}
+    : name(n.ToResourceName()), reference_type(t) {}
 
 Reference::Reference(const ResourceId& i, Type type)
-    : id(i), referenceType(type) {}
+    : id(i), reference_type(type) {}
 
 Reference::Reference(const ResourceNameRef& n, const ResourceId& i)
-    : name(n.toResourceName()), id(i), referenceType(Type::kResource) {}
+    : name(n.ToResourceName()), id(i), reference_type(Type::kResource) {}
 
-bool Reference::equals(const Value* value) const {
-  const Reference* other = valueCast<Reference>(value);
+bool Reference::Equals(const Value* value) const {
+  const Reference* other = ValueCast<Reference>(value);
   if (!other) {
     return false;
   }
-  return referenceType == other->referenceType &&
-         privateReference == other->privateReference && id == other->id &&
+  return reference_type == other->reference_type &&
+         private_reference == other->private_reference && id == other->id &&
          name == other->name;
 }
 
-bool Reference::flatten(android::Res_value* outValue) const {
-  outValue->dataType = (referenceType == Reference::Type::kResource)
-                           ? android::Res_value::TYPE_REFERENCE
-                           : android::Res_value::TYPE_ATTRIBUTE;
-  outValue->data = util::hostToDevice32(id ? id.value().id : 0);
+bool Reference::Flatten(android::Res_value* out_value) const {
+  out_value->dataType = (reference_type == Reference::Type::kResource)
+                            ? android::Res_value::TYPE_REFERENCE
+                            : android::Res_value::TYPE_ATTRIBUTE;
+  out_value->data = util::HostToDevice32(id ? id.value().id : 0);
   return true;
 }
 
-Reference* Reference::clone(StringPool* /*newPool*/) const {
+Reference* Reference::Clone(StringPool* /*new_pool*/) const {
   return new Reference(*this);
 }
 
-void Reference::print(std::ostream* out) const {
+void Reference::Print(std::ostream* out) const {
   *out << "(reference) ";
-  if (referenceType == Reference::Type::kResource) {
+  if (reference_type == Reference::Type::kResource) {
     *out << "@";
-    if (privateReference) {
+    if (private_reference) {
       *out << "*";
     }
   } else {
@@ -118,128 +119,127 @@
   }
 }
 
-bool Id::equals(const Value* value) const {
-  return valueCast<Id>(value) != nullptr;
+bool Id::Equals(const Value* value) const {
+  return ValueCast<Id>(value) != nullptr;
 }
 
-bool Id::flatten(android::Res_value* out) const {
+bool Id::Flatten(android::Res_value* out) const {
   out->dataType = android::Res_value::TYPE_INT_BOOLEAN;
-  out->data = util::hostToDevice32(0);
+  out->data = util::HostToDevice32(0);
   return true;
 }
 
-Id* Id::clone(StringPool* /*newPool*/) const { return new Id(*this); }
+Id* Id::Clone(StringPool* /*new_pool*/) const { return new Id(*this); }
 
-void Id::print(std::ostream* out) const { *out << "(id)"; }
+void Id::Print(std::ostream* out) const { *out << "(id)"; }
 
 String::String(const StringPool::Ref& ref) : value(ref) {}
 
-bool String::equals(const Value* value) const {
-  const String* other = valueCast<String>(value);
+bool String::Equals(const Value* value) const {
+  const String* other = ValueCast<String>(value);
   if (!other) {
     return false;
   }
   return *this->value == *other->value;
 }
 
-bool String::flatten(android::Res_value* outValue) const {
+bool String::Flatten(android::Res_value* out_value) const {
   // Verify that our StringPool index is within encode-able limits.
-  if (value.getIndex() > std::numeric_limits<uint32_t>::max()) {
+  if (value.index() > std::numeric_limits<uint32_t>::max()) {
     return false;
   }
 
-  outValue->dataType = android::Res_value::TYPE_STRING;
-  outValue->data =
-      util::hostToDevice32(static_cast<uint32_t>(value.getIndex()));
+  out_value->dataType = android::Res_value::TYPE_STRING;
+  out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
   return true;
 }
 
-String* String::clone(StringPool* newPool) const {
-  String* str = new String(newPool->makeRef(*value));
-  str->mComment = mComment;
-  str->mSource = mSource;
+String* String::Clone(StringPool* new_pool) const {
+  String* str = new String(new_pool->MakeRef(*value));
+  str->comment_ = comment_;
+  str->source_ = source_;
   return str;
 }
 
-void String::print(std::ostream* out) const {
+void String::Print(std::ostream* out) const {
   *out << "(string) \"" << *value << "\"";
 }
 
 StyledString::StyledString(const StringPool::StyleRef& ref) : value(ref) {}
 
-bool StyledString::equals(const Value* value) const {
-  const StyledString* other = valueCast<StyledString>(value);
+bool StyledString::Equals(const Value* value) const {
+  const StyledString* other = ValueCast<StyledString>(value);
   if (!other) {
     return false;
   }
 
   if (*this->value->str == *other->value->str) {
-    const std::vector<StringPool::Span>& spansA = this->value->spans;
-    const std::vector<StringPool::Span>& spansB = other->value->spans;
+    const std::vector<StringPool::Span>& spans_a = this->value->spans;
+    const std::vector<StringPool::Span>& spans_b = other->value->spans;
     return std::equal(
-        spansA.begin(), spansA.end(), spansB.begin(),
+        spans_a.begin(), spans_a.end(), spans_b.begin(),
         [](const StringPool::Span& a, const StringPool::Span& b) -> bool {
-          return *a.name == *b.name && a.firstChar == b.firstChar &&
-                 a.lastChar == b.lastChar;
+          return *a.name == *b.name && a.first_char == b.first_char &&
+                 a.last_char == b.last_char;
         });
   }
   return false;
 }
 
-bool StyledString::flatten(android::Res_value* outValue) const {
-  if (value.getIndex() > std::numeric_limits<uint32_t>::max()) {
+bool StyledString::Flatten(android::Res_value* out_value) const {
+  if (value.index() > std::numeric_limits<uint32_t>::max()) {
     return false;
   }
 
-  outValue->dataType = android::Res_value::TYPE_STRING;
-  outValue->data =
-      util::hostToDevice32(static_cast<uint32_t>(value.getIndex()));
+  out_value->dataType = android::Res_value::TYPE_STRING;
+  out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
   return true;
 }
 
-StyledString* StyledString::clone(StringPool* newPool) const {
-  StyledString* str = new StyledString(newPool->makeRef(value));
-  str->mComment = mComment;
-  str->mSource = mSource;
+StyledString* StyledString::Clone(StringPool* new_pool) const {
+  StyledString* str = new StyledString(new_pool->MakeRef(value));
+  str->comment_ = comment_;
+  str->source_ = source_;
   return str;
 }
 
-void StyledString::print(std::ostream* out) const {
+void StyledString::Print(std::ostream* out) const {
   *out << "(styled string) \"" << *value->str << "\"";
   for (const StringPool::Span& span : value->spans) {
-    *out << " " << *span.name << ":" << span.firstChar << "," << span.lastChar;
+    *out << " " << *span.name << ":" << span.first_char << ","
+         << span.last_char;
   }
 }
 
 FileReference::FileReference(const StringPool::Ref& _path) : path(_path) {}
 
-bool FileReference::equals(const Value* value) const {
-  const FileReference* other = valueCast<FileReference>(value);
+bool FileReference::Equals(const Value* value) const {
+  const FileReference* other = ValueCast<FileReference>(value);
   if (!other) {
     return false;
   }
   return *path == *other->path;
 }
 
-bool FileReference::flatten(android::Res_value* outValue) const {
-  if (path.getIndex() > std::numeric_limits<uint32_t>::max()) {
+bool FileReference::Flatten(android::Res_value* out_value) const {
+  if (path.index() > std::numeric_limits<uint32_t>::max()) {
     return false;
   }
 
-  outValue->dataType = android::Res_value::TYPE_STRING;
-  outValue->data = util::hostToDevice32(static_cast<uint32_t>(path.getIndex()));
+  out_value->dataType = android::Res_value::TYPE_STRING;
+  out_value->data = util::HostToDevice32(static_cast<uint32_t>(path.index()));
   return true;
 }
 
-FileReference* FileReference::clone(StringPool* newPool) const {
-  FileReference* fr = new FileReference(newPool->makeRef(*path));
+FileReference* FileReference::Clone(StringPool* new_pool) const {
+  FileReference* fr = new FileReference(new_pool->MakeRef(*path));
   fr->file = file;
-  fr->mComment = mComment;
-  fr->mSource = mSource;
+  fr->comment_ = comment_;
+  fr->source_ = source_;
   return fr;
 }
 
-void FileReference::print(std::ostream* out) const {
+void FileReference::Print(std::ostream* out) const {
   *out << "(file) " << *path;
 }
 
@@ -250,8 +250,8 @@
   value.data = data;
 }
 
-bool BinaryPrimitive::equals(const Value* value) const {
-  const BinaryPrimitive* other = valueCast<BinaryPrimitive>(value);
+bool BinaryPrimitive::Equals(const Value* value) const {
+  const BinaryPrimitive* other = ValueCast<BinaryPrimitive>(value);
   if (!other) {
     return false;
   }
@@ -259,17 +259,17 @@
          this->value.data == other->value.data;
 }
 
-bool BinaryPrimitive::flatten(android::Res_value* outValue) const {
-  outValue->dataType = value.dataType;
-  outValue->data = util::hostToDevice32(value.data);
+bool BinaryPrimitive::Flatten(android::Res_value* out_value) const {
+  out_value->dataType = value.dataType;
+  out_value->data = util::HostToDevice32(value.data);
   return true;
 }
 
-BinaryPrimitive* BinaryPrimitive::clone(StringPool* /*newPool*/) const {
+BinaryPrimitive* BinaryPrimitive::Clone(StringPool* /*new_pool*/) const {
   return new BinaryPrimitive(*this);
 }
 
-void BinaryPrimitive::print(std::ostream* out) const {
+void BinaryPrimitive::Print(std::ostream* out) const {
   switch (value.dataType) {
     case android::Res_value::TYPE_NULL:
       *out << "(null)";
@@ -297,10 +297,10 @@
 }
 
 Attribute::Attribute(bool w, uint32_t t)
-    : typeMask(t),
-      minInt(std::numeric_limits<int32_t>::min()),
-      maxInt(std::numeric_limits<int32_t>::max()) {
-  mWeak = w;
+    : type_mask(t),
+      min_int(std::numeric_limits<int32_t>::min()),
+      max_int(std::numeric_limits<int32_t>::max()) {
+  weak_ = w;
 }
 
 template <typename T>
@@ -308,8 +308,8 @@
   return &val;
 }
 
-bool Attribute::equals(const Value* value) const {
-  const Attribute* other = valueCast<Attribute>(value);
+bool Attribute::Equals(const Value* value) const {
+  const Attribute* other = ValueCast<Attribute>(value);
   if (!other) {
     return false;
   }
@@ -318,46 +318,46 @@
     return false;
   }
 
-  if (typeMask != other->typeMask || minInt != other->minInt ||
-      maxInt != other->maxInt) {
+  if (type_mask != other->type_mask || min_int != other->min_int ||
+      max_int != other->max_int) {
     return false;
   }
 
-  std::vector<const Symbol*> sortedA;
-  std::transform(symbols.begin(), symbols.end(), std::back_inserter(sortedA),
+  std::vector<const Symbol*> sorted_a;
+  std::transform(symbols.begin(), symbols.end(), std::back_inserter(sorted_a),
                  addPointer<const Symbol>);
-  std::sort(sortedA.begin(), sortedA.end(),
+  std::sort(sorted_a.begin(), sorted_a.end(),
             [](const Symbol* a, const Symbol* b) -> bool {
               return a->symbol.name < b->symbol.name;
             });
 
-  std::vector<const Symbol*> sortedB;
+  std::vector<const Symbol*> sorted_b;
   std::transform(other->symbols.begin(), other->symbols.end(),
-                 std::back_inserter(sortedB), addPointer<const Symbol>);
-  std::sort(sortedB.begin(), sortedB.end(),
+                 std::back_inserter(sorted_b), addPointer<const Symbol>);
+  std::sort(sorted_b.begin(), sorted_b.end(),
             [](const Symbol* a, const Symbol* b) -> bool {
               return a->symbol.name < b->symbol.name;
             });
 
-  return std::equal(sortedA.begin(), sortedA.end(), sortedB.begin(),
+  return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
                     [](const Symbol* a, const Symbol* b) -> bool {
-                      return a->symbol.equals(&b->symbol) &&
+                      return a->symbol.Equals(&b->symbol) &&
                              a->value == b->value;
                     });
 }
 
-Attribute* Attribute::clone(StringPool* /*newPool*/) const {
+Attribute* Attribute::Clone(StringPool* /*new_pool*/) const {
   return new Attribute(*this);
 }
 
-void Attribute::printMask(std::ostream* out) const {
-  if (typeMask == android::ResTable_map::TYPE_ANY) {
+void Attribute::PrintMask(std::ostream* out) const {
+  if (type_mask == android::ResTable_map::TYPE_ANY) {
     *out << "any";
     return;
   }
 
   bool set = false;
-  if ((typeMask & android::ResTable_map::TYPE_REFERENCE) != 0) {
+  if ((type_mask & android::ResTable_map::TYPE_REFERENCE) != 0) {
     if (!set) {
       set = true;
     } else {
@@ -366,7 +366,7 @@
     *out << "reference";
   }
 
-  if ((typeMask & android::ResTable_map::TYPE_STRING) != 0) {
+  if ((type_mask & android::ResTable_map::TYPE_STRING) != 0) {
     if (!set) {
       set = true;
     } else {
@@ -375,7 +375,7 @@
     *out << "string";
   }
 
-  if ((typeMask & android::ResTable_map::TYPE_INTEGER) != 0) {
+  if ((type_mask & android::ResTable_map::TYPE_INTEGER) != 0) {
     if (!set) {
       set = true;
     } else {
@@ -384,7 +384,7 @@
     *out << "integer";
   }
 
-  if ((typeMask & android::ResTable_map::TYPE_BOOLEAN) != 0) {
+  if ((type_mask & android::ResTable_map::TYPE_BOOLEAN) != 0) {
     if (!set) {
       set = true;
     } else {
@@ -393,7 +393,7 @@
     *out << "boolean";
   }
 
-  if ((typeMask & android::ResTable_map::TYPE_COLOR) != 0) {
+  if ((type_mask & android::ResTable_map::TYPE_COLOR) != 0) {
     if (!set) {
       set = true;
     } else {
@@ -402,7 +402,7 @@
     *out << "color";
   }
 
-  if ((typeMask & android::ResTable_map::TYPE_FLOAT) != 0) {
+  if ((type_mask & android::ResTable_map::TYPE_FLOAT) != 0) {
     if (!set) {
       set = true;
     } else {
@@ -411,7 +411,7 @@
     *out << "float";
   }
 
-  if ((typeMask & android::ResTable_map::TYPE_DIMENSION) != 0) {
+  if ((type_mask & android::ResTable_map::TYPE_DIMENSION) != 0) {
     if (!set) {
       set = true;
     } else {
@@ -420,7 +420,7 @@
     *out << "dimension";
   }
 
-  if ((typeMask & android::ResTable_map::TYPE_FRACTION) != 0) {
+  if ((type_mask & android::ResTable_map::TYPE_FRACTION) != 0) {
     if (!set) {
       set = true;
     } else {
@@ -429,7 +429,7 @@
     *out << "fraction";
   }
 
-  if ((typeMask & android::ResTable_map::TYPE_ENUM) != 0) {
+  if ((type_mask & android::ResTable_map::TYPE_ENUM) != 0) {
     if (!set) {
       set = true;
     } else {
@@ -438,7 +438,7 @@
     *out << "enum";
   }
 
-  if ((typeMask & android::ResTable_map::TYPE_FLAGS) != 0) {
+  if ((type_mask & android::ResTable_map::TYPE_FLAGS) != 0) {
     if (!set) {
       set = true;
     } else {
@@ -448,96 +448,96 @@
   }
 }
 
-void Attribute::print(std::ostream* out) const {
+void Attribute::Print(std::ostream* out) const {
   *out << "(attr) ";
-  printMask(out);
+  PrintMask(out);
 
   if (!symbols.empty()) {
-    *out << " [" << util::joiner(symbols, ", ") << "]";
+    *out << " [" << util::Joiner(symbols, ", ") << "]";
   }
 
-  if (minInt != std::numeric_limits<int32_t>::min()) {
-    *out << " min=" << minInt;
+  if (min_int != std::numeric_limits<int32_t>::min()) {
+    *out << " min=" << min_int;
   }
 
-  if (maxInt != std::numeric_limits<int32_t>::max()) {
-    *out << " max=" << maxInt;
+  if (max_int != std::numeric_limits<int32_t>::max()) {
+    *out << " max=" << max_int;
   }
 
-  if (isWeak()) {
+  if (IsWeak()) {
     *out << " [weak]";
   }
 }
 
-static void buildAttributeMismatchMessage(DiagMessage* msg,
+static void BuildAttributeMismatchMessage(DiagMessage* msg,
                                           const Attribute* attr,
                                           const Item* value) {
   *msg << "expected";
-  if (attr->typeMask & android::ResTable_map::TYPE_BOOLEAN) {
+  if (attr->type_mask & android::ResTable_map::TYPE_BOOLEAN) {
     *msg << " boolean";
   }
 
-  if (attr->typeMask & android::ResTable_map::TYPE_COLOR) {
+  if (attr->type_mask & android::ResTable_map::TYPE_COLOR) {
     *msg << " color";
   }
 
-  if (attr->typeMask & android::ResTable_map::TYPE_DIMENSION) {
+  if (attr->type_mask & android::ResTable_map::TYPE_DIMENSION) {
     *msg << " dimension";
   }
 
-  if (attr->typeMask & android::ResTable_map::TYPE_ENUM) {
+  if (attr->type_mask & android::ResTable_map::TYPE_ENUM) {
     *msg << " enum";
   }
 
-  if (attr->typeMask & android::ResTable_map::TYPE_FLAGS) {
+  if (attr->type_mask & android::ResTable_map::TYPE_FLAGS) {
     *msg << " flags";
   }
 
-  if (attr->typeMask & android::ResTable_map::TYPE_FLOAT) {
+  if (attr->type_mask & android::ResTable_map::TYPE_FLOAT) {
     *msg << " float";
   }
 
-  if (attr->typeMask & android::ResTable_map::TYPE_FRACTION) {
+  if (attr->type_mask & android::ResTable_map::TYPE_FRACTION) {
     *msg << " fraction";
   }
 
-  if (attr->typeMask & android::ResTable_map::TYPE_INTEGER) {
+  if (attr->type_mask & android::ResTable_map::TYPE_INTEGER) {
     *msg << " integer";
   }
 
-  if (attr->typeMask & android::ResTable_map::TYPE_REFERENCE) {
+  if (attr->type_mask & android::ResTable_map::TYPE_REFERENCE) {
     *msg << " reference";
   }
 
-  if (attr->typeMask & android::ResTable_map::TYPE_STRING) {
+  if (attr->type_mask & android::ResTable_map::TYPE_STRING) {
     *msg << " string";
   }
 
   *msg << " but got " << *value;
 }
 
-bool Attribute::matches(const Item* item, DiagMessage* outMsg) const {
+bool Attribute::Matches(const Item* item, DiagMessage* out_msg) const {
   android::Res_value val = {};
-  item->flatten(&val);
+  item->Flatten(&val);
 
   // Always allow references.
-  const uint32_t mask = typeMask | android::ResTable_map::TYPE_REFERENCE;
-  if (!(mask & ResourceUtils::androidTypeToAttributeTypeMask(val.dataType))) {
-    if (outMsg) {
-      buildAttributeMismatchMessage(outMsg, this, item);
+  const uint32_t mask = type_mask | android::ResTable_map::TYPE_REFERENCE;
+  if (!(mask & ResourceUtils::AndroidTypeToAttributeTypeMask(val.dataType))) {
+    if (out_msg) {
+      BuildAttributeMismatchMessage(out_msg, this, item);
     }
     return false;
 
-  } else if (ResourceUtils::androidTypeToAttributeTypeMask(val.dataType) &
+  } else if (ResourceUtils::AndroidTypeToAttributeTypeMask(val.dataType) &
              android::ResTable_map::TYPE_INTEGER) {
-    if (static_cast<int32_t>(util::deviceToHost32(val.data)) < minInt) {
-      if (outMsg) {
-        *outMsg << *item << " is less than minimum integer " << minInt;
+    if (static_cast<int32_t>(util::DeviceToHost32(val.data)) < min_int) {
+      if (out_msg) {
+        *out_msg << *item << " is less than minimum integer " << min_int;
       }
       return false;
-    } else if (static_cast<int32_t>(util::deviceToHost32(val.data)) > maxInt) {
-      if (outMsg) {
-        *outMsg << *item << " is greater than maximum integer " << maxInt;
+    } else if (static_cast<int32_t>(util::DeviceToHost32(val.data)) > max_int) {
+      if (out_msg) {
+        *out_msg << *item << " is greater than maximum integer " << max_int;
       }
       return false;
     }
@@ -545,14 +545,14 @@
   return true;
 }
 
-bool Style::equals(const Value* value) const {
-  const Style* other = valueCast<Style>(value);
+bool Style::Equals(const Value* value) const {
+  const Style* other = ValueCast<Style>(value);
   if (!other) {
     return false;
   }
   if (bool(parent) != bool(other->parent) ||
       (parent && other->parent &&
-       !parent.value().equals(&other->parent.value()))) {
+       !parent.value().Equals(&other->parent.value()))) {
     return false;
   }
 
@@ -560,51 +560,51 @@
     return false;
   }
 
-  std::vector<const Entry*> sortedA;
-  std::transform(entries.begin(), entries.end(), std::back_inserter(sortedA),
+  std::vector<const Entry*> sorted_a;
+  std::transform(entries.begin(), entries.end(), std::back_inserter(sorted_a),
                  addPointer<const Entry>);
-  std::sort(sortedA.begin(), sortedA.end(),
+  std::sort(sorted_a.begin(), sorted_a.end(),
             [](const Entry* a, const Entry* b) -> bool {
               return a->key.name < b->key.name;
             });
 
-  std::vector<const Entry*> sortedB;
+  std::vector<const Entry*> sorted_b;
   std::transform(other->entries.begin(), other->entries.end(),
-                 std::back_inserter(sortedB), addPointer<const Entry>);
-  std::sort(sortedB.begin(), sortedB.end(),
+                 std::back_inserter(sorted_b), addPointer<const Entry>);
+  std::sort(sorted_b.begin(), sorted_b.end(),
             [](const Entry* a, const Entry* b) -> bool {
               return a->key.name < b->key.name;
             });
 
-  return std::equal(sortedA.begin(), sortedA.end(), sortedB.begin(),
+  return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
                     [](const Entry* a, const Entry* b) -> bool {
-                      return a->key.equals(&b->key) &&
-                             a->value->equals(b->value.get());
+                      return a->key.Equals(&b->key) &&
+                             a->value->Equals(b->value.get());
                     });
 }
 
-Style* Style::clone(StringPool* newPool) const {
+Style* Style::Clone(StringPool* new_pool) const {
   Style* style = new Style();
   style->parent = parent;
-  style->parentInferred = parentInferred;
-  style->mComment = mComment;
-  style->mSource = mSource;
+  style->parent_inferred = parent_inferred;
+  style->comment_ = comment_;
+  style->source_ = source_;
   for (auto& entry : entries) {
     style->entries.push_back(
-        Entry{entry.key, std::unique_ptr<Item>(entry.value->clone(newPool))});
+        Entry{entry.key, std::unique_ptr<Item>(entry.value->Clone(new_pool))});
   }
   return style;
 }
 
-void Style::print(std::ostream* out) const {
+void Style::Print(std::ostream* out) const {
   *out << "(style) ";
   if (parent && parent.value().name) {
-    if (parent.value().privateReference) {
+    if (parent.value().private_reference) {
       *out << "*";
     }
     *out << parent.value().name.value();
   }
-  *out << " [" << util::joiner(entries, ", ") << "]";
+  *out << " [" << util::Joiner(entries, ", ") << "]";
 }
 
 static ::std::ostream& operator<<(::std::ostream& out,
@@ -617,12 +617,12 @@
     out << "???";
   }
   out << " = ";
-  value.value->print(&out);
+  value.value->Print(&out);
   return out;
 }
 
-bool Array::equals(const Value* value) const {
-  const Array* other = valueCast<Array>(value);
+bool Array::Equals(const Value* value) const {
+  const Array* other = ValueCast<Array>(value);
   if (!other) {
     return false;
   }
@@ -634,26 +634,26 @@
   return std::equal(items.begin(), items.end(), other->items.begin(),
                     [](const std::unique_ptr<Item>& a,
                        const std::unique_ptr<Item>& b) -> bool {
-                      return a->equals(b.get());
+                      return a->Equals(b.get());
                     });
 }
 
-Array* Array::clone(StringPool* newPool) const {
+Array* Array::Clone(StringPool* new_pool) const {
   Array* array = new Array();
-  array->mComment = mComment;
-  array->mSource = mSource;
+  array->comment_ = comment_;
+  array->source_ = source_;
   for (auto& item : items) {
-    array->items.emplace_back(std::unique_ptr<Item>(item->clone(newPool)));
+    array->items.emplace_back(std::unique_ptr<Item>(item->Clone(new_pool)));
   }
   return array;
 }
 
-void Array::print(std::ostream* out) const {
-  *out << "(array) [" << util::joiner(items, ", ") << "]";
+void Array::Print(std::ostream* out) const {
+  *out << "(array) [" << util::Joiner(items, ", ") << "]";
 }
 
-bool Plural::equals(const Value* value) const {
-  const Plural* other = valueCast<Plural>(value);
+bool Plural::Equals(const Value* value) const {
+  const Plural* other = ValueCast<Plural>(value);
   if (!other) {
     return false;
   }
@@ -668,24 +668,24 @@
                       if (bool(a) != bool(b)) {
                         return false;
                       }
-                      return bool(a) == bool(b) || a->equals(b.get());
+                      return bool(a) == bool(b) || a->Equals(b.get());
                     });
 }
 
-Plural* Plural::clone(StringPool* newPool) const {
+Plural* Plural::Clone(StringPool* new_pool) const {
   Plural* p = new Plural();
-  p->mComment = mComment;
-  p->mSource = mSource;
+  p->comment_ = comment_;
+  p->source_ = source_;
   const size_t count = values.size();
   for (size_t i = 0; i < count; i++) {
     if (values[i]) {
-      p->values[i] = std::unique_ptr<Item>(values[i]->clone(newPool));
+      p->values[i] = std::unique_ptr<Item>(values[i]->Clone(new_pool));
     }
   }
   return p;
 }
 
-void Plural::print(std::ostream* out) const {
+void Plural::Print(std::ostream* out) const {
   *out << "(plural)";
   if (values[Zero]) {
     *out << " zero=" << *values[Zero];
@@ -713,8 +713,8 @@
   return out << *item;
 }
 
-bool Styleable::equals(const Value* value) const {
-  const Styleable* other = valueCast<Styleable>(value);
+bool Styleable::Equals(const Value* value) const {
+  const Styleable* other = ValueCast<Styleable>(value);
   if (!other) {
     return false;
   }
@@ -725,21 +725,21 @@
 
   return std::equal(entries.begin(), entries.end(), other->entries.begin(),
                     [](const Reference& a, const Reference& b) -> bool {
-                      return a.equals(&b);
+                      return a.Equals(&b);
                     });
 }
 
-Styleable* Styleable::clone(StringPool* /*newPool*/) const {
+Styleable* Styleable::Clone(StringPool* /*new_pool*/) const {
   return new Styleable(*this);
 }
 
-void Styleable::print(std::ostream* out) const {
+void Styleable::Print(std::ostream* out) const {
   *out << "(styleable) "
-       << " [" << util::joiner(entries, ", ") << "]";
+       << " [" << util::Joiner(entries, ", ") << "]";
 }
 
 bool operator<(const Reference& a, const Reference& b) {
-  int cmp = a.name.valueOrDefault({}).compare(b.name.valueOrDefault({}));
+  int cmp = a.name.value_or_default({}).compare(b.name.value_or_default({}));
   if (cmp != 0) return cmp < 0;
   return a.id < b.id;
 }
@@ -758,7 +758,7 @@
   }
 };
 
-void Styleable::mergeWith(Styleable* other) {
+void Styleable::MergeWith(Styleable* other) {
   // Compare only names, because some References may already have their IDs
   // assigned
   // (framework IDs that don't change).
diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h
index a28ffe5..ea73615 100644
--- a/tools/aapt2/ResourceValues.h
+++ b/tools/aapt2/ResourceValues.h
@@ -17,17 +17,18 @@
 #ifndef AAPT_RESOURCE_VALUES_H
 #define AAPT_RESOURCE_VALUES_H
 
+#include <array>
+#include <ostream>
+#include <vector>
+
+#include "androidfw/ResourceTypes.h"
+
 #include "Diagnostics.h"
 #include "Resource.h"
 #include "StringPool.h"
 #include "io/File.h"
 #include "util/Maybe.h"
 
-#include <androidfw/ResourceTypes.h>
-#include <array>
-#include <ostream>
-#include <vector>
-
 namespace aapt {
 
 struct RawValueVisitor;
@@ -46,58 +47,59 @@
    * Whether this value is weak and can be overridden without
    * warning or error. Default is false.
    */
-  bool isWeak() const { return mWeak; }
+  bool IsWeak() const { return weak_; }
 
-  void setWeak(bool val) { mWeak = val; }
+  void SetWeak(bool val) { weak_ = val; }
 
   // Whether the value is marked as translateable.
   // This does not persist when flattened.
   // It is only used during compilation phase.
-  void setTranslateable(bool val) { mTranslateable = val; }
+  void SetTranslateable(bool val) { translateable_ = val; }
 
   // Default true.
-  bool isTranslateable() const { return mTranslateable; }
+  bool IsTranslateable() const { return translateable_; }
 
   /**
    * Returns the source where this value was defined.
    */
-  const Source& getSource() const { return mSource; }
+  const Source& GetSource() const { return source_; }
 
-  void setSource(const Source& source) { mSource = source; }
+  void SetSource(const Source& source) { source_ = source; }
 
-  void setSource(Source&& source) { mSource = std::move(source); }
+  void SetSource(Source&& source) { source_ = std::move(source); }
 
   /**
    * Returns the comment that was associated with this resource.
    */
-  const std::string& getComment() const { return mComment; }
+  const std::string& GetComment() const { return comment_; }
 
-  void setComment(const StringPiece& str) { mComment = str.toString(); }
+  void SetComment(const StringPiece& str) { comment_ = str.ToString(); }
 
-  void setComment(std::string&& str) { mComment = std::move(str); }
+  void SetComment(std::string&& str) { comment_ = std::move(str); }
 
-  virtual bool equals(const Value* value) const = 0;
+  virtual bool Equals(const Value* value) const = 0;
 
   /**
    * Calls the appropriate overload of ValueVisitor.
    */
-  virtual void accept(RawValueVisitor* visitor) = 0;
+  virtual void Accept(RawValueVisitor* visitor) = 0;
 
   /**
-   * Clone the value.
+   * Clone the value. new_pool is the new StringPool that
+   * any resources with strings should use when copying their string.
    */
-  virtual Value* clone(StringPool* newPool) const = 0;
+  virtual Value* Clone(StringPool* new_pool) const = 0;
 
   /**
    * Human readable printout of this value.
    */
-  virtual void print(std::ostream* out) const = 0;
+  virtual void Print(std::ostream* out) const = 0;
 
  protected:
-  Source mSource;
-  std::string mComment;
-  bool mWeak = false;
-  bool mTranslateable = true;
+  Source source_;
+  std::string comment_;
+  bool weak_ = false;
+  bool translateable_ = true;
 };
 
 /**
@@ -105,7 +107,7 @@
  */
 template <typename Derived>
 struct BaseValue : public Value {
-  void accept(RawValueVisitor* visitor) override;
+  void Accept(RawValueVisitor* visitor) override;
 };
 
 /**
@@ -115,14 +117,14 @@
   /**
    * Clone the Item.
    */
-  virtual Item* clone(StringPool* newPool) const override = 0;
+  virtual Item* Clone(StringPool* new_pool) const override = 0;
 
   /**
    * Fills in an android::Res_value structure with this Item's binary
    * representation.
    * Returns false if an error occurred.
    */
-  virtual bool flatten(android::Res_value* outValue) const = 0;
+  virtual bool Flatten(android::Res_value* out_value) const = 0;
 };
 
 /**
@@ -130,7 +132,7 @@
  */
 template <typename Derived>
 struct BaseItem : public Item {
-  void accept(RawValueVisitor* visitor) override;
+  void Accept(RawValueVisitor* visitor) override;
 };
 
 /**
@@ -149,18 +151,18 @@
 
   Maybe<ResourceName> name;
   Maybe<ResourceId> id;
-  Reference::Type referenceType;
-  bool privateReference = false;
+  Reference::Type reference_type;
+  bool private_reference = false;
 
   Reference();
   explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
   explicit Reference(const ResourceId& i, Type type = Type::kResource);
-  explicit Reference(const ResourceNameRef& n, const ResourceId& i);
+  Reference(const ResourceNameRef& n, const ResourceId& i);
 
-  bool equals(const Value* value) const override;
-  bool flatten(android::Res_value* outValue) const override;
-  Reference* clone(StringPool* newPool) const override;
-  void print(std::ostream* out) const override;
+  bool Equals(const Value* value) const override;
+  bool Flatten(android::Res_value* out_value) const override;
+  Reference* Clone(StringPool* new_pool) const override;
+  void Print(std::ostream* out) const override;
 };
 
 bool operator<(const Reference&, const Reference&);
@@ -170,11 +172,11 @@
  * An ID resource. Has no real value, just a place holder.
  */
 struct Id : public BaseItem<Id> {
-  Id() { mWeak = true; }
-  bool equals(const Value* value) const override;
-  bool flatten(android::Res_value* out) const override;
-  Id* clone(StringPool* newPool) const override;
-  void print(std::ostream* out) const override;
+  Id() { weak_ = true; }
+  bool Equals(const Value* value) const override;
+  bool Flatten(android::Res_value* out) const override;
+  Id* Clone(StringPool* new_pool) const override;
+  void Print(std::ostream* out) const override;
 };
 
 /**
@@ -187,10 +189,10 @@
 
   explicit RawString(const StringPool::Ref& ref);
 
-  bool equals(const Value* value) const override;
-  bool flatten(android::Res_value* outValue) const override;
-  RawString* clone(StringPool* newPool) const override;
-  void print(std::ostream* out) const override;
+  bool Equals(const Value* value) const override;
+  bool Flatten(android::Res_value* out_value) const override;
+  RawString* Clone(StringPool* new_pool) const override;
+  void Print(std::ostream* out) const override;
 };
 
 struct String : public BaseItem<String> {
@@ -198,10 +200,10 @@
 
   explicit String(const StringPool::Ref& ref);
 
-  bool equals(const Value* value) const override;
-  bool flatten(android::Res_value* outValue) const override;
-  String* clone(StringPool* newPool) const override;
-  void print(std::ostream* out) const override;
+  bool Equals(const Value* value) const override;
+  bool Flatten(android::Res_value* out_value) const override;
+  String* Clone(StringPool* new_pool) const override;
+  void Print(std::ostream* out) const override;
 };
 
 struct StyledString : public BaseItem<StyledString> {
@@ -209,10 +211,10 @@
 
   explicit StyledString(const StringPool::StyleRef& ref);
 
-  bool equals(const Value* value) const override;
-  bool flatten(android::Res_value* outValue) const override;
-  StyledString* clone(StringPool* newPool) const override;
-  void print(std::ostream* out) const override;
+  bool Equals(const Value* value) const override;
+  bool Flatten(android::Res_value* out_value) const override;
+  StyledString* Clone(StringPool* new_pool) const override;
+  void Print(std::ostream* out) const override;
 };
 
 struct FileReference : public BaseItem<FileReference> {
@@ -226,10 +228,10 @@
   FileReference() = default;
   explicit FileReference(const StringPool::Ref& path);
 
-  bool equals(const Value* value) const override;
-  bool flatten(android::Res_value* outValue) const override;
-  FileReference* clone(StringPool* newPool) const override;
-  void print(std::ostream* out) const override;
+  bool Equals(const Value* value) const override;
+  bool Flatten(android::Res_value* out_value) const override;
+  FileReference* Clone(StringPool* new_pool) const override;
+  void Print(std::ostream* out) const override;
 };
 
 /**
@@ -242,10 +244,10 @@
   explicit BinaryPrimitive(const android::Res_value& val);
   BinaryPrimitive(uint8_t dataType, uint32_t data);
 
-  bool equals(const Value* value) const override;
-  bool flatten(android::Res_value* outValue) const override;
-  BinaryPrimitive* clone(StringPool* newPool) const override;
-  void print(std::ostream* out) const override;
+  bool Equals(const Value* value) const override;
+  bool Flatten(android::Res_value* out_value) const override;
+  BinaryPrimitive* Clone(StringPool* new_pool) const override;
+  void Print(std::ostream* out) const override;
 };
 
 struct Attribute : public BaseValue<Attribute> {
@@ -254,18 +256,18 @@
     uint32_t value;
   };
 
-  uint32_t typeMask;
-  int32_t minInt;
-  int32_t maxInt;
+  uint32_t type_mask;
+  int32_t min_int;
+  int32_t max_int;
   std::vector<Symbol> symbols;
 
   explicit Attribute(bool w, uint32_t t = 0u);
 
-  bool equals(const Value* value) const override;
-  Attribute* clone(StringPool* newPool) const override;
-  void printMask(std::ostream* out) const;
-  void print(std::ostream* out) const override;
-  bool matches(const Item* item, DiagMessage* outMsg) const;
+  bool Equals(const Value* value) const override;
+  Attribute* Clone(StringPool* new_pool) const override;
+  void PrintMask(std::ostream* out) const;
+  void Print(std::ostream* out) const override;
+  bool Matches(const Item* item, DiagMessage* out_msg) const;
 };
 
 struct Style : public BaseValue<Style> {
@@ -280,21 +282,21 @@
    * If set to true, the parent was auto inferred from the
    * style's name.
    */
-  bool parentInferred = false;
+  bool parent_inferred = false;
 
   std::vector<Entry> entries;
 
-  bool equals(const Value* value) const override;
-  Style* clone(StringPool* newPool) const override;
-  void print(std::ostream* out) const override;
+  bool Equals(const Value* value) const override;
+  Style* Clone(StringPool* new_pool) const override;
+  void Print(std::ostream* out) const override;
 };
 
 struct Array : public BaseValue<Array> {
   std::vector<std::unique_ptr<Item>> items;
 
-  bool equals(const Value* value) const override;
-  Array* clone(StringPool* newPool) const override;
-  void print(std::ostream* out) const override;
+  bool Equals(const Value* value) const override;
+  Array* Clone(StringPool* new_pool) const override;
+  void Print(std::ostream* out) const override;
 };
 
 struct Plural : public BaseValue<Plural> {
@@ -302,25 +304,25 @@
 
   std::array<std::unique_ptr<Item>, Count> values;
 
-  bool equals(const Value* value) const override;
-  Plural* clone(StringPool* newPool) const override;
-  void print(std::ostream* out) const override;
+  bool Equals(const Value* value) const override;
+  Plural* Clone(StringPool* new_pool) const override;
+  void Print(std::ostream* out) const override;
 };
 
 struct Styleable : public BaseValue<Styleable> {
   std::vector<Reference> entries;
 
-  bool equals(const Value* value) const override;
-  Styleable* clone(StringPool* newPool) const override;
-  void print(std::ostream* out) const override;
-  void mergeWith(Styleable* styleable);
+  bool Equals(const Value* value) const override;
+  Styleable* Clone(StringPool* newPool) const override;
+  void Print(std::ostream* out) const override;
+  void MergeWith(Styleable* styleable);
 };
 
 /**
  * Stream operator for printing Value objects.
  */
 inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
-  value.print(&out);
+  value.Print(&out);
   return out;
 }
 
diff --git a/tools/aapt2/Resource_test.cpp b/tools/aapt2/Resource_test.cpp
index 4b6b122..720ab91 100644
--- a/tools/aapt2/Resource_test.cpp
+++ b/tools/aapt2/Resource_test.cpp
@@ -15,100 +15,101 @@
  */
 
 #include "Resource.h"
+
 #include "test/Test.h"
 
 namespace aapt {
 
 TEST(ResourceTypeTest, ParseResourceTypes) {
-  const ResourceType* type = parseResourceType("anim");
+  const ResourceType* type = ParseResourceType("anim");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kAnim);
 
-  type = parseResourceType("animator");
+  type = ParseResourceType("animator");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kAnimator);
 
-  type = parseResourceType("array");
+  type = ParseResourceType("array");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kArray);
 
-  type = parseResourceType("attr");
+  type = ParseResourceType("attr");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kAttr);
 
-  type = parseResourceType("^attr-private");
+  type = ParseResourceType("^attr-private");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kAttrPrivate);
 
-  type = parseResourceType("bool");
+  type = ParseResourceType("bool");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kBool);
 
-  type = parseResourceType("color");
+  type = ParseResourceType("color");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kColor);
 
-  type = parseResourceType("dimen");
+  type = ParseResourceType("dimen");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kDimen);
 
-  type = parseResourceType("drawable");
+  type = ParseResourceType("drawable");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kDrawable);
 
-  type = parseResourceType("fraction");
+  type = ParseResourceType("fraction");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kFraction);
 
-  type = parseResourceType("id");
+  type = ParseResourceType("id");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kId);
 
-  type = parseResourceType("integer");
+  type = ParseResourceType("integer");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kInteger);
 
-  type = parseResourceType("interpolator");
+  type = ParseResourceType("interpolator");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kInterpolator);
 
-  type = parseResourceType("layout");
+  type = ParseResourceType("layout");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kLayout);
 
-  type = parseResourceType("menu");
+  type = ParseResourceType("menu");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kMenu);
 
-  type = parseResourceType("mipmap");
+  type = ParseResourceType("mipmap");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kMipmap);
 
-  type = parseResourceType("plurals");
+  type = ParseResourceType("plurals");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kPlurals);
 
-  type = parseResourceType("raw");
+  type = ParseResourceType("raw");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kRaw);
 
-  type = parseResourceType("string");
+  type = ParseResourceType("string");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kString);
 
-  type = parseResourceType("style");
+  type = ParseResourceType("style");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kStyle);
 
-  type = parseResourceType("transition");
+  type = ParseResourceType("transition");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kTransition);
 
-  type = parseResourceType("xml");
+  type = ParseResourceType("xml");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kXml);
 
-  type = parseResourceType("blahaha");
+  type = ParseResourceType("blahaha");
   EXPECT_EQ(type, nullptr);
 }
 
diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp
index 75375da..c7f920a 100644
--- a/tools/aapt2/SdkConstants.cpp
+++ b/tools/aapt2/SdkConstants.cpp
@@ -48,17 +48,17 @@
     {0x04ce, SDK_LOLLIPOP},
 };
 
-static bool lessEntryId(const std::pair<uint16_t, size_t>& p,
+static bool less_entry_id(const std::pair<uint16_t, size_t>& p,
                         uint16_t entryId) {
   return p.first < entryId;
 }
 
-size_t findAttributeSdkLevel(const ResourceId& id) {
-  if (id.packageId() != 0x01 && id.typeId() != 0x01) {
+size_t FindAttributeSdkLevel(const ResourceId& id) {
+  if (id.package_id() != 0x01 && id.type_id() != 0x01) {
     return 0;
   }
   auto iter = std::lower_bound(sAttrIdMap.begin(), sAttrIdMap.end(),
-                               id.entryId(), lessEntryId);
+                               id.entry_id(), less_entry_id);
   if (iter == sAttrIdMap.end()) {
     return SDK_LOLLIPOP_MR1;
   }
@@ -727,7 +727,7 @@
     {"windowActivityTransitions", 21},
     {"colorEdgeEffect", 21}};
 
-size_t findAttributeSdkLevel(const ResourceName& name) {
+size_t FindAttributeSdkLevel(const ResourceName& name) {
   if (name.package != "android" && name.type != ResourceType::kAttr) {
     return 0;
   }
@@ -739,7 +739,7 @@
   return SDK_LOLLIPOP_MR1;
 }
 
-std::pair<StringPiece, int> getDevelopmentSdkCodeNameAndVersion() {
+std::pair<StringPiece, int> GetDevelopmentSdkCodeNameAndVersion() {
   return std::make_pair(StringPiece(sDevelopmentSdkCodeName),
                         sDevelopmentSdkLevel);
 }
diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h
index bd17fe4..9b38ecb 100644
--- a/tools/aapt2/SdkConstants.h
+++ b/tools/aapt2/SdkConstants.h
@@ -17,10 +17,10 @@
 #ifndef AAPT_SDK_CONSTANTS_H
 #define AAPT_SDK_CONSTANTS_H
 
-#include "Resource.h"
-
 #include <utility>
 
+#include "Resource.h"
+
 namespace aapt {
 
 enum {
@@ -47,9 +47,9 @@
   SDK_MARSHMALLOW = 23,
 };
 
-size_t findAttributeSdkLevel(const ResourceId& id);
-size_t findAttributeSdkLevel(const ResourceName& name);
-std::pair<StringPiece, int> getDevelopmentSdkCodeNameAndVersion();
+size_t FindAttributeSdkLevel(const ResourceId& id);
+size_t FindAttributeSdkLevel(const ResourceName& name);
+std::pair<StringPiece, int> GetDevelopmentSdkCodeNameAndVersion();
 
 }  // namespace aapt
 
diff --git a/tools/aapt2/SdkConstants_test.cpp b/tools/aapt2/SdkConstants_test.cpp
index 3b70acb..716d922 100644
--- a/tools/aapt2/SdkConstants_test.cpp
+++ b/tools/aapt2/SdkConstants_test.cpp
@@ -16,23 +16,23 @@
 
 #include "SdkConstants.h"
 
-#include <gtest/gtest.h>
+#include "gtest/gtest.h"
 
 namespace aapt {
 
 TEST(SdkConstantsTest, FirstAttributeIsSdk1) {
-  EXPECT_EQ(1u, findAttributeSdkLevel(ResourceId(0x01010000)));
+  EXPECT_EQ(1u, FindAttributeSdkLevel(ResourceId(0x01010000)));
 }
 
 TEST(SdkConstantsTest, AllAttributesAfterLollipopAreLollipopMR1) {
-  EXPECT_EQ(SDK_LOLLIPOP, findAttributeSdkLevel(ResourceId(0x010103f7)));
-  EXPECT_EQ(SDK_LOLLIPOP, findAttributeSdkLevel(ResourceId(0x010104ce)));
+  EXPECT_EQ(SDK_LOLLIPOP, FindAttributeSdkLevel(ResourceId(0x010103f7)));
+  EXPECT_EQ(SDK_LOLLIPOP, FindAttributeSdkLevel(ResourceId(0x010104ce)));
 
-  EXPECT_EQ(SDK_LOLLIPOP_MR1, findAttributeSdkLevel(ResourceId(0x010104cf)));
-  EXPECT_EQ(SDK_LOLLIPOP_MR1, findAttributeSdkLevel(ResourceId(0x010104d8)));
+  EXPECT_EQ(SDK_LOLLIPOP_MR1, FindAttributeSdkLevel(ResourceId(0x010104cf)));
+  EXPECT_EQ(SDK_LOLLIPOP_MR1, FindAttributeSdkLevel(ResourceId(0x010104d8)));
 
-  EXPECT_EQ(SDK_LOLLIPOP_MR1, findAttributeSdkLevel(ResourceId(0x010104d9)));
-  EXPECT_EQ(SDK_LOLLIPOP_MR1, findAttributeSdkLevel(ResourceId(0x0101ffff)));
+  EXPECT_EQ(SDK_LOLLIPOP_MR1, FindAttributeSdkLevel(ResourceId(0x010104d9)));
+  EXPECT_EQ(SDK_LOLLIPOP_MR1, FindAttributeSdkLevel(ResourceId(0x0101ffff)));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/Source.h b/tools/aapt2/Source.h
index 422b361..459a8e6 100644
--- a/tools/aapt2/Source.h
+++ b/tools/aapt2/Source.h
@@ -17,12 +17,12 @@
 #ifndef AAPT_SOURCE_H
 #define AAPT_SOURCE_H
 
-#include "util/Maybe.h"
-#include "util/StringPiece.h"
-
 #include <ostream>
 #include <string>
 
+#include "util/Maybe.h"
+#include "util/StringPiece.h"
+
 namespace aapt {
 
 /**
@@ -36,13 +36,13 @@
   Source() = default;
 
   inline Source(const StringPiece& path)
-      : path(path.toString()) {  // NOLINT(implicit)
+      : path(path.ToString()) {  // NOLINT(implicit)
   }
 
   inline Source(const StringPiece& path, size_t line)
-      : path(path.toString()), line(line) {}
+      : path(path.ToString()), line(line) {}
 
-  inline Source withLine(size_t line) const { return Source(path, line); }
+  inline Source WithLine(size_t line) const { return Source(path, line); }
 };
 
 //
diff --git a/tools/aapt2/StringPool.cpp b/tools/aapt2/StringPool.cpp
index a167a6a..3032829 100644
--- a/tools/aapt2/StringPool.cpp
+++ b/tools/aapt2/StringPool.cpp
@@ -15,263 +15,266 @@
  */
 
 #include "StringPool.h"
-#include "util/BigBuffer.h"
-#include "util/StringPiece.h"
-#include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
 #include <algorithm>
 #include <memory>
 #include <string>
 
+#include "android-base/logging.h"
+#include "androidfw/ResourceTypes.h"
+
+#include "util/BigBuffer.h"
+#include "util/StringPiece.h"
+#include "util/Util.h"
+
 namespace aapt {
 
-StringPool::Ref::Ref() : mEntry(nullptr) {}
+StringPool::Ref::Ref() : entry_(nullptr) {}
 
-StringPool::Ref::Ref(const StringPool::Ref& rhs) : mEntry(rhs.mEntry) {
-  if (mEntry != nullptr) {
-    mEntry->ref++;
+StringPool::Ref::Ref(const StringPool::Ref& rhs) : entry_(rhs.entry_) {
+  if (entry_ != nullptr) {
+    entry_->ref_++;
   }
 }
 
-StringPool::Ref::Ref(StringPool::Entry* entry) : mEntry(entry) {
-  if (mEntry != nullptr) {
-    mEntry->ref++;
+StringPool::Ref::Ref(StringPool::Entry* entry) : entry_(entry) {
+  if (entry_ != nullptr) {
+    entry_->ref_++;
   }
 }
 
 StringPool::Ref::~Ref() {
-  if (mEntry != nullptr) {
-    mEntry->ref--;
+  if (entry_ != nullptr) {
+    entry_->ref_--;
   }
 }
 
 StringPool::Ref& StringPool::Ref::operator=(const StringPool::Ref& rhs) {
-  if (rhs.mEntry != nullptr) {
-    rhs.mEntry->ref++;
+  if (rhs.entry_ != nullptr) {
+    rhs.entry_->ref_++;
   }
 
-  if (mEntry != nullptr) {
-    mEntry->ref--;
+  if (entry_ != nullptr) {
+    entry_->ref_--;
   }
-  mEntry = rhs.mEntry;
+  entry_ = rhs.entry_;
   return *this;
 }
 
 const std::string* StringPool::Ref::operator->() const {
-  return &mEntry->value;
+  return &entry_->value;
 }
 
-const std::string& StringPool::Ref::operator*() const { return mEntry->value; }
+const std::string& StringPool::Ref::operator*() const { return entry_->value; }
 
-size_t StringPool::Ref::getIndex() const { return mEntry->index; }
+size_t StringPool::Ref::index() const { return entry_->index; }
 
-const StringPool::Context& StringPool::Ref::getContext() const {
-  return mEntry->context;
+const StringPool::Context& StringPool::Ref::GetContext() const {
+  return entry_->context;
 }
 
-StringPool::StyleRef::StyleRef() : mEntry(nullptr) {}
+StringPool::StyleRef::StyleRef() : entry_(nullptr) {}
 
 StringPool::StyleRef::StyleRef(const StringPool::StyleRef& rhs)
-    : mEntry(rhs.mEntry) {
-  if (mEntry != nullptr) {
-    mEntry->ref++;
+    : entry_(rhs.entry_) {
+  if (entry_ != nullptr) {
+    entry_->ref_++;
   }
 }
 
-StringPool::StyleRef::StyleRef(StringPool::StyleEntry* entry) : mEntry(entry) {
-  if (mEntry != nullptr) {
-    mEntry->ref++;
+StringPool::StyleRef::StyleRef(StringPool::StyleEntry* entry) : entry_(entry) {
+  if (entry_ != nullptr) {
+    entry_->ref_++;
   }
 }
 
 StringPool::StyleRef::~StyleRef() {
-  if (mEntry != nullptr) {
-    mEntry->ref--;
+  if (entry_ != nullptr) {
+    entry_->ref_--;
   }
 }
 
 StringPool::StyleRef& StringPool::StyleRef::operator=(
     const StringPool::StyleRef& rhs) {
-  if (rhs.mEntry != nullptr) {
-    rhs.mEntry->ref++;
+  if (rhs.entry_ != nullptr) {
+    rhs.entry_->ref_++;
   }
 
-  if (mEntry != nullptr) {
-    mEntry->ref--;
+  if (entry_ != nullptr) {
+    entry_->ref_--;
   }
-  mEntry = rhs.mEntry;
+  entry_ = rhs.entry_;
   return *this;
 }
 
 const StringPool::StyleEntry* StringPool::StyleRef::operator->() const {
-  return mEntry;
+  return entry_;
 }
 
 const StringPool::StyleEntry& StringPool::StyleRef::operator*() const {
-  return *mEntry;
+  return *entry_;
 }
 
-size_t StringPool::StyleRef::getIndex() const { return mEntry->str.getIndex(); }
+size_t StringPool::StyleRef::index() const { return entry_->str.index(); }
 
-const StringPool::Context& StringPool::StyleRef::getContext() const {
-  return mEntry->str.getContext();
+const StringPool::Context& StringPool::StyleRef::GetContext() const {
+  return entry_->str.GetContext();
 }
 
-StringPool::Ref StringPool::makeRef(const StringPiece& str) {
-  return makeRefImpl(str, Context{}, true);
+StringPool::Ref StringPool::MakeRef(const StringPiece& str) {
+  return MakeRefImpl(str, Context{}, true);
 }
 
-StringPool::Ref StringPool::makeRef(const StringPiece& str,
+StringPool::Ref StringPool::MakeRef(const StringPiece& str,
                                     const Context& context) {
-  return makeRefImpl(str, context, true);
+  return MakeRefImpl(str, context, true);
 }
 
-StringPool::Ref StringPool::makeRefImpl(const StringPiece& str,
+StringPool::Ref StringPool::MakeRefImpl(const StringPiece& str,
                                         const Context& context, bool unique) {
   if (unique) {
-    auto iter = mIndexedStrings.find(str);
-    if (iter != std::end(mIndexedStrings)) {
+    auto iter = indexed_strings_.find(str);
+    if (iter != std::end(indexed_strings_)) {
       return Ref(iter->second);
     }
   }
 
   Entry* entry = new Entry();
-  entry->value = str.toString();
+  entry->value = str.ToString();
   entry->context = context;
-  entry->index = mStrings.size();
-  entry->ref = 0;
-  mStrings.emplace_back(entry);
-  mIndexedStrings.insert(std::make_pair(StringPiece(entry->value), entry));
+  entry->index = strings_.size();
+  entry->ref_ = 0;
+  strings_.emplace_back(entry);
+  indexed_strings_.insert(std::make_pair(StringPiece(entry->value), entry));
   return Ref(entry);
 }
 
-StringPool::StyleRef StringPool::makeRef(const StyleString& str) {
-  return makeRef(str, Context{});
+StringPool::StyleRef StringPool::MakeRef(const StyleString& str) {
+  return MakeRef(str, Context{});
 }
 
-StringPool::StyleRef StringPool::makeRef(const StyleString& str,
+StringPool::StyleRef StringPool::MakeRef(const StyleString& str,
                                          const Context& context) {
   Entry* entry = new Entry();
   entry->value = str.str;
   entry->context = context;
-  entry->index = mStrings.size();
-  entry->ref = 0;
-  mStrings.emplace_back(entry);
-  mIndexedStrings.insert(std::make_pair(StringPiece(entry->value), entry));
+  entry->index = strings_.size();
+  entry->ref_ = 0;
+  strings_.emplace_back(entry);
+  indexed_strings_.insert(std::make_pair(StringPiece(entry->value), entry));
 
-  StyleEntry* styleEntry = new StyleEntry();
-  styleEntry->str = Ref(entry);
+  StyleEntry* style_entry = new StyleEntry();
+  style_entry->str = Ref(entry);
   for (const aapt::Span& span : str.spans) {
-    styleEntry->spans.emplace_back(
-        Span{makeRef(span.name), span.firstChar, span.lastChar});
+    style_entry->spans.emplace_back(
+        Span{MakeRef(span.name), span.first_char, span.last_char});
   }
-  styleEntry->ref = 0;
-  mStyles.emplace_back(styleEntry);
-  return StyleRef(styleEntry);
+  style_entry->ref_ = 0;
+  styles_.emplace_back(style_entry);
+  return StyleRef(style_entry);
 }
 
-StringPool::StyleRef StringPool::makeRef(const StyleRef& ref) {
+StringPool::StyleRef StringPool::MakeRef(const StyleRef& ref) {
   Entry* entry = new Entry();
-  entry->value = *ref.mEntry->str;
-  entry->context = ref.mEntry->str.mEntry->context;
-  entry->index = mStrings.size();
-  entry->ref = 0;
-  mStrings.emplace_back(entry);
-  mIndexedStrings.insert(std::make_pair(StringPiece(entry->value), entry));
+  entry->value = *ref.entry_->str;
+  entry->context = ref.entry_->str.entry_->context;
+  entry->index = strings_.size();
+  entry->ref_ = 0;
+  strings_.emplace_back(entry);
+  indexed_strings_.insert(std::make_pair(StringPiece(entry->value), entry));
 
-  StyleEntry* styleEntry = new StyleEntry();
-  styleEntry->str = Ref(entry);
-  for (const Span& span : ref.mEntry->spans) {
-    styleEntry->spans.emplace_back(
-        Span{makeRef(*span.name), span.firstChar, span.lastChar});
+  StyleEntry* style_entry = new StyleEntry();
+  style_entry->str = Ref(entry);
+  for (const Span& span : ref.entry_->spans) {
+    style_entry->spans.emplace_back(
+        Span{MakeRef(*span.name), span.first_char, span.last_char});
   }
-  styleEntry->ref = 0;
-  mStyles.emplace_back(styleEntry);
-  return StyleRef(styleEntry);
+  style_entry->ref_ = 0;
+  styles_.emplace_back(style_entry);
+  return StyleRef(style_entry);
 }
 
-void StringPool::merge(StringPool&& pool) {
-  mIndexedStrings.insert(pool.mIndexedStrings.begin(),
-                         pool.mIndexedStrings.end());
-  pool.mIndexedStrings.clear();
-  std::move(pool.mStrings.begin(), pool.mStrings.end(),
-            std::back_inserter(mStrings));
-  pool.mStrings.clear();
-  std::move(pool.mStyles.begin(), pool.mStyles.end(),
-            std::back_inserter(mStyles));
-  pool.mStyles.clear();
+void StringPool::Merge(StringPool&& pool) {
+  indexed_strings_.insert(pool.indexed_strings_.begin(),
+                          pool.indexed_strings_.end());
+  pool.indexed_strings_.clear();
+  std::move(pool.strings_.begin(), pool.strings_.end(),
+            std::back_inserter(strings_));
+  pool.strings_.clear();
+  std::move(pool.styles_.begin(), pool.styles_.end(),
+            std::back_inserter(styles_));
+  pool.styles_.clear();
 
   // Assign the indices.
-  const size_t len = mStrings.size();
+  const size_t len = strings_.size();
   for (size_t index = 0; index < len; index++) {
-    mStrings[index]->index = index;
+    strings_[index]->index = index;
   }
 }
 
-void StringPool::hintWillAdd(size_t stringCount, size_t styleCount) {
-  mStrings.reserve(mStrings.size() + stringCount);
-  mStyles.reserve(mStyles.size() + styleCount);
+void StringPool::HintWillAdd(size_t stringCount, size_t styleCount) {
+  strings_.reserve(strings_.size() + stringCount);
+  styles_.reserve(styles_.size() + styleCount);
 }
 
-void StringPool::prune() {
-  const auto iterEnd = std::end(mIndexedStrings);
-  auto indexIter = std::begin(mIndexedStrings);
-  while (indexIter != iterEnd) {
-    if (indexIter->second->ref <= 0) {
-      indexIter = mIndexedStrings.erase(indexIter);
+void StringPool::Prune() {
+  const auto iter_end = indexed_strings_.end();
+  auto index_iter = indexed_strings_.begin();
+  while (index_iter != iter_end) {
+    if (index_iter->second->ref_ <= 0) {
+      index_iter = indexed_strings_.erase(index_iter);
     } else {
-      ++indexIter;
+      ++index_iter;
     }
   }
 
-  auto endIter2 =
-      std::remove_if(std::begin(mStrings), std::end(mStrings),
+  auto end_iter2 =
+      std::remove_if(strings_.begin(), strings_.end(),
                      [](const std::unique_ptr<Entry>& entry) -> bool {
-                       return entry->ref <= 0;
+                       return entry->ref_ <= 0;
                      });
 
-  auto endIter3 =
-      std::remove_if(std::begin(mStyles), std::end(mStyles),
+  auto end_iter3 =
+      std::remove_if(styles_.begin(), styles_.end(),
                      [](const std::unique_ptr<StyleEntry>& entry) -> bool {
-                       return entry->ref <= 0;
+                       return entry->ref_ <= 0;
                      });
 
   // Remove the entries at the end or else we'll be accessing
   // a deleted string from the StyleEntry.
-  mStrings.erase(endIter2, std::end(mStrings));
-  mStyles.erase(endIter3, std::end(mStyles));
+  strings_.erase(end_iter2, strings_.end());
+  styles_.erase(end_iter3, styles_.end());
 
   // Reassign the indices.
-  const size_t len = mStrings.size();
+  const size_t len = strings_.size();
   for (size_t index = 0; index < len; index++) {
-    mStrings[index]->index = index;
+    strings_[index]->index = index;
   }
 }
 
-void StringPool::sort(
+void StringPool::Sort(
     const std::function<bool(const Entry&, const Entry&)>& cmp) {
   std::sort(
-      std::begin(mStrings), std::end(mStrings),
+      strings_.begin(), strings_.end(),
       [&cmp](const std::unique_ptr<Entry>& a,
              const std::unique_ptr<Entry>& b) -> bool { return cmp(*a, *b); });
 
   // Assign the indices.
-  const size_t len = mStrings.size();
+  const size_t len = strings_.size();
   for (size_t index = 0; index < len; index++) {
-    mStrings[index]->index = index;
+    strings_[index]->index = index;
   }
 
   // Reorder the styles.
-  std::sort(std::begin(mStyles), std::end(mStyles),
+  std::sort(styles_.begin(), styles_.end(),
             [](const std::unique_ptr<StyleEntry>& lhs,
                const std::unique_ptr<StyleEntry>& rhs) -> bool {
-              return lhs->str.getIndex() < rhs->str.getIndex();
+              return lhs->str.index() < rhs->str.index();
             });
 }
 
 template <typename T>
-static T* encodeLength(T* data, size_t length) {
+static T* EncodeLength(T* data, size_t length) {
   static_assert(std::is_integral<T>::value, "wat.");
 
   constexpr size_t kMask = 1 << ((sizeof(T) * 8) - 1);
@@ -284,7 +287,7 @@
 }
 
 template <typename T>
-static size_t encodedLengthUnits(size_t length) {
+static size_t EncodedLengthUnits(size_t length) {
   static_assert(std::is_integral<T>::value, "wat.");
 
   constexpr size_t kMask = 1 << ((sizeof(T) * 8) - 1);
@@ -292,10 +295,10 @@
   return length > kMaxSize ? 2 : 1;
 }
 
-bool StringPool::flatten(BigBuffer* out, const StringPool& pool, bool utf8) {
-  const size_t startIndex = out->size();
+bool StringPool::Flatten(BigBuffer* out, const StringPool& pool, bool utf8) {
+  const size_t start_index = out->size();
   android::ResStringPool_header* header =
-      out->nextBlock<android::ResStringPool_header>();
+      out->NextBlock<android::ResStringPool_header>();
   header->header.type = android::RES_STRING_POOL_TYPE;
   header->header.headerSize = sizeof(*header);
   header->stringCount = pool.size();
@@ -304,92 +307,90 @@
   }
 
   uint32_t* indices =
-      pool.size() != 0 ? out->nextBlock<uint32_t>(pool.size()) : nullptr;
+      pool.size() != 0 ? out->NextBlock<uint32_t>(pool.size()) : nullptr;
 
-  uint32_t* styleIndices = nullptr;
-  if (!pool.mStyles.empty()) {
-    header->styleCount = pool.mStyles.back()->str.getIndex() + 1;
-    styleIndices = out->nextBlock<uint32_t>(header->styleCount);
+  uint32_t* style_indices = nullptr;
+  if (!pool.styles_.empty()) {
+    header->styleCount = pool.styles_.back()->str.index() + 1;
+    style_indices = out->NextBlock<uint32_t>(header->styleCount);
   }
 
-  const size_t beforeStringsIndex = out->size();
-  header->stringsStart = beforeStringsIndex - startIndex;
+  const size_t before_strings_index = out->size();
+  header->stringsStart = before_strings_index - start_index;
 
   for (const auto& entry : pool) {
-    *indices = out->size() - beforeStringsIndex;
+    *indices = out->size() - before_strings_index;
     indices++;
 
     if (utf8) {
       const std::string& encoded = entry->value;
-      const ssize_t utf16Length = utf8_to_utf16_length(
+      const ssize_t utf16_length = utf8_to_utf16_length(
           reinterpret_cast<const uint8_t*>(entry->value.data()),
           entry->value.size());
-      assert(utf16Length >= 0);
+      CHECK(utf16_length >= 0);
 
-      const size_t totalSize = encodedLengthUnits<char>(utf16Length) +
-                               encodedLengthUnits<char>(encoded.length()) +
-                               encoded.size() + 1;
+      const size_t total_size = EncodedLengthUnits<char>(utf16_length) +
+                                EncodedLengthUnits<char>(encoded.length()) +
+                                encoded.size() + 1;
 
-      char* data = out->nextBlock<char>(totalSize);
+      char* data = out->NextBlock<char>(total_size);
 
       // First encode the UTF16 string length.
-      data = encodeLength(data, utf16Length);
+      data = EncodeLength(data, utf16_length);
 
       // Now encode the size of the real UTF8 string.
-      data = encodeLength(data, encoded.length());
+      data = EncodeLength(data, encoded.length());
       strncpy(data, encoded.data(), encoded.size());
 
     } else {
-      const std::u16string encoded = util::utf8ToUtf16(entry->value);
-      const ssize_t utf16Length = encoded.size();
+      const std::u16string encoded = util::Utf8ToUtf16(entry->value);
+      const ssize_t utf16_length = encoded.size();
 
       // Total number of 16-bit words to write.
-      const size_t totalSize =
-          encodedLengthUnits<char16_t>(utf16Length) + encoded.size() + 1;
+      const size_t total_size =
+          EncodedLengthUnits<char16_t>(utf16_length) + encoded.size() + 1;
 
-      char16_t* data = out->nextBlock<char16_t>(totalSize);
+      char16_t* data = out->NextBlock<char16_t>(total_size);
 
       // Encode the actual UTF16 string length.
-      data = encodeLength(data, utf16Length);
-      const size_t byteLength = encoded.size() * sizeof(char16_t);
+      data = EncodeLength(data, utf16_length);
+      const size_t byte_length = encoded.size() * sizeof(char16_t);
 
       // NOTE: For some reason, strncpy16(data, entry->value.data(),
-      // entry->value.size())
-      // truncates the string.
-      memcpy(data, encoded.data(), byteLength);
+      // entry->value.size()) truncates the string.
+      memcpy(data, encoded.data(), byte_length);
 
       // The null-terminating character is already here due to the block of data
-      // being set
-      // to 0s on allocation.
+      // being set to 0s on allocation.
     }
   }
 
-  out->align4();
+  out->Align4();
 
-  if (!pool.mStyles.empty()) {
-    const size_t beforeStylesIndex = out->size();
-    header->stylesStart = beforeStylesIndex - startIndex;
+  if (!pool.styles_.empty()) {
+    const size_t before_styles_index = out->size();
+    header->stylesStart = before_styles_index - start_index;
 
-    size_t currentIndex = 0;
-    for (const auto& entry : pool.mStyles) {
-      while (entry->str.getIndex() > currentIndex) {
-        styleIndices[currentIndex++] = out->size() - beforeStylesIndex;
+    size_t current_index = 0;
+    for (const auto& entry : pool.styles_) {
+      while (entry->str.index() > current_index) {
+        style_indices[current_index++] = out->size() - before_styles_index;
 
-        uint32_t* spanOffset = out->nextBlock<uint32_t>();
-        *spanOffset = android::ResStringPool_span::END;
+        uint32_t* span_offset = out->NextBlock<uint32_t>();
+        *span_offset = android::ResStringPool_span::END;
       }
-      styleIndices[currentIndex++] = out->size() - beforeStylesIndex;
+      style_indices[current_index++] = out->size() - before_styles_index;
 
       android::ResStringPool_span* span =
-          out->nextBlock<android::ResStringPool_span>(entry->spans.size());
+          out->NextBlock<android::ResStringPool_span>(entry->spans.size());
       for (const auto& s : entry->spans) {
-        span->name.index = s.name.getIndex();
-        span->firstChar = s.firstChar;
-        span->lastChar = s.lastChar;
+        span->name.index = s.name.index();
+        span->firstChar = s.first_char;
+        span->lastChar = s.last_char;
         span++;
       }
 
-      uint32_t* spanEnd = out->nextBlock<uint32_t>();
+      uint32_t* spanEnd = out->NextBlock<uint32_t>();
       *spanEnd = android::ResStringPool_span::END;
     }
 
@@ -397,22 +398,22 @@
     // ResStringPool_span structure worth of 0xFFFFFFFF at the end
     // of the style block, so fill in the remaining 2 32bit words
     // with 0xFFFFFFFF.
-    const size_t paddingLength = sizeof(android::ResStringPool_span) -
-                                 sizeof(android::ResStringPool_span::name);
-    uint8_t* padding = out->nextBlock<uint8_t>(paddingLength);
-    memset(padding, 0xff, paddingLength);
-    out->align4();
+    const size_t padding_length = sizeof(android::ResStringPool_span) -
+                                  sizeof(android::ResStringPool_span::name);
+    uint8_t* padding = out->NextBlock<uint8_t>(padding_length);
+    memset(padding, 0xff, padding_length);
+    out->Align4();
   }
-  header->header.size = out->size() - startIndex;
+  header->header.size = out->size() - start_index;
   return true;
 }
 
-bool StringPool::flattenUtf8(BigBuffer* out, const StringPool& pool) {
-  return flatten(out, pool, true);
+bool StringPool::FlattenUtf8(BigBuffer* out, const StringPool& pool) {
+  return Flatten(out, pool, true);
 }
 
-bool StringPool::flattenUtf16(BigBuffer* out, const StringPool& pool) {
-  return flatten(out, pool, false);
+bool StringPool::FlattenUtf16(BigBuffer* out, const StringPool& pool) {
+  return Flatten(out, pool, false);
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/StringPool.h b/tools/aapt2/StringPool.h
index 05c26e7..a4f556c 100644
--- a/tools/aapt2/StringPool.h
+++ b/tools/aapt2/StringPool.h
@@ -17,22 +17,22 @@
 #ifndef AAPT_STRING_POOL_H
 #define AAPT_STRING_POOL_H
 
-#include "ConfigDescription.h"
-#include "util/BigBuffer.h"
-#include "util/StringPiece.h"
-
 #include <functional>
 #include <memory>
 #include <string>
 #include <unordered_map>
 #include <vector>
 
+#include "ConfigDescription.h"
+#include "util/BigBuffer.h"
+#include "util/StringPiece.h"
+
 namespace aapt {
 
 struct Span {
   std::string name;
-  uint32_t firstChar;
-  uint32_t lastChar;
+  uint32_t first_char;
+  uint32_t last_char;
 };
 
 struct StyleString {
@@ -42,9 +42,22 @@
 
 class StringPool {
  public:
-  struct Context {
-    uint32_t priority;
+  class Context {
+   public:
+    enum : uint32_t {
+      kStylePriority = 0u,
+      kHighPriority = 1u,
+      kNormalPriority = 0x7fffffffu,
+      kLowPriority = 0xffffffffu,
+    };
+    uint32_t priority = kNormalPriority;
     ConfigDescription config;
+
+    Context() = default;
+    Context(uint32_t p, const ConfigDescription& c) : priority(p), config(c) {}
+    explicit Context(uint32_t p) : priority(p) {}
+    explicit Context(const ConfigDescription& c)
+        : priority(kNormalPriority), config(c) {}
   };
 
   class Entry;
@@ -59,15 +72,15 @@
     const std::string* operator->() const;
     const std::string& operator*() const;
 
-    size_t getIndex() const;
-    const Context& getContext() const;
+    size_t index() const;
+    const Context& GetContext() const;
 
    private:
     friend class StringPool;
 
     explicit Ref(Entry* entry);
 
-    Entry* mEntry;
+    Entry* entry_;
   };
 
   class StyleEntry;
@@ -82,15 +95,15 @@
     const StyleEntry* operator->() const;
     const StyleEntry& operator*() const;
 
-    size_t getIndex() const;
-    const Context& getContext() const;
+    size_t index() const;
+    const Context& GetContext() const;
 
    private:
     friend class StringPool;
 
     explicit StyleRef(StyleEntry* entry);
 
-    StyleEntry* mEntry;
+    StyleEntry* entry_;
   };
 
   class Entry {
@@ -103,13 +116,13 @@
     friend class StringPool;
     friend class Ref;
 
-    int ref;
+    int ref_;
   };
 
   struct Span {
     Ref name;
-    uint32_t firstChar;
-    uint32_t lastChar;
+    uint32_t first_char;
+    uint32_t last_char;
   };
 
   class StyleEntry {
@@ -121,13 +134,13 @@
     friend class StringPool;
     friend class StyleRef;
 
-    int ref;
+    int ref_;
   };
 
   using const_iterator = std::vector<std::unique_ptr<Entry>>::const_iterator;
 
-  static bool flattenUtf8(BigBuffer* out, const StringPool& pool);
-  static bool flattenUtf16(BigBuffer* out, const StringPool& pool);
+  static bool FlattenUtf8(BigBuffer* out, const StringPool& pool);
+  static bool FlattenUtf16(BigBuffer* out, const StringPool& pool);
 
   StringPool() = default;
   StringPool(const StringPool&) = delete;
@@ -136,84 +149,84 @@
    * Adds a string to the pool, unless it already exists. Returns
    * a reference to the string in the pool.
    */
-  Ref makeRef(const StringPiece& str);
+  Ref MakeRef(const StringPiece& str);
 
   /**
    * Adds a string to the pool, unless it already exists, with a context
    * object that can be used when sorting the string pool. Returns
    * a reference to the string in the pool.
    */
-  Ref makeRef(const StringPiece& str, const Context& context);
+  Ref MakeRef(const StringPiece& str, const Context& context);
 
   /**
    * Adds a style to the string pool and returns a reference to it.
    */
-  StyleRef makeRef(const StyleString& str);
+  StyleRef MakeRef(const StyleString& str);
 
   /**
    * Adds a style to the string pool with a context object that
    * can be used when sorting the string pool. Returns a reference
    * to the style in the string pool.
    */
-  StyleRef makeRef(const StyleString& str, const Context& context);
+  StyleRef MakeRef(const StyleString& str, const Context& context);
 
   /**
    * Adds a style from another string pool. Returns a reference to the
    * style in the string pool.
    */
-  StyleRef makeRef(const StyleRef& ref);
+  StyleRef MakeRef(const StyleRef& ref);
 
   /**
    * Moves pool into this one without coalescing strings. When this
    * function returns, pool will be empty.
    */
-  void merge(StringPool&& pool);
+  void Merge(StringPool&& pool);
 
   /**
-   * Retuns the number of strings in the table.
+   * Returns the number of strings in the table.
    */
   inline size_t size() const;
 
   /**
    * Reserves space for strings and styles as an optimization.
    */
-  void hintWillAdd(size_t stringCount, size_t styleCount);
+  void HintWillAdd(size_t string_count, size_t style_count);
 
   /**
    * Sorts the strings according to some comparison function.
    */
-  void sort(const std::function<bool(const Entry&, const Entry&)>& cmp);
+  void Sort(const std::function<bool(const Entry&, const Entry&)>& cmp);
 
   /**
    * Removes any strings that have no references.
    */
-  void prune();
+  void Prune();
 
  private:
   friend const_iterator begin(const StringPool& pool);
   friend const_iterator end(const StringPool& pool);
 
-  static bool flatten(BigBuffer* out, const StringPool& pool, bool utf8);
+  static bool Flatten(BigBuffer* out, const StringPool& pool, bool utf8);
 
-  Ref makeRefImpl(const StringPiece& str, const Context& context, bool unique);
+  Ref MakeRefImpl(const StringPiece& str, const Context& context, bool unique);
 
-  std::vector<std::unique_ptr<Entry>> mStrings;
-  std::vector<std::unique_ptr<StyleEntry>> mStyles;
-  std::unordered_multimap<StringPiece, Entry*> mIndexedStrings;
+  std::vector<std::unique_ptr<Entry>> strings_;
+  std::vector<std::unique_ptr<StyleEntry>> styles_;
+  std::unordered_multimap<StringPiece, Entry*> indexed_strings_;
 };
 
 //
 // Inline implementation
 //
 
-inline size_t StringPool::size() const { return mStrings.size(); }
+inline size_t StringPool::size() const { return strings_.size(); }
 
 inline StringPool::const_iterator begin(const StringPool& pool) {
-  return pool.mStrings.begin();
+  return pool.strings_.begin();
 }
 
 inline StringPool::const_iterator end(const StringPool& pool) {
-  return pool.mStrings.end();
+  return pool.strings_.end();
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/StringPool_test.cpp b/tools/aapt2/StringPool_test.cpp
index 2a7e1dd..e1394fc 100644
--- a/tools/aapt2/StringPool_test.cpp
+++ b/tools/aapt2/StringPool_test.cpp
@@ -15,25 +15,26 @@
  */
 
 #include "StringPool.h"
-#include "test/Test.h"
-#include "util/Util.h"
 
 #include <string>
 
+#include "test/Test.h"
+#include "util/Util.h"
+
 namespace aapt {
 
 TEST(StringPoolTest, InsertOneString) {
   StringPool pool;
 
-  StringPool::Ref ref = pool.makeRef("wut");
+  StringPool::Ref ref = pool.MakeRef("wut");
   EXPECT_EQ(*ref, "wut");
 }
 
 TEST(StringPoolTest, InsertTwoUniqueStrings) {
   StringPool pool;
 
-  StringPool::Ref ref = pool.makeRef("wut");
-  StringPool::Ref ref2 = pool.makeRef("hey");
+  StringPool::Ref ref = pool.MakeRef("wut");
+  StringPool::Ref ref2 = pool.MakeRef("hey");
 
   EXPECT_EQ(*ref, "wut");
   EXPECT_EQ(*ref2, "hey");
@@ -42,8 +43,8 @@
 TEST(StringPoolTest, DoNotInsertNewDuplicateString) {
   StringPool pool;
 
-  StringPool::Ref ref = pool.makeRef("wut");
-  StringPool::Ref ref2 = pool.makeRef("wut");
+  StringPool::Ref ref = pool.MakeRef("wut");
+  StringPool::Ref ref2 = pool.MakeRef("wut");
 
   EXPECT_EQ(*ref, "wut");
   EXPECT_EQ(*ref2, "wut");
@@ -53,28 +54,28 @@
 TEST(StringPoolTest, MaintainInsertionOrderIndex) {
   StringPool pool;
 
-  StringPool::Ref ref = pool.makeRef("z");
-  StringPool::Ref ref2 = pool.makeRef("a");
-  StringPool::Ref ref3 = pool.makeRef("m");
+  StringPool::Ref ref = pool.MakeRef("z");
+  StringPool::Ref ref2 = pool.MakeRef("a");
+  StringPool::Ref ref3 = pool.MakeRef("m");
 
-  EXPECT_EQ(0u, ref.getIndex());
-  EXPECT_EQ(1u, ref2.getIndex());
-  EXPECT_EQ(2u, ref3.getIndex());
+  EXPECT_EQ(0u, ref.index());
+  EXPECT_EQ(1u, ref2.index());
+  EXPECT_EQ(2u, ref3.index());
 }
 
 TEST(StringPoolTest, PruneStringsWithNoReferences) {
   StringPool pool;
 
-  StringPool::Ref refA = pool.makeRef("foo");
+  StringPool::Ref refA = pool.MakeRef("foo");
   {
-    StringPool::Ref ref = pool.makeRef("wut");
+    StringPool::Ref ref = pool.MakeRef("wut");
     EXPECT_EQ(*ref, "wut");
     EXPECT_EQ(2u, pool.size());
   }
-  StringPool::Ref refB = pool.makeRef("bar");
+  StringPool::Ref refB = pool.MakeRef("bar");
 
   EXPECT_EQ(3u, pool.size());
-  pool.prune();
+  pool.Prune();
   EXPECT_EQ(2u, pool.size());
   StringPool::const_iterator iter = begin(pool);
   EXPECT_EQ((*iter)->value, "foo");
@@ -87,51 +88,51 @@
 TEST(StringPoolTest, SortAndMaintainIndexesInReferences) {
   StringPool pool;
 
-  StringPool::Ref ref = pool.makeRef("z");
-  StringPool::StyleRef ref2 = pool.makeRef(StyleString{{"a"}});
-  StringPool::Ref ref3 = pool.makeRef("m");
+  StringPool::Ref ref = pool.MakeRef("z");
+  StringPool::StyleRef ref2 = pool.MakeRef(StyleString{{"a"}});
+  StringPool::Ref ref3 = pool.MakeRef("m");
 
   EXPECT_EQ(*ref, "z");
-  EXPECT_EQ(0u, ref.getIndex());
+  EXPECT_EQ(0u, ref.index());
 
   EXPECT_EQ(*(ref2->str), "a");
-  EXPECT_EQ(1u, ref2.getIndex());
+  EXPECT_EQ(1u, ref2.index());
 
   EXPECT_EQ(*ref3, "m");
-  EXPECT_EQ(2u, ref3.getIndex());
+  EXPECT_EQ(2u, ref3.index());
 
-  pool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
+  pool.Sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
     return a.value < b.value;
   });
 
   EXPECT_EQ(*ref, "z");
-  EXPECT_EQ(2u, ref.getIndex());
+  EXPECT_EQ(2u, ref.index());
 
   EXPECT_EQ(*(ref2->str), "a");
-  EXPECT_EQ(0u, ref2.getIndex());
+  EXPECT_EQ(0u, ref2.index());
 
   EXPECT_EQ(*ref3, "m");
-  EXPECT_EQ(1u, ref3.getIndex());
+  EXPECT_EQ(1u, ref3.index());
 }
 
 TEST(StringPoolTest, SortAndStillDedupe) {
   StringPool pool;
 
-  StringPool::Ref ref = pool.makeRef("z");
-  StringPool::Ref ref2 = pool.makeRef("a");
-  StringPool::Ref ref3 = pool.makeRef("m");
+  StringPool::Ref ref = pool.MakeRef("z");
+  StringPool::Ref ref2 = pool.MakeRef("a");
+  StringPool::Ref ref3 = pool.MakeRef("m");
 
-  pool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
+  pool.Sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
     return a.value < b.value;
   });
 
-  StringPool::Ref ref4 = pool.makeRef("z");
-  StringPool::Ref ref5 = pool.makeRef("a");
-  StringPool::Ref ref6 = pool.makeRef("m");
+  StringPool::Ref ref4 = pool.MakeRef("z");
+  StringPool::Ref ref5 = pool.MakeRef("a");
+  StringPool::Ref ref6 = pool.MakeRef("m");
 
-  EXPECT_EQ(ref4.getIndex(), ref.getIndex());
-  EXPECT_EQ(ref5.getIndex(), ref2.getIndex());
-  EXPECT_EQ(ref6.getIndex(), ref3.getIndex());
+  EXPECT_EQ(ref4.index(), ref.index());
+  EXPECT_EQ(ref5.index(), ref2.index());
+  EXPECT_EQ(ref6.index(), ref3.index());
 }
 
 TEST(StringPoolTest, AddStyles) {
@@ -139,27 +140,27 @@
 
   StyleString str{{"android"}, {Span{{"b"}, 2, 6}}};
 
-  StringPool::StyleRef ref = pool.makeRef(str);
+  StringPool::StyleRef ref = pool.MakeRef(str);
 
-  EXPECT_EQ(0u, ref.getIndex());
+  EXPECT_EQ(0u, ref.index());
   EXPECT_EQ(std::string("android"), *(ref->str));
   ASSERT_EQ(1u, ref->spans.size());
 
   const StringPool::Span& span = ref->spans.front();
   EXPECT_EQ(*(span.name), "b");
-  EXPECT_EQ(2u, span.firstChar);
-  EXPECT_EQ(6u, span.lastChar);
+  EXPECT_EQ(2u, span.first_char);
+  EXPECT_EQ(6u, span.last_char);
 }
 
 TEST(StringPoolTest, DoNotDedupeStyleWithSameStringAsNonStyle) {
   StringPool pool;
 
-  StringPool::Ref ref = pool.makeRef("android");
+  StringPool::Ref ref = pool.MakeRef("android");
 
   StyleString str{{"android"}};
-  StringPool::StyleRef styleRef = pool.makeRef(str);
+  StringPool::StyleRef styleRef = pool.MakeRef(str);
 
-  EXPECT_NE(ref.getIndex(), styleRef.getIndex());
+  EXPECT_NE(ref.index(), styleRef.index());
 }
 
 TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) {
@@ -167,9 +168,9 @@
 
   StringPool pool;
   BigBuffer buffer(1024);
-  StringPool::flattenUtf8(&buffer, pool);
+  StringPool::FlattenUtf8(&buffer, pool);
 
-  std::unique_ptr<uint8_t[]> data = util::copy(buffer);
+  std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
   ResStringPool test;
   ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
 }
@@ -178,11 +179,11 @@
   using namespace android;  // For NO_ERROR on Windows.
 
   StringPool pool;
-  pool.makeRef("\u093f");
+  pool.MakeRef("\u093f");
   BigBuffer buffer(1024);
-  StringPool::flattenUtf16(&buffer, pool);
+  StringPool::FlattenUtf16(&buffer, pool);
 
-  std::unique_ptr<uint8_t[]> data = util::copy(buffer);
+  std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
   ResStringPool test;
   ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
   size_t len = 0;
@@ -204,58 +205,58 @@
 
   StringPool pool;
 
-  StringPool::Ref ref1 = pool.makeRef("hello");
-  StringPool::Ref ref2 = pool.makeRef("goodbye");
-  StringPool::Ref ref3 = pool.makeRef(sLongString);
-  StringPool::Ref ref4 = pool.makeRef("");
-  StringPool::StyleRef ref5 = pool.makeRef(
+  StringPool::Ref ref1 = pool.MakeRef("hello");
+  StringPool::Ref ref2 = pool.MakeRef("goodbye");
+  StringPool::Ref ref3 = pool.MakeRef(sLongString);
+  StringPool::Ref ref4 = pool.MakeRef("");
+  StringPool::StyleRef ref5 = pool.MakeRef(
       StyleString{{"style"}, {Span{{"b"}, 0, 1}, Span{{"i"}, 2, 3}}});
 
-  EXPECT_EQ(0u, ref1.getIndex());
-  EXPECT_EQ(1u, ref2.getIndex());
-  EXPECT_EQ(2u, ref3.getIndex());
-  EXPECT_EQ(3u, ref4.getIndex());
-  EXPECT_EQ(4u, ref5.getIndex());
+  EXPECT_EQ(0u, ref1.index());
+  EXPECT_EQ(1u, ref2.index());
+  EXPECT_EQ(2u, ref3.index());
+  EXPECT_EQ(3u, ref4.index());
+  EXPECT_EQ(4u, ref5.index());
 
   BigBuffer buffers[2] = {BigBuffer(1024), BigBuffer(1024)};
-  StringPool::flattenUtf8(&buffers[0], pool);
-  StringPool::flattenUtf16(&buffers[1], pool);
+  StringPool::FlattenUtf8(&buffers[0], pool);
+  StringPool::FlattenUtf16(&buffers[1], pool);
 
   // Test both UTF-8 and UTF-16 buffers.
   for (const BigBuffer& buffer : buffers) {
-    std::unique_ptr<uint8_t[]> data = util::copy(buffer);
+    std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
 
     ResStringPool test;
     ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
 
-    EXPECT_EQ(std::string("hello"), util::getString(test, 0));
-    EXPECT_EQ(StringPiece16(u"hello"), util::getString16(test, 0));
+    EXPECT_EQ(std::string("hello"), util::GetString(test, 0));
+    EXPECT_EQ(StringPiece16(u"hello"), util::GetString16(test, 0));
 
-    EXPECT_EQ(std::string("goodbye"), util::getString(test, 1));
-    EXPECT_EQ(StringPiece16(u"goodbye"), util::getString16(test, 1));
+    EXPECT_EQ(std::string("goodbye"), util::GetString(test, 1));
+    EXPECT_EQ(StringPiece16(u"goodbye"), util::GetString16(test, 1));
 
-    EXPECT_EQ(StringPiece(sLongString), util::getString(test, 2));
-    EXPECT_EQ(util::utf8ToUtf16(sLongString),
-              util::getString16(test, 2).toString());
+    EXPECT_EQ(StringPiece(sLongString), util::GetString(test, 2));
+    EXPECT_EQ(util::Utf8ToUtf16(sLongString),
+              util::GetString16(test, 2).ToString());
 
     size_t len;
     EXPECT_TRUE(test.stringAt(3, &len) != nullptr ||
                 test.string8At(3, &len) != nullptr);
 
-    EXPECT_EQ(std::string("style"), util::getString(test, 4));
-    EXPECT_EQ(StringPiece16(u"style"), util::getString16(test, 4));
+    EXPECT_EQ(std::string("style"), util::GetString(test, 4));
+    EXPECT_EQ(StringPiece16(u"style"), util::GetString16(test, 4));
 
     const ResStringPool_span* span = test.styleAt(4);
     ASSERT_NE(nullptr, span);
-    EXPECT_EQ(std::string("b"), util::getString(test, span->name.index));
-    EXPECT_EQ(StringPiece16(u"b"), util::getString16(test, span->name.index));
+    EXPECT_EQ(std::string("b"), util::GetString(test, span->name.index));
+    EXPECT_EQ(StringPiece16(u"b"), util::GetString16(test, span->name.index));
     EXPECT_EQ(0u, span->firstChar);
     EXPECT_EQ(1u, span->lastChar);
     span++;
 
     ASSERT_NE(ResStringPool_span::END, span->name.index);
-    EXPECT_EQ(std::string("i"), util::getString(test, span->name.index));
-    EXPECT_EQ(StringPiece16(u"i"), util::getString16(test, span->name.index));
+    EXPECT_EQ(std::string("i"), util::GetString(test, span->name.index));
+    EXPECT_EQ(StringPiece16(u"i"), util::GetString16(test, span->name.index));
     EXPECT_EQ(2u, span->firstChar);
     EXPECT_EQ(3u, span->lastChar);
     span++;
diff --git a/tools/aapt2/ValueVisitor.h b/tools/aapt2/ValueVisitor.h
index 121c337..1cb6aa1 100644
--- a/tools/aapt2/ValueVisitor.h
+++ b/tools/aapt2/ValueVisitor.h
@@ -24,32 +24,31 @@
 
 /**
  * Visits a value and invokes the appropriate method based on its type. Does not
- * traverse
- * into compound types. Use ValueVisitor for that.
+ * traverse into compound types. Use ValueVisitor for that.
  */
 struct RawValueVisitor {
   virtual ~RawValueVisitor() = default;
 
-  virtual void visitItem(Item* value) {}
-  virtual void visit(Reference* value) { visitItem(value); }
-  virtual void visit(RawString* value) { visitItem(value); }
-  virtual void visit(String* value) { visitItem(value); }
-  virtual void visit(StyledString* value) { visitItem(value); }
-  virtual void visit(FileReference* value) { visitItem(value); }
-  virtual void visit(Id* value) { visitItem(value); }
-  virtual void visit(BinaryPrimitive* value) { visitItem(value); }
+  virtual void VisitItem(Item* value) {}
+  virtual void Visit(Reference* value) { VisitItem(value); }
+  virtual void Visit(RawString* value) { VisitItem(value); }
+  virtual void Visit(String* value) { VisitItem(value); }
+  virtual void Visit(StyledString* value) { VisitItem(value); }
+  virtual void Visit(FileReference* value) { VisitItem(value); }
+  virtual void Visit(Id* value) { VisitItem(value); }
+  virtual void Visit(BinaryPrimitive* value) { VisitItem(value); }
 
-  virtual void visit(Attribute* value) {}
-  virtual void visit(Style* value) {}
-  virtual void visit(Array* value) {}
-  virtual void visit(Plural* value) {}
-  virtual void visit(Styleable* value) {}
+  virtual void Visit(Attribute* value) {}
+  virtual void Visit(Style* value) {}
+  virtual void Visit(Array* value) {}
+  virtual void Visit(Plural* value) {}
+  virtual void Visit(Styleable* value) {}
 };
 
 // NOLINT, do not add parentheses around T.
-#define DECL_VISIT_COMPOUND_VALUE(T)          \
-  virtual void visit(T* value) { /* NOLINT */ \
-    visitSubValues(value);                    \
+#define DECL_VISIT_COMPOUND_VALUE(T)                   \
+  virtual void Visit(T* value) override { /* NOLINT */ \
+    VisitSubValues(value);                             \
   }
 
 /**
@@ -59,44 +58,43 @@
 struct ValueVisitor : public RawValueVisitor {
   // The compiler will think we're hiding an overload, when we actually intend
   // to call into RawValueVisitor. This will expose the visit methods in the
-  // super
-  // class so the compiler knows we are trying to call them.
-  using RawValueVisitor::visit;
+  // super class so the compiler knows we are trying to call them.
+  using RawValueVisitor::Visit;
 
-  void visitSubValues(Attribute* attribute) {
+  void VisitSubValues(Attribute* attribute) {
     for (Attribute::Symbol& symbol : attribute->symbols) {
-      visit(&symbol.symbol);
+      Visit(&symbol.symbol);
     }
   }
 
-  void visitSubValues(Style* style) {
+  void VisitSubValues(Style* style) {
     if (style->parent) {
-      visit(&style->parent.value());
+      Visit(&style->parent.value());
     }
 
     for (Style::Entry& entry : style->entries) {
-      visit(&entry.key);
-      entry.value->accept(this);
+      Visit(&entry.key);
+      entry.value->Accept(this);
     }
   }
 
-  void visitSubValues(Array* array) {
+  void VisitSubValues(Array* array) {
     for (std::unique_ptr<Item>& item : array->items) {
-      item->accept(this);
+      item->Accept(this);
     }
   }
 
-  void visitSubValues(Plural* plural) {
+  void VisitSubValues(Plural* plural) {
     for (std::unique_ptr<Item>& item : plural->values) {
       if (item) {
-        item->accept(this);
+        item->Accept(this);
       }
     }
   }
 
-  void visitSubValues(Styleable* styleable) {
+  void VisitSubValues(Styleable* styleable) {
     for (Reference& reference : styleable->entries) {
-      visit(&reference);
+      Visit(&reference);
     }
   }
 
@@ -114,7 +112,7 @@
 struct DynCastVisitor : public RawValueVisitor {
   T* value = nullptr;
 
-  void visit(T* v) override { value = v; }
+  void Visit(T* v) override { value = v; }
 };
 
 /**
@@ -124,12 +122,12 @@
 struct DynCastVisitor<Item> : public RawValueVisitor {
   Item* value = nullptr;
 
-  void visitItem(Item* item) override { value = item; }
+  void VisitItem(Item* item) override { value = item; }
 };
 
 template <typename T>
-const T* valueCast(const Value* value) {
-  return valueCast<T>(const_cast<Value*>(value));
+const T* ValueCast(const Value* value) {
+  return ValueCast<T>(const_cast<Value*>(value));
 }
 
 /**
@@ -137,30 +135,30 @@
  * Otherwise, returns nullptr.
  */
 template <typename T>
-T* valueCast(Value* value) {
+T* ValueCast(Value* value) {
   if (!value) {
     return nullptr;
   }
   DynCastVisitor<T> visitor;
-  value->accept(&visitor);
+  value->Accept(&visitor);
   return visitor.value;
 }
 
-inline void visitAllValuesInPackage(ResourceTablePackage* pkg,
+inline void VisitAllValuesInPackage(ResourceTablePackage* pkg,
                                     RawValueVisitor* visitor) {
   for (auto& type : pkg->types) {
     for (auto& entry : type->entries) {
-      for (auto& configValue : entry->values) {
-        configValue->value->accept(visitor);
+      for (auto& config_value : entry->values) {
+        config_value->value->Accept(visitor);
       }
     }
   }
 }
 
-inline void visitAllValuesInTable(ResourceTable* table,
+inline void VisitAllValuesInTable(ResourceTable* table,
                                   RawValueVisitor* visitor) {
   for (auto& pkg : table->packages) {
-    visitAllValuesInPackage(pkg.get(), visitor);
+    VisitAllValuesInPackage(pkg.get(), visitor);
   }
 }
 
diff --git a/tools/aapt2/ValueVisitor_test.cpp b/tools/aapt2/ValueVisitor_test.cpp
index ed9c7f6..eb75b10 100644
--- a/tools/aapt2/ValueVisitor_test.cpp
+++ b/tools/aapt2/ValueVisitor_test.cpp
@@ -15,40 +15,41 @@
  */
 
 #include "ValueVisitor.h"
+
+#include <string>
+
 #include "ResourceValues.h"
 #include "test/Test.h"
 #include "util/Util.h"
 
-#include <string>
-
 namespace aapt {
 
 struct SingleReferenceVisitor : public ValueVisitor {
-  using ValueVisitor::visit;
+  using ValueVisitor::Visit;
 
   Reference* visited = nullptr;
 
-  void visit(Reference* ref) override { visited = ref; }
+  void Visit(Reference* ref) override { visited = ref; }
 };
 
 struct StyleVisitor : public ValueVisitor {
-  using ValueVisitor::visit;
+  using ValueVisitor::Visit;
 
-  std::list<Reference*> visitedRefs;
-  Style* visitedStyle = nullptr;
+  std::list<Reference*> visited_refs;
+  Style* visited_style = nullptr;
 
-  void visit(Reference* ref) override { visitedRefs.push_back(ref); }
+  void Visit(Reference* ref) override { visited_refs.push_back(ref); }
 
-  void visit(Style* style) override {
-    visitedStyle = style;
-    ValueVisitor::visit(style);
+  void Visit(Style* style) override {
+    visited_style = style;
+    ValueVisitor::Visit(style);
   }
 };
 
 TEST(ValueVisitorTest, VisitsReference) {
   Reference ref(ResourceName{"android", ResourceType::kAttr, "foo"});
   SingleReferenceVisitor visitor;
-  ref.accept(&visitor);
+  ref.Accept(&visitor);
 
   EXPECT_EQ(visitor.visited, &ref);
 }
@@ -56,31 +57,31 @@
 TEST(ValueVisitorTest, VisitsReferencesInStyle) {
   std::unique_ptr<Style> style =
       test::StyleBuilder()
-          .setParent("android:style/foo")
-          .addItem("android:attr/one", test::buildReference("android:id/foo"))
-          .build();
+          .SetParent("android:style/foo")
+          .AddItem("android:attr/one", test::BuildReference("android:id/foo"))
+          .Build();
 
   StyleVisitor visitor;
-  style->accept(&visitor);
+  style->Accept(&visitor);
 
-  ASSERT_EQ(style.get(), visitor.visitedStyle);
+  ASSERT_EQ(style.get(), visitor.visited_style);
 
   // Entry attribute references, plus the parent reference, plus one value
   // reference.
-  ASSERT_EQ(style->entries.size() + 2, visitor.visitedRefs.size());
+  ASSERT_EQ(style->entries.size() + 2, visitor.visited_refs.size());
 }
 
 TEST(ValueVisitorTest, ValueCast) {
-  std::unique_ptr<Reference> ref = test::buildReference("android:color/white");
-  EXPECT_NE(valueCast<Reference>(ref.get()), nullptr);
+  std::unique_ptr<Reference> ref = test::BuildReference("android:color/white");
+  EXPECT_NE(ValueCast<Reference>(ref.get()), nullptr);
 
   std::unique_ptr<Style> style =
       test::StyleBuilder()
-          .addItem("android:attr/foo",
-                   test::buildReference("android:color/black"))
-          .build();
-  EXPECT_NE(valueCast<Style>(style.get()), nullptr);
-  EXPECT_EQ(valueCast<Reference>(style.get()), nullptr);
+          .AddItem("android:attr/foo",
+                   test::BuildReference("android:color/black"))
+          .Build();
+  EXPECT_NE(ValueCast<Style>(style.get()), nullptr);
+  EXPECT_EQ(ValueCast<Reference>(style.get()), nullptr);
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/compile/Compile.cpp b/tools/aapt2/compile/Compile.cpp
index d001228..a06140c 100644
--- a/tools/aapt2/compile/Compile.cpp
+++ b/tools/aapt2/compile/Compile.cpp
@@ -14,6 +14,11 @@
  * limitations under the License.
  */
 
+#include <dirent.h>
+
+#include <fstream>
+#include <string>
+
 #include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "Flags.h"
@@ -33,14 +38,10 @@
 #include "xml/XmlDom.h"
 #include "xml/XmlPullParser.h"
 
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
-
-#include <android-base/errors.h>
-#include <android-base/file.h>
-#include <dirent.h>
-#include <fstream>
-#include <string>
+#include "android-base/errors.h"
+#include "android-base/file.h"
+#include "google/protobuf/io/coded_stream.h"
+#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
 
 using google::protobuf::io::CopyingOutputStreamAdaptor;
 using google::protobuf::io::ZeroCopyOutputStream;
@@ -49,7 +50,7 @@
 
 struct ResourcePathData {
   Source source;
-  std::string resourceDir;
+  std::string resource_dir;
   std::string name;
   std::string extension;
 
@@ -58,7 +59,7 @@
   // version qualifiers. We want to preserve the original input so the output is
   // easily
   // computed before hand.
-  std::string configStr;
+  std::string config_str;
   ConfigDescription config;
 };
 
@@ -66,60 +67,60 @@
  * Resource file paths are expected to look like:
  * [--/res/]type[-config]/name
  */
-static Maybe<ResourcePathData> extractResourcePathData(const std::string& path,
-                                                       std::string* outError) {
-  std::vector<std::string> parts = util::split(path, file::sDirSep);
+static Maybe<ResourcePathData> ExtractResourcePathData(const std::string& path,
+                                                       std::string* out_error) {
+  std::vector<std::string> parts = util::Split(path, file::sDirSep);
   if (parts.size() < 2) {
-    if (outError) *outError = "bad resource path";
+    if (out_error) *out_error = "bad resource path";
     return {};
   }
 
   std::string& dir = parts[parts.size() - 2];
-  StringPiece dirStr = dir;
+  StringPiece dir_str = dir;
 
-  StringPiece configStr;
+  StringPiece config_str;
   ConfigDescription config;
-  size_t dashPos = dir.find('-');
-  if (dashPos != std::string::npos) {
-    configStr = dirStr.substr(dashPos + 1, dir.size() - (dashPos + 1));
-    if (!ConfigDescription::parse(configStr, &config)) {
-      if (outError) {
-        std::stringstream errStr;
-        errStr << "invalid configuration '" << configStr << "'";
-        *outError = errStr.str();
+  size_t dash_pos = dir.find('-');
+  if (dash_pos != std::string::npos) {
+    config_str = dir_str.substr(dash_pos + 1, dir.size() - (dash_pos + 1));
+    if (!ConfigDescription::Parse(config_str, &config)) {
+      if (out_error) {
+        std::stringstream err_str;
+        err_str << "invalid configuration '" << config_str << "'";
+        *out_error = err_str.str();
       }
       return {};
     }
-    dirStr = dirStr.substr(0, dashPos);
+    dir_str = dir_str.substr(0, dash_pos);
   }
 
   std::string& filename = parts[parts.size() - 1];
   StringPiece name = filename;
   StringPiece extension;
-  size_t dotPos = filename.find('.');
-  if (dotPos != std::string::npos) {
-    extension = name.substr(dotPos + 1, filename.size() - (dotPos + 1));
-    name = name.substr(0, dotPos);
+  size_t dot_pos = filename.find('.');
+  if (dot_pos != std::string::npos) {
+    extension = name.substr(dot_pos + 1, filename.size() - (dot_pos + 1));
+    name = name.substr(0, dot_pos);
   }
 
-  return ResourcePathData{Source(path),         dirStr.toString(),
-                          name.toString(),      extension.toString(),
-                          configStr.toString(), config};
+  return ResourcePathData{Source(path),          dir_str.ToString(),
+                          name.ToString(),       extension.ToString(),
+                          config_str.ToString(), config};
 }
 
 struct CompileOptions {
-  std::string outputPath;
-  Maybe<std::string> resDir;
+  std::string output_path;
+  Maybe<std::string> res_dir;
   bool pseudolocalize = false;
-  bool legacyMode = false;
+  bool legacy_mode = false;
   bool verbose = false;
 };
 
-static std::string buildIntermediateFilename(const ResourcePathData& data) {
+static std::string BuildIntermediateFilename(const ResourcePathData& data) {
   std::stringstream name;
-  name << data.resourceDir;
-  if (!data.configStr.empty()) {
-    name << "-" << data.configStr;
+  name << data.resource_dir;
+  if (!data.config_str.empty()) {
+    name << "-" << data.config_str;
   }
   name << "_" << data.name;
   if (!data.extension.empty()) {
@@ -129,92 +130,93 @@
   return name.str();
 }
 
-static bool isHidden(const StringPiece& filename) {
-  return util::stringStartsWith(filename, ".");
+static bool IsHidden(const StringPiece& filename) {
+  return util::StartsWith(filename, ".");
 }
 
 /**
  * Walks the res directory structure, looking for resource files.
  */
-static bool loadInputFilesFromDir(IAaptContext* context,
-                                  const CompileOptions& options,
-                                  std::vector<ResourcePathData>* outPathData) {
-  const std::string& rootDir = options.resDir.value();
-  std::unique_ptr<DIR, decltype(closedir)*> d(opendir(rootDir.data()),
+static bool LoadInputFilesFromDir(
+    IAaptContext* context, const CompileOptions& options,
+    std::vector<ResourcePathData>* out_path_data) {
+  const std::string& root_dir = options.res_dir.value();
+  std::unique_ptr<DIR, decltype(closedir)*> d(opendir(root_dir.data()),
                                               closedir);
   if (!d) {
-    context->getDiagnostics()->error(DiagMessage() << strerror(errno));
+    context->GetDiagnostics()->Error(DiagMessage() << strerror(errno));
     return false;
   }
 
   while (struct dirent* entry = readdir(d.get())) {
-    if (isHidden(entry->d_name)) {
+    if (IsHidden(entry->d_name)) {
       continue;
     }
 
-    std::string prefixPath = rootDir;
-    file::appendPath(&prefixPath, entry->d_name);
+    std::string prefix_path = root_dir;
+    file::AppendPath(&prefix_path, entry->d_name);
 
-    if (file::getFileType(prefixPath) != file::FileType::kDirectory) {
+    if (file::GetFileType(prefix_path) != file::FileType::kDirectory) {
       continue;
     }
 
-    std::unique_ptr<DIR, decltype(closedir)*> subDir(opendir(prefixPath.data()),
-                                                     closedir);
-    if (!subDir) {
-      context->getDiagnostics()->error(DiagMessage() << strerror(errno));
+    std::unique_ptr<DIR, decltype(closedir)*> subdir(
+        opendir(prefix_path.data()), closedir);
+    if (!subdir) {
+      context->GetDiagnostics()->Error(DiagMessage() << strerror(errno));
       return false;
     }
 
-    while (struct dirent* leafEntry = readdir(subDir.get())) {
-      if (isHidden(leafEntry->d_name)) {
+    while (struct dirent* leaf_entry = readdir(subdir.get())) {
+      if (IsHidden(leaf_entry->d_name)) {
         continue;
       }
 
-      std::string fullPath = prefixPath;
-      file::appendPath(&fullPath, leafEntry->d_name);
+      std::string full_path = prefix_path;
+      file::AppendPath(&full_path, leaf_entry->d_name);
 
-      std::string errStr;
-      Maybe<ResourcePathData> pathData =
-          extractResourcePathData(fullPath, &errStr);
-      if (!pathData) {
-        context->getDiagnostics()->error(DiagMessage() << errStr);
+      std::string err_str;
+      Maybe<ResourcePathData> path_data =
+          ExtractResourcePathData(full_path, &err_str);
+      if (!path_data) {
+        context->GetDiagnostics()->Error(DiagMessage() << err_str);
         return false;
       }
 
-      outPathData->push_back(std::move(pathData.value()));
+      out_path_data->push_back(std::move(path_data.value()));
     }
   }
   return true;
 }
 
-static bool compileTable(IAaptContext* context, const CompileOptions& options,
-                         const ResourcePathData& pathData,
+static bool CompileTable(IAaptContext* context, const CompileOptions& options,
+                         const ResourcePathData& path_data,
                          IArchiveWriter* writer,
-                         const std::string& outputPath) {
+                         const std::string& output_path) {
   ResourceTable table;
   {
-    std::ifstream fin(pathData.source.path, std::ifstream::binary);
+    std::ifstream fin(path_data.source.path, std::ifstream::binary);
     if (!fin) {
-      context->getDiagnostics()->error(DiagMessage(pathData.source)
+      context->GetDiagnostics()->Error(DiagMessage(path_data.source)
                                        << strerror(errno));
       return false;
     }
 
     // Parse the values file from XML.
-    xml::XmlPullParser xmlParser(fin);
+    xml::XmlPullParser xml_parser(fin);
 
-    ResourceParserOptions parserOptions;
-    parserOptions.errorOnPositionalArguments = !options.legacyMode;
+    ResourceParserOptions parser_options;
+    parser_options.error_on_positional_arguments = !options.legacy_mode;
 
     // If the filename includes donottranslate, then the default translatable is
     // false.
-    parserOptions.translatable =
-        pathData.name.find("donottranslate") == std::string::npos;
+    parser_options.translatable =
+        path_data.name.find("donottranslate") == std::string::npos;
 
-    ResourceParser resParser(context->getDiagnostics(), &table, pathData.source,
-                             pathData.config, parserOptions);
-    if (!resParser.parse(&xmlParser)) {
+    ResourceParser res_parser(context->GetDiagnostics(), &table,
+                              path_data.source, path_data.config,
+                              parser_options);
+    if (!res_parser.Parse(&xml_parser)) {
       return false;
     }
 
@@ -226,242 +228,241 @@
     // These are created as weak symbols, and are only generated from default
     // configuration
     // strings and plurals.
-    PseudolocaleGenerator pseudolocaleGenerator;
-    if (!pseudolocaleGenerator.consume(context, &table)) {
+    PseudolocaleGenerator pseudolocale_generator;
+    if (!pseudolocale_generator.Consume(context, &table)) {
       return false;
     }
   }
 
   // Ensure we have the compilation package at least.
-  table.createPackage(context->getCompilationPackage());
+  table.CreatePackage(context->GetCompilationPackage());
 
   // Assign an ID to any package that has resources.
   for (auto& pkg : table.packages) {
     if (!pkg->id) {
       // If no package ID was set while parsing (public identifiers), auto
       // assign an ID.
-      pkg->id = context->getPackageId();
+      pkg->id = context->GetPackageId();
     }
   }
 
   // Create the file/zip entry.
-  if (!writer->startEntry(outputPath, 0)) {
-    context->getDiagnostics()->error(DiagMessage(outputPath)
+  if (!writer->StartEntry(output_path, 0)) {
+    context->GetDiagnostics()->Error(DiagMessage(output_path)
                                      << "failed to open");
     return false;
   }
 
   // Make sure CopyingOutputStreamAdaptor is deleted before we call
-  // writer->finishEntry().
+  // writer->FinishEntry().
   {
     // Wrap our IArchiveWriter with an adaptor that implements the
     // ZeroCopyOutputStream
     // interface.
-    CopyingOutputStreamAdaptor copyingAdaptor(writer);
+    CopyingOutputStreamAdaptor copying_adaptor(writer);
 
-    std::unique_ptr<pb::ResourceTable> pbTable = serializeTableToPb(&table);
-    if (!pbTable->SerializeToZeroCopyStream(&copyingAdaptor)) {
-      context->getDiagnostics()->error(DiagMessage(outputPath)
+    std::unique_ptr<pb::ResourceTable> pb_table = SerializeTableToPb(&table);
+    if (!pb_table->SerializeToZeroCopyStream(&copying_adaptor)) {
+      context->GetDiagnostics()->Error(DiagMessage(output_path)
                                        << "failed to write");
       return false;
     }
   }
 
-  if (!writer->finishEntry()) {
-    context->getDiagnostics()->error(DiagMessage(outputPath)
+  if (!writer->FinishEntry()) {
+    context->GetDiagnostics()->Error(DiagMessage(output_path)
                                      << "failed to finish entry");
     return false;
   }
   return true;
 }
 
-static bool writeHeaderAndBufferToWriter(const StringPiece& outputPath,
+static bool WriteHeaderAndBufferToWriter(const StringPiece& output_path,
                                          const ResourceFile& file,
                                          const BigBuffer& buffer,
                                          IArchiveWriter* writer,
                                          IDiagnostics* diag) {
   // Start the entry so we can write the header.
-  if (!writer->startEntry(outputPath, 0)) {
-    diag->error(DiagMessage(outputPath) << "failed to open file");
+  if (!writer->StartEntry(output_path, 0)) {
+    diag->Error(DiagMessage(output_path) << "failed to open file");
     return false;
   }
 
   // Make sure CopyingOutputStreamAdaptor is deleted before we call
-  // writer->finishEntry().
+  // writer->FinishEntry().
   {
     // Wrap our IArchiveWriter with an adaptor that implements the
     // ZeroCopyOutputStream
     // interface.
-    CopyingOutputStreamAdaptor copyingAdaptor(writer);
-    CompiledFileOutputStream outputStream(&copyingAdaptor);
+    CopyingOutputStreamAdaptor copying_adaptor(writer);
+    CompiledFileOutputStream output_stream(&copying_adaptor);
 
     // Number of CompiledFiles.
-    outputStream.WriteLittleEndian32(1);
+    output_stream.WriteLittleEndian32(1);
 
-    std::unique_ptr<pb::CompiledFile> compiledFile =
-        serializeCompiledFileToPb(file);
-    outputStream.WriteCompiledFile(compiledFile.get());
-    outputStream.WriteData(&buffer);
+    std::unique_ptr<pb::CompiledFile> compiled_file =
+        SerializeCompiledFileToPb(file);
+    output_stream.WriteCompiledFile(compiled_file.get());
+    output_stream.WriteData(&buffer);
 
-    if (outputStream.HadError()) {
-      diag->error(DiagMessage(outputPath) << "failed to write data");
+    if (output_stream.HadError()) {
+      diag->Error(DiagMessage(output_path) << "failed to write data");
       return false;
     }
   }
 
-  if (!writer->finishEntry()) {
-    diag->error(DiagMessage(outputPath) << "failed to finish writing data");
+  if (!writer->FinishEntry()) {
+    diag->Error(DiagMessage(output_path) << "failed to finish writing data");
     return false;
   }
   return true;
 }
 
-static bool writeHeaderAndMmapToWriter(const StringPiece& outputPath,
+static bool WriteHeaderAndMmapToWriter(const StringPiece& output_path,
                                        const ResourceFile& file,
                                        const android::FileMap& map,
                                        IArchiveWriter* writer,
                                        IDiagnostics* diag) {
   // Start the entry so we can write the header.
-  if (!writer->startEntry(outputPath, 0)) {
-    diag->error(DiagMessage(outputPath) << "failed to open file");
+  if (!writer->StartEntry(output_path, 0)) {
+    diag->Error(DiagMessage(output_path) << "failed to open file");
     return false;
   }
 
   // Make sure CopyingOutputStreamAdaptor is deleted before we call
-  // writer->finishEntry().
+  // writer->FinishEntry().
   {
     // Wrap our IArchiveWriter with an adaptor that implements the
-    // ZeroCopyOutputStream
-    // interface.
-    CopyingOutputStreamAdaptor copyingAdaptor(writer);
-    CompiledFileOutputStream outputStream(&copyingAdaptor);
+    // ZeroCopyOutputStream interface.
+    CopyingOutputStreamAdaptor copying_adaptor(writer);
+    CompiledFileOutputStream output_stream(&copying_adaptor);
 
     // Number of CompiledFiles.
-    outputStream.WriteLittleEndian32(1);
+    output_stream.WriteLittleEndian32(1);
 
-    std::unique_ptr<pb::CompiledFile> compiledFile =
-        serializeCompiledFileToPb(file);
-    outputStream.WriteCompiledFile(compiledFile.get());
-    outputStream.WriteData(map.getDataPtr(), map.getDataLength());
+    std::unique_ptr<pb::CompiledFile> compiled_file =
+        SerializeCompiledFileToPb(file);
+    output_stream.WriteCompiledFile(compiled_file.get());
+    output_stream.WriteData(map.getDataPtr(), map.getDataLength());
 
-    if (outputStream.HadError()) {
-      diag->error(DiagMessage(outputPath) << "failed to write data");
+    if (output_stream.HadError()) {
+      diag->Error(DiagMessage(output_path) << "failed to write data");
       return false;
     }
   }
 
-  if (!writer->finishEntry()) {
-    diag->error(DiagMessage(outputPath) << "failed to finish writing data");
+  if (!writer->FinishEntry()) {
+    diag->Error(DiagMessage(output_path) << "failed to finish writing data");
     return false;
   }
   return true;
 }
 
-static bool flattenXmlToOutStream(IAaptContext* context,
-                                  const StringPiece& outputPath,
-                                  xml::XmlResource* xmlRes,
+static bool FlattenXmlToOutStream(IAaptContext* context,
+                                  const StringPiece& output_path,
+                                  xml::XmlResource* xmlres,
                                   CompiledFileOutputStream* out) {
   BigBuffer buffer(1024);
-  XmlFlattenerOptions xmlFlattenerOptions;
-  xmlFlattenerOptions.keepRawValues = true;
-  XmlFlattener flattener(&buffer, xmlFlattenerOptions);
-  if (!flattener.consume(context, xmlRes)) {
+  XmlFlattenerOptions xml_flattener_options;
+  xml_flattener_options.keep_raw_values = true;
+  XmlFlattener flattener(&buffer, xml_flattener_options);
+  if (!flattener.Consume(context, xmlres)) {
     return false;
   }
 
-  std::unique_ptr<pb::CompiledFile> pbCompiledFile =
-      serializeCompiledFileToPb(xmlRes->file);
-  out->WriteCompiledFile(pbCompiledFile.get());
+  std::unique_ptr<pb::CompiledFile> pb_compiled_file =
+      SerializeCompiledFileToPb(xmlres->file);
+  out->WriteCompiledFile(pb_compiled_file.get());
   out->WriteData(&buffer);
 
   if (out->HadError()) {
-    context->getDiagnostics()->error(DiagMessage(outputPath)
+    context->GetDiagnostics()->Error(DiagMessage(output_path)
                                      << "failed to write data");
     return false;
   }
   return true;
 }
 
-static bool compileXml(IAaptContext* context, const CompileOptions& options,
-                       const ResourcePathData& pathData, IArchiveWriter* writer,
-                       const std::string& outputPath) {
-  if (context->verbose()) {
-    context->getDiagnostics()->note(DiagMessage(pathData.source)
+static bool CompileXml(IAaptContext* context, const CompileOptions& options,
+                       const ResourcePathData& path_data,
+                       IArchiveWriter* writer, const std::string& output_path) {
+  if (context->IsVerbose()) {
+    context->GetDiagnostics()->Note(DiagMessage(path_data.source)
                                     << "compiling XML");
   }
 
-  std::unique_ptr<xml::XmlResource> xmlRes;
+  std::unique_ptr<xml::XmlResource> xmlres;
   {
-    std::ifstream fin(pathData.source.path, std::ifstream::binary);
+    std::ifstream fin(path_data.source.path, std::ifstream::binary);
     if (!fin) {
-      context->getDiagnostics()->error(DiagMessage(pathData.source)
+      context->GetDiagnostics()->Error(DiagMessage(path_data.source)
                                        << strerror(errno));
       return false;
     }
 
-    xmlRes = xml::inflate(&fin, context->getDiagnostics(), pathData.source);
+    xmlres = xml::Inflate(&fin, context->GetDiagnostics(), path_data.source);
 
     fin.close();
   }
 
-  if (!xmlRes) {
+  if (!xmlres) {
     return false;
   }
 
-  xmlRes->file.name =
-      ResourceName({}, *parseResourceType(pathData.resourceDir), pathData.name);
-  xmlRes->file.config = pathData.config;
-  xmlRes->file.source = pathData.source;
+  xmlres->file.name = ResourceName(
+      {}, *ParseResourceType(path_data.resource_dir), path_data.name);
+  xmlres->file.config = path_data.config;
+  xmlres->file.source = path_data.source;
 
   // Collect IDs that are defined here.
   XmlIdCollector collector;
-  if (!collector.consume(context, xmlRes.get())) {
+  if (!collector.Consume(context, xmlres.get())) {
     return false;
   }
 
   // Look for and process any <aapt:attr> tags and create sub-documents.
-  InlineXmlFormatParser inlineXmlFormatParser;
-  if (!inlineXmlFormatParser.consume(context, xmlRes.get())) {
+  InlineXmlFormatParser inline_xml_format_parser;
+  if (!inline_xml_format_parser.Consume(context, xmlres.get())) {
     return false;
   }
 
   // Start the entry so we can write the header.
-  if (!writer->startEntry(outputPath, 0)) {
-    context->getDiagnostics()->error(DiagMessage(outputPath)
+  if (!writer->StartEntry(output_path, 0)) {
+    context->GetDiagnostics()->Error(DiagMessage(output_path)
                                      << "failed to open file");
     return false;
   }
 
   // Make sure CopyingOutputStreamAdaptor is deleted before we call
-  // writer->finishEntry().
+  // writer->FinishEntry().
   {
     // Wrap our IArchiveWriter with an adaptor that implements the
     // ZeroCopyOutputStream
     // interface.
-    CopyingOutputStreamAdaptor copyingAdaptor(writer);
-    CompiledFileOutputStream outputStream(&copyingAdaptor);
+    CopyingOutputStreamAdaptor copying_adaptor(writer);
+    CompiledFileOutputStream output_stream(&copying_adaptor);
 
-    std::vector<std::unique_ptr<xml::XmlResource>>& inlineDocuments =
-        inlineXmlFormatParser.getExtractedInlineXmlDocuments();
+    std::vector<std::unique_ptr<xml::XmlResource>>& inline_documents =
+        inline_xml_format_parser.GetExtractedInlineXmlDocuments();
 
     // Number of CompiledFiles.
-    outputStream.WriteLittleEndian32(1 + inlineDocuments.size());
+    output_stream.WriteLittleEndian32(1 + inline_documents.size());
 
-    if (!flattenXmlToOutStream(context, outputPath, xmlRes.get(),
-                               &outputStream)) {
+    if (!FlattenXmlToOutStream(context, output_path, xmlres.get(),
+                               &output_stream)) {
       return false;
     }
 
-    for (auto& inlineXmlDoc : inlineDocuments) {
-      if (!flattenXmlToOutStream(context, outputPath, inlineXmlDoc.get(),
-                                 &outputStream)) {
+    for (auto& inline_xml_doc : inline_documents) {
+      if (!FlattenXmlToOutStream(context, output_path, inline_xml_doc.get(),
+                                 &output_stream)) {
         return false;
       }
     }
   }
 
-  if (!writer->finishEntry()) {
-    context->getDiagnostics()->error(DiagMessage(outputPath)
+  if (!writer->FinishEntry()) {
+    context->GetDiagnostics()->Error(DiagMessage(output_path)
                                      << "failed to finish writing data");
     return false;
   }
@@ -470,69 +471,69 @@
 
 class BigBufferOutputStream : public io::OutputStream {
  public:
-  explicit BigBufferOutputStream(BigBuffer* buffer) : mBuffer(buffer) {}
+  explicit BigBufferOutputStream(BigBuffer* buffer) : buffer_(buffer) {}
 
   bool Next(void** data, int* len) override {
     size_t count;
-    *data = mBuffer->nextBlock(&count);
+    *data = buffer_->NextBlock(&count);
     *len = static_cast<int>(count);
     return true;
   }
 
-  void BackUp(int count) override { mBuffer->backUp(count); }
+  void BackUp(int count) override { buffer_->BackUp(count); }
 
-  int64_t ByteCount() const override { return mBuffer->size(); }
+  int64_t ByteCount() const override { return buffer_->size(); }
 
   bool HadError() const override { return false; }
 
  private:
-  BigBuffer* mBuffer;
+  BigBuffer* buffer_;
 
   DISALLOW_COPY_AND_ASSIGN(BigBufferOutputStream);
 };
 
-static bool compilePng(IAaptContext* context, const CompileOptions& options,
-                       const ResourcePathData& pathData, IArchiveWriter* writer,
-                       const std::string& outputPath) {
-  if (context->verbose()) {
-    context->getDiagnostics()->note(DiagMessage(pathData.source)
+static bool CompilePng(IAaptContext* context, const CompileOptions& options,
+                       const ResourcePathData& path_data,
+                       IArchiveWriter* writer, const std::string& output_path) {
+  if (context->IsVerbose()) {
+    context->GetDiagnostics()->Note(DiagMessage(path_data.source)
                                     << "compiling PNG");
   }
 
   BigBuffer buffer(4096);
-  ResourceFile resFile;
-  resFile.name =
-      ResourceName({}, *parseResourceType(pathData.resourceDir), pathData.name);
-  resFile.config = pathData.config;
-  resFile.source = pathData.source;
+  ResourceFile res_file;
+  res_file.name = ResourceName({}, *ParseResourceType(path_data.resource_dir),
+                               path_data.name);
+  res_file.config = path_data.config;
+  res_file.source = path_data.source;
 
   {
     std::string content;
-    if (!android::base::ReadFileToString(pathData.source.path, &content)) {
-      context->getDiagnostics()->error(
-          DiagMessage(pathData.source)
+    if (!android::base::ReadFileToString(path_data.source.path, &content)) {
+      context->GetDiagnostics()->Error(
+          DiagMessage(path_data.source)
           << android::base::SystemErrorCodeToString(errno));
       return false;
     }
 
-    BigBuffer crunchedPngBuffer(4096);
-    BigBufferOutputStream crunchedPngBufferOut(&crunchedPngBuffer);
+    BigBuffer crunched_png_buffer(4096);
+    BigBufferOutputStream crunched_png_buffer_out(&crunched_png_buffer);
 
     // Ensure that we only keep the chunks we care about if we end up
     // using the original PNG instead of the crunched one.
-    PngChunkFilter pngChunkFilter(content);
-    std::unique_ptr<Image> image = readPng(context, &pngChunkFilter);
+    PngChunkFilter png_chunk_filter(content);
+    std::unique_ptr<Image> image = ReadPng(context, &png_chunk_filter);
     if (!image) {
       return false;
     }
 
-    std::unique_ptr<NinePatch> ninePatch;
-    if (pathData.extension == "9.png") {
+    std::unique_ptr<NinePatch> nine_patch;
+    if (path_data.extension == "9.png") {
       std::string err;
-      ninePatch = NinePatch::create(image->rows.get(), image->width,
-                                    image->height, &err);
-      if (!ninePatch) {
-        context->getDiagnostics()->error(DiagMessage() << err);
+      nine_patch = NinePatch::Create(image->rows.get(), image->width,
+                                     image->height, &err);
+      if (!nine_patch) {
+        context->GetDiagnostics()->Error(DiagMessage() << err);
         return false;
       }
 
@@ -549,89 +550,91 @@
         memmove(image->rows[h], image->rows[h] + 4, image->width * 4);
       }
 
-      if (context->verbose()) {
-        context->getDiagnostics()->note(DiagMessage(pathData.source)
-                                        << "9-patch: " << *ninePatch);
+      if (context->IsVerbose()) {
+        context->GetDiagnostics()->Note(DiagMessage(path_data.source)
+                                        << "9-patch: " << *nine_patch);
       }
     }
 
     // Write the crunched PNG.
-    if (!writePng(context, image.get(), ninePatch.get(), &crunchedPngBufferOut,
-                  {})) {
+    if (!WritePng(context, image.get(), nine_patch.get(),
+                  &crunched_png_buffer_out, {})) {
       return false;
     }
 
-    if (ninePatch != nullptr ||
-        crunchedPngBufferOut.ByteCount() <= pngChunkFilter.ByteCount()) {
+    if (nine_patch != nullptr ||
+        crunched_png_buffer_out.ByteCount() <= png_chunk_filter.ByteCount()) {
       // No matter what, we must use the re-encoded PNG, even if it is larger.
       // 9-patch images must be re-encoded since their borders are stripped.
-      buffer.appendBuffer(std::move(crunchedPngBuffer));
+      buffer.AppendBuffer(std::move(crunched_png_buffer));
     } else {
       // The re-encoded PNG is larger than the original, and there is
       // no mandatory transformation. Use the original.
-      if (context->verbose()) {
-        context->getDiagnostics()->note(
-            DiagMessage(pathData.source)
+      if (context->IsVerbose()) {
+        context->GetDiagnostics()->Note(
+            DiagMessage(path_data.source)
             << "original PNG is smaller than crunched PNG"
             << ", using original");
       }
 
-      PngChunkFilter pngChunkFilterAgain(content);
-      BigBuffer filteredPngBuffer(4096);
-      BigBufferOutputStream filteredPngBufferOut(&filteredPngBuffer);
-      io::copy(&filteredPngBufferOut, &pngChunkFilterAgain);
-      buffer.appendBuffer(std::move(filteredPngBuffer));
+      PngChunkFilter png_chunk_filter_again(content);
+      BigBuffer filtered_png_buffer(4096);
+      BigBufferOutputStream filtered_png_buffer_out(&filtered_png_buffer);
+      io::Copy(&filtered_png_buffer_out, &png_chunk_filter_again);
+      buffer.AppendBuffer(std::move(filtered_png_buffer));
     }
 
-    if (context->verbose()) {
+    if (context->IsVerbose()) {
       // For debugging only, use the legacy PNG cruncher and compare the
       // resulting file sizes.
       // This will help catch exotic cases where the new code may generate
       // larger PNGs.
-      std::stringstream legacyStream(content);
-      BigBuffer legacyBuffer(4096);
-      Png png(context->getDiagnostics());
-      if (!png.process(pathData.source, &legacyStream, &legacyBuffer, {})) {
+      std::stringstream legacy_stream(content);
+      BigBuffer legacy_buffer(4096);
+      Png png(context->GetDiagnostics());
+      if (!png.process(path_data.source, &legacy_stream, &legacy_buffer, {})) {
         return false;
       }
 
-      context->getDiagnostics()->note(DiagMessage(pathData.source)
-                                      << "legacy=" << legacyBuffer.size()
+      context->GetDiagnostics()->Note(DiagMessage(path_data.source)
+                                      << "legacy=" << legacy_buffer.size()
                                       << " new=" << buffer.size());
     }
   }
 
-  if (!writeHeaderAndBufferToWriter(outputPath, resFile, buffer, writer,
-                                    context->getDiagnostics())) {
+  if (!WriteHeaderAndBufferToWriter(output_path, res_file, buffer, writer,
+                                    context->GetDiagnostics())) {
     return false;
   }
   return true;
 }
 
-static bool compileFile(IAaptContext* context, const CompileOptions& options,
-                        const ResourcePathData& pathData,
-                        IArchiveWriter* writer, const std::string& outputPath) {
-  if (context->verbose()) {
-    context->getDiagnostics()->note(DiagMessage(pathData.source)
+static bool CompileFile(IAaptContext* context, const CompileOptions& options,
+                        const ResourcePathData& path_data,
+                        IArchiveWriter* writer,
+                        const std::string& output_path) {
+  if (context->IsVerbose()) {
+    context->GetDiagnostics()->Note(DiagMessage(path_data.source)
                                     << "compiling file");
   }
 
   BigBuffer buffer(256);
-  ResourceFile resFile;
-  resFile.name =
-      ResourceName({}, *parseResourceType(pathData.resourceDir), pathData.name);
-  resFile.config = pathData.config;
-  resFile.source = pathData.source;
+  ResourceFile res_file;
+  res_file.name = ResourceName({}, *ParseResourceType(path_data.resource_dir),
+                               path_data.name);
+  res_file.config = path_data.config;
+  res_file.source = path_data.source;
 
-  std::string errorStr;
-  Maybe<android::FileMap> f = file::mmapPath(pathData.source.path, &errorStr);
+  std::string error_str;
+  Maybe<android::FileMap> f = file::MmapPath(path_data.source.path, &error_str);
   if (!f) {
-    context->getDiagnostics()->error(DiagMessage(pathData.source) << errorStr);
+    context->GetDiagnostics()->Error(DiagMessage(path_data.source)
+                                     << error_str);
     return false;
   }
 
-  if (!writeHeaderAndMmapToWriter(outputPath, resFile, f.value(), writer,
-                                  context->getDiagnostics())) {
+  if (!WriteHeaderAndMmapToWriter(output_path, res_file, f.value(), writer,
+                                  context->GetDiagnostics())) {
     return false;
   }
   return true;
@@ -639,155 +642,156 @@
 
 class CompileContext : public IAaptContext {
  public:
-  void setVerbose(bool val) { mVerbose = val; }
+  void SetVerbose(bool val) { verbose_ = val; }
 
-  bool verbose() override { return mVerbose; }
+  bool IsVerbose() override { return verbose_; }
 
-  IDiagnostics* getDiagnostics() override { return &mDiagnostics; }
+  IDiagnostics* GetDiagnostics() override { return &diagnostics_; }
 
-  NameMangler* getNameMangler() override {
+  NameMangler* GetNameMangler() override {
     abort();
     return nullptr;
   }
 
-  const std::string& getCompilationPackage() override {
+  const std::string& GetCompilationPackage() override {
     static std::string empty;
     return empty;
   }
 
-  uint8_t getPackageId() override { return 0x0; }
+  uint8_t GetPackageId() override { return 0x0; }
 
-  SymbolTable* getExternalSymbols() override {
+  SymbolTable* GetExternalSymbols() override {
     abort();
     return nullptr;
   }
 
-  int getMinSdkVersion() override { return 0; }
+  int GetMinSdkVersion() override { return 0; }
 
  private:
-  StdErrDiagnostics mDiagnostics;
-  bool mVerbose = false;
+  StdErrDiagnostics diagnostics_;
+  bool verbose_ = false;
 };
 
 /**
  * Entry point for compilation phase. Parses arguments and dispatches to the
  * correct steps.
  */
-int compile(const std::vector<StringPiece>& args) {
+int Compile(const std::vector<StringPiece>& args) {
   CompileContext context;
   CompileOptions options;
 
   bool verbose = false;
   Flags flags =
       Flags()
-          .requiredFlag("-o", "Output path", &options.outputPath)
-          .optionalFlag("--dir", "Directory to scan for resources",
-                        &options.resDir)
-          .optionalSwitch("--pseudo-localize",
+          .RequiredFlag("-o", "Output path", &options.output_path)
+          .OptionalFlag("--dir", "Directory to scan for resources",
+                        &options.res_dir)
+          .OptionalSwitch("--pseudo-localize",
                           "Generate resources for pseudo-locales "
                           "(en-XA and ar-XB)",
                           &options.pseudolocalize)
-          .optionalSwitch(
+          .OptionalSwitch(
               "--legacy",
               "Treat errors that used to be valid in AAPT as warnings",
-              &options.legacyMode)
-          .optionalSwitch("-v", "Enables verbose logging", &verbose);
-  if (!flags.parse("aapt2 compile", args, &std::cerr)) {
+              &options.legacy_mode)
+          .OptionalSwitch("-v", "Enables verbose logging", &verbose);
+  if (!flags.Parse("aapt2 compile", args, &std::cerr)) {
     return 1;
   }
 
-  context.setVerbose(verbose);
+  context.SetVerbose(verbose);
 
-  std::unique_ptr<IArchiveWriter> archiveWriter;
+  std::unique_ptr<IArchiveWriter> archive_writer;
 
-  std::vector<ResourcePathData> inputData;
-  if (options.resDir) {
-    if (!flags.getArgs().empty()) {
+  std::vector<ResourcePathData> input_data;
+  if (options.res_dir) {
+    if (!flags.GetArgs().empty()) {
       // Can't have both files and a resource directory.
-      context.getDiagnostics()->error(DiagMessage()
+      context.GetDiagnostics()->Error(DiagMessage()
                                       << "files given but --dir specified");
-      flags.usage("aapt2 compile", &std::cerr);
+      flags.Usage("aapt2 compile", &std::cerr);
       return 1;
     }
 
-    if (!loadInputFilesFromDir(&context, options, &inputData)) {
+    if (!LoadInputFilesFromDir(&context, options, &input_data)) {
       return 1;
     }
 
-    archiveWriter = createZipFileArchiveWriter(context.getDiagnostics(),
-                                               options.outputPath);
+    archive_writer = CreateZipFileArchiveWriter(context.GetDiagnostics(),
+                                                options.output_path);
 
   } else {
-    inputData.reserve(flags.getArgs().size());
+    input_data.reserve(flags.GetArgs().size());
 
     // Collect data from the path for each input file.
-    for (const std::string& arg : flags.getArgs()) {
-      std::string errorStr;
-      if (Maybe<ResourcePathData> pathData =
-              extractResourcePathData(arg, &errorStr)) {
-        inputData.push_back(std::move(pathData.value()));
+    for (const std::string& arg : flags.GetArgs()) {
+      std::string error_str;
+      if (Maybe<ResourcePathData> path_data =
+              ExtractResourcePathData(arg, &error_str)) {
+        input_data.push_back(std::move(path_data.value()));
       } else {
-        context.getDiagnostics()->error(DiagMessage() << errorStr << " (" << arg
-                                                      << ")");
+        context.GetDiagnostics()->Error(DiagMessage() << error_str << " ("
+                                                      << arg << ")");
         return 1;
       }
     }
 
-    archiveWriter = createDirectoryArchiveWriter(context.getDiagnostics(),
-                                                 options.outputPath);
+    archive_writer = CreateDirectoryArchiveWriter(context.GetDiagnostics(),
+                                                  options.output_path);
   }
 
-  if (!archiveWriter) {
-    return false;
+  if (!archive_writer) {
+    return 1;
   }
 
   bool error = false;
-  for (ResourcePathData& pathData : inputData) {
+  for (ResourcePathData& path_data : input_data) {
     if (options.verbose) {
-      context.getDiagnostics()->note(DiagMessage(pathData.source)
+      context.GetDiagnostics()->Note(DiagMessage(path_data.source)
                                      << "processing");
     }
 
-    if (pathData.resourceDir == "values") {
+    if (path_data.resource_dir == "values") {
       // Overwrite the extension.
-      pathData.extension = "arsc";
+      path_data.extension = "arsc";
 
-      const std::string outputFilename = buildIntermediateFilename(pathData);
-      if (!compileTable(&context, options, pathData, archiveWriter.get(),
-                        outputFilename)) {
+      const std::string output_filename = BuildIntermediateFilename(path_data);
+      if (!CompileTable(&context, options, path_data, archive_writer.get(),
+                        output_filename)) {
         error = true;
       }
 
     } else {
-      const std::string outputFilename = buildIntermediateFilename(pathData);
-      if (const ResourceType* type = parseResourceType(pathData.resourceDir)) {
+      const std::string output_filename = BuildIntermediateFilename(path_data);
+      if (const ResourceType* type =
+              ParseResourceType(path_data.resource_dir)) {
         if (*type != ResourceType::kRaw) {
-          if (pathData.extension == "xml") {
-            if (!compileXml(&context, options, pathData, archiveWriter.get(),
-                            outputFilename)) {
+          if (path_data.extension == "xml") {
+            if (!CompileXml(&context, options, path_data, archive_writer.get(),
+                            output_filename)) {
               error = true;
             }
-          } else if (pathData.extension == "png" ||
-                     pathData.extension == "9.png") {
-            if (!compilePng(&context, options, pathData, archiveWriter.get(),
-                            outputFilename)) {
+          } else if (path_data.extension == "png" ||
+                     path_data.extension == "9.png") {
+            if (!CompilePng(&context, options, path_data, archive_writer.get(),
+                            output_filename)) {
               error = true;
             }
           } else {
-            if (!compileFile(&context, options, pathData, archiveWriter.get(),
-                             outputFilename)) {
+            if (!CompileFile(&context, options, path_data, archive_writer.get(),
+                             output_filename)) {
               error = true;
             }
           }
         } else {
-          if (!compileFile(&context, options, pathData, archiveWriter.get(),
-                           outputFilename)) {
+          if (!CompileFile(&context, options, path_data, archive_writer.get(),
+                           output_filename)) {
             error = true;
           }
         }
       } else {
-        context.getDiagnostics()->error(
-            DiagMessage() << "invalid file path '" << pathData.source << "'");
+        context.GetDiagnostics()->Error(
+            DiagMessage() << "invalid file path '" << path_data.source << "'");
         error = true;
       }
     }
diff --git a/tools/aapt2/compile/IdAssigner.cpp b/tools/aapt2/compile/IdAssigner.cpp
index 73eb066..17c22c5 100644
--- a/tools/aapt2/compile/IdAssigner.cpp
+++ b/tools/aapt2/compile/IdAssigner.cpp
@@ -15,13 +15,15 @@
  */
 
 #include "compile/IdAssigner.h"
+
+#include <map>
+
+#include "android-base/logging.h"
+
 #include "ResourceTable.h"
 #include "process/IResourceTableConsumer.h"
 #include "util/Util.h"
 
-#include <cassert>
-#include <map>
-
 namespace aapt {
 
 /**
@@ -29,44 +31,44 @@
  * ResourceEntry,
  * as long as there is no existing ID or the ID is the same.
  */
-static bool assignId(IDiagnostics* diag, const ResourceId& id,
+static bool AssignId(IDiagnostics* diag, const ResourceId& id,
                      const ResourceName& name, ResourceTablePackage* pkg,
                      ResourceTableType* type, ResourceEntry* entry) {
-  if (pkg->id.value() == id.packageId()) {
-    if (!type->id || type->id.value() == id.typeId()) {
-      type->id = id.typeId();
+  if (pkg->id.value() == id.package_id()) {
+    if (!type->id || type->id.value() == id.type_id()) {
+      type->id = id.type_id();
 
-      if (!entry->id || entry->id.value() == id.entryId()) {
-        entry->id = id.entryId();
+      if (!entry->id || entry->id.value() == id.entry_id()) {
+        entry->id = id.entry_id();
         return true;
       }
     }
   }
 
-  const ResourceId existingId(pkg->id.value(), type->id ? type->id.value() : 0,
-                              entry->id ? entry->id.value() : 0);
-  diag->error(DiagMessage() << "can't assign ID " << id << " to resource "
-                            << name << " with conflicting ID " << existingId);
+  const ResourceId existing_id(pkg->id.value(), type->id ? type->id.value() : 0,
+                               entry->id ? entry->id.value() : 0);
+  diag->Error(DiagMessage() << "can't assign ID " << id << " to resource "
+                            << name << " with conflicting ID " << existing_id);
   return false;
 }
 
-bool IdAssigner::consume(IAaptContext* context, ResourceTable* table) {
-  std::map<ResourceId, ResourceName> assignedIds;
+bool IdAssigner::Consume(IAaptContext* context, ResourceTable* table) {
+  std::map<ResourceId, ResourceName> assigned_ids;
 
   for (auto& package : table->packages) {
-    assert(package->id && "packages must have manually assigned IDs");
+    CHECK(bool(package->id)) << "packages must have manually assigned IDs";
 
     for (auto& type : package->types) {
       for (auto& entry : type->entries) {
         const ResourceName name(package->name, type->type, entry->name);
 
-        if (mAssignedIdMap) {
+        if (assigned_id_map_) {
           // Assign the pre-assigned stable ID meant for this resource.
-          const auto iter = mAssignedIdMap->find(name);
-          if (iter != mAssignedIdMap->end()) {
-            const ResourceId assignedId = iter->second;
+          const auto iter = assigned_id_map_->find(name);
+          if (iter != assigned_id_map_->end()) {
+            const ResourceId assigned_id = iter->second;
             const bool result =
-                assignId(context->getDiagnostics(), assignedId, name,
+                AssignId(context->GetDiagnostics(), assigned_id, name,
                          package.get(), type.get(), entry.get());
             if (!result) {
               return false;
@@ -76,14 +78,14 @@
 
         if (package->id && type->id && entry->id) {
           // If the ID is set for this resource, then reserve it.
-          ResourceId resourceId(package->id.value(), type->id.value(),
-                                entry->id.value());
-          auto result = assignedIds.insert({resourceId, name});
-          const ResourceName& existingName = result.first->second;
+          ResourceId resource_id(package->id.value(), type->id.value(),
+                                 entry->id.value());
+          auto result = assigned_ids.insert({resource_id, name});
+          const ResourceName& existing_name = result.first->second;
           if (!result.second) {
-            context->getDiagnostics()->error(
+            context->GetDiagnostics()->Error(
                 DiagMessage() << "resource " << name << " has same ID "
-                              << resourceId << " as " << existingName);
+                              << resource_id << " as " << existing_name);
             return false;
           }
         }
@@ -91,20 +93,20 @@
     }
   }
 
-  if (mAssignedIdMap) {
+  if (assigned_id_map_) {
     // Reserve all the IDs mentioned in the stable ID map. That way we won't
     // assign
     // IDs that were listed in the map if they don't exist in the table.
-    for (const auto& stableIdEntry : *mAssignedIdMap) {
-      const ResourceName& preAssignedName = stableIdEntry.first;
-      const ResourceId& preAssignedId = stableIdEntry.second;
-      auto result = assignedIds.insert({preAssignedId, preAssignedName});
-      const ResourceName& existingName = result.first->second;
-      if (!result.second && existingName != preAssignedName) {
-        context->getDiagnostics()->error(
-            DiagMessage() << "stable ID " << preAssignedId << " for resource "
-                          << preAssignedName << " is already taken by resource "
-                          << existingName);
+    for (const auto& stable_id_entry : *assigned_id_map_) {
+      const ResourceName& pre_assigned_name = stable_id_entry.first;
+      const ResourceId& pre_assigned_id = stable_id_entry.second;
+      auto result = assigned_ids.insert({pre_assigned_id, pre_assigned_name});
+      const ResourceName& existing_name = result.first->second;
+      if (!result.second && existing_name != pre_assigned_name) {
+        context->GetDiagnostics()->Error(
+            DiagMessage() << "stable ID " << pre_assigned_id << " for resource "
+                          << pre_assigned_name
+                          << " is already taken by resource " << existing_name);
         return false;
       }
     }
@@ -114,21 +116,21 @@
   // if possible,
   // unless those IDs have been reserved.
 
-  const auto assignedIdsIterEnd = assignedIds.end();
+  const auto assigned_ids_iter_end = assigned_ids.end();
   for (auto& package : table->packages) {
-    assert(package->id && "packages must have manually assigned IDs");
+    CHECK(bool(package->id)) << "packages must have manually assigned IDs";
 
     // Build a half filled ResourceId object, which will be used to find the
     // closest matching
     // reserved ID in the assignedId map. From that point the next available
     // type ID can be
     // found.
-    ResourceId resourceId(package->id.value(), 0, 0);
-    uint8_t nextExpectedTypeId = 1;
+    ResourceId resource_id(package->id.value(), 0, 0);
+    uint8_t next_expected_type_id = 1;
 
     // Find the closest matching ResourceId that is <= the one with only the
     // package set.
-    auto nextTypeIter = assignedIds.lower_bound(resourceId);
+    auto next_type_iter = assigned_ids.lower_bound(resource_id);
     for (auto& type : package->types) {
       if (!type->id) {
         // We need to assign a type ID. Iterate over the reserved IDs until we
@@ -136,41 +138,41 @@
         // some type ID that is a distance of 2 greater than the last one we've
         // seen.
         // That means there is an available type ID between these reserved IDs.
-        while (nextTypeIter != assignedIdsIterEnd) {
-          if (nextTypeIter->first.packageId() != package->id.value()) {
+        while (next_type_iter != assigned_ids_iter_end) {
+          if (next_type_iter->first.package_id() != package->id.value()) {
             break;
           }
 
-          const uint8_t typeId = nextTypeIter->first.typeId();
-          if (typeId > nextExpectedTypeId) {
+          const uint8_t type_id = next_type_iter->first.type_id();
+          if (type_id > next_expected_type_id) {
             // There is a gap in the type IDs, so use the missing one.
-            type->id = nextExpectedTypeId++;
+            type->id = next_expected_type_id++;
             break;
           }
 
           // Set our expectation to be the next type ID after the reserved one
           // we
           // just saw.
-          nextExpectedTypeId = typeId + 1;
+          next_expected_type_id = type_id + 1;
 
           // Move to the next reserved ID.
-          ++nextTypeIter;
+          ++next_type_iter;
         }
 
         if (!type->id) {
           // We must have hit the end of the reserved IDs and not found a gap.
           // That means the next ID is available.
-          type->id = nextExpectedTypeId++;
+          type->id = next_expected_type_id++;
         }
       }
 
-      resourceId = ResourceId(package->id.value(), type->id.value(), 0);
-      uint16_t nextExpectedEntryId = 0;
+      resource_id = ResourceId(package->id.value(), type->id.value(), 0);
+      uint16_t next_expected_entry_id = 0;
 
       // Find the closest matching ResourceId that is <= the one with only the
       // package
       // and type set.
-      auto nextEntryIter = assignedIds.lower_bound(resourceId);
+      auto next_entry_iter = assigned_ids.lower_bound(resource_id);
       for (auto& entry : type->entries) {
         if (!entry->id) {
           // We need to assign an entry ID. Iterate over the reserved IDs until
@@ -179,32 +181,32 @@
           // we've seen.
           // That means there is an available entry ID between these reserved
           // IDs.
-          while (nextEntryIter != assignedIdsIterEnd) {
-            if (nextEntryIter->first.packageId() != package->id.value() ||
-                nextEntryIter->first.typeId() != type->id.value()) {
+          while (next_entry_iter != assigned_ids_iter_end) {
+            if (next_entry_iter->first.package_id() != package->id.value() ||
+                next_entry_iter->first.type_id() != type->id.value()) {
               break;
             }
 
-            const uint16_t entryId = nextEntryIter->first.entryId();
-            if (entryId > nextExpectedEntryId) {
+            const uint16_t entry_id = next_entry_iter->first.entry_id();
+            if (entry_id > next_expected_entry_id) {
               // There is a gap in the entry IDs, so use the missing one.
-              entry->id = nextExpectedEntryId++;
+              entry->id = next_expected_entry_id++;
               break;
             }
 
             // Set our expectation to be the next type ID after the reserved one
             // we
             // just saw.
-            nextExpectedEntryId = entryId + 1;
+            next_expected_entry_id = entry_id + 1;
 
             // Move to the next reserved entry ID.
-            ++nextEntryIter;
+            ++next_entry_iter;
           }
 
           if (!entry->id) {
             // We must have hit the end of the reserved IDs and not found a gap.
             // That means the next ID is available.
-            entry->id = nextExpectedEntryId++;
+            entry->id = next_expected_entry_id++;
           }
         }
       }
diff --git a/tools/aapt2/compile/IdAssigner.h b/tools/aapt2/compile/IdAssigner.h
index d399064..371ec01 100644
--- a/tools/aapt2/compile/IdAssigner.h
+++ b/tools/aapt2/compile/IdAssigner.h
@@ -17,11 +17,12 @@
 #ifndef AAPT_COMPILE_IDASSIGNER_H
 #define AAPT_COMPILE_IDASSIGNER_H
 
+#include <unordered_map>
+
 #include "Resource.h"
 #include "process/IResourceTableConsumer.h"
 
-#include <android-base/macros.h>
-#include <unordered_map>
+#include "android-base/macros.h"
 
 namespace aapt {
 
@@ -34,12 +35,13 @@
  public:
   IdAssigner() = default;
   explicit IdAssigner(const std::unordered_map<ResourceName, ResourceId>* map)
-      : mAssignedIdMap(map) {}
+      : assigned_id_map_(map) {}
 
-  bool consume(IAaptContext* context, ResourceTable* table) override;
+  bool Consume(IAaptContext* context, ResourceTable* table) override;
 
  private:
-  const std::unordered_map<ResourceName, ResourceId>* mAssignedIdMap = nullptr;
+  const std::unordered_map<ResourceName, ResourceId>* assigned_id_map_ =
+      nullptr;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/compile/IdAssigner_test.cpp b/tools/aapt2/compile/IdAssigner_test.cpp
index ff7bf5c..d465091 100644
--- a/tools/aapt2/compile/IdAssigner_test.cpp
+++ b/tools/aapt2/compile/IdAssigner_test.cpp
@@ -15,128 +15,129 @@
  */
 
 #include "compile/IdAssigner.h"
+
 #include "test/Test.h"
 
 namespace aapt {
 
-::testing::AssertionResult verifyIds(ResourceTable* table);
+::testing::AssertionResult VerifyIds(ResourceTable* table);
 
 TEST(IdAssignerTest, AssignIds) {
   std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-                                             .addSimple("android:attr/foo")
-                                             .addSimple("android:attr/bar")
-                                             .addSimple("android:id/foo")
-                                             .setPackageId("android", 0x01)
-                                             .build();
+                                             .AddSimple("android:attr/foo")
+                                             .AddSimple("android:attr/bar")
+                                             .AddSimple("android:id/foo")
+                                             .SetPackageId("android", 0x01)
+                                             .Build();
 
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   IdAssigner assigner;
 
-  ASSERT_TRUE(assigner.consume(context.get(), table.get()));
-  ASSERT_TRUE(verifyIds(table.get()));
+  ASSERT_TRUE(assigner.Consume(context.get(), table.get()));
+  ASSERT_TRUE(VerifyIds(table.get()));
 }
 
 TEST(IdAssignerTest, AssignIdsWithReservedIds) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .addSimple("android:id/foo", ResourceId(0x01010000))
-          .addSimple("android:dimen/two")
-          .addSimple("android:integer/three")
-          .addSimple("android:string/five")
-          .addSimple("android:attr/fun", ResourceId(0x01040000))
-          .addSimple("android:attr/foo", ResourceId(0x01040006))
-          .addSimple("android:attr/bar")
-          .addSimple("android:attr/baz")
-          .addSimple("app:id/biz")
-          .setPackageId("android", 0x01)
-          .setPackageId("app", 0x7f)
-          .build();
+          .AddSimple("android:id/foo", ResourceId(0x01010000))
+          .AddSimple("android:dimen/two")
+          .AddSimple("android:integer/three")
+          .AddSimple("android:string/five")
+          .AddSimple("android:attr/fun", ResourceId(0x01040000))
+          .AddSimple("android:attr/foo", ResourceId(0x01040006))
+          .AddSimple("android:attr/bar")
+          .AddSimple("android:attr/baz")
+          .AddSimple("app:id/biz")
+          .SetPackageId("android", 0x01)
+          .SetPackageId("app", 0x7f)
+          .Build();
 
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   IdAssigner assigner;
 
-  ASSERT_TRUE(assigner.consume(context.get(), table.get()));
-  ASSERT_TRUE(verifyIds(table.get()));
+  ASSERT_TRUE(assigner.Consume(context.get(), table.get()));
+  ASSERT_TRUE(VerifyIds(table.get()));
 
-  Maybe<ResourceTable::SearchResult> maybeResult;
+  Maybe<ResourceTable::SearchResult> maybe_result;
 
   // Expect to fill in the gaps between 0x0101XXXX and 0x0104XXXX.
 
-  maybeResult = table->findResource(test::parseNameOrDie("android:dimen/two"));
-  AAPT_ASSERT_TRUE(maybeResult);
-  EXPECT_EQ(make_value<uint8_t>(2), maybeResult.value().type->id);
+  maybe_result = table->FindResource(test::ParseNameOrDie("android:dimen/two"));
+  AAPT_ASSERT_TRUE(maybe_result);
+  EXPECT_EQ(make_value<uint8_t>(2), maybe_result.value().type->id);
 
-  maybeResult =
-      table->findResource(test::parseNameOrDie("android:integer/three"));
-  AAPT_ASSERT_TRUE(maybeResult);
-  EXPECT_EQ(make_value<uint8_t>(3), maybeResult.value().type->id);
+  maybe_result =
+      table->FindResource(test::ParseNameOrDie("android:integer/three"));
+  AAPT_ASSERT_TRUE(maybe_result);
+  EXPECT_EQ(make_value<uint8_t>(3), maybe_result.value().type->id);
 
   // Expect to bypass the reserved 0x0104XXXX IDs and use the next 0x0105XXXX
   // IDs.
 
-  maybeResult =
-      table->findResource(test::parseNameOrDie("android:string/five"));
-  AAPT_ASSERT_TRUE(maybeResult);
-  EXPECT_EQ(make_value<uint8_t>(5), maybeResult.value().type->id);
+  maybe_result =
+      table->FindResource(test::ParseNameOrDie("android:string/five"));
+  AAPT_ASSERT_TRUE(maybe_result);
+  EXPECT_EQ(make_value<uint8_t>(5), maybe_result.value().type->id);
 
   // Expect to fill in the gaps between 0x01040000 and 0x01040006.
 
-  maybeResult = table->findResource(test::parseNameOrDie("android:attr/bar"));
-  AAPT_ASSERT_TRUE(maybeResult);
-  EXPECT_EQ(make_value<uint16_t>(1), maybeResult.value().entry->id);
+  maybe_result = table->FindResource(test::ParseNameOrDie("android:attr/bar"));
+  AAPT_ASSERT_TRUE(maybe_result);
+  EXPECT_EQ(make_value<uint16_t>(1), maybe_result.value().entry->id);
 
-  maybeResult = table->findResource(test::parseNameOrDie("android:attr/baz"));
-  AAPT_ASSERT_TRUE(maybeResult);
-  EXPECT_EQ(make_value<uint16_t>(2), maybeResult.value().entry->id);
+  maybe_result = table->FindResource(test::ParseNameOrDie("android:attr/baz"));
+  AAPT_ASSERT_TRUE(maybe_result);
+  EXPECT_EQ(make_value<uint16_t>(2), maybe_result.value().entry->id);
 }
 
 TEST(IdAssignerTest, FailWhenNonUniqueIdsAssigned) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .addSimple("android:attr/foo", ResourceId(0x01040006))
-          .addSimple("android:attr/bar", ResourceId(0x01040006))
-          .setPackageId("android", 0x01)
-          .setPackageId("app", 0x7f)
-          .build();
+          .AddSimple("android:attr/foo", ResourceId(0x01040006))
+          .AddSimple("android:attr/bar", ResourceId(0x01040006))
+          .SetPackageId("android", 0x01)
+          .SetPackageId("app", 0x7f)
+          .Build();
 
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   IdAssigner assigner;
 
-  ASSERT_FALSE(assigner.consume(context.get(), table.get()));
+  ASSERT_FALSE(assigner.Consume(context.get(), table.get()));
 }
 
 TEST(IdAssignerTest, AssignIdsWithIdMap) {
   std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-                                             .addSimple("android:attr/foo")
-                                             .addSimple("android:attr/bar")
-                                             .setPackageId("android", 0x01)
-                                             .build();
+                                             .AddSimple("android:attr/foo")
+                                             .AddSimple("android:attr/bar")
+                                             .SetPackageId("android", 0x01)
+                                             .Build();
 
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
-  std::unordered_map<ResourceName, ResourceId> idMap = {
-      {test::parseNameOrDie("android:attr/foo"), ResourceId(0x01010002)}};
-  IdAssigner assigner(&idMap);
-  ASSERT_TRUE(assigner.consume(context.get(), table.get()));
-  ASSERT_TRUE(verifyIds(table.get()));
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unordered_map<ResourceName, ResourceId> id_map = {
+      {test::ParseNameOrDie("android:attr/foo"), ResourceId(0x01010002)}};
+  IdAssigner assigner(&id_map);
+  ASSERT_TRUE(assigner.Consume(context.get(), table.get()));
+  ASSERT_TRUE(VerifyIds(table.get()));
   Maybe<ResourceTable::SearchResult> result =
-      table->findResource(test::parseNameOrDie("android:attr/foo"));
+      table->FindResource(test::ParseNameOrDie("android:attr/foo"));
   AAPT_ASSERT_TRUE(result);
 
-  const ResourceTable::SearchResult& searchResult = result.value();
-  EXPECT_EQ(make_value<uint8_t>(0x01), searchResult.package->id);
-  EXPECT_EQ(make_value<uint8_t>(0x01), searchResult.type->id);
-  EXPECT_EQ(make_value<uint16_t>(0x0002), searchResult.entry->id);
+  const ResourceTable::SearchResult& search_result = result.value();
+  EXPECT_EQ(make_value<uint8_t>(0x01), search_result.package->id);
+  EXPECT_EQ(make_value<uint8_t>(0x01), search_result.type->id);
+  EXPECT_EQ(make_value<uint16_t>(0x0002), search_result.entry->id);
 }
 
-::testing::AssertionResult verifyIds(ResourceTable* table) {
-  std::set<uint8_t> packageIds;
+::testing::AssertionResult VerifyIds(ResourceTable* table) {
+  std::set<uint8_t> package_ids;
   for (auto& package : table->packages) {
     if (!package->id) {
       return ::testing::AssertionFailure() << "package " << package->name
                                            << " has no ID";
     }
 
-    if (!packageIds.insert(package->id.value()).second) {
+    if (!package_ids.insert(package->id.value()).second) {
       return ::testing::AssertionFailure()
              << "package " << package->name << " has non-unique ID " << std::hex
              << (int)package->id.value() << std::dec;
@@ -144,7 +145,7 @@
   }
 
   for (auto& package : table->packages) {
-    std::set<uint8_t> typeIds;
+    std::set<uint8_t> type_ids;
     for (auto& type : package->types) {
       if (!type->id) {
         return ::testing::AssertionFailure() << "type " << type->type
@@ -152,7 +153,7 @@
                                              << " has no ID";
       }
 
-      if (!typeIds.insert(type->id.value()).second) {
+      if (!type_ids.insert(type->id.value()).second) {
         return ::testing::AssertionFailure()
                << "type " << type->type << " of package " << package->name
                << " has non-unique ID " << std::hex << (int)type->id.value()
@@ -161,7 +162,7 @@
     }
 
     for (auto& type : package->types) {
-      std::set<uint16_t> entryIds;
+      std::set<uint16_t> entry_ids;
       for (auto& entry : type->entries) {
         if (!entry->id) {
           return ::testing::AssertionFailure()
@@ -169,7 +170,7 @@
                  << " of package " << package->name << " has no ID";
         }
 
-        if (!entryIds.insert(entry->id.value()).second) {
+        if (!entry_ids.insert(entry->id.value()).second) {
           return ::testing::AssertionFailure()
                  << "entry " << entry->name << " of type " << type->type
                  << " of package " << package->name << " has non-unique ID "
diff --git a/tools/aapt2/compile/Image.h b/tools/aapt2/compile/Image.h
index 4cf2ea7..db0b945 100644
--- a/tools/aapt2/compile/Image.h
+++ b/tools/aapt2/compile/Image.h
@@ -17,12 +17,13 @@
 #ifndef AAPT_COMPILE_IMAGE_H
 #define AAPT_COMPILE_IMAGE_H
 
-#include <android-base/macros.h>
 #include <cstdint>
 #include <memory>
 #include <string>
 #include <vector>
 
+#include "android-base/macros.h"
+
 namespace aapt {
 
 /**
@@ -113,15 +114,15 @@
  */
 class NinePatch {
  public:
-  static std::unique_ptr<NinePatch> create(uint8_t** rows, const int32_t width,
+  static std::unique_ptr<NinePatch> Create(uint8_t** rows, const int32_t width,
                                            const int32_t height,
-                                           std::string* errOut);
+                                           std::string* err_out);
 
   /**
    * Packs the RGBA_8888 data pointed to by pixel into a uint32_t
    * with format 0xAARRGGBB (the way 9-patch expects it).
    */
-  static uint32_t packRGBA(const uint8_t* pixel);
+  static uint32_t PackRGBA(const uint8_t* pixel);
 
   /**
    * 9-patch content padding/insets. All positions are relative to the 9-patch
@@ -136,7 +137,7 @@
    * See
    * https://developer.android.com/about/versions/android-4.3.html#OpticalBounds
    */
-  Bounds layoutBounds;
+  Bounds layout_bounds;
 
   /**
    * Outline of the image, calculated based on opacity.
@@ -147,51 +148,51 @@
    * The computed radius of the outline. If non-zero, the outline is a
    * rounded-rect.
    */
-  float outlineRadius = 0.0f;
+  float outline_radius = 0.0f;
 
   /**
    * The largest alpha value within the outline.
    */
-  uint32_t outlineAlpha = 0x000000ffu;
+  uint32_t outline_alpha = 0x000000ffu;
 
   /**
    * Horizontal regions of the image that are stretchable.
    * All positions are relative to the 9-patch
    * NOT including the 1px thick source border.
    */
-  std::vector<Range> horizontalStretchRegions;
+  std::vector<Range> horizontal_stretch_regions;
 
   /**
    * Vertical regions of the image that are stretchable.
    * All positions are relative to the 9-patch
    * NOT including the 1px thick source border.
    */
-  std::vector<Range> verticalStretchRegions;
+  std::vector<Range> vertical_stretch_regions;
 
   /**
    * The colors within each region, fixed or stretchable.
    * For w*h regions, the color of region (x,y) is addressable
    * via index y*w + x.
    */
-  std::vector<uint32_t> regionColors;
+  std::vector<uint32_t> region_colors;
 
   /**
    * Returns serialized data containing the original basic 9-patch meta data.
    * Optical layout bounds and round rect outline data must be serialized
-   * separately using serializeOpticalLayoutBounds() and
-   * serializeRoundedRectOutline().
+   * separately using SerializeOpticalLayoutBounds() and
+   * SerializeRoundedRectOutline().
    */
-  std::unique_ptr<uint8_t[]> serializeBase(size_t* outLen) const;
+  std::unique_ptr<uint8_t[]> SerializeBase(size_t* out_len) const;
 
   /**
    * Serializes the layout bounds.
    */
-  std::unique_ptr<uint8_t[]> serializeLayoutBounds(size_t* outLen) const;
+  std::unique_ptr<uint8_t[]> SerializeLayoutBounds(size_t* out_len) const;
 
   /**
    * Serializes the rounded-rect outline.
    */
-  std::unique_ptr<uint8_t[]> serializeRoundedRectOutline(size_t* outLen) const;
+  std::unique_ptr<uint8_t[]> SerializeRoundedRectOutline(size_t* out_len) const;
 
  private:
   explicit NinePatch() = default;
@@ -201,7 +202,7 @@
 
 ::std::ostream& operator<<(::std::ostream& out, const Range& range);
 ::std::ostream& operator<<(::std::ostream& out, const Bounds& bounds);
-::std::ostream& operator<<(::std::ostream& out, const NinePatch& ninePatch);
+::std::ostream& operator<<(::std::ostream& out, const NinePatch& nine_patch);
 
 }  // namespace aapt
 
diff --git a/tools/aapt2/compile/InlineXmlFormatParser.cpp b/tools/aapt2/compile/InlineXmlFormatParser.cpp
index 56f72b5..786494b 100644
--- a/tools/aapt2/compile/InlineXmlFormatParser.cpp
+++ b/tools/aapt2/compile/InlineXmlFormatParser.cpp
@@ -15,16 +15,18 @@
  */
 
 #include "compile/InlineXmlFormatParser.h"
+
+#include <sstream>
+#include <string>
+
+#include "android-base/macros.h"
+
 #include "Debug.h"
 #include "ResourceUtils.h"
 #include "util/Util.h"
 #include "xml/XmlDom.h"
 #include "xml/XmlUtil.h"
 
-#include <android-base/macros.h>
-#include <sstream>
-#include <string>
-
 namespace aapt {
 
 namespace {
@@ -34,38 +36,38 @@
  */
 class Visitor : public xml::PackageAwareVisitor {
  public:
-  using xml::PackageAwareVisitor::visit;
+  using xml::PackageAwareVisitor::Visit;
 
   struct InlineDeclaration {
     xml::Element* el;
-    std::string attrNamespaceUri;
-    std::string attrName;
+    std::string attr_namespace_uri;
+    std::string attr_name;
   };
 
-  explicit Visitor(IAaptContext* context, xml::XmlResource* xmlResource)
-      : mContext(context), mXmlResource(xmlResource) {}
+  explicit Visitor(IAaptContext* context, xml::XmlResource* xml_resource)
+      : context_(context), xml_resource_(xml_resource) {}
 
-  void visit(xml::Element* el) override {
-    if (el->namespaceUri != xml::kSchemaAapt || el->name != "attr") {
-      xml::PackageAwareVisitor::visit(el);
+  void Visit(xml::Element* el) override {
+    if (el->namespace_uri != xml::kSchemaAapt || el->name != "attr") {
+      xml::PackageAwareVisitor::Visit(el);
       return;
     }
 
-    const Source& src = mXmlResource->file.source.withLine(el->lineNumber);
+    const Source& src = xml_resource_->file.source.WithLine(el->line_number);
 
-    xml::Attribute* attr = el->findAttribute({}, "name");
+    xml::Attribute* attr = el->FindAttribute({}, "name");
     if (!attr) {
-      mContext->getDiagnostics()->error(DiagMessage(src)
+      context_->GetDiagnostics()->Error(DiagMessage(src)
                                         << "missing 'name' attribute");
-      mError = true;
+      error_ = true;
       return;
     }
 
-    Maybe<Reference> ref = ResourceUtils::parseXmlAttributeName(attr->value);
+    Maybe<Reference> ref = ResourceUtils::ParseXmlAttributeName(attr->value);
     if (!ref) {
-      mContext->getDiagnostics()->error(
+      context_->GetDiagnostics()->Error(
           DiagMessage(src) << "invalid XML attribute '" << attr->value << "'");
-      mError = true;
+      error_ = true;
       return;
     }
 
@@ -76,63 +78,63 @@
     // the local package if the user specified name="style" or something. This
     // should just
     // be the default namespace.
-    Maybe<xml::ExtractedPackage> maybePkg =
-        transformPackageAlias(name.package, {});
-    if (!maybePkg) {
-      mContext->getDiagnostics()->error(DiagMessage(src)
+    Maybe<xml::ExtractedPackage> maybe_pkg =
+        TransformPackageAlias(name.package, {});
+    if (!maybe_pkg) {
+      context_->GetDiagnostics()->Error(DiagMessage(src)
                                         << "invalid namespace prefix '"
                                         << name.package << "'");
-      mError = true;
+      error_ = true;
       return;
     }
 
-    const xml::ExtractedPackage& pkg = maybePkg.value();
-    const bool privateNamespace =
-        pkg.privateNamespace || ref.value().privateReference;
+    const xml::ExtractedPackage& pkg = maybe_pkg.value();
+    const bool private_namespace =
+        pkg.private_namespace || ref.value().private_reference;
 
     InlineDeclaration decl;
     decl.el = el;
-    decl.attrName = name.entry;
+    decl.attr_name = name.entry;
     if (!pkg.package.empty()) {
-      decl.attrNamespaceUri =
-          xml::buildPackageNamespace(pkg.package, privateNamespace);
+      decl.attr_namespace_uri =
+          xml::BuildPackageNamespace(pkg.package, private_namespace);
     }
 
-    mInlineDeclarations.push_back(std::move(decl));
+    inline_declarations_.push_back(std::move(decl));
   }
 
-  const std::vector<InlineDeclaration>& getInlineDeclarations() const {
-    return mInlineDeclarations;
+  const std::vector<InlineDeclaration>& GetInlineDeclarations() const {
+    return inline_declarations_;
   }
 
-  bool hasError() const { return mError; }
+  bool HasError() const { return error_; }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(Visitor);
 
-  IAaptContext* mContext;
-  xml::XmlResource* mXmlResource;
-  std::vector<InlineDeclaration> mInlineDeclarations;
-  bool mError = false;
+  IAaptContext* context_;
+  xml::XmlResource* xml_resource_;
+  std::vector<InlineDeclaration> inline_declarations_;
+  bool error_ = false;
 };
 
 }  // namespace
 
-bool InlineXmlFormatParser::consume(IAaptContext* context,
+bool InlineXmlFormatParser::Consume(IAaptContext* context,
                                     xml::XmlResource* doc) {
   Visitor visitor(context, doc);
-  doc->root->accept(&visitor);
-  if (visitor.hasError()) {
+  doc->root->Accept(&visitor);
+  if (visitor.HasError()) {
     return false;
   }
 
-  size_t nameSuffixCounter = 0;
+  size_t name_suffix_counter = 0;
   for (const Visitor::InlineDeclaration& decl :
-       visitor.getInlineDeclarations()) {
-    auto newDoc = util::make_unique<xml::XmlResource>();
-    newDoc->file.config = doc->file.config;
-    newDoc->file.source = doc->file.source.withLine(decl.el->lineNumber);
-    newDoc->file.name = doc->file.name;
+       visitor.GetInlineDeclarations()) {
+    auto new_doc = util::make_unique<xml::XmlResource>();
+    new_doc->file.config = doc->file.config;
+    new_doc->file.source = doc->file.source.WithLine(decl.el->line_number);
+    new_doc->file.name = doc->file.name;
 
     // Modify the new entry name. We need to suffix the entry with a number to
     // avoid
@@ -140,63 +142,64 @@
     // won't show up
     // in R.java.
 
-    newDoc->file.name.entry = NameMangler::mangleEntry(
-        {}, newDoc->file.name.entry + "__" + std::to_string(nameSuffixCounter));
+    new_doc->file.name.entry =
+        NameMangler::MangleEntry({}, new_doc->file.name.entry + "__" +
+                                         std::to_string(name_suffix_counter));
 
     // Extracted elements must be the only child of <aapt:attr>.
     // Make sure there is one root node in the children (ignore empty text).
     for (auto& child : decl.el->children) {
-      const Source childSource = doc->file.source.withLine(child->lineNumber);
-      if (xml::Text* t = xml::nodeCast<xml::Text>(child.get())) {
-        if (!util::trimWhitespace(t->text).empty()) {
-          context->getDiagnostics()->error(
-              DiagMessage(childSource)
+      const Source child_source = doc->file.source.WithLine(child->line_number);
+      if (xml::Text* t = xml::NodeCast<xml::Text>(child.get())) {
+        if (!util::TrimWhitespace(t->text).empty()) {
+          context->GetDiagnostics()->Error(
+              DiagMessage(child_source)
               << "can't extract text into its own resource");
           return false;
         }
-      } else if (newDoc->root) {
-        context->getDiagnostics()->error(
-            DiagMessage(childSource)
+      } else if (new_doc->root) {
+        context->GetDiagnostics()->Error(
+            DiagMessage(child_source)
             << "inline XML resources must have a single root");
         return false;
       } else {
-        newDoc->root = std::move(child);
-        newDoc->root->parent = nullptr;
+        new_doc->root = std::move(child);
+        new_doc->root->parent = nullptr;
       }
     }
 
     // Walk up and find the parent element.
     xml::Node* node = decl.el;
-    xml::Element* parentEl = nullptr;
+    xml::Element* parent_el = nullptr;
     while (node->parent &&
-           (parentEl = xml::nodeCast<xml::Element>(node->parent)) == nullptr) {
+           (parent_el = xml::NodeCast<xml::Element>(node->parent)) == nullptr) {
       node = node->parent;
     }
 
-    if (!parentEl) {
-      context->getDiagnostics()->error(
-          DiagMessage(newDoc->file.source)
+    if (!parent_el) {
+      context->GetDiagnostics()->Error(
+          DiagMessage(new_doc->file.source)
           << "no suitable parent for inheriting attribute");
       return false;
     }
 
     // Add the inline attribute to the parent.
-    parentEl->attributes.push_back(
-        xml::Attribute{decl.attrNamespaceUri, decl.attrName,
-                       "@" + newDoc->file.name.toString()});
+    parent_el->attributes.push_back(
+        xml::Attribute{decl.attr_namespace_uri, decl.attr_name,
+                       "@" + new_doc->file.name.ToString()});
 
     // Delete the subtree.
-    for (auto iter = parentEl->children.begin();
-         iter != parentEl->children.end(); ++iter) {
+    for (auto iter = parent_el->children.begin();
+         iter != parent_el->children.end(); ++iter) {
       if (iter->get() == node) {
-        parentEl->children.erase(iter);
+        parent_el->children.erase(iter);
         break;
       }
     }
 
-    mQueue.push_back(std::move(newDoc));
+    queue_.push_back(std::move(new_doc));
 
-    nameSuffixCounter++;
+    name_suffix_counter++;
   }
   return true;
 }
diff --git a/tools/aapt2/compile/InlineXmlFormatParser.h b/tools/aapt2/compile/InlineXmlFormatParser.h
index cd8794b..1a658fd 100644
--- a/tools/aapt2/compile/InlineXmlFormatParser.h
+++ b/tools/aapt2/compile/InlineXmlFormatParser.h
@@ -17,12 +17,13 @@
 #ifndef AAPT_COMPILE_INLINEXMLFORMATPARSER_H
 #define AAPT_COMPILE_INLINEXMLFORMATPARSER_H
 
-#include "process/IResourceTableConsumer.h"
-
-#include <android-base/macros.h>
 #include <memory>
 #include <vector>
 
+#include "android-base/macros.h"
+
+#include "process/IResourceTableConsumer.h"
+
 namespace aapt {
 
 /**
@@ -50,17 +51,17 @@
  public:
   explicit InlineXmlFormatParser() = default;
 
-  bool consume(IAaptContext* context, xml::XmlResource* doc) override;
+  bool Consume(IAaptContext* context, xml::XmlResource* doc) override;
 
   std::vector<std::unique_ptr<xml::XmlResource>>&
-  getExtractedInlineXmlDocuments() {
-    return mQueue;
+  GetExtractedInlineXmlDocuments() {
+    return queue_;
   }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(InlineXmlFormatParser);
 
-  std::vector<std::unique_ptr<xml::XmlResource>> mQueue;
+  std::vector<std::unique_ptr<xml::XmlResource>> queue_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/compile/InlineXmlFormatParser_test.cpp b/tools/aapt2/compile/InlineXmlFormatParser_test.cpp
index 4adb21c..348796c 100644
--- a/tools/aapt2/compile/InlineXmlFormatParser_test.cpp
+++ b/tools/aapt2/compile/InlineXmlFormatParser_test.cpp
@@ -15,13 +15,14 @@
  */
 
 #include "compile/InlineXmlFormatParser.h"
+
 #include "test/Test.h"
 
 namespace aapt {
 
 TEST(InlineXmlFormatParserTest, PassThrough) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
-  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
       <View xmlns:android="http://schemas.android.com/apk/res/android">
         <View android:text="hey">
           <View android:id="hi" />
@@ -29,13 +30,13 @@
       </View>)EOF");
 
   InlineXmlFormatParser parser;
-  ASSERT_TRUE(parser.consume(context.get(), doc.get()));
-  EXPECT_EQ(0u, parser.getExtractedInlineXmlDocuments().size());
+  ASSERT_TRUE(parser.Consume(context.get(), doc.get()));
+  EXPECT_EQ(0u, parser.GetExtractedInlineXmlDocuments().size());
 }
 
 TEST(InlineXmlFormatParserTest, ExtractOneXmlResource) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
-  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
       <View1 xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:aapt="http://schemas.android.com/aapt">
         <aapt:attr name="android:text">
@@ -45,48 +46,48 @@
         </aapt:attr>
       </View1>)EOF");
 
-  doc->file.name = test::parseNameOrDie("layout/main");
+  doc->file.name = test::ParseNameOrDie("layout/main");
 
   InlineXmlFormatParser parser;
-  ASSERT_TRUE(parser.consume(context.get(), doc.get()));
+  ASSERT_TRUE(parser.Consume(context.get(), doc.get()));
 
   // One XML resource should have been extracted.
-  EXPECT_EQ(1u, parser.getExtractedInlineXmlDocuments().size());
+  EXPECT_EQ(1u, parser.GetExtractedInlineXmlDocuments().size());
 
-  xml::Element* el = xml::findRootElement(doc.get());
+  xml::Element* el = xml::FindRootElement(doc.get());
   ASSERT_NE(nullptr, el);
 
   EXPECT_EQ("View1", el->name);
 
   // The <aapt:attr> tag should be extracted.
-  EXPECT_EQ(nullptr, el->findChild(xml::kSchemaAapt, "attr"));
+  EXPECT_EQ(nullptr, el->FindChild(xml::kSchemaAapt, "attr"));
 
   // The 'android:text' attribute should be set with a reference.
-  xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, "text");
+  xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "text");
   ASSERT_NE(nullptr, attr);
 
-  ResourceNameRef nameRef;
-  ASSERT_TRUE(ResourceUtils::parseReference(attr->value, &nameRef));
+  ResourceNameRef name_ref;
+  ASSERT_TRUE(ResourceUtils::ParseReference(attr->value, &name_ref));
 
-  xml::XmlResource* extractedDoc =
-      parser.getExtractedInlineXmlDocuments()[0].get();
-  ASSERT_NE(nullptr, extractedDoc);
+  xml::XmlResource* extracted_doc =
+      parser.GetExtractedInlineXmlDocuments()[0].get();
+  ASSERT_NE(nullptr, extracted_doc);
 
   // Make sure the generated reference is correct.
-  EXPECT_EQ(nameRef.package, extractedDoc->file.name.package);
-  EXPECT_EQ(nameRef.type, extractedDoc->file.name.type);
-  EXPECT_EQ(nameRef.entry, extractedDoc->file.name.entry);
+  EXPECT_EQ(name_ref.package, extracted_doc->file.name.package);
+  EXPECT_EQ(name_ref.type, extracted_doc->file.name.type);
+  EXPECT_EQ(name_ref.entry, extracted_doc->file.name.entry);
 
   // Verify the structure of the extracted XML.
-  el = xml::findRootElement(extractedDoc);
+  el = xml::FindRootElement(extracted_doc);
   ASSERT_NE(nullptr, el);
   EXPECT_EQ("View2", el->name);
-  EXPECT_NE(nullptr, el->findChild({}, "View3"));
+  EXPECT_NE(nullptr, el->FindChild({}, "View3"));
 }
 
 TEST(InlineXmlFormatParserTest, ExtractTwoXmlResources) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
-  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
       <View1 xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:aapt="http://schemas.android.com/aapt">
         <aapt:attr name="android:text">
@@ -100,41 +101,41 @@
         </aapt:attr>
       </View1>)EOF");
 
-  doc->file.name = test::parseNameOrDie("layout/main");
+  doc->file.name = test::ParseNameOrDie("layout/main");
 
   InlineXmlFormatParser parser;
-  ASSERT_TRUE(parser.consume(context.get(), doc.get()));
-  ASSERT_EQ(2u, parser.getExtractedInlineXmlDocuments().size());
+  ASSERT_TRUE(parser.Consume(context.get(), doc.get()));
+  ASSERT_EQ(2u, parser.GetExtractedInlineXmlDocuments().size());
 
-  xml::Element* el = xml::findRootElement(doc.get());
+  xml::Element* el = xml::FindRootElement(doc.get());
   ASSERT_NE(nullptr, el);
 
   EXPECT_EQ("View1", el->name);
 
-  xml::Attribute* attrText = el->findAttribute(xml::kSchemaAndroid, "text");
-  ASSERT_NE(nullptr, attrText);
+  xml::Attribute* attr_text = el->FindAttribute(xml::kSchemaAndroid, "text");
+  ASSERT_NE(nullptr, attr_text);
 
-  xml::Attribute* attrDrawable =
-      el->findAttribute(xml::kSchemaAndroid, "drawable");
-  ASSERT_NE(nullptr, attrDrawable);
+  xml::Attribute* attr_drawable =
+      el->FindAttribute(xml::kSchemaAndroid, "drawable");
+  ASSERT_NE(nullptr, attr_drawable);
 
   // The two extracted resources should have different names.
-  EXPECT_NE(attrText->value, attrDrawable->value);
+  EXPECT_NE(attr_text->value, attr_drawable->value);
 
   // The child <aapt:attr> elements should be gone.
-  EXPECT_EQ(nullptr, el->findChild(xml::kSchemaAapt, "attr"));
+  EXPECT_EQ(nullptr, el->FindChild(xml::kSchemaAapt, "attr"));
 
-  xml::XmlResource* extractedDocText =
-      parser.getExtractedInlineXmlDocuments()[0].get();
-  ASSERT_NE(nullptr, extractedDocText);
-  el = xml::findRootElement(extractedDocText);
+  xml::XmlResource* extracted_doc_text =
+      parser.GetExtractedInlineXmlDocuments()[0].get();
+  ASSERT_NE(nullptr, extracted_doc_text);
+  el = xml::FindRootElement(extracted_doc_text);
   ASSERT_NE(nullptr, el);
   EXPECT_EQ("View2", el->name);
 
-  xml::XmlResource* extractedDocDrawable =
-      parser.getExtractedInlineXmlDocuments()[1].get();
-  ASSERT_NE(nullptr, extractedDocDrawable);
-  el = xml::findRootElement(extractedDocDrawable);
+  xml::XmlResource* extracted_doc_drawable =
+      parser.GetExtractedInlineXmlDocuments()[1].get();
+  ASSERT_NE(nullptr, extracted_doc_drawable);
+  el = xml::FindRootElement(extracted_doc_drawable);
   ASSERT_NE(nullptr, el);
   EXPECT_EQ("vector", el->name);
 }
diff --git a/tools/aapt2/compile/NinePatch.cpp b/tools/aapt2/compile/NinePatch.cpp
index 8842eb7..eab5c97 100644
--- a/tools/aapt2/compile/NinePatch.cpp
+++ b/tools/aapt2/compile/NinePatch.cpp
@@ -15,14 +15,16 @@
  */
 
 #include "compile/Image.h"
-#include "util/StringPiece.h"
-#include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
 #include <sstream>
 #include <string>
 #include <vector>
 
+#include "androidfw/ResourceTypes.h"
+
+#include "util/StringPiece.h"
+#include "util/Util.h"
+
 namespace aapt {
 
 // Colors in the format 0xAARRGGBB (the way 9-patch expects it).
@@ -36,7 +38,7 @@
 /**
  * Returns the alpha value encoded in the 0xAARRGBB encoded pixel.
  */
-static uint32_t getAlpha(uint32_t color);
+static uint32_t get_alpha(uint32_t color);
 
 /**
  * Determines whether a color on an ImageLine is valid.
@@ -53,19 +55,19 @@
    * Returns true if the color specified is a neutral color
    * (no padding, stretching, or optical bounds).
    */
-  virtual bool isNeutralColor(uint32_t color) const = 0;
+  virtual bool IsNeutralColor(uint32_t color) const = 0;
 
   /**
    * Returns true if the color is either a neutral color
    * or one denoting padding, stretching, or optical bounds.
    */
-  bool isValidColor(uint32_t color) const {
+  bool IsValidColor(uint32_t color) const {
     switch (color) {
       case kPrimaryColor:
       case kSecondaryColor:
         return true;
     }
-    return isNeutralColor(color);
+    return IsNeutralColor(color);
   }
 };
 
@@ -81,42 +83,43 @@
 //
 // class ImageLine {
 // public:
-//      virtual int32_t getLength() const = 0;
-//      virtual uint32_t getColor(int32_t idx) const = 0;
+//      virtual int32_t GetLength() const = 0;
+//      virtual uint32_t GetColor(int32_t idx) const = 0;
 // };
 //
 template <typename ImageLine>
-static bool fillRanges(const ImageLine* imageLine,
-                       const ColorValidator* colorValidator,
-                       std::vector<Range>* primaryRanges,
-                       std::vector<Range>* secondaryRanges, std::string* err) {
-  const int32_t length = imageLine->getLength();
+static bool FillRanges(const ImageLine* image_line,
+                       const ColorValidator* color_validator,
+                       std::vector<Range>* primary_ranges,
+                       std::vector<Range>* secondary_ranges,
+                       std::string* out_err) {
+  const int32_t length = image_line->GetLength();
 
-  uint32_t lastColor = 0xffffffffu;
+  uint32_t last_color = 0xffffffffu;
   for (int32_t idx = 1; idx < length - 1; idx++) {
-    const uint32_t color = imageLine->getColor(idx);
-    if (!colorValidator->isValidColor(color)) {
-      *err = "found an invalid color";
+    const uint32_t color = image_line->GetColor(idx);
+    if (!color_validator->IsValidColor(color)) {
+      *out_err = "found an invalid color";
       return false;
     }
 
-    if (color != lastColor) {
+    if (color != last_color) {
       // We are ending a range. Which range?
       // note: encode the x offset without the final 1 pixel border.
-      if (lastColor == kPrimaryColor) {
-        primaryRanges->back().end = idx - 1;
-      } else if (lastColor == kSecondaryColor) {
-        secondaryRanges->back().end = idx - 1;
+      if (last_color == kPrimaryColor) {
+        primary_ranges->back().end = idx - 1;
+      } else if (last_color == kSecondaryColor) {
+        secondary_ranges->back().end = idx - 1;
       }
 
       // We are starting a range. Which range?
       // note: encode the x offset without the final 1 pixel border.
       if (color == kPrimaryColor) {
-        primaryRanges->push_back(Range(idx - 1, length - 2));
+        primary_ranges->push_back(Range(idx - 1, length - 2));
       } else if (color == kSecondaryColor) {
-        secondaryRanges->push_back(Range(idx - 1, length - 2));
+        secondary_ranges->push_back(Range(idx - 1, length - 2));
       }
-      lastColor = color;
+      last_color = color;
     }
   }
   return true;
@@ -128,19 +131,19 @@
  */
 class HorizontalImageLine {
  public:
-  explicit HorizontalImageLine(uint8_t** rows, int32_t xOffset, int32_t yOffset,
+  explicit HorizontalImageLine(uint8_t** rows, int32_t xoffset, int32_t yoffset,
                                int32_t length)
-      : mRows(rows), mXOffset(xOffset), mYOffset(yOffset), mLength(length) {}
+      : rows_(rows), xoffset_(xoffset), yoffset_(yoffset), length_(length) {}
 
-  inline int32_t getLength() const { return mLength; }
+  inline int32_t GetLength() const { return length_; }
 
-  inline uint32_t getColor(int32_t idx) const {
-    return NinePatch::packRGBA(mRows[mYOffset] + (idx + mXOffset) * 4);
+  inline uint32_t GetColor(int32_t idx) const {
+    return NinePatch::PackRGBA(rows_[yoffset_] + (idx + xoffset_) * 4);
   }
 
  private:
-  uint8_t** mRows;
-  int32_t mXOffset, mYOffset, mLength;
+  uint8_t** rows_;
+  int32_t xoffset_, yoffset_, length_;
 
   DISALLOW_COPY_AND_ASSIGN(HorizontalImageLine);
 };
@@ -151,179 +154,180 @@
  */
 class VerticalImageLine {
  public:
-  explicit VerticalImageLine(uint8_t** rows, int32_t xOffset, int32_t yOffset,
+  explicit VerticalImageLine(uint8_t** rows, int32_t xoffset, int32_t yoffset,
                              int32_t length)
-      : mRows(rows), mXOffset(xOffset), mYOffset(yOffset), mLength(length) {}
+      : rows_(rows), xoffset_(xoffset), yoffset_(yoffset), length_(length) {}
 
-  inline int32_t getLength() const { return mLength; }
+  inline int32_t GetLength() const { return length_; }
 
-  inline uint32_t getColor(int32_t idx) const {
-    return NinePatch::packRGBA(mRows[mYOffset + idx] + (mXOffset * 4));
+  inline uint32_t GetColor(int32_t idx) const {
+    return NinePatch::PackRGBA(rows_[yoffset_ + idx] + (xoffset_ * 4));
   }
 
  private:
-  uint8_t** mRows;
-  int32_t mXOffset, mYOffset, mLength;
+  uint8_t** rows_;
+  int32_t xoffset_, yoffset_, length_;
 
   DISALLOW_COPY_AND_ASSIGN(VerticalImageLine);
 };
 
 class DiagonalImageLine {
  public:
-  explicit DiagonalImageLine(uint8_t** rows, int32_t xOffset, int32_t yOffset,
-                             int32_t xStep, int32_t yStep, int32_t length)
-      : mRows(rows),
-        mXOffset(xOffset),
-        mYOffset(yOffset),
-        mXStep(xStep),
-        mYStep(yStep),
-        mLength(length) {}
+  explicit DiagonalImageLine(uint8_t** rows, int32_t xoffset, int32_t yoffset,
+                             int32_t xstep, int32_t ystep, int32_t length)
+      : rows_(rows),
+        xoffset_(xoffset),
+        yoffset_(yoffset),
+        xstep_(xstep),
+        ystep_(ystep),
+        length_(length) {}
 
-  inline int32_t getLength() const { return mLength; }
+  inline int32_t GetLength() const { return length_; }
 
-  inline uint32_t getColor(int32_t idx) const {
-    return NinePatch::packRGBA(mRows[mYOffset + (idx * mYStep)] +
-                               ((idx + mXOffset) * mXStep) * 4);
+  inline uint32_t GetColor(int32_t idx) const {
+    return NinePatch::PackRGBA(rows_[yoffset_ + (idx * ystep_)] +
+                               ((idx + xoffset_) * xstep_) * 4);
   }
 
  private:
-  uint8_t** mRows;
-  int32_t mXOffset, mYOffset, mXStep, mYStep, mLength;
+  uint8_t** rows_;
+  int32_t xoffset_, yoffset_, xstep_, ystep_, length_;
 
   DISALLOW_COPY_AND_ASSIGN(DiagonalImageLine);
 };
 
 class TransparentNeutralColorValidator : public ColorValidator {
  public:
-  bool isNeutralColor(uint32_t color) const override {
-    return getAlpha(color) == 0;
+  bool IsNeutralColor(uint32_t color) const override {
+    return get_alpha(color) == 0;
   }
 };
 
 class WhiteNeutralColorValidator : public ColorValidator {
  public:
-  bool isNeutralColor(uint32_t color) const override {
+  bool IsNeutralColor(uint32_t color) const override {
     return color == kColorOpaqueWhite;
   }
 };
 
-inline static uint32_t getAlpha(uint32_t color) {
+inline static uint32_t get_alpha(uint32_t color) {
   return (color & 0xff000000u) >> 24;
 }
 
-static bool populateBounds(const std::vector<Range>& padding,
-                           const std::vector<Range>& layoutBounds,
-                           const std::vector<Range>& stretchRegions,
-                           const int32_t length, int32_t* paddingStart,
-                           int32_t* paddingEnd, int32_t* layoutStart,
-                           int32_t* layoutEnd, const StringPiece& edgeName,
-                           std::string* err) {
+static bool PopulateBounds(const std::vector<Range>& padding,
+                           const std::vector<Range>& layout_bounds,
+                           const std::vector<Range>& stretch_regions,
+                           const int32_t length, int32_t* padding_start,
+                           int32_t* padding_end, int32_t* layout_start,
+                           int32_t* layout_end, const StringPiece& edge_name,
+                           std::string* out_err) {
   if (padding.size() > 1) {
-    std::stringstream errStream;
-    errStream << "too many padding sections on " << edgeName << " border";
-    *err = errStream.str();
+    std::stringstream err_stream;
+    err_stream << "too many padding sections on " << edge_name << " border";
+    *out_err = err_stream.str();
     return false;
   }
 
-  *paddingStart = 0;
-  *paddingEnd = 0;
+  *padding_start = 0;
+  *padding_end = 0;
   if (!padding.empty()) {
     const Range& range = padding.front();
-    *paddingStart = range.start;
-    *paddingEnd = length - range.end;
-  } else if (!stretchRegions.empty()) {
+    *padding_start = range.start;
+    *padding_end = length - range.end;
+  } else if (!stretch_regions.empty()) {
     // No padding was defined. Compute the padding from the first and last
     // stretch regions.
-    *paddingStart = stretchRegions.front().start;
-    *paddingEnd = length - stretchRegions.back().end;
+    *padding_start = stretch_regions.front().start;
+    *padding_end = length - stretch_regions.back().end;
   }
 
-  if (layoutBounds.size() > 2) {
-    std::stringstream errStream;
-    errStream << "too many layout bounds sections on " << edgeName << " border";
-    *err = errStream.str();
+  if (layout_bounds.size() > 2) {
+    std::stringstream err_stream;
+    err_stream << "too many layout bounds sections on " << edge_name
+               << " border";
+    *out_err = err_stream.str();
     return false;
   }
 
-  *layoutStart = 0;
-  *layoutEnd = 0;
-  if (layoutBounds.size() >= 1) {
-    const Range& range = layoutBounds.front();
+  *layout_start = 0;
+  *layout_end = 0;
+  if (layout_bounds.size() >= 1) {
+    const Range& range = layout_bounds.front();
     // If there is only one layout bound segment, it might not start at 0, but
     // then it should
     // end at length.
     if (range.start != 0 && range.end != length) {
-      std::stringstream errStream;
-      errStream << "layout bounds on " << edgeName
-                << " border must start at edge";
-      *err = errStream.str();
+      std::stringstream err_stream;
+      err_stream << "layout bounds on " << edge_name
+                 << " border must start at edge";
+      *out_err = err_stream.str();
       return false;
     }
-    *layoutStart = range.end;
+    *layout_start = range.end;
 
-    if (layoutBounds.size() >= 2) {
-      const Range& range = layoutBounds.back();
+    if (layout_bounds.size() >= 2) {
+      const Range& range = layout_bounds.back();
       if (range.end != length) {
-        std::stringstream errStream;
-        errStream << "layout bounds on " << edgeName
-                  << " border must start at edge";
-        *err = errStream.str();
+        std::stringstream err_stream;
+        err_stream << "layout bounds on " << edge_name
+                   << " border must start at edge";
+        *out_err = err_stream.str();
         return false;
       }
-      *layoutEnd = length - range.start;
+      *layout_end = length - range.start;
     }
   }
   return true;
 }
 
-static int32_t calculateSegmentCount(const std::vector<Range>& stretchRegions,
+static int32_t CalculateSegmentCount(const std::vector<Range>& stretch_regions,
                                      int32_t length) {
-  if (stretchRegions.size() == 0) {
+  if (stretch_regions.size() == 0) {
     return 0;
   }
 
-  const bool startIsFixed = stretchRegions.front().start != 0;
-  const bool endIsFixed = stretchRegions.back().end != length;
+  const bool start_is_fixed = stretch_regions.front().start != 0;
+  const bool end_is_fixed = stretch_regions.back().end != length;
   int32_t modifier = 0;
-  if (startIsFixed && endIsFixed) {
+  if (start_is_fixed && end_is_fixed) {
     modifier = 1;
-  } else if (!startIsFixed && !endIsFixed) {
+  } else if (!start_is_fixed && !end_is_fixed) {
     modifier = -1;
   }
-  return static_cast<int32_t>(stretchRegions.size()) * 2 + modifier;
+  return static_cast<int32_t>(stretch_regions.size()) * 2 + modifier;
 }
 
-static uint32_t getRegionColor(uint8_t** rows, const Bounds& region) {
+static uint32_t GetRegionColor(uint8_t** rows, const Bounds& region) {
   // Sample the first pixel to compare against.
-  const uint32_t expectedColor =
-      NinePatch::packRGBA(rows[region.top] + region.left * 4);
+  const uint32_t expected_color =
+      NinePatch::PackRGBA(rows[region.top] + region.left * 4);
   for (int32_t y = region.top; y < region.bottom; y++) {
     const uint8_t* row = rows[y];
     for (int32_t x = region.left; x < region.right; x++) {
-      const uint32_t color = NinePatch::packRGBA(row + x * 4);
-      if (getAlpha(color) == 0) {
+      const uint32_t color = NinePatch::PackRGBA(row + x * 4);
+      if (get_alpha(color) == 0) {
         // The color is transparent.
         // If the expectedColor is not transparent, NO_COLOR.
-        if (getAlpha(expectedColor) != 0) {
+        if (get_alpha(expected_color) != 0) {
           return android::Res_png_9patch::NO_COLOR;
         }
-      } else if (color != expectedColor) {
+      } else if (color != expected_color) {
         return android::Res_png_9patch::NO_COLOR;
       }
     }
   }
 
-  if (getAlpha(expectedColor) == 0) {
+  if (get_alpha(expected_color) == 0) {
     return android::Res_png_9patch::TRANSPARENT_COLOR;
   }
-  return expectedColor;
+  return expected_color;
 }
 
-// Fills outColors with each 9-patch section's colour. If the whole section is
+// Fills out_colors with each 9-patch section's color. If the whole section is
 // transparent,
-// it gets the special TRANSPARENT colour. If the whole section is the same
-// colour, it is assigned
-// that colour. Otherwise it gets the special NO_COLOR colour.
+// it gets the special TRANSPARENT color. If the whole section is the same
+// color, it is assigned
+// that color. Otherwise it gets the special NO_COLOR color.
 //
 // Note that the rows contain the 9-patch 1px border, and the indices in the
 // stretch regions are
@@ -332,63 +336,63 @@
 // the indices must be offset by 1.
 //
 // width and height also include the 9-patch 1px border.
-static void calculateRegionColors(
-    uint8_t** rows, const std::vector<Range>& horizontalStretchRegions,
-    const std::vector<Range>& verticalStretchRegions, const int32_t width,
-    const int32_t height, std::vector<uint32_t>* outColors) {
-  int32_t nextTop = 0;
+static void CalculateRegionColors(
+    uint8_t** rows, const std::vector<Range>& horizontal_stretch_regions,
+    const std::vector<Range>& vertical_stretch_regions, const int32_t width,
+    const int32_t height, std::vector<uint32_t>* out_colors) {
+  int32_t next_top = 0;
   Bounds bounds;
-  auto rowIter = verticalStretchRegions.begin();
-  while (nextTop != height) {
-    if (rowIter != verticalStretchRegions.end()) {
-      if (nextTop != rowIter->start) {
+  auto row_iter = vertical_stretch_regions.begin();
+  while (next_top != height) {
+    if (row_iter != vertical_stretch_regions.end()) {
+      if (next_top != row_iter->start) {
         // This is a fixed segment.
         // Offset the bounds by 1 to accommodate the border.
-        bounds.top = nextTop + 1;
-        bounds.bottom = rowIter->start + 1;
-        nextTop = rowIter->start;
+        bounds.top = next_top + 1;
+        bounds.bottom = row_iter->start + 1;
+        next_top = row_iter->start;
       } else {
         // This is a stretchy segment.
         // Offset the bounds by 1 to accommodate the border.
-        bounds.top = rowIter->start + 1;
-        bounds.bottom = rowIter->end + 1;
-        nextTop = rowIter->end;
-        ++rowIter;
+        bounds.top = row_iter->start + 1;
+        bounds.bottom = row_iter->end + 1;
+        next_top = row_iter->end;
+        ++row_iter;
       }
     } else {
       // This is the end, fixed section.
       // Offset the bounds by 1 to accommodate the border.
-      bounds.top = nextTop + 1;
+      bounds.top = next_top + 1;
       bounds.bottom = height + 1;
-      nextTop = height;
+      next_top = height;
     }
 
-    int32_t nextLeft = 0;
-    auto colIter = horizontalStretchRegions.begin();
-    while (nextLeft != width) {
-      if (colIter != horizontalStretchRegions.end()) {
-        if (nextLeft != colIter->start) {
+    int32_t next_left = 0;
+    auto col_iter = horizontal_stretch_regions.begin();
+    while (next_left != width) {
+      if (col_iter != horizontal_stretch_regions.end()) {
+        if (next_left != col_iter->start) {
           // This is a fixed segment.
           // Offset the bounds by 1 to accommodate the border.
-          bounds.left = nextLeft + 1;
-          bounds.right = colIter->start + 1;
-          nextLeft = colIter->start;
+          bounds.left = next_left + 1;
+          bounds.right = col_iter->start + 1;
+          next_left = col_iter->start;
         } else {
           // This is a stretchy segment.
           // Offset the bounds by 1 to accommodate the border.
-          bounds.left = colIter->start + 1;
-          bounds.right = colIter->end + 1;
-          nextLeft = colIter->end;
-          ++colIter;
+          bounds.left = col_iter->start + 1;
+          bounds.right = col_iter->end + 1;
+          next_left = col_iter->end;
+          ++col_iter;
         }
       } else {
         // This is the end, fixed section.
         // Offset the bounds by 1 to accommodate the border.
-        bounds.left = nextLeft + 1;
+        bounds.left = next_left + 1;
         bounds.right = width + 1;
-        nextLeft = width;
+        next_left = width;
       }
-      outColors->push_back(getRegionColor(rows, bounds));
+      out_colors->push_back(GetRegionColor(rows, bounds));
     }
   }
 }
@@ -397,12 +401,12 @@
 // alpha value begins
 // (on both sides).
 template <typename ImageLine>
-static void findOutlineInsets(const ImageLine* imageLine, int32_t* outStart,
-                              int32_t* outEnd) {
-  *outStart = 0;
-  *outEnd = 0;
+static void FindOutlineInsets(const ImageLine* image_line, int32_t* out_start,
+                              int32_t* out_end) {
+  *out_start = 0;
+  *out_end = 0;
 
-  const int32_t length = imageLine->getLength();
+  const int32_t length = image_line->GetLength();
   if (length < 3) {
     return;
   }
@@ -413,179 +417,181 @@
   const int32_t mid2 = length / 2;
   const int32_t mid1 = mid2 + (length % 2);
 
-  uint32_t maxAlpha = 0;
-  for (int32_t i = 0; i < mid1 && maxAlpha != 0xff; i++) {
-    uint32_t alpha = getAlpha(imageLine->getColor(i));
-    if (alpha > maxAlpha) {
-      maxAlpha = alpha;
-      *outStart = i;
+  uint32_t max_alpha = 0;
+  for (int32_t i = 0; i < mid1 && max_alpha != 0xff; i++) {
+    uint32_t alpha = get_alpha(image_line->GetColor(i));
+    if (alpha > max_alpha) {
+      max_alpha = alpha;
+      *out_start = i;
     }
   }
 
-  maxAlpha = 0;
-  for (int32_t i = length - 1; i >= mid2 && maxAlpha != 0xff; i--) {
-    uint32_t alpha = getAlpha(imageLine->getColor(i));
-    if (alpha > maxAlpha) {
-      maxAlpha = alpha;
-      *outEnd = length - (i + 1);
+  max_alpha = 0;
+  for (int32_t i = length - 1; i >= mid2 && max_alpha != 0xff; i--) {
+    uint32_t alpha = get_alpha(image_line->GetColor(i));
+    if (alpha > max_alpha) {
+      max_alpha = alpha;
+      *out_end = length - (i + 1);
     }
   }
   return;
 }
 
 template <typename ImageLine>
-static uint32_t findMaxAlpha(const ImageLine* imageLine) {
-  const int32_t length = imageLine->getLength();
-  uint32_t maxAlpha = 0;
-  for (int32_t idx = 0; idx < length && maxAlpha != 0xff; idx++) {
-    uint32_t alpha = getAlpha(imageLine->getColor(idx));
-    if (alpha > maxAlpha) {
-      maxAlpha = alpha;
+static uint32_t FindMaxAlpha(const ImageLine* image_line) {
+  const int32_t length = image_line->GetLength();
+  uint32_t max_alpha = 0;
+  for (int32_t idx = 0; idx < length && max_alpha != 0xff; idx++) {
+    uint32_t alpha = get_alpha(image_line->GetColor(idx));
+    if (alpha > max_alpha) {
+      max_alpha = alpha;
     }
   }
-  return maxAlpha;
+  return max_alpha;
 }
 
 // Pack the pixels in as 0xAARRGGBB (as 9-patch expects it).
-uint32_t NinePatch::packRGBA(const uint8_t* pixel) {
+uint32_t NinePatch::PackRGBA(const uint8_t* pixel) {
   return (pixel[3] << 24) | (pixel[0] << 16) | (pixel[1] << 8) | pixel[2];
 }
 
-std::unique_ptr<NinePatch> NinePatch::create(uint8_t** rows,
+std::unique_ptr<NinePatch> NinePatch::Create(uint8_t** rows,
                                              const int32_t width,
                                              const int32_t height,
-                                             std::string* err) {
+                                             std::string* out_err) {
   if (width < 3 || height < 3) {
-    *err = "image must be at least 3x3 (1x1 image with 1 pixel border)";
+    *out_err = "image must be at least 3x3 (1x1 image with 1 pixel border)";
     return {};
   }
 
-  std::vector<Range> horizontalPadding;
-  std::vector<Range> horizontalOpticalBounds;
-  std::vector<Range> verticalPadding;
-  std::vector<Range> verticalOpticalBounds;
-  std::vector<Range> unexpectedRanges;
-  std::unique_ptr<ColorValidator> colorValidator;
+  std::vector<Range> horizontal_padding;
+  std::vector<Range> horizontal_layout_bounds;
+  std::vector<Range> vertical_padding;
+  std::vector<Range> vertical_layout_bounds;
+  std::vector<Range> unexpected_ranges;
+  std::unique_ptr<ColorValidator> color_validator;
 
   if (rows[0][3] == 0) {
-    colorValidator = util::make_unique<TransparentNeutralColorValidator>();
-  } else if (packRGBA(rows[0]) == kColorOpaqueWhite) {
-    colorValidator = util::make_unique<WhiteNeutralColorValidator>();
+    color_validator = util::make_unique<TransparentNeutralColorValidator>();
+  } else if (PackRGBA(rows[0]) == kColorOpaqueWhite) {
+    color_validator = util::make_unique<WhiteNeutralColorValidator>();
   } else {
-    *err = "top-left corner pixel must be either opaque white or transparent";
+    *out_err =
+        "top-left corner pixel must be either opaque white or transparent";
     return {};
   }
 
   // Private constructor, can't use make_unique.
-  auto ninePatch = std::unique_ptr<NinePatch>(new NinePatch());
+  auto nine_patch = std::unique_ptr<NinePatch>(new NinePatch());
 
-  HorizontalImageLine topRow(rows, 0, 0, width);
-  if (!fillRanges(&topRow, colorValidator.get(),
-                  &ninePatch->horizontalStretchRegions, &unexpectedRanges,
-                  err)) {
+  HorizontalImageLine top_row(rows, 0, 0, width);
+  if (!FillRanges(&top_row, color_validator.get(),
+                  &nine_patch->horizontal_stretch_regions, &unexpected_ranges,
+                  out_err)) {
     return {};
   }
 
-  if (!unexpectedRanges.empty()) {
-    const Range& range = unexpectedRanges[0];
-    std::stringstream errStream;
-    errStream << "found unexpected optical bounds (red pixel) on top border "
-              << "at x=" << range.start + 1;
-    *err = errStream.str();
+  if (!unexpected_ranges.empty()) {
+    const Range& range = unexpected_ranges[0];
+    std::stringstream err_stream;
+    err_stream << "found unexpected optical bounds (red pixel) on top border "
+               << "at x=" << range.start + 1;
+    *out_err = err_stream.str();
     return {};
   }
 
-  VerticalImageLine leftCol(rows, 0, 0, height);
-  if (!fillRanges(&leftCol, colorValidator.get(),
-                  &ninePatch->verticalStretchRegions, &unexpectedRanges, err)) {
+  VerticalImageLine left_col(rows, 0, 0, height);
+  if (!FillRanges(&left_col, color_validator.get(),
+                  &nine_patch->vertical_stretch_regions, &unexpected_ranges,
+                  out_err)) {
     return {};
   }
 
-  if (!unexpectedRanges.empty()) {
-    const Range& range = unexpectedRanges[0];
-    std::stringstream errStream;
-    errStream << "found unexpected optical bounds (red pixel) on left border "
-              << "at y=" << range.start + 1;
+  if (!unexpected_ranges.empty()) {
+    const Range& range = unexpected_ranges[0];
+    std::stringstream err_stream;
+    err_stream << "found unexpected optical bounds (red pixel) on left border "
+               << "at y=" << range.start + 1;
     return {};
   }
 
-  HorizontalImageLine bottomRow(rows, 0, height - 1, width);
-  if (!fillRanges(&bottomRow, colorValidator.get(), &horizontalPadding,
-                  &horizontalOpticalBounds, err)) {
+  HorizontalImageLine bottom_row(rows, 0, height - 1, width);
+  if (!FillRanges(&bottom_row, color_validator.get(), &horizontal_padding,
+                  &horizontal_layout_bounds, out_err)) {
     return {};
   }
 
-  if (!populateBounds(horizontalPadding, horizontalOpticalBounds,
-                      ninePatch->horizontalStretchRegions, width - 2,
-                      &ninePatch->padding.left, &ninePatch->padding.right,
-                      &ninePatch->layoutBounds.left,
-                      &ninePatch->layoutBounds.right, "bottom", err)) {
+  if (!PopulateBounds(horizontal_padding, horizontal_layout_bounds,
+                      nine_patch->horizontal_stretch_regions, width - 2,
+                      &nine_patch->padding.left, &nine_patch->padding.right,
+                      &nine_patch->layout_bounds.left,
+                      &nine_patch->layout_bounds.right, "bottom", out_err)) {
     return {};
   }
 
-  VerticalImageLine rightCol(rows, width - 1, 0, height);
-  if (!fillRanges(&rightCol, colorValidator.get(), &verticalPadding,
-                  &verticalOpticalBounds, err)) {
+  VerticalImageLine right_col(rows, width - 1, 0, height);
+  if (!FillRanges(&right_col, color_validator.get(), &vertical_padding,
+                  &vertical_layout_bounds, out_err)) {
     return {};
   }
 
-  if (!populateBounds(verticalPadding, verticalOpticalBounds,
-                      ninePatch->verticalStretchRegions, height - 2,
-                      &ninePatch->padding.top, &ninePatch->padding.bottom,
-                      &ninePatch->layoutBounds.top,
-                      &ninePatch->layoutBounds.bottom, "right", err)) {
+  if (!PopulateBounds(vertical_padding, vertical_layout_bounds,
+                      nine_patch->vertical_stretch_regions, height - 2,
+                      &nine_patch->padding.top, &nine_patch->padding.bottom,
+                      &nine_patch->layout_bounds.top,
+                      &nine_patch->layout_bounds.bottom, "right", out_err)) {
     return {};
   }
 
   // Fill the region colors of the 9-patch.
-  const int32_t numRows =
-      calculateSegmentCount(ninePatch->horizontalStretchRegions, width - 2);
-  const int32_t numCols =
-      calculateSegmentCount(ninePatch->verticalStretchRegions, height - 2);
-  if ((int64_t)numRows * (int64_t)numCols > 0x7f) {
-    *err = "too many regions in 9-patch";
+  const int32_t num_rows =
+      CalculateSegmentCount(nine_patch->horizontal_stretch_regions, width - 2);
+  const int32_t num_cols =
+      CalculateSegmentCount(nine_patch->vertical_stretch_regions, height - 2);
+  if ((int64_t)num_rows * (int64_t)num_cols > 0x7f) {
+    *out_err = "too many regions in 9-patch";
     return {};
   }
 
-  ninePatch->regionColors.reserve(numRows * numCols);
-  calculateRegionColors(rows, ninePatch->horizontalStretchRegions,
-                        ninePatch->verticalStretchRegions, width - 2,
-                        height - 2, &ninePatch->regionColors);
+  nine_patch->region_colors.reserve(num_rows * num_cols);
+  CalculateRegionColors(rows, nine_patch->horizontal_stretch_regions,
+                        nine_patch->vertical_stretch_regions, width - 2,
+                        height - 2, &nine_patch->region_colors);
 
   // Compute the outline based on opacity.
 
   // Find left and right extent of 9-patch content on center row.
-  HorizontalImageLine midRow(rows, 1, height / 2, width - 2);
-  findOutlineInsets(&midRow, &ninePatch->outline.left,
-                    &ninePatch->outline.right);
+  HorizontalImageLine mid_row(rows, 1, height / 2, width - 2);
+  FindOutlineInsets(&mid_row, &nine_patch->outline.left,
+                    &nine_patch->outline.right);
 
   // Find top and bottom extent of 9-patch content on center column.
-  VerticalImageLine midCol(rows, width / 2, 1, height - 2);
-  findOutlineInsets(&midCol, &ninePatch->outline.top,
-                    &ninePatch->outline.bottom);
+  VerticalImageLine mid_col(rows, width / 2, 1, height - 2);
+  FindOutlineInsets(&mid_col, &nine_patch->outline.top,
+                    &nine_patch->outline.bottom);
 
-  const int32_t outlineWidth =
-      (width - 2) - ninePatch->outline.left - ninePatch->outline.right;
-  const int32_t outlineHeight =
-      (height - 2) - ninePatch->outline.top - ninePatch->outline.bottom;
+  const int32_t outline_width =
+      (width - 2) - nine_patch->outline.left - nine_patch->outline.right;
+  const int32_t outline_height =
+      (height - 2) - nine_patch->outline.top - nine_patch->outline.bottom;
 
   // Find the largest alpha value within the outline area.
-  HorizontalImageLine outlineMidRow(
-      rows, 1 + ninePatch->outline.left,
-      1 + ninePatch->outline.top + (outlineHeight / 2), outlineWidth);
-  VerticalImageLine outlineMidCol(
-      rows, 1 + ninePatch->outline.left + (outlineWidth / 2),
-      1 + ninePatch->outline.top, outlineHeight);
-  ninePatch->outlineAlpha =
-      std::max(findMaxAlpha(&outlineMidRow), findMaxAlpha(&outlineMidCol));
+  HorizontalImageLine outline_mid_row(
+      rows, 1 + nine_patch->outline.left,
+      1 + nine_patch->outline.top + (outline_height / 2), outline_width);
+  VerticalImageLine outline_mid_col(
+      rows, 1 + nine_patch->outline.left + (outline_width / 2),
+      1 + nine_patch->outline.top, outline_height);
+  nine_patch->outline_alpha =
+      std::max(FindMaxAlpha(&outline_mid_row), FindMaxAlpha(&outline_mid_col));
 
   // Assuming the image is a round rect, compute the radius by marching
   // diagonally from the top left corner towards the center.
-  DiagonalImageLine diagonal(rows, 1 + ninePatch->outline.left,
-                             1 + ninePatch->outline.top, 1, 1,
-                             std::min(outlineWidth, outlineHeight));
-  int32_t topLeft, bottomRight;
-  findOutlineInsets(&diagonal, &topLeft, &bottomRight);
+  DiagonalImageLine diagonal(rows, 1 + nine_patch->outline.left,
+                             1 + nine_patch->outline.top, 1, 1,
+                             std::min(outline_width, outline_height));
+  int32_t top_left, bottom_right;
+  FindOutlineInsets(&diagonal, &top_left, &bottom_right);
 
   /* Determine source radius based upon inset:
    *     sqrt(r^2 + r^2) = sqrt(i^2 + i^2) + r
@@ -593,15 +599,15 @@
    *     (sqrt(2) - 1) * r = sqrt(2) * i
    *     r = sqrt(2) / (sqrt(2) - 1) * i
    */
-  ninePatch->outlineRadius = 3.4142f * topLeft;
-  return ninePatch;
+  nine_patch->outline_radius = 3.4142f * top_left;
+  return nine_patch;
 }
 
-std::unique_ptr<uint8_t[]> NinePatch::serializeBase(size_t* outLen) const {
+std::unique_ptr<uint8_t[]> NinePatch::SerializeBase(size_t* outLen) const {
   android::Res_png_9patch data;
-  data.numXDivs = static_cast<uint8_t>(horizontalStretchRegions.size()) * 2;
-  data.numYDivs = static_cast<uint8_t>(verticalStretchRegions.size()) * 2;
-  data.numColors = static_cast<uint8_t>(regionColors.size());
+  data.numXDivs = static_cast<uint8_t>(horizontal_stretch_regions.size()) * 2;
+  data.numYDivs = static_cast<uint8_t>(vertical_stretch_regions.size()) * 2;
+  data.numColors = static_cast<uint8_t>(region_colors.size());
   data.paddingLeft = padding.left;
   data.paddingRight = padding.right;
   data.paddingTop = padding.top;
@@ -609,8 +615,8 @@
 
   auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[data.serializedSize()]);
   android::Res_png_9patch::serialize(
-      data, (const int32_t*)horizontalStretchRegions.data(),
-      (const int32_t*)verticalStretchRegions.data(), regionColors.data(),
+      data, (const int32_t*)horizontal_stretch_regions.data(),
+      (const int32_t*)vertical_stretch_regions.data(), region_colors.data(),
       buffer.get());
   // Convert to file endianness.
   reinterpret_cast<android::Res_png_9patch*>(buffer.get())->deviceToFile();
@@ -619,32 +625,32 @@
   return buffer;
 }
 
-std::unique_ptr<uint8_t[]> NinePatch::serializeLayoutBounds(
-    size_t* outLen) const {
-  size_t chunkLen = sizeof(uint32_t) * 4;
-  auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunkLen]);
+std::unique_ptr<uint8_t[]> NinePatch::SerializeLayoutBounds(
+    size_t* out_len) const {
+  size_t chunk_len = sizeof(uint32_t) * 4;
+  auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunk_len]);
   uint8_t* cursor = buffer.get();
 
-  memcpy(cursor, &layoutBounds.left, sizeof(layoutBounds.left));
-  cursor += sizeof(layoutBounds.left);
+  memcpy(cursor, &layout_bounds.left, sizeof(layout_bounds.left));
+  cursor += sizeof(layout_bounds.left);
 
-  memcpy(cursor, &layoutBounds.top, sizeof(layoutBounds.top));
-  cursor += sizeof(layoutBounds.top);
+  memcpy(cursor, &layout_bounds.top, sizeof(layout_bounds.top));
+  cursor += sizeof(layout_bounds.top);
 
-  memcpy(cursor, &layoutBounds.right, sizeof(layoutBounds.right));
-  cursor += sizeof(layoutBounds.right);
+  memcpy(cursor, &layout_bounds.right, sizeof(layout_bounds.right));
+  cursor += sizeof(layout_bounds.right);
 
-  memcpy(cursor, &layoutBounds.bottom, sizeof(layoutBounds.bottom));
-  cursor += sizeof(layoutBounds.bottom);
+  memcpy(cursor, &layout_bounds.bottom, sizeof(layout_bounds.bottom));
+  cursor += sizeof(layout_bounds.bottom);
 
-  *outLen = chunkLen;
+  *out_len = chunk_len;
   return buffer;
 }
 
-std::unique_ptr<uint8_t[]> NinePatch::serializeRoundedRectOutline(
-    size_t* outLen) const {
-  size_t chunkLen = sizeof(uint32_t) * 6;
-  auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunkLen]);
+std::unique_ptr<uint8_t[]> NinePatch::SerializeRoundedRectOutline(
+    size_t* out_len) const {
+  size_t chunk_len = sizeof(uint32_t) * 6;
+  auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunk_len]);
   uint8_t* cursor = buffer.get();
 
   memcpy(cursor, &outline.left, sizeof(outline.left));
@@ -659,12 +665,12 @@
   memcpy(cursor, &outline.bottom, sizeof(outline.bottom));
   cursor += sizeof(outline.bottom);
 
-  *((float*)cursor) = outlineRadius;
-  cursor += sizeof(outlineRadius);
+  *((float*)cursor) = outline_radius;
+  cursor += sizeof(outline_radius);
 
-  *((uint32_t*)cursor) = outlineAlpha;
+  *((uint32_t*)cursor) = outline_alpha;
 
-  *outLen = chunkLen;
+  *out_len = chunk_len;
   return buffer;
 }
 
@@ -677,16 +683,16 @@
              << " r=" << bounds.right << " b=" << bounds.bottom;
 }
 
-::std::ostream& operator<<(::std::ostream& out, const NinePatch& ninePatch) {
+::std::ostream& operator<<(::std::ostream& out, const NinePatch& nine_patch) {
   return out << "horizontalStretch:"
-             << util::joiner(ninePatch.horizontalStretchRegions, " ")
+             << util::Joiner(nine_patch.horizontal_stretch_regions, " ")
              << " verticalStretch:"
-             << util::joiner(ninePatch.verticalStretchRegions, " ")
-             << " padding: " << ninePatch.padding
-             << ", bounds: " << ninePatch.layoutBounds
-             << ", outline: " << ninePatch.outline
-             << " rad=" << ninePatch.outlineRadius
-             << " alpha=" << ninePatch.outlineAlpha;
+             << util::Joiner(nine_patch.vertical_stretch_regions, " ")
+             << " padding: " << nine_patch.padding
+             << ", bounds: " << nine_patch.layout_bounds
+             << ", outline: " << nine_patch.outline
+             << " rad=" << nine_patch.outline_radius
+             << " alpha=" << nine_patch.outline_alpha;
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/compile/NinePatch_test.cpp b/tools/aapt2/compile/NinePatch_test.cpp
index b8eda09..f54bb2e 100644
--- a/tools/aapt2/compile/NinePatch_test.cpp
+++ b/tools/aapt2/compile/NinePatch_test.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "compile/Image.h"
+
 #include "test/Test.h"
 
 namespace aapt {
@@ -182,169 +183,168 @@
 
 TEST(NinePatchTest, Minimum3x3) {
   std::string err;
-  EXPECT_EQ(nullptr, NinePatch::create(k2x2, 2, 2, &err));
+  EXPECT_EQ(nullptr, NinePatch::Create(k2x2, 2, 2, &err));
   EXPECT_FALSE(err.empty());
 }
 
 TEST(NinePatchTest, MixedNeutralColors) {
   std::string err;
-  EXPECT_EQ(nullptr, NinePatch::create(kMixedNeutralColor3x3, 3, 3, &err));
+  EXPECT_EQ(nullptr, NinePatch::Create(kMixedNeutralColor3x3, 3, 3, &err));
   EXPECT_FALSE(err.empty());
 }
 
 TEST(NinePatchTest, TransparentNeutralColor) {
   std::string err;
   EXPECT_NE(nullptr,
-            NinePatch::create(kTransparentNeutralColor3x3, 3, 3, &err));
+            NinePatch::Create(kTransparentNeutralColor3x3, 3, 3, &err));
 }
 
 TEST(NinePatchTest, SingleStretchRegion) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kSingleStretch7x6, 7, 6, &err);
-  ASSERT_NE(nullptr, ninePatch);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kSingleStretch7x6, 7, 6, &err);
+  ASSERT_NE(nullptr, nine_patch);
 
-  ASSERT_EQ(1u, ninePatch->horizontalStretchRegions.size());
-  ASSERT_EQ(1u, ninePatch->verticalStretchRegions.size());
+  ASSERT_EQ(1u, nine_patch->horizontal_stretch_regions.size());
+  ASSERT_EQ(1u, nine_patch->vertical_stretch_regions.size());
 
-  EXPECT_EQ(Range(1, 4), ninePatch->horizontalStretchRegions.front());
-  EXPECT_EQ(Range(1, 3), ninePatch->verticalStretchRegions.front());
+  EXPECT_EQ(Range(1, 4), nine_patch->horizontal_stretch_regions.front());
+  EXPECT_EQ(Range(1, 3), nine_patch->vertical_stretch_regions.front());
 }
 
 TEST(NinePatchTest, MultipleStretchRegions) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kMultipleStretch10x7, 10, 7, &err);
-  ASSERT_NE(nullptr, ninePatch);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kMultipleStretch10x7, 10, 7, &err);
+  ASSERT_NE(nullptr, nine_patch);
 
-  ASSERT_EQ(3u, ninePatch->horizontalStretchRegions.size());
-  ASSERT_EQ(2u, ninePatch->verticalStretchRegions.size());
+  ASSERT_EQ(3u, nine_patch->horizontal_stretch_regions.size());
+  ASSERT_EQ(2u, nine_patch->vertical_stretch_regions.size());
 
-  EXPECT_EQ(Range(1, 2), ninePatch->horizontalStretchRegions[0]);
-  EXPECT_EQ(Range(3, 5), ninePatch->horizontalStretchRegions[1]);
-  EXPECT_EQ(Range(6, 7), ninePatch->horizontalStretchRegions[2]);
+  EXPECT_EQ(Range(1, 2), nine_patch->horizontal_stretch_regions[0]);
+  EXPECT_EQ(Range(3, 5), nine_patch->horizontal_stretch_regions[1]);
+  EXPECT_EQ(Range(6, 7), nine_patch->horizontal_stretch_regions[2]);
 
-  EXPECT_EQ(Range(0, 2), ninePatch->verticalStretchRegions[0]);
-  EXPECT_EQ(Range(3, 5), ninePatch->verticalStretchRegions[1]);
+  EXPECT_EQ(Range(0, 2), nine_patch->vertical_stretch_regions[0]);
+  EXPECT_EQ(Range(3, 5), nine_patch->vertical_stretch_regions[1]);
 }
 
 TEST(NinePatchTest, InferPaddingFromStretchRegions) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kMultipleStretch10x7, 10, 7, &err);
-  ASSERT_NE(nullptr, ninePatch);
-  EXPECT_EQ(Bounds(1, 0, 1, 0), ninePatch->padding);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kMultipleStretch10x7, 10, 7, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(1, 0, 1, 0), nine_patch->padding);
 }
 
 TEST(NinePatchTest, Padding) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kPadding6x5, 6, 5, &err);
-  ASSERT_NE(nullptr, ninePatch);
-  EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->padding);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kPadding6x5, 6, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->padding);
 }
 
 TEST(NinePatchTest, LayoutBoundsAreOnWrongEdge) {
   std::string err;
-  EXPECT_EQ(nullptr, NinePatch::create(kLayoutBoundsWrongEdge3x3, 3, 3, &err));
+  EXPECT_EQ(nullptr, NinePatch::Create(kLayoutBoundsWrongEdge3x3, 3, 3, &err));
   EXPECT_FALSE(err.empty());
 }
 
 TEST(NinePatchTest, LayoutBoundsMustTouchEdges) {
   std::string err;
   EXPECT_EQ(nullptr,
-            NinePatch::create(kLayoutBoundsNotEdgeAligned5x5, 5, 5, &err));
+            NinePatch::Create(kLayoutBoundsNotEdgeAligned5x5, 5, 5, &err));
   EXPECT_FALSE(err.empty());
 }
 
 TEST(NinePatchTest, LayoutBounds) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kLayoutBounds5x5, 5, 5, &err);
-  ASSERT_NE(nullptr, ninePatch);
-  EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->layoutBounds);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kLayoutBounds5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->layout_bounds);
 
-  ninePatch = NinePatch::create(kAsymmetricLayoutBounds5x5, 5, 5, &err);
-  ASSERT_NE(nullptr, ninePatch);
-  EXPECT_EQ(Bounds(1, 1, 0, 0), ninePatch->layoutBounds);
+  nine_patch = NinePatch::Create(kAsymmetricLayoutBounds5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(1, 1, 0, 0), nine_patch->layout_bounds);
 }
 
 TEST(NinePatchTest, PaddingAndLayoutBounds) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kPaddingAndLayoutBounds5x5, 5, 5, &err);
-  ASSERT_NE(nullptr, ninePatch);
-  EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->padding);
-  EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->layoutBounds);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kPaddingAndLayoutBounds5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->padding);
+  EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->layout_bounds);
 }
 
 TEST(NinePatchTest, RegionColorsAreCorrect) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kColorfulImage5x5, 5, 5, &err);
-  ASSERT_NE(nullptr, ninePatch);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kColorfulImage5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
 
-  std::vector<uint32_t> expectedColors = {
-      NinePatch::packRGBA((uint8_t*)RED),
+  std::vector<uint32_t> expected_colors = {
+      NinePatch::PackRGBA((uint8_t*)RED),
       (uint32_t)android::Res_png_9patch::NO_COLOR,
-      NinePatch::packRGBA((uint8_t*)GREEN),
+      NinePatch::PackRGBA((uint8_t*)GREEN),
       (uint32_t)android::Res_png_9patch::TRANSPARENT_COLOR,
-      NinePatch::packRGBA((uint8_t*)BLUE),
-      NinePatch::packRGBA((uint8_t*)GREEN),
+      NinePatch::PackRGBA((uint8_t*)BLUE),
+      NinePatch::PackRGBA((uint8_t*)GREEN),
   };
-  EXPECT_EQ(expectedColors, ninePatch->regionColors);
+  EXPECT_EQ(expected_colors, nine_patch->region_colors);
 }
 
 TEST(NinePatchTest, OutlineFromOpaqueImage) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kOutlineOpaque10x10, 10, 10, &err);
-  ASSERT_NE(nullptr, ninePatch);
-  EXPECT_EQ(Bounds(2, 2, 2, 2), ninePatch->outline);
-  EXPECT_EQ(0x000000ffu, ninePatch->outlineAlpha);
-  EXPECT_EQ(0.0f, ninePatch->outlineRadius);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kOutlineOpaque10x10, 10, 10, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(2, 2, 2, 2), nine_patch->outline);
+  EXPECT_EQ(0x000000ffu, nine_patch->outline_alpha);
+  EXPECT_EQ(0.0f, nine_patch->outline_radius);
 }
 
 TEST(NinePatchTest, OutlineFromTranslucentImage) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kOutlineTranslucent10x10, 10, 10, &err);
-  ASSERT_NE(nullptr, ninePatch);
-  EXPECT_EQ(Bounds(3, 3, 3, 3), ninePatch->outline);
-  EXPECT_EQ(0x000000b3u, ninePatch->outlineAlpha);
-  EXPECT_EQ(0.0f, ninePatch->outlineRadius);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kOutlineTranslucent10x10, 10, 10, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(3, 3, 3, 3), nine_patch->outline);
+  EXPECT_EQ(0x000000b3u, nine_patch->outline_alpha);
+  EXPECT_EQ(0.0f, nine_patch->outline_radius);
 }
 
 TEST(NinePatchTest, OutlineFromOffCenterImage) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kOutlineOffsetTranslucent12x10, 12, 10, &err);
-  ASSERT_NE(nullptr, ninePatch);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kOutlineOffsetTranslucent12x10, 12, 10, &err);
+  ASSERT_NE(nullptr, nine_patch);
 
   // TODO(adamlesinski): The old AAPT algorithm searches from the outside to the
-  // middle
-  // for each inset. If the outline is shifted, the search may not find a closer
-  // bounds.
+  // middle for each inset. If the outline is shifted, the search may not find a
+  // closer bounds.
   // This check should be:
   //   EXPECT_EQ(Bounds(5, 3, 3, 3), ninePatch->outline);
-  // but until I know what behaviour I'm breaking, I will leave it at the
+  // but until I know what behavior I'm breaking, I will leave it at the
   // incorrect:
-  EXPECT_EQ(Bounds(4, 3, 3, 3), ninePatch->outline);
+  EXPECT_EQ(Bounds(4, 3, 3, 3), nine_patch->outline);
 
-  EXPECT_EQ(0x000000b3u, ninePatch->outlineAlpha);
-  EXPECT_EQ(0.0f, ninePatch->outlineRadius);
+  EXPECT_EQ(0x000000b3u, nine_patch->outline_alpha);
+  EXPECT_EQ(0.0f, nine_patch->outline_radius);
 }
 
 TEST(NinePatchTest, OutlineRadius) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kOutlineRadius5x5, 5, 5, &err);
-  ASSERT_NE(nullptr, ninePatch);
-  EXPECT_EQ(Bounds(0, 0, 0, 0), ninePatch->outline);
-  EXPECT_EQ(3.4142f, ninePatch->outlineRadius);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kOutlineRadius5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(0, 0, 0, 0), nine_patch->outline);
+  EXPECT_EQ(3.4142f, nine_patch->outline_radius);
 }
 
-::testing::AssertionResult bigEndianOne(uint8_t* cursor) {
+::testing::AssertionResult BigEndianOne(uint8_t* cursor) {
   if (cursor[0] == 0 && cursor[1] == 0 && cursor[2] == 0 && cursor[3] == 1) {
     return ::testing::AssertionSuccess();
   }
@@ -353,12 +353,12 @@
 
 TEST(NinePatchTest, SerializePngEndianness) {
   std::string err;
-  std::unique_ptr<NinePatch> ninePatch =
-      NinePatch::create(kStretchAndPadding5x5, 5, 5, &err);
-  ASSERT_NE(nullptr, ninePatch);
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kStretchAndPadding5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
 
   size_t len;
-  std::unique_ptr<uint8_t[]> data = ninePatch->serializeBase(&len);
+  std::unique_ptr<uint8_t[]> data = nine_patch->SerializeBase(&len);
   ASSERT_NE(nullptr, data);
   ASSERT_NE(0u, len);
 
@@ -368,10 +368,10 @@
   uint8_t* cursor = data.get() + 12;
 
   // Check that padding is big-endian. Expecting value 1.
-  EXPECT_TRUE(bigEndianOne(cursor));
-  EXPECT_TRUE(bigEndianOne(cursor + 4));
-  EXPECT_TRUE(bigEndianOne(cursor + 8));
-  EXPECT_TRUE(bigEndianOne(cursor + 12));
+  EXPECT_TRUE(BigEndianOne(cursor));
+  EXPECT_TRUE(BigEndianOne(cursor + 4));
+  EXPECT_TRUE(BigEndianOne(cursor + 8));
+  EXPECT_TRUE(BigEndianOne(cursor + 12));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/compile/Png.cpp b/tools/aapt2/compile/Png.cpp
index 9b5fa7e09..f1bc53e 100644
--- a/tools/aapt2/compile/Png.cpp
+++ b/tools/aapt2/compile/Png.cpp
@@ -89,7 +89,7 @@
 static void writeDataToStream(png_structp writePtr, png_bytep data,
                               png_size_t length) {
   BigBuffer* outBuffer = reinterpret_cast<BigBuffer*>(png_get_io_ptr(writePtr));
-  png_bytep buf = outBuffer->nextBlock<png_byte>(length);
+  png_bytep buf = outBuffer->NextBlock<png_byte>(length);
   memcpy(buf, data, length);
 }
 
@@ -98,13 +98,13 @@
 static void logWarning(png_structp readPtr, png_const_charp warningMessage) {
   IDiagnostics* diag =
       reinterpret_cast<IDiagnostics*>(png_get_error_ptr(readPtr));
-  diag->warn(DiagMessage() << warningMessage);
+  diag->Warn(DiagMessage() << warningMessage);
 }
 
 static bool readPng(IDiagnostics* diag, png_structp readPtr, png_infop infoPtr,
                     PngInfo* outInfo) {
   if (setjmp(png_jmpbuf(readPtr))) {
-    diag->error(DiagMessage() << "failed reading png");
+    diag->Error(DiagMessage() << "failed reading png");
     return false;
   }
 
@@ -373,7 +373,7 @@
     *colorType = PNG_COLOR_TYPE_PALETTE;
   } else {
     if (maxGrayDeviation <= grayscaleTolerance) {
-      diag->note(DiagMessage() << "forcing image to gray (max deviation = "
+      diag->Note(DiagMessage() << "forcing image to gray (max deviation = "
                                << maxGrayDeviation << ")");
       *colorType = isOpaque ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_GRAY_ALPHA;
     } else {
@@ -424,7 +424,7 @@
 static bool writePng(IDiagnostics* diag, png_structp writePtr,
                      png_infop infoPtr, PngInfo* info, int grayScaleTolerance) {
   if (setjmp(png_jmpbuf(writePtr))) {
-    diag->error(DiagMessage() << "failed to write png");
+    diag->Error(DiagMessage() << "failed to write png");
     return false;
   }
 
@@ -453,7 +453,7 @@
   png_set_compression_level(writePtr, Z_BEST_COMPRESSION);
 
   if (kDebug) {
-    diag->note(DiagMessage() << "writing image: w = " << info->width
+    diag->Note(DiagMessage() << "writing image: w = " << info->width
                              << ", h = " << info->height);
   }
 
@@ -476,23 +476,23 @@
   if (kDebug) {
     switch (colorType) {
       case PNG_COLOR_TYPE_PALETTE:
-        diag->note(DiagMessage() << "has " << paletteEntries << " colors"
+        diag->Note(DiagMessage() << "has " << paletteEntries << " colors"
                                  << (hasTransparency ? " (with alpha)" : "")
                                  << ", using PNG_COLOR_TYPE_PALLETTE");
         break;
       case PNG_COLOR_TYPE_GRAY:
-        diag->note(DiagMessage()
+        diag->Note(DiagMessage()
                    << "is opaque gray, using PNG_COLOR_TYPE_GRAY");
         break;
       case PNG_COLOR_TYPE_GRAY_ALPHA:
-        diag->note(DiagMessage()
+        diag->Note(DiagMessage()
                    << "is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA");
         break;
       case PNG_COLOR_TYPE_RGB:
-        diag->note(DiagMessage() << "is opaque RGB, using PNG_COLOR_TYPE_RGB");
+        diag->Note(DiagMessage() << "is opaque RGB, using PNG_COLOR_TYPE_RGB");
         break;
       case PNG_COLOR_TYPE_RGB_ALPHA:
-        diag->note(DiagMessage()
+        diag->Note(DiagMessage()
                    << "is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA");
         break;
     }
@@ -527,7 +527,7 @@
 
     // base 9 patch data
     if (kDebug) {
-      diag->note(DiagMessage() << "adding 9-patch info..");
+      diag->Note(DiagMessage() << "adding 9-patch info..");
     }
     strcpy((char*)unknowns[pIndex].name, "npTc");
     unknowns[pIndex].data = (png_byte*)info->serialize9Patch();
@@ -604,7 +604,7 @@
                &interlaceType, &compressionType, nullptr);
 
   if (kDebug) {
-    diag->note(DiagMessage() << "image written: w = " << width
+    diag->Note(DiagMessage() << "image written: w = " << width
                              << ", h = " << height << ", d = " << bitDepth
                              << ", colors = " << colorType
                              << ", inter = " << interlaceType
@@ -1228,13 +1228,13 @@
 
   // Read the PNG signature first.
   if (!input->read(reinterpret_cast<char*>(signature), kPngSignatureSize)) {
-    mDiag->error(DiagMessage() << strerror(errno));
+    mDiag->Error(DiagMessage() << strerror(errno));
     return false;
   }
 
   // If the PNG signature doesn't match, bail early.
   if (png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
-    mDiag->error(DiagMessage() << "not a valid png file");
+    mDiag->Error(DiagMessage() << "not a valid png file");
     return false;
   }
 
@@ -1247,13 +1247,13 @@
 
   readPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, nullptr, nullptr);
   if (!readPtr) {
-    mDiag->error(DiagMessage() << "failed to allocate read ptr");
+    mDiag->Error(DiagMessage() << "failed to allocate read ptr");
     goto bail;
   }
 
   infoPtr = png_create_info_struct(readPtr);
   if (!infoPtr) {
-    mDiag->error(DiagMessage() << "failed to allocate info ptr");
+    mDiag->Error(DiagMessage() << "failed to allocate info ptr");
     goto bail;
   }
 
@@ -1267,10 +1267,10 @@
     goto bail;
   }
 
-  if (util::stringEndsWith(source.path, ".9.png")) {
+  if (util::EndsWith(source.path, ".9.png")) {
     std::string errorMsg;
     if (!do9Patch(&pngInfo, &errorMsg)) {
-      mDiag->error(DiagMessage() << errorMsg);
+      mDiag->Error(DiagMessage() << errorMsg);
       goto bail;
     }
   }
@@ -1278,13 +1278,13 @@
   writePtr =
       png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, nullptr, nullptr);
   if (!writePtr) {
-    mDiag->error(DiagMessage() << "failed to allocate write ptr");
+    mDiag->Error(DiagMessage() << "failed to allocate write ptr");
     goto bail;
   }
 
   writeInfoPtr = png_create_info_struct(writePtr);
   if (!writeInfoPtr) {
-    mDiag->error(DiagMessage() << "failed to allocate write info ptr");
+    mDiag->Error(DiagMessage() << "failed to allocate write info ptr");
     goto bail;
   }
 
@@ -1295,7 +1295,7 @@
                    flushDataToStream);
 
   if (!writePng(mDiag, writePtr, writeInfoPtr, &pngInfo,
-                options.grayScaleTolerance)) {
+                options.grayscale_tolerance)) {
     goto bail;
   }
 
diff --git a/tools/aapt2/compile/Png.h b/tools/aapt2/compile/Png.h
index f9038af..01c9adb 100644
--- a/tools/aapt2/compile/Png.h
+++ b/tools/aapt2/compile/Png.h
@@ -17,6 +17,11 @@
 #ifndef AAPT_PNG_H
 #define AAPT_PNG_H
 
+#include <iostream>
+#include <string>
+
+#include "android-base/macros.h"
+
 #include "Diagnostics.h"
 #include "Source.h"
 #include "compile/Image.h"
@@ -24,16 +29,15 @@
 #include "process/IResourceTableConsumer.h"
 #include "util/BigBuffer.h"
 
-#include <android-base/macros.h>
-#include <iostream>
-#include <string>
-
 namespace aapt {
 
 struct PngOptions {
-  int grayScaleTolerance = 0;
+  int grayscale_tolerance = 0;
 };
 
+/**
+ * Deprecated. Removing once new PNG crunching code is proved to be correct.
+ */
 class Png {
  public:
   explicit Png(IDiagnostics* diag) : mDiag(diag) {}
@@ -59,18 +63,18 @@
   bool Skip(int count) override;
 
   int64_t ByteCount() const override {
-    return static_cast<int64_t>(mWindowStart);
+    return static_cast<int64_t>(window_start_);
   }
 
-  bool HadError() const override { return mError; }
+  bool HadError() const override { return error_; }
 
  private:
-  bool consumeWindow(const void** buffer, int* len);
+  bool ConsumeWindow(const void** buffer, int* len);
 
-  StringPiece mData;
-  size_t mWindowStart = 0;
-  size_t mWindowEnd = 0;
-  bool mError = false;
+  StringPiece data_;
+  size_t window_start_ = 0;
+  size_t window_end_ = 0;
+  bool error_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(PngChunkFilter);
 };
@@ -78,14 +82,14 @@
 /**
  * Reads a PNG from the InputStream into memory as an RGBA Image.
  */
-std::unique_ptr<Image> readPng(IAaptContext* context, io::InputStream* in);
+std::unique_ptr<Image> ReadPng(IAaptContext* context, io::InputStream* in);
 
 /**
  * Writes the RGBA Image, with optional 9-patch meta-data, into the OutputStream
  * as a PNG.
  */
-bool writePng(IAaptContext* context, const Image* image,
-              const NinePatch* ninePatch, io::OutputStream* out,
+bool WritePng(IAaptContext* context, const Image* image,
+              const NinePatch* nine_patch, io::OutputStream* out,
               const PngOptions& options);
 
 }  // namespace aapt
diff --git a/tools/aapt2/compile/PngChunkFilter.cpp b/tools/aapt2/compile/PngChunkFilter.cpp
index fb7fe92..4cbefb9 100644
--- a/tools/aapt2/compile/PngChunkFilter.cpp
+++ b/tools/aapt2/compile/PngChunkFilter.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "compile/Png.h"
+
 #include "io/Io.h"
 #include "util/StringPiece.h"
 
@@ -39,7 +40,7 @@
   kPngChunksRGB = u32(115, 82, 71, 66),
 };
 
-static uint32_t peek32LE(const char* data) {
+static uint32_t Peek32LE(const char* data) {
   uint32_t word = ((uint32_t)data[0]) & 0x000000ff;
   word <<= 8;
   word |= ((uint32_t)data[1]) & 0x000000ff;
@@ -50,7 +51,7 @@
   return word;
 }
 
-static bool isPngChunkWhitelisted(uint32_t type) {
+static bool IsPngChunkWhitelisted(uint32_t type) {
   switch (type) {
     case kPngChunkIHDR:
     case kPngChunkIDAT:
@@ -64,93 +65,93 @@
   }
 }
 
-PngChunkFilter::PngChunkFilter(const StringPiece& data) : mData(data) {
-  if (util::stringStartsWith(mData, kPngSignature)) {
-    mWindowStart = 0;
-    mWindowEnd = strlen(kPngSignature);
+PngChunkFilter::PngChunkFilter(const StringPiece& data) : data_(data) {
+  if (util::StartsWith(data_, kPngSignature)) {
+    window_start_ = 0;
+    window_end_ = strlen(kPngSignature);
   } else {
-    mError = true;
+    error_ = true;
   }
 }
 
-bool PngChunkFilter::consumeWindow(const void** buffer, int* len) {
-  if (mWindowStart != mWindowEnd) {
+bool PngChunkFilter::ConsumeWindow(const void** buffer, int* len) {
+  if (window_start_ != window_end_) {
     // We have bytes to give from our window.
-    const int bytesRead = (int)(mWindowEnd - mWindowStart);
-    *buffer = mData.data() + mWindowStart;
-    *len = bytesRead;
-    mWindowStart = mWindowEnd;
+    const int bytes_read = (int)(window_end_ - window_start_);
+    *buffer = data_.data() + window_start_;
+    *len = bytes_read;
+    window_start_ = window_end_;
     return true;
   }
   return false;
 }
 
 bool PngChunkFilter::Next(const void** buffer, int* len) {
-  if (mError) {
+  if (error_) {
     return false;
   }
 
   // In case BackUp was called, we must consume the window.
-  if (consumeWindow(buffer, len)) {
+  if (ConsumeWindow(buffer, len)) {
     return true;
   }
 
   // Advance the window as far as possible (until we meet a chunk that
   // we want to strip).
-  while (mWindowEnd < mData.size()) {
+  while (window_end_ < data_.size()) {
     // Chunk length (4 bytes) + type (4 bytes) + crc32 (4 bytes) = 12 bytes.
     const size_t kMinChunkHeaderSize = 3 * sizeof(uint32_t);
 
     // Is there enough room for a chunk header?
-    if (mData.size() - mWindowStart < kMinChunkHeaderSize) {
-      mError = true;
+    if (data_.size() - window_start_ < kMinChunkHeaderSize) {
+      error_ = true;
       return false;
     }
 
     // Verify the chunk length.
-    const uint32_t chunkLen = peek32LE(mData.data() + mWindowEnd);
-    if (((uint64_t)chunkLen) + ((uint64_t)mWindowEnd) + sizeof(uint32_t) >
-        mData.size()) {
+    const uint32_t chunk_len = Peek32LE(data_.data() + window_end_);
+    if (((uint64_t)chunk_len) + ((uint64_t)window_end_) + sizeof(uint32_t) >
+        data_.size()) {
       // Overflow.
-      mError = true;
+      error_ = true;
       return false;
     }
 
     // Do we strip this chunk?
-    const uint32_t chunkType =
-        peek32LE(mData.data() + mWindowEnd + sizeof(uint32_t));
-    if (isPngChunkWhitelisted(chunkType)) {
+    const uint32_t chunk_type =
+        Peek32LE(data_.data() + window_end_ + sizeof(uint32_t));
+    if (IsPngChunkWhitelisted(chunk_type)) {
       // Advance the window to include this chunk.
-      mWindowEnd += kMinChunkHeaderSize + chunkLen;
+      window_end_ += kMinChunkHeaderSize + chunk_len;
     } else {
       // We want to strip this chunk. If we accumulated a window,
       // we must return the window now.
-      if (mWindowStart != mWindowEnd) {
+      if (window_start_ != window_end_) {
         break;
       }
 
       // The window is empty, so we can advance past this chunk
       // and keep looking for the next good chunk,
-      mWindowEnd += kMinChunkHeaderSize + chunkLen;
-      mWindowStart = mWindowEnd;
+      window_end_ += kMinChunkHeaderSize + chunk_len;
+      window_start_ = window_end_;
     }
   }
 
-  if (consumeWindow(buffer, len)) {
+  if (ConsumeWindow(buffer, len)) {
     return true;
   }
   return false;
 }
 
 void PngChunkFilter::BackUp(int count) {
-  if (mError) {
+  if (error_) {
     return;
   }
-  mWindowStart -= count;
+  window_start_ -= count;
 }
 
 bool PngChunkFilter::Skip(int count) {
-  if (mError) {
+  if (error_) {
     return false;
   }
 
diff --git a/tools/aapt2/compile/PngCrunch.cpp b/tools/aapt2/compile/PngCrunch.cpp
index 4a74f7af7..3b46d8b 100644
--- a/tools/aapt2/compile/PngCrunch.cpp
+++ b/tools/aapt2/compile/PngCrunch.cpp
@@ -16,14 +16,17 @@
 
 #include "compile/Png.h"
 
-#include <android-base/errors.h>
-#include <android-base/macros.h>
 #include <png.h>
 #include <zlib.h>
+
 #include <algorithm>
 #include <unordered_map>
 #include <unordered_set>
 
+#include "android-base/errors.h"
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+
 namespace aapt {
 
 // Size in bytes of the PNG signature.
@@ -34,16 +37,16 @@
  */
 class PngReadStructDeleter {
  public:
-  explicit PngReadStructDeleter(png_structp readPtr, png_infop infoPtr)
-      : mReadPtr(readPtr), mInfoPtr(infoPtr) {}
+  PngReadStructDeleter(png_structp read_ptr, png_infop info_ptr)
+      : read_ptr_(read_ptr), info_ptr_(info_ptr) {}
 
   ~PngReadStructDeleter() {
-    png_destroy_read_struct(&mReadPtr, &mInfoPtr, nullptr);
+    png_destroy_read_struct(&read_ptr_, &info_ptr_, nullptr);
   }
 
  private:
-  png_structp mReadPtr;
-  png_infop mInfoPtr;
+  png_structp read_ptr_;
+  png_infop info_ptr_;
 
   DISALLOW_COPY_AND_ASSIGN(PngReadStructDeleter);
 };
@@ -53,226 +56,229 @@
  */
 class PngWriteStructDeleter {
  public:
-  explicit PngWriteStructDeleter(png_structp writePtr, png_infop infoPtr)
-      : mWritePtr(writePtr), mInfoPtr(infoPtr) {}
+  PngWriteStructDeleter(png_structp write_ptr, png_infop info_ptr)
+      : write_ptr_(write_ptr), info_ptr_(info_ptr) {}
 
-  ~PngWriteStructDeleter() { png_destroy_write_struct(&mWritePtr, &mInfoPtr); }
+  ~PngWriteStructDeleter() {
+    png_destroy_write_struct(&write_ptr_, &info_ptr_);
+  }
 
  private:
-  png_structp mWritePtr;
-  png_infop mInfoPtr;
+  png_structp write_ptr_;
+  png_infop info_ptr_;
 
   DISALLOW_COPY_AND_ASSIGN(PngWriteStructDeleter);
 };
 
 // Custom warning logging method that uses IDiagnostics.
-static void logWarning(png_structp pngPtr, png_const_charp warningMsg) {
-  IDiagnostics* diag = (IDiagnostics*)png_get_error_ptr(pngPtr);
-  diag->warn(DiagMessage() << warningMsg);
+static void LogWarning(png_structp png_ptr, png_const_charp warning_msg) {
+  IDiagnostics* diag = (IDiagnostics*)png_get_error_ptr(png_ptr);
+  diag->Warn(DiagMessage() << warning_msg);
 }
 
 // Custom error logging method that uses IDiagnostics.
-static void logError(png_structp pngPtr, png_const_charp errorMsg) {
-  IDiagnostics* diag = (IDiagnostics*)png_get_error_ptr(pngPtr);
-  diag->error(DiagMessage() << errorMsg);
+static void LogError(png_structp png_ptr, png_const_charp error_msg) {
+  IDiagnostics* diag = (IDiagnostics*)png_get_error_ptr(png_ptr);
+  diag->Error(DiagMessage() << error_msg);
 }
 
-static void readDataFromStream(png_structp pngPtr, png_bytep buffer,
+static void ReadDataFromStream(png_structp png_ptr, png_bytep buffer,
                                png_size_t len) {
-  io::InputStream* in = (io::InputStream*)png_get_io_ptr(pngPtr);
+  io::InputStream* in = (io::InputStream*)png_get_io_ptr(png_ptr);
 
-  const void* inBuffer;
-  int inLen;
-  if (!in->Next(&inBuffer, &inLen)) {
+  const void* in_buffer;
+  int in_len;
+  if (!in->Next(&in_buffer, &in_len)) {
     if (in->HadError()) {
       std::string err = in->GetError();
-      png_error(pngPtr, err.c_str());
+      png_error(png_ptr, err.c_str());
     }
     return;
   }
 
-  const size_t bytesRead = std::min(static_cast<size_t>(inLen), len);
-  memcpy(buffer, inBuffer, bytesRead);
-  if (bytesRead != static_cast<size_t>(inLen)) {
-    in->BackUp(inLen - static_cast<int>(bytesRead));
+  const size_t bytes_read = std::min(static_cast<size_t>(in_len), len);
+  memcpy(buffer, in_buffer, bytes_read);
+  if (bytes_read != static_cast<size_t>(in_len)) {
+    in->BackUp(in_len - static_cast<int>(bytes_read));
   }
 }
 
-static void writeDataToStream(png_structp pngPtr, png_bytep buffer,
+static void WriteDataToStream(png_structp png_ptr, png_bytep buffer,
                               png_size_t len) {
-  io::OutputStream* out = (io::OutputStream*)png_get_io_ptr(pngPtr);
+  io::OutputStream* out = (io::OutputStream*)png_get_io_ptr(png_ptr);
 
-  void* outBuffer;
-  int outLen;
+  void* out_buffer;
+  int out_len;
   while (len > 0) {
-    if (!out->Next(&outBuffer, &outLen)) {
+    if (!out->Next(&out_buffer, &out_len)) {
       if (out->HadError()) {
         std::string err = out->GetError();
-        png_error(pngPtr, err.c_str());
+        png_error(png_ptr, err.c_str());
       }
       return;
     }
 
-    const size_t bytesWritten = std::min(static_cast<size_t>(outLen), len);
-    memcpy(outBuffer, buffer, bytesWritten);
+    const size_t bytes_written = std::min(static_cast<size_t>(out_len), len);
+    memcpy(out_buffer, buffer, bytes_written);
 
     // Advance the input buffer.
-    buffer += bytesWritten;
-    len -= bytesWritten;
+    buffer += bytes_written;
+    len -= bytes_written;
 
     // Advance the output buffer.
-    outLen -= static_cast<int>(bytesWritten);
+    out_len -= static_cast<int>(bytes_written);
   }
 
   // If the entire output buffer wasn't used, backup.
-  if (outLen > 0) {
-    out->BackUp(outLen);
+  if (out_len > 0) {
+    out->BackUp(out_len);
   }
 }
 
-std::unique_ptr<Image> readPng(IAaptContext* context, io::InputStream* in) {
+std::unique_ptr<Image> ReadPng(IAaptContext* context, io::InputStream* in) {
   // Read the first 8 bytes of the file looking for the PNG signature.
   // Bail early if it does not match.
   const png_byte* signature;
-  int bufferSize;
-  if (!in->Next((const void**)&signature, &bufferSize)) {
-    context->getDiagnostics()->error(
+  int buffer_size;
+  if (!in->Next((const void**)&signature, &buffer_size)) {
+    context->GetDiagnostics()->Error(
         DiagMessage() << android::base::SystemErrorCodeToString(errno));
     return {};
   }
 
-  if (static_cast<size_t>(bufferSize) < kPngSignatureSize ||
+  if (static_cast<size_t>(buffer_size) < kPngSignatureSize ||
       png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
-    context->getDiagnostics()->error(
+    context->GetDiagnostics()->Error(
         DiagMessage() << "file signature does not match PNG signature");
     return {};
   }
 
   // Start at the beginning of the first chunk.
-  in->BackUp(bufferSize - static_cast<int>(kPngSignatureSize));
+  in->BackUp(buffer_size - static_cast<int>(kPngSignatureSize));
 
   // Create and initialize the png_struct with the default error and warning
   // handlers.
   // The header version is also passed in to ensure that this was built against
   // the same
   // version of libpng.
-  png_structp readPtr =
+  png_structp read_ptr =
       png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
-  if (readPtr == nullptr) {
-    context->getDiagnostics()->error(
+  if (read_ptr == nullptr) {
+    context->GetDiagnostics()->Error(
         DiagMessage() << "failed to create libpng read png_struct");
     return {};
   }
 
   // Create and initialize the memory for image header and data.
-  png_infop infoPtr = png_create_info_struct(readPtr);
-  if (infoPtr == nullptr) {
-    context->getDiagnostics()->error(
+  png_infop info_ptr = png_create_info_struct(read_ptr);
+  if (info_ptr == nullptr) {
+    context->GetDiagnostics()->Error(
         DiagMessage() << "failed to create libpng read png_info");
-    png_destroy_read_struct(&readPtr, nullptr, nullptr);
+    png_destroy_read_struct(&read_ptr, nullptr, nullptr);
     return {};
   }
 
   // Automatically release PNG resources at end of scope.
-  PngReadStructDeleter pngReadDeleter(readPtr, infoPtr);
+  PngReadStructDeleter png_read_deleter(read_ptr, info_ptr);
 
   // libpng uses longjmp to jump to an error handling routine.
   // setjmp will only return true if it was jumped to, aka there was
   // an error.
-  if (setjmp(png_jmpbuf(readPtr))) {
+  if (setjmp(png_jmpbuf(read_ptr))) {
     return {};
   }
 
   // Handle warnings ourselves via IDiagnostics.
-  png_set_error_fn(readPtr, (png_voidp)context->getDiagnostics(), logError,
-                   logWarning);
+  png_set_error_fn(read_ptr, (png_voidp)context->GetDiagnostics(), LogError,
+                   LogWarning);
 
   // Set up the read functions which read from our custom data sources.
-  png_set_read_fn(readPtr, (png_voidp)in, readDataFromStream);
+  png_set_read_fn(read_ptr, (png_voidp)in, ReadDataFromStream);
 
   // Skip the signature that we already read.
-  png_set_sig_bytes(readPtr, kPngSignatureSize);
+  png_set_sig_bytes(read_ptr, kPngSignatureSize);
 
   // Read the chunk headers.
-  png_read_info(readPtr, infoPtr);
+  png_read_info(read_ptr, info_ptr);
 
   // Extract image meta-data from the various chunk headers.
   uint32_t width, height;
-  int bitDepth, colorType, interlaceMethod, compressionMethod, filterMethod;
-  png_get_IHDR(readPtr, infoPtr, &width, &height, &bitDepth, &colorType,
-               &interlaceMethod, &compressionMethod, &filterMethod);
+  int bit_depth, color_type, interlace_method, compression_method,
+      filter_method;
+  png_get_IHDR(read_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+               &interlace_method, &compression_method, &filter_method);
 
   // When the image is read, expand it so that it is in RGBA 8888 format
   // so that image handling is uniform.
 
-  if (colorType == PNG_COLOR_TYPE_PALETTE) {
-    png_set_palette_to_rgb(readPtr);
+  if (color_type == PNG_COLOR_TYPE_PALETTE) {
+    png_set_palette_to_rgb(read_ptr);
   }
 
-  if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) {
-    png_set_expand_gray_1_2_4_to_8(readPtr);
+  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
+    png_set_expand_gray_1_2_4_to_8(read_ptr);
   }
 
-  if (png_get_valid(readPtr, infoPtr, PNG_INFO_tRNS)) {
-    png_set_tRNS_to_alpha(readPtr);
+  if (png_get_valid(read_ptr, info_ptr, PNG_INFO_tRNS)) {
+    png_set_tRNS_to_alpha(read_ptr);
   }
 
-  if (bitDepth == 16) {
-    png_set_strip_16(readPtr);
+  if (bit_depth == 16) {
+    png_set_strip_16(read_ptr);
   }
 
-  if (!(colorType & PNG_COLOR_MASK_ALPHA)) {
-    png_set_add_alpha(readPtr, 0xFF, PNG_FILLER_AFTER);
+  if (!(color_type & PNG_COLOR_MASK_ALPHA)) {
+    png_set_add_alpha(read_ptr, 0xFF, PNG_FILLER_AFTER);
   }
 
-  if (colorType == PNG_COLOR_TYPE_GRAY ||
-      colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
-    png_set_gray_to_rgb(readPtr);
+  if (color_type == PNG_COLOR_TYPE_GRAY ||
+      color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+    png_set_gray_to_rgb(read_ptr);
   }
 
-  if (interlaceMethod != PNG_INTERLACE_NONE) {
-    png_set_interlace_handling(readPtr);
+  if (interlace_method != PNG_INTERLACE_NONE) {
+    png_set_interlace_handling(read_ptr);
   }
 
   // Once all the options for reading have been set, we need to flush
   // them to libpng.
-  png_read_update_info(readPtr, infoPtr);
+  png_read_update_info(read_ptr, info_ptr);
 
   // 9-patch uses int32_t to index images, so we cap the image dimensions to
   // something
   // that can always be represented by 9-patch.
   if (width > std::numeric_limits<int32_t>::max() ||
       height > std::numeric_limits<int32_t>::max()) {
-    context->getDiagnostics()->error(DiagMessage()
+    context->GetDiagnostics()->Error(DiagMessage()
                                      << "PNG image dimensions are too large: "
                                      << width << "x" << height);
     return {};
   }
 
-  std::unique_ptr<Image> outputImage = util::make_unique<Image>();
-  outputImage->width = static_cast<int32_t>(width);
-  outputImage->height = static_cast<int32_t>(height);
+  std::unique_ptr<Image> output_image = util::make_unique<Image>();
+  output_image->width = static_cast<int32_t>(width);
+  output_image->height = static_cast<int32_t>(height);
 
-  const size_t rowBytes = png_get_rowbytes(readPtr, infoPtr);
-  assert(rowBytes == 4 * width);  // RGBA
+  const size_t row_bytes = png_get_rowbytes(read_ptr, info_ptr);
+  CHECK(row_bytes == 4 * width);  // RGBA
 
   // Allocate one large block to hold the image.
-  outputImage->data =
-      std::unique_ptr<uint8_t[]>(new uint8_t[height * rowBytes]);
+  output_image->data =
+      std::unique_ptr<uint8_t[]>(new uint8_t[height * row_bytes]);
 
   // Create an array of rows that index into the data block.
-  outputImage->rows = std::unique_ptr<uint8_t* []>(new uint8_t*[height]);
+  output_image->rows = std::unique_ptr<uint8_t* []>(new uint8_t*[height]);
   for (uint32_t h = 0; h < height; h++) {
-    outputImage->rows[h] = outputImage->data.get() + (h * rowBytes);
+    output_image->rows[h] = output_image->data.get() + (h * row_bytes);
   }
 
   // Actually read the image pixels.
-  png_read_image(readPtr, outputImage->rows.get());
+  png_read_image(read_ptr, output_image->rows.get());
 
   // Finish reading. This will read any other chunks after the image data.
-  png_read_end(readPtr, infoPtr);
+  png_read_end(read_ptr, info_ptr);
 
-  return outputImage;
+  return output_image;
 }
 
 /**
@@ -309,57 +315,58 @@
 // - Grayscale + cheap alpha
 // - Grayscale + alpha
 //
-static int pickColorType(int32_t width, int32_t height, bool grayScale,
-                         bool convertibleToGrayScale, bool hasNinePatch,
-                         size_t colorPaletteSize, size_t alphaPaletteSize) {
-  const size_t paletteChunkSize = 16 + colorPaletteSize * 3;
-  const size_t alphaChunkSize = 16 + alphaPaletteSize;
-  const size_t colorAlphaDataChunkSize = 16 + 4 * width * height;
-  const size_t colorDataChunkSize = 16 + 3 * width * height;
-  const size_t grayScaleAlphaDataChunkSize = 16 + 2 * width * height;
-  const size_t paletteDataChunkSize = 16 + width * height;
+static int PickColorType(int32_t width, int32_t height, bool grayscale,
+                         bool convertible_to_grayscale, bool has_nine_patch,
+                         size_t color_palette_size, size_t alpha_palette_size) {
+  const size_t palette_chunk_size = 16 + color_palette_size * 3;
+  const size_t alpha_chunk_size = 16 + alpha_palette_size;
+  const size_t color_alpha_data_chunk_size = 16 + 4 * width * height;
+  const size_t color_data_chunk_size = 16 + 3 * width * height;
+  const size_t grayscale_alpha_data_chunk_size = 16 + 2 * width * height;
+  const size_t palette_data_chunk_size = 16 + width * height;
 
-  if (grayScale) {
-    if (alphaPaletteSize == 0) {
+  if (grayscale) {
+    if (alpha_palette_size == 0) {
       // This is the smallest the data can be.
       return PNG_COLOR_TYPE_GRAY;
-    } else if (colorPaletteSize <= 256 && !hasNinePatch) {
+    } else if (color_palette_size <= 256 && !has_nine_patch) {
       // This grayscale has alpha and can fit within a palette.
       // See if it is worth fitting into a palette.
-      const size_t paletteThreshold = paletteChunkSize + alphaChunkSize +
-                                      paletteDataChunkSize +
-                                      kPaletteOverheadConstant;
-      if (grayScaleAlphaDataChunkSize > paletteThreshold) {
+      const size_t palette_threshold = palette_chunk_size + alpha_chunk_size +
+                                       palette_data_chunk_size +
+                                       kPaletteOverheadConstant;
+      if (grayscale_alpha_data_chunk_size > palette_threshold) {
         return PNG_COLOR_TYPE_PALETTE;
       }
     }
     return PNG_COLOR_TYPE_GRAY_ALPHA;
   }
 
-  if (colorPaletteSize <= 256 && !hasNinePatch) {
+  if (color_palette_size <= 256 && !has_nine_patch) {
     // This image can fit inside a palette. Let's see if it is worth it.
-    size_t totalSizeWithPalette = paletteDataChunkSize + paletteChunkSize;
-    size_t totalSizeWithoutPalette = colorDataChunkSize;
-    if (alphaPaletteSize > 0) {
-      totalSizeWithPalette += alphaPaletteSize;
-      totalSizeWithoutPalette = colorAlphaDataChunkSize;
+    size_t total_size_with_palette =
+        palette_data_chunk_size + palette_chunk_size;
+    size_t total_size_without_palette = color_data_chunk_size;
+    if (alpha_palette_size > 0) {
+      total_size_with_palette += alpha_palette_size;
+      total_size_without_palette = color_alpha_data_chunk_size;
     }
 
-    if (totalSizeWithoutPalette >
-        totalSizeWithPalette + kPaletteOverheadConstant) {
+    if (total_size_without_palette >
+        total_size_with_palette + kPaletteOverheadConstant) {
       return PNG_COLOR_TYPE_PALETTE;
     }
   }
 
-  if (convertibleToGrayScale) {
-    if (alphaPaletteSize == 0) {
+  if (convertible_to_grayscale) {
+    if (alpha_palette_size == 0) {
       return PNG_COLOR_TYPE_GRAY;
     } else {
       return PNG_COLOR_TYPE_GRAY_ALPHA;
     }
   }
 
-  if (alphaPaletteSize == 0) {
+  if (alpha_palette_size == 0) {
     return PNG_COLOR_TYPE_RGB;
   }
   return PNG_COLOR_TYPE_RGBA;
@@ -371,11 +378,11 @@
 // This must be done before writing image data.
 // Image data must be transformed to use the indices assigned within the
 // palette.
-static void writePalette(png_structp writePtr, png_infop writeInfoPtr,
-                         std::unordered_map<uint32_t, int>* colorPalette,
-                         std::unordered_set<uint32_t>* alphaPalette) {
-  assert(colorPalette->size() <= 256);
-  assert(alphaPalette->size() <= 256);
+static void WritePalette(png_structp write_ptr, png_infop write_info_ptr,
+                         std::unordered_map<uint32_t, int>* color_palette,
+                         std::unordered_set<uint32_t>* alpha_palette) {
+  CHECK(color_palette->size() <= 256);
+  CHECK(alpha_palette->size() <= 256);
 
   // Populate the PNG palette struct and assign indices to the color
   // palette.
@@ -384,160 +391,161 @@
   // This will ensure that we can truncate the alpha palette if it is
   // smaller than the color palette.
   int index = 0;
-  for (uint32_t color : *alphaPalette) {
-    (*colorPalette)[color] = index++;
+  for (uint32_t color : *alpha_palette) {
+    (*color_palette)[color] = index++;
   }
 
   // Assign the rest of the entries.
-  for (auto& entry : *colorPalette) {
+  for (auto& entry : *color_palette) {
     if (entry.second == -1) {
       entry.second = index++;
     }
   }
 
   // Create the PNG color palette struct.
-  auto colorPaletteBytes =
-      std::unique_ptr<png_color[]>(new png_color[colorPalette->size()]);
+  auto color_palette_bytes =
+      std::unique_ptr<png_color[]>(new png_color[color_palette->size()]);
 
-  std::unique_ptr<png_byte[]> alphaPaletteBytes;
-  if (!alphaPalette->empty()) {
-    alphaPaletteBytes =
-        std::unique_ptr<png_byte[]>(new png_byte[alphaPalette->size()]);
+  std::unique_ptr<png_byte[]> alpha_palette_bytes;
+  if (!alpha_palette->empty()) {
+    alpha_palette_bytes =
+        std::unique_ptr<png_byte[]>(new png_byte[alpha_palette->size()]);
   }
 
-  for (const auto& entry : *colorPalette) {
+  for (const auto& entry : *color_palette) {
     const uint32_t color = entry.first;
     const int index = entry.second;
-    assert(index >= 0);
-    assert(static_cast<size_t>(index) < colorPalette->size());
+    CHECK(index >= 0);
+    CHECK(static_cast<size_t>(index) < color_palette->size());
 
-    png_colorp slot = colorPaletteBytes.get() + index;
+    png_colorp slot = color_palette_bytes.get() + index;
     slot->red = color >> 24;
     slot->green = color >> 16;
     slot->blue = color >> 8;
 
     const png_byte alpha = color & 0x000000ff;
-    if (alpha != 0xff && alphaPaletteBytes) {
-      assert(static_cast<size_t>(index) < alphaPalette->size());
-      alphaPaletteBytes[index] = alpha;
+    if (alpha != 0xff && alpha_palette_bytes) {
+      CHECK(static_cast<size_t>(index) < alpha_palette->size());
+      alpha_palette_bytes[index] = alpha;
     }
   }
 
-  // The bytes get copied here, so it is safe to release colorPaletteBytes at
+  // The bytes get copied here, so it is safe to release color_palette_bytes at
   // the end of function
   // scope.
-  png_set_PLTE(writePtr, writeInfoPtr, colorPaletteBytes.get(),
-               colorPalette->size());
+  png_set_PLTE(write_ptr, write_info_ptr, color_palette_bytes.get(),
+               color_palette->size());
 
-  if (alphaPaletteBytes) {
-    png_set_tRNS(writePtr, writeInfoPtr, alphaPaletteBytes.get(),
-                 alphaPalette->size(), nullptr);
+  if (alpha_palette_bytes) {
+    png_set_tRNS(write_ptr, write_info_ptr, alpha_palette_bytes.get(),
+                 alpha_palette->size(), nullptr);
   }
 }
 
-// Write the 9-patch custom PNG chunks to writeInfoPtr. This must be done before
+// Write the 9-patch custom PNG chunks to write_info_ptr. This must be done
+// before
 // writing image data.
-static void writeNinePatch(png_structp writePtr, png_infop writeInfoPtr,
-                           const NinePatch* ninePatch) {
+static void WriteNinePatch(png_structp write_ptr, png_infop write_info_ptr,
+                           const NinePatch* nine_patch) {
   // The order of the chunks is important.
   // 9-patch code in older platforms expects the 9-patch chunk to
   // be last.
 
-  png_unknown_chunk unknownChunks[3];
-  memset(unknownChunks, 0, sizeof(unknownChunks));
+  png_unknown_chunk unknown_chunks[3];
+  memset(unknown_chunks, 0, sizeof(unknown_chunks));
 
   size_t index = 0;
-  size_t chunkLen = 0;
+  size_t chunk_len = 0;
 
-  std::unique_ptr<uint8_t[]> serializedOutline =
-      ninePatch->serializeRoundedRectOutline(&chunkLen);
-  strcpy((char*)unknownChunks[index].name, "npOl");
-  unknownChunks[index].size = chunkLen;
-  unknownChunks[index].data = (png_bytep)serializedOutline.get();
-  unknownChunks[index].location = PNG_HAVE_PLTE;
+  std::unique_ptr<uint8_t[]> serialized_outline =
+      nine_patch->SerializeRoundedRectOutline(&chunk_len);
+  strcpy((char*)unknown_chunks[index].name, "npOl");
+  unknown_chunks[index].size = chunk_len;
+  unknown_chunks[index].data = (png_bytep)serialized_outline.get();
+  unknown_chunks[index].location = PNG_HAVE_PLTE;
   index++;
 
-  std::unique_ptr<uint8_t[]> serializedLayoutBounds;
-  if (ninePatch->layoutBounds.nonZero()) {
-    serializedLayoutBounds = ninePatch->serializeLayoutBounds(&chunkLen);
-    strcpy((char*)unknownChunks[index].name, "npLb");
-    unknownChunks[index].size = chunkLen;
-    unknownChunks[index].data = (png_bytep)serializedLayoutBounds.get();
-    unknownChunks[index].location = PNG_HAVE_PLTE;
+  std::unique_ptr<uint8_t[]> serialized_layout_bounds;
+  if (nine_patch->layout_bounds.nonZero()) {
+    serialized_layout_bounds = nine_patch->SerializeLayoutBounds(&chunk_len);
+    strcpy((char*)unknown_chunks[index].name, "npLb");
+    unknown_chunks[index].size = chunk_len;
+    unknown_chunks[index].data = (png_bytep)serialized_layout_bounds.get();
+    unknown_chunks[index].location = PNG_HAVE_PLTE;
     index++;
   }
 
-  std::unique_ptr<uint8_t[]> serializedNinePatch =
-      ninePatch->serializeBase(&chunkLen);
-  strcpy((char*)unknownChunks[index].name, "npTc");
-  unknownChunks[index].size = chunkLen;
-  unknownChunks[index].data = (png_bytep)serializedNinePatch.get();
-  unknownChunks[index].location = PNG_HAVE_PLTE;
+  std::unique_ptr<uint8_t[]> serialized_nine_patch =
+      nine_patch->SerializeBase(&chunk_len);
+  strcpy((char*)unknown_chunks[index].name, "npTc");
+  unknown_chunks[index].size = chunk_len;
+  unknown_chunks[index].data = (png_bytep)serialized_nine_patch.get();
+  unknown_chunks[index].location = PNG_HAVE_PLTE;
   index++;
 
   // Handle all unknown chunks. We are manually setting the chunks here,
   // so we will only ever handle our custom chunks.
-  png_set_keep_unknown_chunks(writePtr, PNG_HANDLE_CHUNK_ALWAYS, nullptr, 0);
+  png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, nullptr, 0);
 
   // Set the actual chunks here. The data gets copied, so our buffers can
   // safely go out of scope.
-  png_set_unknown_chunks(writePtr, writeInfoPtr, unknownChunks, index);
+  png_set_unknown_chunks(write_ptr, write_info_ptr, unknown_chunks, index);
 }
 
-bool writePng(IAaptContext* context, const Image* image,
-              const NinePatch* ninePatch, io::OutputStream* out,
+bool WritePng(IAaptContext* context, const Image* image,
+              const NinePatch* nine_patch, io::OutputStream* out,
               const PngOptions& options) {
   // Create and initialize the write png_struct with the default error and
   // warning handlers.
   // The header version is also passed in to ensure that this was built against
   // the same
   // version of libpng.
-  png_structp writePtr =
+  png_structp write_ptr =
       png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
-  if (writePtr == nullptr) {
-    context->getDiagnostics()->error(
+  if (write_ptr == nullptr) {
+    context->GetDiagnostics()->Error(
         DiagMessage() << "failed to create libpng write png_struct");
     return false;
   }
 
   // Allocate memory to store image header data.
-  png_infop writeInfoPtr = png_create_info_struct(writePtr);
-  if (writeInfoPtr == nullptr) {
-    context->getDiagnostics()->error(
+  png_infop write_info_ptr = png_create_info_struct(write_ptr);
+  if (write_info_ptr == nullptr) {
+    context->GetDiagnostics()->Error(
         DiagMessage() << "failed to create libpng write png_info");
-    png_destroy_write_struct(&writePtr, nullptr);
+    png_destroy_write_struct(&write_ptr, nullptr);
     return false;
   }
 
   // Automatically release PNG resources at end of scope.
-  PngWriteStructDeleter pngWriteDeleter(writePtr, writeInfoPtr);
+  PngWriteStructDeleter png_write_deleter(write_ptr, write_info_ptr);
 
   // libpng uses longjmp to jump to error handling routines.
   // setjmp will return true only if it was jumped to, aka, there was an error.
-  if (setjmp(png_jmpbuf(writePtr))) {
+  if (setjmp(png_jmpbuf(write_ptr))) {
     return false;
   }
 
   // Handle warnings with our IDiagnostics.
-  png_set_error_fn(writePtr, (png_voidp)context->getDiagnostics(), logError,
-                   logWarning);
+  png_set_error_fn(write_ptr, (png_voidp)context->GetDiagnostics(), LogError,
+                   LogWarning);
 
   // Set up the write functions which write to our custom data sources.
-  png_set_write_fn(writePtr, (png_voidp)out, writeDataToStream, nullptr);
+  png_set_write_fn(write_ptr, (png_voidp)out, WriteDataToStream, nullptr);
 
   // We want small files and can take the performance hit to achieve this goal.
-  png_set_compression_level(writePtr, Z_BEST_COMPRESSION);
+  png_set_compression_level(write_ptr, Z_BEST_COMPRESSION);
 
   // Begin analysis of the image data.
   // Scan the entire image and determine if:
   // 1. Every pixel has R == G == B (grayscale)
   // 2. Every pixel has A == 255 (opaque)
   // 3. There are no more than 256 distinct RGBA colors (palette).
-  std::unordered_map<uint32_t, int> colorPalette;
-  std::unordered_set<uint32_t> alphaPalette;
-  bool needsToZeroRGBChannelsOfTransparentPixels = false;
-  bool grayScale = true;
-  int maxGrayDeviation = 0;
+  std::unordered_map<uint32_t, int> color_palette;
+  std::unordered_set<uint32_t> alpha_palette;
+  bool needs_to_zero_rgb_channels_of_transparent_pixels = false;
+  bool grayscale = true;
+  int max_gray_deviation = 0;
 
   for (int32_t y = 0; y < image->height; y++) {
     const uint8_t* row = image->rows[y];
@@ -551,60 +559,60 @@
         // The color is completely transparent.
         // For purposes of palettes and grayscale optimization,
         // treat all channels as 0x00.
-        needsToZeroRGBChannelsOfTransparentPixels =
-            needsToZeroRGBChannelsOfTransparentPixels ||
+        needs_to_zero_rgb_channels_of_transparent_pixels =
+            needs_to_zero_rgb_channels_of_transparent_pixels ||
             (red != 0 || green != 0 || blue != 0);
         red = green = blue = 0;
       }
 
       // Insert the color into the color palette.
       const uint32_t color = red << 24 | green << 16 | blue << 8 | alpha;
-      colorPalette[color] = -1;
+      color_palette[color] = -1;
 
       // If the pixel has non-opaque alpha, insert it into the
       // alpha palette.
       if (alpha != 0xff) {
-        alphaPalette.insert(color);
+        alpha_palette.insert(color);
       }
 
       // Check if the image is indeed grayscale.
-      if (grayScale) {
+      if (grayscale) {
         if (red != green || red != blue) {
-          grayScale = false;
+          grayscale = false;
         }
       }
 
       // Calculate the gray scale deviation so that it can be compared
       // with the threshold.
-      maxGrayDeviation = std::max(std::abs(red - green), maxGrayDeviation);
-      maxGrayDeviation = std::max(std::abs(green - blue), maxGrayDeviation);
-      maxGrayDeviation = std::max(std::abs(blue - red), maxGrayDeviation);
+      max_gray_deviation = std::max(std::abs(red - green), max_gray_deviation);
+      max_gray_deviation = std::max(std::abs(green - blue), max_gray_deviation);
+      max_gray_deviation = std::max(std::abs(blue - red), max_gray_deviation);
     }
   }
 
-  if (context->verbose()) {
+  if (context->IsVerbose()) {
     DiagMessage msg;
-    msg << " paletteSize=" << colorPalette.size()
-        << " alphaPaletteSize=" << alphaPalette.size()
-        << " maxGrayDeviation=" << maxGrayDeviation
-        << " grayScale=" << (grayScale ? "true" : "false");
-    context->getDiagnostics()->note(msg);
+    msg << " paletteSize=" << color_palette.size()
+        << " alphaPaletteSize=" << alpha_palette.size()
+        << " maxGrayDeviation=" << max_gray_deviation
+        << " grayScale=" << (grayscale ? "true" : "false");
+    context->GetDiagnostics()->Note(msg);
   }
 
-  const bool convertibleToGrayScale =
-      maxGrayDeviation <= options.grayScaleTolerance;
+  const bool convertible_to_grayscale =
+      max_gray_deviation <= options.grayscale_tolerance;
 
-  const int newColorType = pickColorType(
-      image->width, image->height, grayScale, convertibleToGrayScale,
-      ninePatch != nullptr, colorPalette.size(), alphaPalette.size());
+  const int new_color_type = PickColorType(
+      image->width, image->height, grayscale, convertible_to_grayscale,
+      nine_patch != nullptr, color_palette.size(), alpha_palette.size());
 
-  if (context->verbose()) {
+  if (context->IsVerbose()) {
     DiagMessage msg;
     msg << "encoding PNG ";
-    if (ninePatch) {
+    if (nine_patch) {
       msg << "(with 9-patch) as ";
     }
-    switch (newColorType) {
+    switch (new_color_type) {
       case PNG_COLOR_TYPE_GRAY:
         msg << "GRAY";
         break;
@@ -621,137 +629,138 @@
         msg << "PALETTE";
         break;
       default:
-        msg << "unknown type " << newColorType;
+        msg << "unknown type " << new_color_type;
         break;
     }
-    context->getDiagnostics()->note(msg);
+    context->GetDiagnostics()->Note(msg);
   }
 
-  png_set_IHDR(writePtr, writeInfoPtr, image->width, image->height, 8,
-               newColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
+  png_set_IHDR(write_ptr, write_info_ptr, image->width, image->height, 8,
+               new_color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
                PNG_FILTER_TYPE_DEFAULT);
 
-  if (newColorType & PNG_COLOR_MASK_PALETTE) {
+  if (new_color_type & PNG_COLOR_MASK_PALETTE) {
     // Assigns indices to the palette, and writes the encoded palette to the
     // libpng writePtr.
-    writePalette(writePtr, writeInfoPtr, &colorPalette, &alphaPalette);
-    png_set_filter(writePtr, 0, PNG_NO_FILTERS);
+    WritePalette(write_ptr, write_info_ptr, &color_palette, &alpha_palette);
+    png_set_filter(write_ptr, 0, PNG_NO_FILTERS);
   } else {
-    png_set_filter(writePtr, 0, PNG_ALL_FILTERS);
+    png_set_filter(write_ptr, 0, PNG_ALL_FILTERS);
   }
 
-  if (ninePatch) {
-    writeNinePatch(writePtr, writeInfoPtr, ninePatch);
+  if (nine_patch) {
+    WriteNinePatch(write_ptr, write_info_ptr, nine_patch);
   }
 
   // Flush our updates to the header.
-  png_write_info(writePtr, writeInfoPtr);
+  png_write_info(write_ptr, write_info_ptr);
 
   // Write out each row of image data according to its encoding.
-  if (newColorType == PNG_COLOR_TYPE_PALETTE) {
+  if (new_color_type == PNG_COLOR_TYPE_PALETTE) {
     // 1 byte/pixel.
-    auto outRow = std::unique_ptr<png_byte[]>(new png_byte[image->width]);
+    auto out_row = std::unique_ptr<png_byte[]>(new png_byte[image->width]);
 
     for (int32_t y = 0; y < image->height; y++) {
-      png_const_bytep inRow = image->rows[y];
+      png_const_bytep in_row = image->rows[y];
       for (int32_t x = 0; x < image->width; x++) {
-        int rr = *inRow++;
-        int gg = *inRow++;
-        int bb = *inRow++;
-        int aa = *inRow++;
+        int rr = *in_row++;
+        int gg = *in_row++;
+        int bb = *in_row++;
+        int aa = *in_row++;
         if (aa == 0) {
           // Zero out color channels when transparent.
           rr = gg = bb = 0;
         }
 
         const uint32_t color = rr << 24 | gg << 16 | bb << 8 | aa;
-        const int idx = colorPalette[color];
-        assert(idx != -1);
-        outRow[x] = static_cast<png_byte>(idx);
+        const int idx = color_palette[color];
+        CHECK(idx != -1);
+        out_row[x] = static_cast<png_byte>(idx);
       }
-      png_write_row(writePtr, outRow.get());
+      png_write_row(write_ptr, out_row.get());
     }
-  } else if (newColorType == PNG_COLOR_TYPE_GRAY ||
-             newColorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
-    const size_t bpp = newColorType == PNG_COLOR_TYPE_GRAY ? 1 : 2;
-    auto outRow = std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]);
+  } else if (new_color_type == PNG_COLOR_TYPE_GRAY ||
+             new_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+    const size_t bpp = new_color_type == PNG_COLOR_TYPE_GRAY ? 1 : 2;
+    auto out_row =
+        std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]);
 
     for (int32_t y = 0; y < image->height; y++) {
-      png_const_bytep inRow = image->rows[y];
+      png_const_bytep in_row = image->rows[y];
       for (int32_t x = 0; x < image->width; x++) {
-        int rr = inRow[x * 4];
-        int gg = inRow[x * 4 + 1];
-        int bb = inRow[x * 4 + 2];
-        int aa = inRow[x * 4 + 3];
+        int rr = in_row[x * 4];
+        int gg = in_row[x * 4 + 1];
+        int bb = in_row[x * 4 + 2];
+        int aa = in_row[x * 4 + 3];
         if (aa == 0) {
           // Zero out the gray channel when transparent.
           rr = gg = bb = 0;
         }
 
-        if (grayScale) {
+        if (grayscale) {
           // The image was already grayscale, red == green == blue.
-          outRow[x * bpp] = inRow[x * 4];
+          out_row[x * bpp] = in_row[x * 4];
         } else {
           // The image is convertible to grayscale, use linear-luminance of
           // sRGB colorspace:
           // https://en.wikipedia.org/wiki/Grayscale#Colorimetric_.28luminance-preserving.29_conversion_to_grayscale
-          outRow[x * bpp] =
+          out_row[x * bpp] =
               (png_byte)(rr * 0.2126f + gg * 0.7152f + bb * 0.0722f);
         }
 
         if (bpp == 2) {
           // Write out alpha if we have it.
-          outRow[x * bpp + 1] = aa;
+          out_row[x * bpp + 1] = aa;
         }
       }
-      png_write_row(writePtr, outRow.get());
+      png_write_row(write_ptr, out_row.get());
     }
-  } else if (newColorType == PNG_COLOR_TYPE_RGB ||
-             newColorType == PNG_COLOR_TYPE_RGBA) {
-    const size_t bpp = newColorType == PNG_COLOR_TYPE_RGB ? 3 : 4;
-    if (needsToZeroRGBChannelsOfTransparentPixels) {
+  } else if (new_color_type == PNG_COLOR_TYPE_RGB ||
+             new_color_type == PNG_COLOR_TYPE_RGBA) {
+    const size_t bpp = new_color_type == PNG_COLOR_TYPE_RGB ? 3 : 4;
+    if (needs_to_zero_rgb_channels_of_transparent_pixels) {
       // The source RGBA data can't be used as-is, because we need to zero out
       // the RGB
       // values of transparent pixels.
-      auto outRow =
+      auto out_row =
           std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]);
 
       for (int32_t y = 0; y < image->height; y++) {
-        png_const_bytep inRow = image->rows[y];
+        png_const_bytep in_row = image->rows[y];
         for (int32_t x = 0; x < image->width; x++) {
-          int rr = *inRow++;
-          int gg = *inRow++;
-          int bb = *inRow++;
-          int aa = *inRow++;
+          int rr = *in_row++;
+          int gg = *in_row++;
+          int bb = *in_row++;
+          int aa = *in_row++;
           if (aa == 0) {
             // Zero out the RGB channels when transparent.
             rr = gg = bb = 0;
           }
-          outRow[x * bpp] = rr;
-          outRow[x * bpp + 1] = gg;
-          outRow[x * bpp + 2] = bb;
+          out_row[x * bpp] = rr;
+          out_row[x * bpp + 1] = gg;
+          out_row[x * bpp + 2] = bb;
           if (bpp == 4) {
-            outRow[x * bpp + 3] = aa;
+            out_row[x * bpp + 3] = aa;
           }
         }
-        png_write_row(writePtr, outRow.get());
+        png_write_row(write_ptr, out_row.get());
       }
     } else {
       // The source image can be used as-is, just tell libpng whether or not to
       // ignore
       // the alpha channel.
-      if (newColorType == PNG_COLOR_TYPE_RGB) {
+      if (new_color_type == PNG_COLOR_TYPE_RGB) {
         // Delete the extraneous alpha values that we appended to our buffer
         // when reading the original values.
-        png_set_filler(writePtr, 0, PNG_FILLER_AFTER);
+        png_set_filler(write_ptr, 0, PNG_FILLER_AFTER);
       }
-      png_write_image(writePtr, image->rows.get());
+      png_write_image(write_ptr, image->rows.get());
     }
   } else {
-    assert(false && "unreachable");
+    LOG(FATAL) << "unreachable";
   }
 
-  png_write_end(writePtr, writeInfoPtr);
+  png_write_end(write_ptr, write_info_ptr);
   return true;
 }
 
diff --git a/tools/aapt2/compile/PseudolocaleGenerator.cpp b/tools/aapt2/compile/PseudolocaleGenerator.cpp
index d8ed0bb..055a725 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator.cpp
@@ -15,27 +15,29 @@
  */
 
 #include "compile/PseudolocaleGenerator.h"
+
+#include <algorithm>
+
 #include "ResourceTable.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
 #include "compile/Pseudolocalizer.h"
 
-#include <algorithm>
-
 namespace aapt {
 
-std::unique_ptr<StyledString> pseudolocalizeStyledString(
+std::unique_ptr<StyledString> PseudolocalizeStyledString(
     StyledString* string, Pseudolocalizer::Method method, StringPool* pool) {
   Pseudolocalizer localizer(method);
 
-  const StringPiece originalText = *string->value->str;
+  const StringPiece original_text = *string->value->str;
 
   StyleString localized;
 
   // Copy the spans. We will update their offsets when we localize.
   localized.spans.reserve(string->value->spans.size());
   for (const StringPool::Span& span : string->value->spans) {
-    localized.spans.push_back(Span{*span.name, span.firstChar, span.lastChar});
+    localized.spans.push_back(
+        Span{*span.name, span.first_char, span.last_char});
   }
 
   // The ranges are all represented with a single value. This is the start of
@@ -49,8 +51,8 @@
     // Since this struct represents the start of one range and end of another,
     // we have
     // the two pointers respectively.
-    uint32_t* updateStart;
-    uint32_t* updateEnd;
+    uint32_t* update_start;
+    uint32_t* update_end;
   };
 
   auto cmp = [](const Range& r, size_t index) -> bool {
@@ -64,109 +66,113 @@
   //
   std::vector<Range> ranges;
   ranges.push_back(Range{0});
-  ranges.push_back(Range{originalText.size() - 1});
+  ranges.push_back(Range{original_text.size() - 1});
   for (size_t i = 0; i < string->value->spans.size(); i++) {
     const StringPool::Span& span = string->value->spans[i];
 
     // Insert or update the Range marker for the start of this span.
     auto iter =
-        std::lower_bound(ranges.begin(), ranges.end(), span.firstChar, cmp);
-    if (iter != ranges.end() && iter->start == span.firstChar) {
-      iter->updateStart = &localized.spans[i].firstChar;
+        std::lower_bound(ranges.begin(), ranges.end(), span.first_char, cmp);
+    if (iter != ranges.end() && iter->start == span.first_char) {
+      iter->update_start = &localized.spans[i].first_char;
     } else {
-      ranges.insert(
-          iter, Range{span.firstChar, &localized.spans[i].firstChar, nullptr});
+      ranges.insert(iter, Range{span.first_char, &localized.spans[i].first_char,
+                                nullptr});
     }
 
     // Insert or update the Range marker for the end of this span.
-    iter = std::lower_bound(ranges.begin(), ranges.end(), span.lastChar, cmp);
-    if (iter != ranges.end() && iter->start == span.lastChar) {
-      iter->updateEnd = &localized.spans[i].lastChar;
+    iter = std::lower_bound(ranges.begin(), ranges.end(), span.last_char, cmp);
+    if (iter != ranges.end() && iter->start == span.last_char) {
+      iter->update_end = &localized.spans[i].last_char;
     } else {
       ranges.insert(
-          iter, Range{span.lastChar, nullptr, &localized.spans[i].lastChar});
+          iter, Range{span.last_char, nullptr, &localized.spans[i].last_char});
     }
   }
 
-  localized.str += localizer.start();
+  localized.str += localizer.Start();
 
   // Iterate over the ranges and localize each section.
   for (size_t i = 0; i < ranges.size(); i++) {
     const size_t start = ranges[i].start;
-    size_t len = originalText.size() - start;
+    size_t len = original_text.size() - start;
     if (i + 1 < ranges.size()) {
       len = ranges[i + 1].start - start;
     }
 
-    if (ranges[i].updateStart) {
-      *ranges[i].updateStart = localized.str.size();
+    if (ranges[i].update_start) {
+      *ranges[i].update_start = localized.str.size();
     }
 
-    if (ranges[i].updateEnd) {
-      *ranges[i].updateEnd = localized.str.size();
+    if (ranges[i].update_end) {
+      *ranges[i].update_end = localized.str.size();
     }
 
-    localized.str += localizer.text(originalText.substr(start, len));
+    localized.str += localizer.Text(original_text.substr(start, len));
   }
 
-  localized.str += localizer.end();
+  localized.str += localizer.End();
 
-  std::unique_ptr<StyledString> localizedString =
-      util::make_unique<StyledString>(pool->makeRef(localized));
-  localizedString->setSource(string->getSource());
-  return localizedString;
+  std::unique_ptr<StyledString> localized_string =
+      util::make_unique<StyledString>(pool->MakeRef(localized));
+  localized_string->SetSource(string->GetSource());
+  return localized_string;
 }
 
 namespace {
 
-struct Visitor : public RawValueVisitor {
-  StringPool* mPool;
-  Pseudolocalizer::Method mMethod;
-  Pseudolocalizer mLocalizer;
-
+class Visitor : public RawValueVisitor {
+ public:
   // Either value or item will be populated upon visiting the value.
-  std::unique_ptr<Value> mValue;
-  std::unique_ptr<Item> mItem;
+  std::unique_ptr<Value> value;
+  std::unique_ptr<Item> item;
 
   Visitor(StringPool* pool, Pseudolocalizer::Method method)
-      : mPool(pool), mMethod(method), mLocalizer(method) {}
+      : pool_(pool), method_(method), localizer_(method) {}
 
-  void visit(Plural* plural) override {
+  void Visit(Plural* plural) override {
     std::unique_ptr<Plural> localized = util::make_unique<Plural>();
     for (size_t i = 0; i < plural->values.size(); i++) {
-      Visitor subVisitor(mPool, mMethod);
+      Visitor sub_visitor(pool_, method_);
       if (plural->values[i]) {
-        plural->values[i]->accept(&subVisitor);
-        if (subVisitor.mValue) {
-          localized->values[i] = std::move(subVisitor.mItem);
+        plural->values[i]->Accept(&sub_visitor);
+        if (sub_visitor.value) {
+          localized->values[i] = std::move(sub_visitor.item);
         } else {
           localized->values[i] =
-              std::unique_ptr<Item>(plural->values[i]->clone(mPool));
+              std::unique_ptr<Item>(plural->values[i]->Clone(pool_));
         }
       }
     }
-    localized->setSource(plural->getSource());
-    localized->setWeak(true);
-    mValue = std::move(localized);
+    localized->SetSource(plural->GetSource());
+    localized->SetWeak(true);
+    value = std::move(localized);
   }
 
-  void visit(String* string) override {
+  void Visit(String* string) override {
     std::string result =
-        mLocalizer.start() + mLocalizer.text(*string->value) + mLocalizer.end();
+        localizer_.Start() + localizer_.Text(*string->value) + localizer_.End();
     std::unique_ptr<String> localized =
-        util::make_unique<String>(mPool->makeRef(result));
-    localized->setSource(string->getSource());
-    localized->setWeak(true);
-    mItem = std::move(localized);
+        util::make_unique<String>(pool_->MakeRef(result));
+    localized->SetSource(string->GetSource());
+    localized->SetWeak(true);
+    item = std::move(localized);
   }
 
-  void visit(StyledString* string) override {
-    mItem = pseudolocalizeStyledString(string, mMethod, mPool);
-    mItem->setWeak(true);
+  void Visit(StyledString* string) override {
+    item = PseudolocalizeStyledString(string, method_, pool_);
+    item->SetWeak(true);
   }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Visitor);
+
+  StringPool* pool_;
+  Pseudolocalizer::Method method_;
+  Pseudolocalizer localizer_;
 };
 
-ConfigDescription modifyConfigForPseudoLocale(const ConfigDescription& base,
+ConfigDescription ModifyConfigForPseudoLocale(const ConfigDescription& base,
                                               Pseudolocalizer::Method m) {
   ConfigDescription modified = base;
   switch (m) {
@@ -189,31 +195,31 @@
   return modified;
 }
 
-void pseudolocalizeIfNeeded(const Pseudolocalizer::Method method,
-                            ResourceConfigValue* originalValue,
+void PseudolocalizeIfNeeded(const Pseudolocalizer::Method method,
+                            ResourceConfigValue* original_value,
                             StringPool* pool, ResourceEntry* entry) {
   Visitor visitor(pool, method);
-  originalValue->value->accept(&visitor);
+  original_value->value->Accept(&visitor);
 
-  std::unique_ptr<Value> localizedValue;
-  if (visitor.mValue) {
-    localizedValue = std::move(visitor.mValue);
-  } else if (visitor.mItem) {
-    localizedValue = std::move(visitor.mItem);
+  std::unique_ptr<Value> localized_value;
+  if (visitor.value) {
+    localized_value = std::move(visitor.value);
+  } else if (visitor.item) {
+    localized_value = std::move(visitor.item);
   }
 
-  if (!localizedValue) {
+  if (!localized_value) {
     return;
   }
 
-  ConfigDescription configWithAccent =
-      modifyConfigForPseudoLocale(originalValue->config, method);
+  ConfigDescription config_with_accent =
+      ModifyConfigForPseudoLocale(original_value->config, method);
 
-  ResourceConfigValue* newConfigValue =
-      entry->findOrCreateValue(configWithAccent, originalValue->product);
-  if (!newConfigValue->value) {
+  ResourceConfigValue* new_config_value =
+      entry->FindOrCreateValue(config_with_accent, original_value->product);
+  if (!new_config_value->value) {
     // Only use auto-generated pseudo-localization if none is defined.
-    newConfigValue->value = std::move(localizedValue);
+    new_config_value->value = std::move(localized_value);
   }
 }
 
@@ -222,29 +228,30 @@
  * default locale)
  * and is translateable.
  */
-static bool isPseudolocalizable(ResourceConfigValue* configValue) {
-  const int diff = configValue->config.diff(ConfigDescription::defaultConfig());
+static bool IsPseudolocalizable(ResourceConfigValue* config_value) {
+  const int diff =
+      config_value->config.diff(ConfigDescription::DefaultConfig());
   if (diff & ConfigDescription::CONFIG_LOCALE) {
     return false;
   }
-  return configValue->value->isTranslateable();
+  return config_value->value->IsTranslateable();
 }
 
 }  // namespace
 
-bool PseudolocaleGenerator::consume(IAaptContext* context,
+bool PseudolocaleGenerator::Consume(IAaptContext* context,
                                     ResourceTable* table) {
   for (auto& package : table->packages) {
     for (auto& type : package->types) {
       for (auto& entry : type->entries) {
         std::vector<ResourceConfigValue*> values =
-            entry->findValuesIf(isPseudolocalizable);
+            entry->FindValuesIf(IsPseudolocalizable);
 
         for (ResourceConfigValue* value : values) {
-          pseudolocalizeIfNeeded(Pseudolocalizer::Method::kAccent, value,
-                                 &table->stringPool, entry.get());
-          pseudolocalizeIfNeeded(Pseudolocalizer::Method::kBidi, value,
-                                 &table->stringPool, entry.get());
+          PseudolocalizeIfNeeded(Pseudolocalizer::Method::kAccent, value,
+                                 &table->string_pool, entry.get());
+          PseudolocalizeIfNeeded(Pseudolocalizer::Method::kBidi, value,
+                                 &table->string_pool, entry.get());
         }
       }
     }
diff --git a/tools/aapt2/compile/PseudolocaleGenerator.h b/tools/aapt2/compile/PseudolocaleGenerator.h
index 4e97cb9..ace3786 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator.h
+++ b/tools/aapt2/compile/PseudolocaleGenerator.h
@@ -23,11 +23,11 @@
 
 namespace aapt {
 
-std::unique_ptr<StyledString> pseudolocalizeStyledString(
+std::unique_ptr<StyledString> PseudolocalizeStyledString(
     StyledString* string, Pseudolocalizer::Method method, StringPool* pool);
 
 struct PseudolocaleGenerator : public IResourceTableConsumer {
-  bool consume(IAaptContext* context, ResourceTable* table) override;
+  bool Consume(IAaptContext* context, ResourceTable* table) override;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
index 64a3e97..5a9884d 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
@@ -15,118 +15,119 @@
  */
 
 #include "compile/PseudolocaleGenerator.h"
+
 #include "test/Test.h"
 #include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
-
 namespace aapt {
 
 TEST(PseudolocaleGeneratorTest, PseudolocalizeStyledString) {
   StringPool pool;
-  StyleString originalStyle;
-  originalStyle.str = "Hello world!";
-  originalStyle.spans = {Span{"b", 2, 3}, Span{"b", 6, 7}, Span{"i", 1, 10}};
+  StyleString original_style;
+  original_style.str = "Hello world!";
+  original_style.spans = {Span{"b", 2, 3}, Span{"b", 6, 7}, Span{"i", 1, 10}};
 
-  std::unique_ptr<StyledString> newString = pseudolocalizeStyledString(
-      util::make_unique<StyledString>(pool.makeRef(originalStyle)).get(),
+  std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
+      util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
       Pseudolocalizer::Method::kNone, &pool);
 
-  EXPECT_EQ(originalStyle.str, *newString->value->str);
-  ASSERT_EQ(originalStyle.spans.size(), newString->value->spans.size());
+  EXPECT_EQ(original_style.str, *new_string->value->str);
+  ASSERT_EQ(original_style.spans.size(), new_string->value->spans.size());
 
-  EXPECT_EQ(std::string("He").size(), newString->value->spans[0].firstChar);
-  EXPECT_EQ(std::string("Hel").size(), newString->value->spans[0].lastChar);
-  EXPECT_EQ(std::string("b"), *newString->value->spans[0].name);
+  EXPECT_EQ(std::string("He").size(), new_string->value->spans[0].first_char);
+  EXPECT_EQ(std::string("Hel").size(), new_string->value->spans[0].last_char);
+  EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name);
 
-  EXPECT_EQ(std::string("Hello ").size(), newString->value->spans[1].firstChar);
-  EXPECT_EQ(std::string("Hello w").size(), newString->value->spans[1].lastChar);
-  EXPECT_EQ(std::string("b"), *newString->value->spans[1].name);
+  EXPECT_EQ(std::string("Hello ").size(),
+            new_string->value->spans[1].first_char);
+  EXPECT_EQ(std::string("Hello w").size(),
+            new_string->value->spans[1].last_char);
+  EXPECT_EQ(std::string("b"), *new_string->value->spans[1].name);
 
-  EXPECT_EQ(std::string("H").size(), newString->value->spans[2].firstChar);
+  EXPECT_EQ(std::string("H").size(), new_string->value->spans[2].first_char);
   EXPECT_EQ(std::string("Hello worl").size(),
-            newString->value->spans[2].lastChar);
-  EXPECT_EQ(std::string("i"), *newString->value->spans[2].name);
+            new_string->value->spans[2].last_char);
+  EXPECT_EQ(std::string("i"), *new_string->value->spans[2].name);
 
-  originalStyle.spans.push_back(Span{"em", 0, 11u});
+  original_style.spans.push_back(Span{"em", 0, 11u});
 
-  newString = pseudolocalizeStyledString(
-      util::make_unique<StyledString>(pool.makeRef(originalStyle)).get(),
+  new_string = PseudolocalizeStyledString(
+      util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
       Pseudolocalizer::Method::kAccent, &pool);
 
-  EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļð¡ one two]"), *newString->value->str);
-  ASSERT_EQ(originalStyle.spans.size(), newString->value->spans.size());
+  EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļð¡ one two]"), *new_string->value->str);
+  ASSERT_EQ(original_style.spans.size(), new_string->value->spans.size());
 
-  EXPECT_EQ(std::string("[Ĥé").size(), newString->value->spans[0].firstChar);
-  EXPECT_EQ(std::string("[Ĥéļ").size(), newString->value->spans[0].lastChar);
+  EXPECT_EQ(std::string("[Ĥé").size(), new_string->value->spans[0].first_char);
+  EXPECT_EQ(std::string("[Ĥéļ").size(), new_string->value->spans[0].last_char);
 
   EXPECT_EQ(std::string("[Ĥéļļö ").size(),
-            newString->value->spans[1].firstChar);
+            new_string->value->spans[1].first_char);
   EXPECT_EQ(std::string("[Ĥéļļö ŵ").size(),
-            newString->value->spans[1].lastChar);
+            new_string->value->spans[1].last_char);
 
-  EXPECT_EQ(std::string("[Ĥ").size(), newString->value->spans[2].firstChar);
+  EXPECT_EQ(std::string("[Ĥ").size(), new_string->value->spans[2].first_char);
   EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļ").size(),
-            newString->value->spans[2].lastChar);
+            new_string->value->spans[2].last_char);
 
-  EXPECT_EQ(std::string("[").size(), newString->value->spans[3].firstChar);
+  EXPECT_EQ(std::string("[").size(), new_string->value->spans[3].first_char);
   EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļð").size(),
-            newString->value->spans[3].lastChar);
+            new_string->value->spans[3].last_char);
 }
 
 TEST(PseudolocaleGeneratorTest, PseudolocalizeOnlyDefaultConfigs) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .addString("android:string/one", "one")
-          .addString("android:string/two", ResourceId{},
-                     test::parseConfigOrDie("en"), "two")
-          .addString("android:string/three", "three")
-          .addString("android:string/three", ResourceId{},
-                     test::parseConfigOrDie("en-rXA"), "three")
-          .addString("android:string/four", "four")
-          .build();
+          .AddString("android:string/one", "one")
+          .AddString("android:string/two", ResourceId{},
+                     test::ParseConfigOrDie("en"), "two")
+          .AddString("android:string/three", "three")
+          .AddString("android:string/three", ResourceId{},
+                     test::ParseConfigOrDie("en-rXA"), "three")
+          .AddString("android:string/four", "four")
+          .Build();
 
-  String* val = test::getValue<String>(table.get(), "android:string/four");
+  String* val = test::GetValue<String>(table.get(), "android:string/four");
   ASSERT_NE(nullptr, val);
-  val->setTranslateable(false);
+  val->SetTranslateable(false);
 
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   PseudolocaleGenerator generator;
-  ASSERT_TRUE(generator.consume(context.get(), table.get()));
+  ASSERT_TRUE(generator.Consume(context.get(), table.get()));
 
   // Normal pseudolocalization should take place.
   ASSERT_NE(nullptr,
-            test::getValueForConfig<String>(table.get(), "android:string/one",
-                                            test::parseConfigOrDie("en-rXA")));
+            test::GetValueForConfig<String>(table.get(), "android:string/one",
+                                            test::ParseConfigOrDie("en-rXA")));
   ASSERT_NE(nullptr,
-            test::getValueForConfig<String>(table.get(), "android:string/one",
-                                            test::parseConfigOrDie("ar-rXB")));
+            test::GetValueForConfig<String>(table.get(), "android:string/one",
+                                            test::ParseConfigOrDie("ar-rXB")));
 
   // No default config for android:string/two, so no pseudlocales should exist.
   ASSERT_EQ(nullptr,
-            test::getValueForConfig<String>(table.get(), "android:string/two",
-                                            test::parseConfigOrDie("en-rXA")));
+            test::GetValueForConfig<String>(table.get(), "android:string/two",
+                                            test::ParseConfigOrDie("en-rXA")));
   ASSERT_EQ(nullptr,
-            test::getValueForConfig<String>(table.get(), "android:string/two",
-                                            test::parseConfigOrDie("ar-rXB")));
+            test::GetValueForConfig<String>(table.get(), "android:string/two",
+                                            test::ParseConfigOrDie("ar-rXB")));
 
   // Check that we didn't override manual pseudolocalization.
-  val = test::getValueForConfig<String>(table.get(), "android:string/three",
-                                        test::parseConfigOrDie("en-rXA"));
+  val = test::GetValueForConfig<String>(table.get(), "android:string/three",
+                                        test::ParseConfigOrDie("en-rXA"));
   ASSERT_NE(nullptr, val);
   EXPECT_EQ(std::string("three"), *val->value);
 
   ASSERT_NE(nullptr,
-            test::getValueForConfig<String>(table.get(), "android:string/three",
-                                            test::parseConfigOrDie("ar-rXB")));
+            test::GetValueForConfig<String>(table.get(), "android:string/three",
+                                            test::ParseConfigOrDie("ar-rXB")));
 
   // Check that four's translateable marker was honored.
   ASSERT_EQ(nullptr,
-            test::getValueForConfig<String>(table.get(), "android:string/four",
-                                            test::parseConfigOrDie("en-rXA")));
+            test::GetValueForConfig<String>(table.get(), "android:string/four",
+                                            test::ParseConfigOrDie("en-rXA")));
   ASSERT_EQ(nullptr,
-            test::getValueForConfig<String>(table.get(), "android:string/four",
-                                            test::parseConfigOrDie("ar-rXB")));
+            test::GetValueForConfig<String>(table.get(), "android:string/four",
+                                            test::ParseConfigOrDie("ar-rXB")));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/compile/Pseudolocalizer.cpp b/tools/aapt2/compile/Pseudolocalizer.cpp
index c3aec98..f89288f 100644
--- a/tools/aapt2/compile/Pseudolocalizer.cpp
+++ b/tools/aapt2/compile/Pseudolocalizer.cpp
@@ -15,77 +15,78 @@
  */
 
 #include "compile/Pseudolocalizer.h"
+
 #include "util/Util.h"
 
 namespace aapt {
 
 // String basis to generate expansion
-static const std::string k_expansion_string =
+static const std::string kExpansionString =
     "one two three "
     "four five six seven eight nine ten eleven twelve thirteen "
     "fourteen fiveteen sixteen seventeen nineteen twenty";
 
 // Special unicode characters to override directionality of the words
-static const std::string k_rlm = "\u200f";
-static const std::string k_rlo = "\u202e";
-static const std::string k_pdf = "\u202c";
+static const std::string kRlm = "\u200f";
+static const std::string kRlo = "\u202e";
+static const std::string kPdf = "\u202c";
 
 // Placeholder marks
-static const std::string k_placeholder_open = "\u00bb";
-static const std::string k_placeholder_close = "\u00ab";
+static const std::string kPlaceholderOpen = "\u00bb";
+static const std::string kPlaceholderClose = "\u00ab";
 
-static const char k_arg_start = '{';
-static const char k_arg_end = '}';
+static const char kArgStart = '{';
+static const char kArgEnd = '}';
 
 class PseudoMethodNone : public PseudoMethodImpl {
  public:
-  std::string text(const StringPiece& text) override { return text.toString(); }
-  std::string placeholder(const StringPiece& text) override {
-    return text.toString();
+  std::string Text(const StringPiece& text) override { return text.ToString(); }
+  std::string Placeholder(const StringPiece& text) override {
+    return text.ToString();
   }
 };
 
 class PseudoMethodBidi : public PseudoMethodImpl {
  public:
-  std::string text(const StringPiece& text) override;
-  std::string placeholder(const StringPiece& text) override;
+  std::string Text(const StringPiece& text) override;
+  std::string Placeholder(const StringPiece& text) override;
 };
 
 class PseudoMethodAccent : public PseudoMethodImpl {
  public:
-  PseudoMethodAccent() : mDepth(0), mWordCount(0), mLength(0) {}
-  std::string start() override;
-  std::string end() override;
-  std::string text(const StringPiece& text) override;
-  std::string placeholder(const StringPiece& text) override;
+  PseudoMethodAccent() : depth_(0), word_count_(0), length_(0) {}
+  std::string Start() override;
+  std::string End() override;
+  std::string Text(const StringPiece& text) override;
+  std::string Placeholder(const StringPiece& text) override;
 
  private:
-  size_t mDepth;
-  size_t mWordCount;
-  size_t mLength;
+  size_t depth_;
+  size_t word_count_;
+  size_t length_;
 };
 
-Pseudolocalizer::Pseudolocalizer(Method method) : mLastDepth(0) {
-  setMethod(method);
+Pseudolocalizer::Pseudolocalizer(Method method) : last_depth_(0) {
+  SetMethod(method);
 }
 
-void Pseudolocalizer::setMethod(Method method) {
+void Pseudolocalizer::SetMethod(Method method) {
   switch (method) {
     case Method::kNone:
-      mImpl = util::make_unique<PseudoMethodNone>();
+      impl_ = util::make_unique<PseudoMethodNone>();
       break;
     case Method::kAccent:
-      mImpl = util::make_unique<PseudoMethodAccent>();
+      impl_ = util::make_unique<PseudoMethodAccent>();
       break;
     case Method::kBidi:
-      mImpl = util::make_unique<PseudoMethodBidi>();
+      impl_ = util::make_unique<PseudoMethodBidi>();
       break;
   }
 }
 
-std::string Pseudolocalizer::text(const StringPiece& text) {
+std::string Pseudolocalizer::Text(const StringPiece& text) {
   std::string out;
-  size_t depth = mLastDepth;
+  size_t depth = last_depth_;
   size_t lastpos, pos;
   const size_t length = text.size();
   const char* str = text.data();
@@ -101,42 +102,41 @@
       continue;
     }
 
-    if (c == k_arg_start) {
+    if (c == kArgStart) {
       depth++;
-    } else if (c == k_arg_end && depth) {
+    } else if (c == kArgEnd && depth) {
       depth--;
     }
 
-    if (mLastDepth != depth || pos == length - 1) {
-      bool pseudo = ((mLastDepth % 2) == 0);
+    if (last_depth_ != depth || pos == length - 1) {
+      bool pseudo = ((last_depth_ % 2) == 0);
       size_t nextpos = pos;
-      if (!pseudo || depth == mLastDepth) {
+      if (!pseudo || depth == last_depth_) {
         nextpos++;
       }
       size_t size = nextpos - lastpos;
       if (size) {
-        std::string chunk = text.substr(lastpos, size).toString();
+        std::string chunk = text.substr(lastpos, size).ToString();
         if (pseudo) {
-          chunk = mImpl->text(chunk);
-        } else if (str[lastpos] == k_arg_start &&
-                   str[nextpos - 1] == k_arg_end) {
-          chunk = mImpl->placeholder(chunk);
+          chunk = impl_->Text(chunk);
+        } else if (str[lastpos] == kArgStart && str[nextpos - 1] == kArgEnd) {
+          chunk = impl_->Placeholder(chunk);
         }
         out.append(chunk);
       }
-      if (pseudo && depth < mLastDepth) {  // End of message
-        out.append(mImpl->end());
-      } else if (!pseudo && depth > mLastDepth) {  // Start of message
-        out.append(mImpl->start());
+      if (pseudo && depth < last_depth_) {  // End of message
+        out.append(impl_->End());
+      } else if (!pseudo && depth > last_depth_) {  // Start of message
+        out.append(impl_->Start());
       }
       lastpos = nextpos;
-      mLastDepth = depth;
+      last_depth_ = depth;
     }
   }
   return out;
 }
 
-static const char* pseudolocalizeChar(const char c) {
+static const char* PseudolocalizeChar(const char c) {
   switch (c) {
     case 'a':
       return "\u00e5";
@@ -251,7 +251,7 @@
   }
 }
 
-static bool isPossibleNormalPlaceholderEnd(const char c) {
+static bool IsPossibleNormalPlaceholderEnd(const char c) {
   switch (c) {
     case 's':
       return true;
@@ -300,12 +300,12 @@
   }
 }
 
-static std::string pseudoGenerateExpansion(const unsigned int length) {
-  std::string result = k_expansion_string;
+static std::string PseudoGenerateExpansion(const unsigned int length) {
+  std::string result = kExpansionString;
   const char* s = result.data();
   if (result.size() < length) {
     result += " ";
-    result += pseudoGenerateExpansion(length - result.size());
+    result += PseudoGenerateExpansion(length - result.size());
   } else {
     int ext = 0;
     // Should contain only whole words, so looking for a space
@@ -320,25 +320,25 @@
   return result;
 }
 
-std::string PseudoMethodAccent::start() {
+std::string PseudoMethodAccent::Start() {
   std::string result;
-  if (mDepth == 0) {
+  if (depth_ == 0) {
     result = "[";
   }
-  mWordCount = mLength = 0;
-  mDepth++;
+  word_count_ = length_ = 0;
+  depth_++;
   return result;
 }
 
-std::string PseudoMethodAccent::end() {
+std::string PseudoMethodAccent::End() {
   std::string result;
-  if (mLength) {
+  if (length_) {
     result += " ";
-    result += pseudoGenerateExpansion(mWordCount > 3 ? mLength : mLength / 2);
+    result += PseudoGenerateExpansion(word_count_ > 3 ? length_ : length_ / 2);
   }
-  mWordCount = mLength = 0;
-  mDepth--;
-  if (mDepth == 0) {
+  word_count_ = length_ = 0;
+  depth_--;
+  if (depth_ == 0) {
     result += "]";
   }
   return result;
@@ -349,7 +349,7 @@
  *
  * Note: This leaves placeholder syntax untouched.
  */
-std::string PseudoMethodAccent::text(const StringPiece& source) {
+std::string PseudoMethodAccent::Text(const StringPiece& source) {
   const char* s = source.data();
   std::string result;
   const size_t I = source.size();
@@ -365,7 +365,7 @@
         ++i;
         c = s[i];
         chunk.append(&c, 1);
-        if (isPossibleNormalPlaceholderEnd(c)) {
+        if (IsPossibleNormalPlaceholderEnd(c)) {
           end = true;
         } else if (i + 1 < I && c == 't') {
           ++i;
@@ -375,24 +375,24 @@
         }
       }
       // Treat chunk as a placeholder unless it ends with %.
-      result += ((c == '%') ? chunk : placeholder(chunk));
+      result += ((c == '%') ? chunk : Placeholder(chunk));
     } else if (c == '<' || c == '&') {
       // html syntax, no need to pseudolocalize
       bool tag_closed = false;
       while (!tag_closed && i < I) {
         if (c == '&') {
-          std::string escapeText;
-          escapeText.append(&c, 1);
+          std::string escape_text;
+          escape_text.append(&c, 1);
           bool end = false;
-          size_t htmlCodePos = i;
-          while (!end && htmlCodePos < I) {
-            ++htmlCodePos;
-            c = s[htmlCodePos];
-            escapeText.append(&c, 1);
+          size_t html_code_pos = i;
+          while (!end && html_code_pos < I) {
+            ++html_code_pos;
+            c = s[html_code_pos];
+            escape_text.append(&c, 1);
             // Valid html code
             if (c == ';') {
               end = true;
-              i = htmlCodePos;
+              i = html_code_pos;
             }
             // Wrong html code
             else if (!((c == '#' || (c >= 'a' && c <= 'z') ||
@@ -400,8 +400,8 @@
               end = true;
             }
           }
-          result += escapeText;
-          if (escapeText != "&lt;") {
+          result += escape_text;
+          if (escape_text != "&lt;") {
             tag_closed = true;
           }
           continue;
@@ -417,30 +417,30 @@
       }
     } else {
       // This is a pure text that should be pseudolocalized
-      const char* p = pseudolocalizeChar(c);
+      const char* p = PseudolocalizeChar(c);
       if (p != nullptr) {
         result += p;
       } else {
         bool space = isspace(c);
         if (lastspace && !space) {
-          mWordCount++;
+          word_count_++;
         }
         lastspace = space;
         result.append(&c, 1);
       }
       // Count only pseudolocalizable chars and delimiters
-      mLength++;
+      length_++;
     }
   }
   return result;
 }
 
-std::string PseudoMethodAccent::placeholder(const StringPiece& source) {
+std::string PseudoMethodAccent::Placeholder(const StringPiece& source) {
   // Surround a placeholder with brackets
-  return k_placeholder_open + source.toString() + k_placeholder_close;
+  return kPlaceholderOpen + source.ToString() + kPlaceholderClose;
 }
 
-std::string PseudoMethodBidi::text(const StringPiece& source) {
+std::string PseudoMethodBidi::Text(const StringPiece& source) {
   const char* s = source.data();
   std::string result;
   bool lastspace = true;
@@ -450,24 +450,24 @@
     space = isspace(c);
     if (lastspace && !space) {
       // Word start
-      result += k_rlm + k_rlo;
+      result += kRlm + kRlo;
     } else if (!lastspace && space) {
       // Word end
-      result += k_pdf + k_rlm;
+      result += kPdf + kRlm;
     }
     lastspace = space;
     result.append(&c, 1);
   }
   if (!lastspace) {
     // End of last word
-    result += k_pdf + k_rlm;
+    result += kPdf + kRlm;
   }
   return result;
 }
 
-std::string PseudoMethodBidi::placeholder(const StringPiece& source) {
+std::string PseudoMethodBidi::Placeholder(const StringPiece& source) {
   // Surround a placeholder with directionality change sequence
-  return k_rlm + k_rlo + source.toString() + k_pdf + k_rlm;
+  return kRlm + kRlo + source.ToString() + kPdf + kRlm;
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/compile/Pseudolocalizer.h b/tools/aapt2/compile/Pseudolocalizer.h
index a526877..a6d2ad0 100644
--- a/tools/aapt2/compile/Pseudolocalizer.h
+++ b/tools/aapt2/compile/Pseudolocalizer.h
@@ -17,22 +17,23 @@
 #ifndef AAPT_COMPILE_PSEUDOLOCALIZE_H
 #define AAPT_COMPILE_PSEUDOLOCALIZE_H
 
+#include <memory>
+
+#include "android-base/macros.h"
+
 #include "ResourceValues.h"
 #include "StringPool.h"
 #include "util/StringPiece.h"
 
-#include <android-base/macros.h>
-#include <memory>
-
 namespace aapt {
 
 class PseudoMethodImpl {
  public:
   virtual ~PseudoMethodImpl() {}
-  virtual std::string start() { return {}; }
-  virtual std::string end() { return {}; }
-  virtual std::string text(const StringPiece& text) = 0;
-  virtual std::string placeholder(const StringPiece& text) = 0;
+  virtual std::string Start() { return {}; }
+  virtual std::string End() { return {}; }
+  virtual std::string Text(const StringPiece& text) = 0;
+  virtual std::string Placeholder(const StringPiece& text) = 0;
 };
 
 class Pseudolocalizer {
@@ -44,14 +45,14 @@
   };
 
   explicit Pseudolocalizer(Method method);
-  void setMethod(Method method);
-  std::string start() { return mImpl->start(); }
-  std::string end() { return mImpl->end(); }
-  std::string text(const StringPiece& text);
+  void SetMethod(Method method);
+  std::string Start() { return impl_->Start(); }
+  std::string End() { return impl_->End(); }
+  std::string Text(const StringPiece& text);
 
  private:
-  std::unique_ptr<PseudoMethodImpl> mImpl;
-  size_t mLastDepth;
+  std::unique_ptr<PseudoMethodImpl> impl_;
+  size_t last_depth_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/compile/Pseudolocalizer_test.cpp b/tools/aapt2/compile/Pseudolocalizer_test.cpp
index a152ed6..92eb3b5 100644
--- a/tools/aapt2/compile/Pseudolocalizer_test.cpp
+++ b/tools/aapt2/compile/Pseudolocalizer_test.cpp
@@ -15,33 +15,32 @@
  */
 
 #include "compile/Pseudolocalizer.h"
-#include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
-#include <gtest/gtest.h>
+#include "test/Test.h"
+#include "util/Util.h"
 
 namespace aapt {
 
 // In this context, 'Axis' represents a particular field in the configuration,
 // such as language or density.
 
-static ::testing::AssertionResult simpleHelper(const char* input,
+static ::testing::AssertionResult SimpleHelper(const char* input,
                                                const char* expected,
                                                Pseudolocalizer::Method method) {
   Pseudolocalizer pseudo(method);
-  std::string result = pseudo.start() + pseudo.text(input) + pseudo.end();
+  std::string result = pseudo.Start() + pseudo.Text(input) + pseudo.End();
   if (result != expected) {
     return ::testing::AssertionFailure() << expected << " != " << result;
   }
   return ::testing::AssertionSuccess();
 }
 
-static ::testing::AssertionResult compoundHelper(
+static ::testing::AssertionResult CompoundHelper(
     const char* in1, const char* in2, const char* in3, const char* expected,
     Pseudolocalizer::Method method) {
   Pseudolocalizer pseudo(method);
-  std::string result = pseudo.start() + pseudo.text(in1) + pseudo.text(in2) +
-                       pseudo.text(in3) + pseudo.end();
+  std::string result = pseudo.Start() + pseudo.Text(in1) + pseudo.Text(in2) +
+                       pseudo.Text(in3) + pseudo.End();
   if (result != expected) {
     return ::testing::AssertionFailure() << expected << " != " << result;
   }
@@ -49,49 +48,49 @@
 }
 
 TEST(PseudolocalizerTest, NoPseudolocalization) {
-  EXPECT_TRUE(simpleHelper("", "", Pseudolocalizer::Method::kNone));
-  EXPECT_TRUE(simpleHelper("Hello, world", "Hello, world",
+  EXPECT_TRUE(SimpleHelper("", "", Pseudolocalizer::Method::kNone));
+  EXPECT_TRUE(SimpleHelper("Hello, world", "Hello, world",
                            Pseudolocalizer::Method::kNone));
 
-  EXPECT_TRUE(compoundHelper("Hello,", " world", "", "Hello, world",
+  EXPECT_TRUE(CompoundHelper("Hello,", " world", "", "Hello, world",
                              Pseudolocalizer::Method::kNone));
 }
 
 TEST(PseudolocalizerTest, PlaintextAccent) {
-  EXPECT_TRUE(simpleHelper("", "[]", Pseudolocalizer::Method::kAccent));
-  EXPECT_TRUE(simpleHelper("Hello, world", "[Ĥéļļö, ŵöŕļð one two]",
+  EXPECT_TRUE(SimpleHelper("", "[]", Pseudolocalizer::Method::kAccent));
+  EXPECT_TRUE(SimpleHelper("Hello, world", "[Ĥéļļö, ŵöŕļð one two]",
                            Pseudolocalizer::Method::kAccent));
 
-  EXPECT_TRUE(simpleHelper("Hello, %1d", "[Ĥéļļö, »%1d« one two]",
+  EXPECT_TRUE(SimpleHelper("Hello, %1d", "[Ĥéļļö, »%1d« one two]",
                            Pseudolocalizer::Method::kAccent));
 
-  EXPECT_TRUE(simpleHelper("Battery %1d%%", "[βåţţéŕý »%1d«%% one two]",
+  EXPECT_TRUE(SimpleHelper("Battery %1d%%", "[βåţţéŕý »%1d«%% one two]",
                            Pseudolocalizer::Method::kAccent));
   EXPECT_TRUE(
-      simpleHelper("^1 %", "[^1 % one]", Pseudolocalizer::Method::kAccent));
+      SimpleHelper("^1 %", "[^1 % one]", Pseudolocalizer::Method::kAccent));
   EXPECT_TRUE(
-      compoundHelper("", "", "", "[]", Pseudolocalizer::Method::kAccent));
-  EXPECT_TRUE(compoundHelper("Hello,", " world", "", "[Ĥéļļö, ŵöŕļð one two]",
+      CompoundHelper("", "", "", "[]", Pseudolocalizer::Method::kAccent));
+  EXPECT_TRUE(CompoundHelper("Hello,", " world", "", "[Ĥéļļö, ŵöŕļð one two]",
                              Pseudolocalizer::Method::kAccent));
 }
 
 TEST(PseudolocalizerTest, PlaintextBidi) {
-  EXPECT_TRUE(simpleHelper("", "", Pseudolocalizer::Method::kBidi));
-  EXPECT_TRUE(simpleHelper(
+  EXPECT_TRUE(SimpleHelper("", "", Pseudolocalizer::Method::kBidi));
+  EXPECT_TRUE(SimpleHelper(
       "word", "\xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f",
       Pseudolocalizer::Method::kBidi));
-  EXPECT_TRUE(simpleHelper(
+  EXPECT_TRUE(SimpleHelper(
       "  word  ", "  \xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f  ",
       Pseudolocalizer::Method::kBidi));
-  EXPECT_TRUE(simpleHelper(
+  EXPECT_TRUE(SimpleHelper(
       "  word  ", "  \xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f  ",
       Pseudolocalizer::Method::kBidi));
   EXPECT_TRUE(
-      simpleHelper("hello\n  world\n",
+      SimpleHelper("hello\n  world\n",
                    "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\n"
                    "  \xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\n",
                    Pseudolocalizer::Method::kBidi));
-  EXPECT_TRUE(compoundHelper(
+  EXPECT_TRUE(CompoundHelper(
       "hello", "\n ", " world\n",
       "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\n"
       "  \xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\n",
@@ -100,33 +99,33 @@
 
 TEST(PseudolocalizerTest, SimpleICU) {
   // Single-fragment messages
-  EXPECT_TRUE(simpleHelper("{placeholder}", "[»{placeholder}«]",
+  EXPECT_TRUE(SimpleHelper("{placeholder}", "[»{placeholder}«]",
                            Pseudolocalizer::Method::kAccent));
-  EXPECT_TRUE(simpleHelper("{USER} is offline", "[»{USER}« îš öƒƒļîñé one two]",
+  EXPECT_TRUE(SimpleHelper("{USER} is offline", "[»{USER}« îš öƒƒļîñé one two]",
                            Pseudolocalizer::Method::kAccent));
-  EXPECT_TRUE(simpleHelper("Copy from {path1} to {path2}",
+  EXPECT_TRUE(SimpleHelper("Copy from {path1} to {path2}",
                            "[Çöþý ƒŕöḿ »{path1}« ţö »{path2}« one two three]",
                            Pseudolocalizer::Method::kAccent));
-  EXPECT_TRUE(simpleHelper("Today is {1,date} {1,time}",
+  EXPECT_TRUE(SimpleHelper("Today is {1,date} {1,time}",
                            "[Ţöðåý îš »{1,date}« »{1,time}« one two]",
                            Pseudolocalizer::Method::kAccent));
 
   // Multi-fragment messages
-  EXPECT_TRUE(compoundHelper("{USER}", " ", "is offline",
+  EXPECT_TRUE(CompoundHelper("{USER}", " ", "is offline",
                              "[»{USER}« îš öƒƒļîñé one two]",
                              Pseudolocalizer::Method::kAccent));
-  EXPECT_TRUE(compoundHelper("Copy from ", "{path1}", " to {path2}",
+  EXPECT_TRUE(CompoundHelper("Copy from ", "{path1}", " to {path2}",
                              "[Çöþý ƒŕöḿ »{path1}« ţö »{path2}« one two three]",
                              Pseudolocalizer::Method::kAccent));
 }
 
 TEST(PseudolocalizerTest, ICUBidi) {
   // Single-fragment messages
-  EXPECT_TRUE(simpleHelper(
+  EXPECT_TRUE(SimpleHelper(
       "{placeholder}",
       "\xe2\x80\x8f\xE2\x80\xae{placeholder}\xE2\x80\xac\xe2\x80\x8f",
       Pseudolocalizer::Method::kBidi));
-  EXPECT_TRUE(simpleHelper(
+  EXPECT_TRUE(SimpleHelper(
       "{COUNT, plural, one {one} other {other}}",
       "{COUNT, plural, "
       "one {\xe2\x80\x8f\xE2\x80\xaeone\xE2\x80\xac\xe2\x80\x8f} "
@@ -136,30 +135,30 @@
 
 TEST(PseudolocalizerTest, Escaping) {
   // Single-fragment messages
-  EXPECT_TRUE(simpleHelper("'{USER'} is offline",
+  EXPECT_TRUE(SimpleHelper("'{USER'} is offline",
                            "['{ÛŠÉŔ'} îš öƒƒļîñé one two three]",
                            Pseudolocalizer::Method::kAccent));
 
   // Multi-fragment messages
-  EXPECT_TRUE(compoundHelper("'{USER}", " ", "''is offline",
+  EXPECT_TRUE(CompoundHelper("'{USER}", " ", "''is offline",
                              "['{ÛŠÉŔ} ''îš öƒƒļîñé one two three]",
                              Pseudolocalizer::Method::kAccent));
 }
 
 TEST(PseudolocalizerTest, PluralsAndSelects) {
-  EXPECT_TRUE(simpleHelper(
+  EXPECT_TRUE(SimpleHelper(
       "{COUNT, plural, one {Delete a file} other {Delete {COUNT} files}}",
       "[{COUNT, plural, one {Ðéļéţé å ƒîļé one two} "
       "other {Ðéļéţé »{COUNT}« ƒîļéš one two}}]",
       Pseudolocalizer::Method::kAccent));
 
   EXPECT_TRUE(
-      simpleHelper("Distance is {COUNT, plural, one {# mile} other {# miles}}",
+      SimpleHelper("Distance is {COUNT, plural, one {# mile} other {# miles}}",
                    "[Ðîšţåñçé îš {COUNT, plural, one {# ḿîļé one two} "
                    "other {# ḿîļéš one two}}]",
                    Pseudolocalizer::Method::kAccent));
 
-  EXPECT_TRUE(simpleHelper(
+  EXPECT_TRUE(SimpleHelper(
       "{1, select, female {{1} added you} "
       "male {{1} added you} other {{1} added you}}",
       "[{1, select, female {»{1}« åððéð ýöû one two} "
@@ -167,7 +166,7 @@
       Pseudolocalizer::Method::kAccent));
 
   EXPECT_TRUE(
-      compoundHelper("{COUNT, plural, one {Delete a file} "
+      CompoundHelper("{COUNT, plural, one {Delete a file} "
                      "other {Delete ",
                      "{COUNT}", " files}}",
                      "[{COUNT, plural, one {Ðéļéţé å ƒîļé one two} "
@@ -177,7 +176,7 @@
 
 TEST(PseudolocalizerTest, NestedICU) {
   EXPECT_TRUE(
-      simpleHelper("{person, select, "
+      SimpleHelper("{person, select, "
                    "female {"
                    "{num_circles, plural,"
                    "=0{{person} didn't add you to any of her circles.}"
@@ -222,9 +221,9 @@
 
 TEST(PseudolocalizerTest, RedefineMethod) {
   Pseudolocalizer pseudo(Pseudolocalizer::Method::kAccent);
-  std::string result = pseudo.text("Hello, ");
-  pseudo.setMethod(Pseudolocalizer::Method::kNone);
-  result += pseudo.text("world!");
+  std::string result = pseudo.Text("Hello, ");
+  pseudo.SetMethod(Pseudolocalizer::Method::kNone);
+  result += pseudo.Text("world!");
   ASSERT_EQ(StringPiece("Ĥéļļö, world!"), result);
 }
 
diff --git a/tools/aapt2/compile/XmlIdCollector.cpp b/tools/aapt2/compile/XmlIdCollector.cpp
index aa8b1df..d61a15a 100644
--- a/tools/aapt2/compile/XmlIdCollector.cpp
+++ b/tools/aapt2/compile/XmlIdCollector.cpp
@@ -15,55 +15,59 @@
  */
 
 #include "compile/XmlIdCollector.h"
-#include "ResourceUtils.h"
-#include "ResourceValues.h"
-#include "xml/XmlDom.h"
 
 #include <algorithm>
 #include <vector>
 
+#include "ResourceUtils.h"
+#include "ResourceValues.h"
+#include "xml/XmlDom.h"
+
 namespace aapt {
 
 namespace {
 
-static bool cmpName(const SourcedResourceName& a, const ResourceNameRef& b) {
+static bool cmp_name(const SourcedResourceName& a, const ResourceNameRef& b) {
   return a.name < b;
 }
 
 struct IdCollector : public xml::Visitor {
-  using xml::Visitor::visit;
+ public:
+  using xml::Visitor::Visit;
 
-  std::vector<SourcedResourceName>* mOutSymbols;
+  explicit IdCollector(std::vector<SourcedResourceName>* out_symbols)
+      : out_symbols_(out_symbols) {}
 
-  explicit IdCollector(std::vector<SourcedResourceName>* outSymbols)
-      : mOutSymbols(outSymbols) {}
-
-  void visit(xml::Element* element) override {
+  void Visit(xml::Element* element) override {
     for (xml::Attribute& attr : element->attributes) {
       ResourceNameRef name;
       bool create = false;
-      if (ResourceUtils::parseReference(attr.value, &name, &create, nullptr)) {
+      if (ResourceUtils::ParseReference(attr.value, &name, &create, nullptr)) {
         if (create && name.type == ResourceType::kId) {
-          auto iter = std::lower_bound(mOutSymbols->begin(), mOutSymbols->end(),
-                                       name, cmpName);
-          if (iter == mOutSymbols->end() || iter->name != name) {
-            mOutSymbols->insert(iter, SourcedResourceName{name.toResourceName(),
-                                                          element->lineNumber});
+          auto iter = std::lower_bound(out_symbols_->begin(),
+                                       out_symbols_->end(), name, cmp_name);
+          if (iter == out_symbols_->end() || iter->name != name) {
+            out_symbols_->insert(iter,
+                                 SourcedResourceName{name.ToResourceName(),
+                                                     element->line_number});
           }
         }
       }
     }
 
-    xml::Visitor::visit(element);
+    xml::Visitor::Visit(element);
   }
+
+ private:
+  std::vector<SourcedResourceName>* out_symbols_;
 };
 
 }  // namespace
 
-bool XmlIdCollector::consume(IAaptContext* context, xml::XmlResource* xmlRes) {
-  xmlRes->file.exportedSymbols.clear();
-  IdCollector collector(&xmlRes->file.exportedSymbols);
-  xmlRes->root->accept(&collector);
+bool XmlIdCollector::Consume(IAaptContext* context, xml::XmlResource* xmlRes) {
+  xmlRes->file.exported_symbols.clear();
+  IdCollector collector(&xmlRes->file.exported_symbols);
+  xmlRes->root->Accept(&collector);
   return true;
 }
 
diff --git a/tools/aapt2/compile/XmlIdCollector.h b/tools/aapt2/compile/XmlIdCollector.h
index 8423f48..8febf0f 100644
--- a/tools/aapt2/compile/XmlIdCollector.h
+++ b/tools/aapt2/compile/XmlIdCollector.h
@@ -23,7 +23,7 @@
 namespace aapt {
 
 struct XmlIdCollector : public IXmlResourceConsumer {
-  bool consume(IAaptContext* context, xml::XmlResource* xmlRes) override;
+  bool Consume(IAaptContext* context, xml::XmlResource* xml_res) override;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/compile/XmlIdCollector_test.cpp b/tools/aapt2/compile/XmlIdCollector_test.cpp
index 08ca7b1..98da56d 100644
--- a/tools/aapt2/compile/XmlIdCollector_test.cpp
+++ b/tools/aapt2/compile/XmlIdCollector_test.cpp
@@ -15,18 +15,17 @@
  */
 
 #include "compile/XmlIdCollector.h"
-#include "test/Builders.h"
-#include "test/Context.h"
 
-#include <gtest/gtest.h>
 #include <algorithm>
 
+#include "test/Test.h"
+
 namespace aapt {
 
 TEST(XmlIdCollectorTest, CollectsIds) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
 
-  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
             <View xmlns:android="http://schemas.android.com/apk/res/android"
                   android:id="@+id/foo"
                   text="@+id/bar">
@@ -35,34 +34,34 @@
             </View>)EOF");
 
   XmlIdCollector collector;
-  ASSERT_TRUE(collector.consume(context.get(), doc.get()));
+  ASSERT_TRUE(collector.Consume(context.get(), doc.get()));
 
   EXPECT_EQ(
-      1, std::count(doc->file.exportedSymbols.begin(),
-                    doc->file.exportedSymbols.end(),
-                    SourcedResourceName{test::parseNameOrDie("id/foo"), 3u}));
+      1, std::count(doc->file.exported_symbols.begin(),
+                    doc->file.exported_symbols.end(),
+                    SourcedResourceName{test::ParseNameOrDie("id/foo"), 3u}));
 
   EXPECT_EQ(
-      1, std::count(doc->file.exportedSymbols.begin(),
-                    doc->file.exportedSymbols.end(),
-                    SourcedResourceName{test::parseNameOrDie("id/bar"), 3u}));
+      1, std::count(doc->file.exported_symbols.begin(),
+                    doc->file.exported_symbols.end(),
+                    SourcedResourceName{test::ParseNameOrDie("id/bar"), 3u}));
 
   EXPECT_EQ(
-      1, std::count(doc->file.exportedSymbols.begin(),
-                    doc->file.exportedSymbols.end(),
-                    SourcedResourceName{test::parseNameOrDie("id/car"), 6u}));
+      1, std::count(doc->file.exported_symbols.begin(),
+                    doc->file.exported_symbols.end(),
+                    SourcedResourceName{test::ParseNameOrDie("id/car"), 6u}));
 }
 
 TEST(XmlIdCollectorTest, DontCollectNonIds) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
 
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDom("<View foo=\"@+string/foo\"/>");
+      test::BuildXmlDom("<View foo=\"@+string/foo\"/>");
 
   XmlIdCollector collector;
-  ASSERT_TRUE(collector.consume(context.get(), doc.get()));
+  ASSERT_TRUE(collector.Consume(context.get(), doc.get()));
 
-  EXPECT_TRUE(doc->file.exportedSymbols.empty());
+  EXPECT_TRUE(doc->file.exported_symbols.empty());
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/diff/Diff.cpp b/tools/aapt2/diff/Diff.cpp
index 01f4539..593e7ab 100644
--- a/tools/aapt2/diff/Diff.cpp
+++ b/tools/aapt2/diff/Diff.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include "android-base/macros.h"
+
 #include "Flags.h"
 #include "ResourceTable.h"
 #include "ValueVisitor.h"
@@ -22,74 +24,72 @@
 #include "process/SymbolTable.h"
 #include "unflatten/BinaryResourceParser.h"
 
-#include <android-base/macros.h>
-
 namespace aapt {
 
 class DiffContext : public IAaptContext {
  public:
-  const std::string& getCompilationPackage() override { return mEmpty; }
+  const std::string& GetCompilationPackage() override { return empty_; }
 
-  uint8_t getPackageId() override { return 0x0; }
+  uint8_t GetPackageId() override { return 0x0; }
 
-  IDiagnostics* getDiagnostics() override { return &mDiagnostics; }
+  IDiagnostics* GetDiagnostics() override { return &diagnostics_; }
 
-  NameMangler* getNameMangler() override { return &mNameMangler; }
+  NameMangler* GetNameMangler() override { return &name_mangler_; }
 
-  SymbolTable* getExternalSymbols() override { return &mSymbolTable; }
+  SymbolTable* GetExternalSymbols() override { return &symbol_table_; }
 
-  bool verbose() override { return false; }
+  bool IsVerbose() override { return false; }
 
-  int getMinSdkVersion() override { return 0; }
+  int GetMinSdkVersion() override { return 0; }
 
  private:
-  std::string mEmpty;
-  StdErrDiagnostics mDiagnostics;
-  NameMangler mNameMangler = NameMangler(NameManglerPolicy{});
-  SymbolTable mSymbolTable;
+  std::string empty_;
+  StdErrDiagnostics diagnostics_;
+  NameMangler name_mangler_ = NameMangler(NameManglerPolicy{});
+  SymbolTable symbol_table_;
 };
 
 class LoadedApk {
  public:
   LoadedApk(const Source& source, std::unique_ptr<io::IFileCollection> apk,
             std::unique_ptr<ResourceTable> table)
-      : mSource(source), mApk(std::move(apk)), mTable(std::move(table)) {}
+      : source_(source), apk_(std::move(apk)), table_(std::move(table)) {}
 
-  io::IFileCollection* getFileCollection() { return mApk.get(); }
+  io::IFileCollection* GetFileCollection() { return apk_.get(); }
 
-  ResourceTable* getResourceTable() { return mTable.get(); }
+  ResourceTable* GetResourceTable() { return table_.get(); }
 
-  const Source& getSource() { return mSource; }
+  const Source& GetSource() { return source_; }
 
  private:
-  Source mSource;
-  std::unique_ptr<io::IFileCollection> mApk;
-  std::unique_ptr<ResourceTable> mTable;
+  Source source_;
+  std::unique_ptr<io::IFileCollection> apk_;
+  std::unique_ptr<ResourceTable> table_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadedApk);
 };
 
-static std::unique_ptr<LoadedApk> loadApkFromPath(IAaptContext* context,
+static std::unique_ptr<LoadedApk> LoadApkFromPath(IAaptContext* context,
                                                   const StringPiece& path) {
   Source source(path);
   std::string error;
   std::unique_ptr<io::ZipFileCollection> apk =
-      io::ZipFileCollection::create(path, &error);
+      io::ZipFileCollection::Create(path, &error);
   if (!apk) {
-    context->getDiagnostics()->error(DiagMessage(source) << error);
+    context->GetDiagnostics()->Error(DiagMessage(source) << error);
     return {};
   }
 
-  io::IFile* file = apk->findFile("resources.arsc");
+  io::IFile* file = apk->FindFile("resources.arsc");
   if (!file) {
-    context->getDiagnostics()->error(DiagMessage(source)
+    context->GetDiagnostics()->Error(DiagMessage(source)
                                      << "no resources.arsc found");
     return {};
   }
 
-  std::unique_ptr<io::IData> data = file->openAsData();
+  std::unique_ptr<io::IData> data = file->OpenAsData();
   if (!data) {
-    context->getDiagnostics()->error(DiagMessage(source)
+    context->GetDiagnostics()->Error(DiagMessage(source)
                                      << "could not open resources.arsc");
     return {};
   }
@@ -97,276 +97,281 @@
   std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
   BinaryResourceParser parser(context, table.get(), source, data->data(),
                               data->size());
-  if (!parser.parse()) {
+  if (!parser.Parse()) {
     return {};
   }
 
   return util::make_unique<LoadedApk>(source, std::move(apk), std::move(table));
 }
 
-static void emitDiffLine(const Source& source, const StringPiece& message) {
+static void EmitDiffLine(const Source& source, const StringPiece& message) {
   std::cerr << source << ": " << message << "\n";
 }
 
-static bool isSymbolVisibilityDifferent(const Symbol& symbolA,
-                                        const Symbol& symbolB) {
-  return symbolA.state != symbolB.state;
+static bool IsSymbolVisibilityDifferent(const Symbol& symbol_a,
+                                        const Symbol& symbol_b) {
+  return symbol_a.state != symbol_b.state;
 }
 
 template <typename Id>
-static bool isIdDiff(const Symbol& symbolA, const Maybe<Id>& idA,
-                     const Symbol& symbolB, const Maybe<Id>& idB) {
-  if (symbolA.state == SymbolState::kPublic ||
-      symbolB.state == SymbolState::kPublic) {
-    return idA != idB;
+static bool IsIdDiff(const Symbol& symbol_a, const Maybe<Id>& id_a,
+                     const Symbol& symbol_b, const Maybe<Id>& id_b) {
+  if (symbol_a.state == SymbolState::kPublic ||
+      symbol_b.state == SymbolState::kPublic) {
+    return id_a != id_b;
   }
   return false;
 }
 
-static bool emitResourceConfigValueDiff(
-    IAaptContext* context, LoadedApk* apkA, ResourceTablePackage* pkgA,
-    ResourceTableType* typeA, ResourceEntry* entryA,
-    ResourceConfigValue* configValueA, LoadedApk* apkB,
-    ResourceTablePackage* pkgB, ResourceTableType* typeB, ResourceEntry* entryB,
-    ResourceConfigValue* configValueB) {
-  Value* valueA = configValueA->value.get();
-  Value* valueB = configValueB->value.get();
-  if (!valueA->equals(valueB)) {
-    std::stringstream strStream;
-    strStream << "value " << pkgA->name << ":" << typeA->type << "/"
-              << entryA->name << " config=" << configValueA->config
-              << " does not match:\n";
-    valueA->print(&strStream);
-    strStream << "\n vs \n";
-    valueB->print(&strStream);
-    emitDiffLine(apkB->getSource(), strStream.str());
+static bool EmitResourceConfigValueDiff(
+    IAaptContext* context, LoadedApk* apk_a, ResourceTablePackage* pkg_a,
+    ResourceTableType* type_a, ResourceEntry* entry_a,
+    ResourceConfigValue* config_value_a, LoadedApk* apk_b,
+    ResourceTablePackage* pkg_b, ResourceTableType* type_b,
+    ResourceEntry* entry_b, ResourceConfigValue* config_value_b) {
+  Value* value_a = config_value_a->value.get();
+  Value* value_b = config_value_b->value.get();
+  if (!value_a->Equals(value_b)) {
+    std::stringstream str_stream;
+    str_stream << "value " << pkg_a->name << ":" << type_a->type << "/"
+               << entry_a->name << " config=" << config_value_a->config
+               << " does not match:\n";
+    value_a->Print(&str_stream);
+    str_stream << "\n vs \n";
+    value_b->Print(&str_stream);
+    EmitDiffLine(apk_b->GetSource(), str_stream.str());
     return true;
   }
   return false;
 }
 
-static bool emitResourceEntryDiff(IAaptContext* context, LoadedApk* apkA,
-                                  ResourceTablePackage* pkgA,
-                                  ResourceTableType* typeA,
-                                  ResourceEntry* entryA, LoadedApk* apkB,
-                                  ResourceTablePackage* pkgB,
-                                  ResourceTableType* typeB,
-                                  ResourceEntry* entryB) {
+static bool EmitResourceEntryDiff(IAaptContext* context, LoadedApk* apk_a,
+                                  ResourceTablePackage* pkg_a,
+                                  ResourceTableType* type_a,
+                                  ResourceEntry* entry_a, LoadedApk* apk_b,
+                                  ResourceTablePackage* pkg_b,
+                                  ResourceTableType* type_b,
+                                  ResourceEntry* entry_b) {
   bool diff = false;
-  for (std::unique_ptr<ResourceConfigValue>& configValueA : entryA->values) {
-    ResourceConfigValue* configValueB = entryB->findValue(configValueA->config);
-    if (!configValueB) {
-      std::stringstream strStream;
-      strStream << "missing " << pkgA->name << ":" << typeA->type << "/"
-                << entryA->name << " config=" << configValueA->config;
-      emitDiffLine(apkB->getSource(), strStream.str());
+  for (std::unique_ptr<ResourceConfigValue>& config_value_a : entry_a->values) {
+    ResourceConfigValue* config_value_b =
+        entry_b->FindValue(config_value_a->config);
+    if (!config_value_b) {
+      std::stringstream str_stream;
+      str_stream << "missing " << pkg_a->name << ":" << type_a->type << "/"
+                 << entry_a->name << " config=" << config_value_a->config;
+      EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     } else {
-      diff |= emitResourceConfigValueDiff(context, apkA, pkgA, typeA, entryA,
-                                          configValueA.get(), apkB, pkgB, typeB,
-                                          entryB, configValueB);
+      diff |= EmitResourceConfigValueDiff(
+          context, apk_a, pkg_a, type_a, entry_a, config_value_a.get(), apk_b,
+          pkg_b, type_b, entry_b, config_value_b);
     }
   }
 
   // Check for any newly added config values.
-  for (std::unique_ptr<ResourceConfigValue>& configValueB : entryB->values) {
-    ResourceConfigValue* configValueA = entryA->findValue(configValueB->config);
-    if (!configValueA) {
-      std::stringstream strStream;
-      strStream << "new config " << pkgB->name << ":" << typeB->type << "/"
-                << entryB->name << " config=" << configValueB->config;
-      emitDiffLine(apkB->getSource(), strStream.str());
+  for (std::unique_ptr<ResourceConfigValue>& config_value_b : entry_b->values) {
+    ResourceConfigValue* config_value_a =
+        entry_a->FindValue(config_value_b->config);
+    if (!config_value_a) {
+      std::stringstream str_stream;
+      str_stream << "new config " << pkg_b->name << ":" << type_b->type << "/"
+                 << entry_b->name << " config=" << config_value_b->config;
+      EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     }
   }
   return false;
 }
 
-static bool emitResourceTypeDiff(IAaptContext* context, LoadedApk* apkA,
-                                 ResourceTablePackage* pkgA,
-                                 ResourceTableType* typeA, LoadedApk* apkB,
-                                 ResourceTablePackage* pkgB,
-                                 ResourceTableType* typeB) {
+static bool EmitResourceTypeDiff(IAaptContext* context, LoadedApk* apk_a,
+                                 ResourceTablePackage* pkg_a,
+                                 ResourceTableType* type_a, LoadedApk* apk_b,
+                                 ResourceTablePackage* pkg_b,
+                                 ResourceTableType* type_b) {
   bool diff = false;
-  for (std::unique_ptr<ResourceEntry>& entryA : typeA->entries) {
-    ResourceEntry* entryB = typeB->findEntry(entryA->name);
-    if (!entryB) {
-      std::stringstream strStream;
-      strStream << "missing " << pkgA->name << ":" << typeA->type << "/"
-                << entryA->name;
-      emitDiffLine(apkB->getSource(), strStream.str());
+  for (std::unique_ptr<ResourceEntry>& entry_a : type_a->entries) {
+    ResourceEntry* entry_b = type_b->FindEntry(entry_a->name);
+    if (!entry_b) {
+      std::stringstream str_stream;
+      str_stream << "missing " << pkg_a->name << ":" << type_a->type << "/"
+                 << entry_a->name;
+      EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     } else {
-      if (isSymbolVisibilityDifferent(entryA->symbolStatus,
-                                      entryB->symbolStatus)) {
-        std::stringstream strStream;
-        strStream << pkgA->name << ":" << typeA->type << "/" << entryA->name
-                  << " has different visibility (";
-        if (entryB->symbolStatus.state == SymbolState::kPublic) {
-          strStream << "PUBLIC";
+      if (IsSymbolVisibilityDifferent(entry_a->symbol_status,
+                                      entry_b->symbol_status)) {
+        std::stringstream str_stream;
+        str_stream << pkg_a->name << ":" << type_a->type << "/" << entry_a->name
+                   << " has different visibility (";
+        if (entry_b->symbol_status.state == SymbolState::kPublic) {
+          str_stream << "PUBLIC";
         } else {
-          strStream << "PRIVATE";
+          str_stream << "PRIVATE";
         }
-        strStream << " vs ";
-        if (entryA->symbolStatus.state == SymbolState::kPublic) {
-          strStream << "PUBLIC";
+        str_stream << " vs ";
+        if (entry_a->symbol_status.state == SymbolState::kPublic) {
+          str_stream << "PUBLIC";
         } else {
-          strStream << "PRIVATE";
+          str_stream << "PRIVATE";
         }
-        strStream << ")";
-        emitDiffLine(apkB->getSource(), strStream.str());
+        str_stream << ")";
+        EmitDiffLine(apk_b->GetSource(), str_stream.str());
         diff = true;
-      } else if (isIdDiff(entryA->symbolStatus, entryA->id,
-                          entryB->symbolStatus, entryB->id)) {
-        std::stringstream strStream;
-        strStream << pkgA->name << ":" << typeA->type << "/" << entryA->name
-                  << " has different public ID (";
-        if (entryB->id) {
-          strStream << "0x" << std::hex << entryB->id.value();
+      } else if (IsIdDiff(entry_a->symbol_status, entry_a->id,
+                          entry_b->symbol_status, entry_b->id)) {
+        std::stringstream str_stream;
+        str_stream << pkg_a->name << ":" << type_a->type << "/" << entry_a->name
+                   << " has different public ID (";
+        if (entry_b->id) {
+          str_stream << "0x" << std::hex << entry_b->id.value();
         } else {
-          strStream << "none";
+          str_stream << "none";
         }
-        strStream << " vs ";
-        if (entryA->id) {
-          strStream << "0x " << std::hex << entryA->id.value();
+        str_stream << " vs ";
+        if (entry_a->id) {
+          str_stream << "0x " << std::hex << entry_a->id.value();
         } else {
-          strStream << "none";
+          str_stream << "none";
         }
-        strStream << ")";
-        emitDiffLine(apkB->getSource(), strStream.str());
+        str_stream << ")";
+        EmitDiffLine(apk_b->GetSource(), str_stream.str());
         diff = true;
       }
-      diff |= emitResourceEntryDiff(context, apkA, pkgA, typeA, entryA.get(),
-                                    apkB, pkgB, typeB, entryB);
+      diff |=
+          EmitResourceEntryDiff(context, apk_a, pkg_a, type_a, entry_a.get(),
+                                apk_b, pkg_b, type_b, entry_b);
     }
   }
 
   // Check for any newly added entries.
-  for (std::unique_ptr<ResourceEntry>& entryB : typeB->entries) {
-    ResourceEntry* entryA = typeA->findEntry(entryB->name);
-    if (!entryA) {
-      std::stringstream strStream;
-      strStream << "new entry " << pkgB->name << ":" << typeB->type << "/"
-                << entryB->name;
-      emitDiffLine(apkB->getSource(), strStream.str());
+  for (std::unique_ptr<ResourceEntry>& entry_b : type_b->entries) {
+    ResourceEntry* entry_a = type_a->FindEntry(entry_b->name);
+    if (!entry_a) {
+      std::stringstream str_stream;
+      str_stream << "new entry " << pkg_b->name << ":" << type_b->type << "/"
+                 << entry_b->name;
+      EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     }
   }
   return diff;
 }
 
-static bool emitResourcePackageDiff(IAaptContext* context, LoadedApk* apkA,
-                                    ResourceTablePackage* pkgA, LoadedApk* apkB,
-                                    ResourceTablePackage* pkgB) {
+static bool EmitResourcePackageDiff(IAaptContext* context, LoadedApk* apk_a,
+                                    ResourceTablePackage* pkg_a,
+                                    LoadedApk* apk_b,
+                                    ResourceTablePackage* pkg_b) {
   bool diff = false;
-  for (std::unique_ptr<ResourceTableType>& typeA : pkgA->types) {
-    ResourceTableType* typeB = pkgB->findType(typeA->type);
-    if (!typeB) {
-      std::stringstream strStream;
-      strStream << "missing " << pkgA->name << ":" << typeA->type;
-      emitDiffLine(apkA->getSource(), strStream.str());
+  for (std::unique_ptr<ResourceTableType>& type_a : pkg_a->types) {
+    ResourceTableType* type_b = pkg_b->FindType(type_a->type);
+    if (!type_b) {
+      std::stringstream str_stream;
+      str_stream << "missing " << pkg_a->name << ":" << type_a->type;
+      EmitDiffLine(apk_a->GetSource(), str_stream.str());
       diff = true;
     } else {
-      if (isSymbolVisibilityDifferent(typeA->symbolStatus,
-                                      typeB->symbolStatus)) {
-        std::stringstream strStream;
-        strStream << pkgA->name << ":" << typeA->type
-                  << " has different visibility (";
-        if (typeB->symbolStatus.state == SymbolState::kPublic) {
-          strStream << "PUBLIC";
+      if (IsSymbolVisibilityDifferent(type_a->symbol_status,
+                                      type_b->symbol_status)) {
+        std::stringstream str_stream;
+        str_stream << pkg_a->name << ":" << type_a->type
+                   << " has different visibility (";
+        if (type_b->symbol_status.state == SymbolState::kPublic) {
+          str_stream << "PUBLIC";
         } else {
-          strStream << "PRIVATE";
+          str_stream << "PRIVATE";
         }
-        strStream << " vs ";
-        if (typeA->symbolStatus.state == SymbolState::kPublic) {
-          strStream << "PUBLIC";
+        str_stream << " vs ";
+        if (type_a->symbol_status.state == SymbolState::kPublic) {
+          str_stream << "PUBLIC";
         } else {
-          strStream << "PRIVATE";
+          str_stream << "PRIVATE";
         }
-        strStream << ")";
-        emitDiffLine(apkB->getSource(), strStream.str());
+        str_stream << ")";
+        EmitDiffLine(apk_b->GetSource(), str_stream.str());
         diff = true;
-      } else if (isIdDiff(typeA->symbolStatus, typeA->id, typeB->symbolStatus,
-                          typeB->id)) {
-        std::stringstream strStream;
-        strStream << pkgA->name << ":" << typeA->type
-                  << " has different public ID (";
-        if (typeB->id) {
-          strStream << "0x" << std::hex << typeB->id.value();
+      } else if (IsIdDiff(type_a->symbol_status, type_a->id,
+                          type_b->symbol_status, type_b->id)) {
+        std::stringstream str_stream;
+        str_stream << pkg_a->name << ":" << type_a->type
+                   << " has different public ID (";
+        if (type_b->id) {
+          str_stream << "0x" << std::hex << type_b->id.value();
         } else {
-          strStream << "none";
+          str_stream << "none";
         }
-        strStream << " vs ";
-        if (typeA->id) {
-          strStream << "0x " << std::hex << typeA->id.value();
+        str_stream << " vs ";
+        if (type_a->id) {
+          str_stream << "0x " << std::hex << type_a->id.value();
         } else {
-          strStream << "none";
+          str_stream << "none";
         }
-        strStream << ")";
-        emitDiffLine(apkB->getSource(), strStream.str());
+        str_stream << ")";
+        EmitDiffLine(apk_b->GetSource(), str_stream.str());
         diff = true;
       }
-      diff |= emitResourceTypeDiff(context, apkA, pkgA, typeA.get(), apkB, pkgB,
-                                   typeB);
+      diff |= EmitResourceTypeDiff(context, apk_a, pkg_a, type_a.get(), apk_b,
+                                   pkg_b, type_b);
     }
   }
 
   // Check for any newly added types.
-  for (std::unique_ptr<ResourceTableType>& typeB : pkgB->types) {
-    ResourceTableType* typeA = pkgA->findType(typeB->type);
-    if (!typeA) {
-      std::stringstream strStream;
-      strStream << "new type " << pkgB->name << ":" << typeB->type;
-      emitDiffLine(apkB->getSource(), strStream.str());
+  for (std::unique_ptr<ResourceTableType>& type_b : pkg_b->types) {
+    ResourceTableType* type_a = pkg_a->FindType(type_b->type);
+    if (!type_a) {
+      std::stringstream str_stream;
+      str_stream << "new type " << pkg_b->name << ":" << type_b->type;
+      EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     }
   }
   return diff;
 }
 
-static bool emitResourceTableDiff(IAaptContext* context, LoadedApk* apkA,
-                                  LoadedApk* apkB) {
-  ResourceTable* tableA = apkA->getResourceTable();
-  ResourceTable* tableB = apkB->getResourceTable();
+static bool EmitResourceTableDiff(IAaptContext* context, LoadedApk* apk_a,
+                                  LoadedApk* apk_b) {
+  ResourceTable* table_a = apk_a->GetResourceTable();
+  ResourceTable* table_b = apk_b->GetResourceTable();
 
   bool diff = false;
-  for (std::unique_ptr<ResourceTablePackage>& pkgA : tableA->packages) {
-    ResourceTablePackage* pkgB = tableB->findPackage(pkgA->name);
-    if (!pkgB) {
-      std::stringstream strStream;
-      strStream << "missing package " << pkgA->name;
-      emitDiffLine(apkB->getSource(), strStream.str());
+  for (std::unique_ptr<ResourceTablePackage>& pkg_a : table_a->packages) {
+    ResourceTablePackage* pkg_b = table_b->FindPackage(pkg_a->name);
+    if (!pkg_b) {
+      std::stringstream str_stream;
+      str_stream << "missing package " << pkg_a->name;
+      EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     } else {
-      if (pkgA->id != pkgB->id) {
-        std::stringstream strStream;
-        strStream << "package '" << pkgA->name << "' has different id (";
-        if (pkgB->id) {
-          strStream << "0x" << std::hex << pkgB->id.value();
+      if (pkg_a->id != pkg_b->id) {
+        std::stringstream str_stream;
+        str_stream << "package '" << pkg_a->name << "' has different id (";
+        if (pkg_b->id) {
+          str_stream << "0x" << std::hex << pkg_b->id.value();
         } else {
-          strStream << "none";
+          str_stream << "none";
         }
-        strStream << " vs ";
-        if (pkgA->id) {
-          strStream << "0x" << std::hex << pkgA->id.value();
+        str_stream << " vs ";
+        if (pkg_a->id) {
+          str_stream << "0x" << std::hex << pkg_a->id.value();
         } else {
-          strStream << "none";
+          str_stream << "none";
         }
-        strStream << ")";
-        emitDiffLine(apkB->getSource(), strStream.str());
+        str_stream << ")";
+        EmitDiffLine(apk_b->GetSource(), str_stream.str());
         diff = true;
       }
-      diff |= emitResourcePackageDiff(context, apkA, pkgA.get(), apkB, pkgB);
+      diff |=
+          EmitResourcePackageDiff(context, apk_a, pkg_a.get(), apk_b, pkg_b);
     }
   }
 
   // Check for any newly added packages.
-  for (std::unique_ptr<ResourceTablePackage>& pkgB : tableB->packages) {
-    ResourceTablePackage* pkgA = tableA->findPackage(pkgB->name);
-    if (!pkgA) {
-      std::stringstream strStream;
-      strStream << "new package " << pkgB->name;
-      emitDiffLine(apkB->getSource(), strStream.str());
+  for (std::unique_ptr<ResourceTablePackage>& pkg_b : table_b->packages) {
+    ResourceTablePackage* pkg_a = table_a->FindPackage(pkg_b->name);
+    if (!pkg_a) {
+      std::stringstream str_stream;
+      str_stream << "new package " << pkg_b->name;
+      EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     }
   }
@@ -375,49 +380,49 @@
 
 class ZeroingReferenceVisitor : public ValueVisitor {
  public:
-  using ValueVisitor::visit;
+  using ValueVisitor::Visit;
 
-  void visit(Reference* ref) override {
+  void Visit(Reference* ref) override {
     if (ref->name && ref->id) {
-      if (ref->id.value().packageId() == 0x7f) {
+      if (ref->id.value().package_id() == 0x7f) {
         ref->id = {};
       }
     }
   }
 };
 
-static void zeroOutAppReferences(ResourceTable* table) {
+static void ZeroOutAppReferences(ResourceTable* table) {
   ZeroingReferenceVisitor visitor;
-  visitAllValuesInTable(table, &visitor);
+  VisitAllValuesInTable(table, &visitor);
 }
 
-int diff(const std::vector<StringPiece>& args) {
+int Diff(const std::vector<StringPiece>& args) {
   DiffContext context;
 
   Flags flags;
-  if (!flags.parse("aapt2 diff", args, &std::cerr)) {
+  if (!flags.Parse("aapt2 diff", args, &std::cerr)) {
     return 1;
   }
 
-  if (flags.getArgs().size() != 2u) {
+  if (flags.GetArgs().size() != 2u) {
     std::cerr << "must have two apks as arguments.\n\n";
-    flags.usage("aapt2 diff", &std::cerr);
+    flags.Usage("aapt2 diff", &std::cerr);
     return 1;
   }
 
-  std::unique_ptr<LoadedApk> apkA =
-      loadApkFromPath(&context, flags.getArgs()[0]);
-  std::unique_ptr<LoadedApk> apkB =
-      loadApkFromPath(&context, flags.getArgs()[1]);
-  if (!apkA || !apkB) {
+  std::unique_ptr<LoadedApk> apk_a =
+      LoadApkFromPath(&context, flags.GetArgs()[0]);
+  std::unique_ptr<LoadedApk> apk_b =
+      LoadApkFromPath(&context, flags.GetArgs()[1]);
+  if (!apk_a || !apk_b) {
     return 1;
   }
 
   // Zero out Application IDs in references.
-  zeroOutAppReferences(apkA->getResourceTable());
-  zeroOutAppReferences(apkB->getResourceTable());
+  ZeroOutAppReferences(apk_a->GetResourceTable());
+  ZeroOutAppReferences(apk_b->GetResourceTable());
 
-  if (emitResourceTableDiff(&context, apkA.get(), apkB.get())) {
+  if (EmitResourceTableDiff(&context, apk_a.get(), apk_b.get())) {
     // We emitted a diff, so return 1 (failure).
     return 1;
   }
diff --git a/tools/aapt2/dump/Dump.cpp b/tools/aapt2/dump/Dump.cpp
index 3556cd88..2920c2a 100644
--- a/tools/aapt2/dump/Dump.cpp
+++ b/tools/aapt2/dump/Dump.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <vector>
+
 #include "Debug.h"
 #include "Diagnostics.h"
 #include "Flags.h"
@@ -24,20 +26,14 @@
 #include "util/Files.h"
 #include "util/StringPiece.h"
 
-#include <vector>
-
 namespace aapt {
 
-// struct DumpOptions {
-//
-//};
-
-void dumpCompiledFile(const pb::CompiledFile& pbFile, const void* data,
+void DumpCompiledFile(const pb::CompiledFile& pb_file, const void* data,
                       size_t len, const Source& source, IAaptContext* context) {
   std::unique_ptr<ResourceFile> file =
-      deserializeCompiledFileFromPb(pbFile, source, context->getDiagnostics());
+      DeserializeCompiledFileFromPb(pb_file, source, context->GetDiagnostics());
   if (!file) {
-    context->getDiagnostics()->warn(DiagMessage()
+    context->GetDiagnostics()->Warn(DiagMessage()
                                     << "failed to read compiled file");
     return;
   }
@@ -47,50 +43,50 @@
             << "Source:   " << file->source << "\n";
 }
 
-void tryDumpFile(IAaptContext* context, const std::string& filePath) {
+void TryDumpFile(IAaptContext* context, const std::string& file_path) {
   std::unique_ptr<ResourceTable> table;
 
   std::string err;
   std::unique_ptr<io::ZipFileCollection> zip =
-      io::ZipFileCollection::create(filePath, &err);
+      io::ZipFileCollection::Create(file_path, &err);
   if (zip) {
-    io::IFile* file = zip->findFile("resources.arsc.flat");
+    io::IFile* file = zip->FindFile("resources.arsc.flat");
     if (file) {
-      std::unique_ptr<io::IData> data = file->openAsData();
+      std::unique_ptr<io::IData> data = file->OpenAsData();
       if (!data) {
-        context->getDiagnostics()->error(
-            DiagMessage(filePath) << "failed to open resources.arsc.flat");
+        context->GetDiagnostics()->Error(
+            DiagMessage(file_path) << "failed to open resources.arsc.flat");
         return;
       }
 
-      pb::ResourceTable pbTable;
-      if (!pbTable.ParseFromArray(data->data(), data->size())) {
-        context->getDiagnostics()->error(DiagMessage(filePath)
+      pb::ResourceTable pb_table;
+      if (!pb_table.ParseFromArray(data->data(), data->size())) {
+        context->GetDiagnostics()->Error(DiagMessage(file_path)
                                          << "invalid resources.arsc.flat");
         return;
       }
 
-      table = deserializeTableFromPb(pbTable, Source(filePath),
-                                     context->getDiagnostics());
+      table = DeserializeTableFromPb(pb_table, Source(file_path),
+                                     context->GetDiagnostics());
       if (!table) {
         return;
       }
     }
 
     if (!table) {
-      file = zip->findFile("resources.arsc");
+      file = zip->FindFile("resources.arsc");
       if (file) {
-        std::unique_ptr<io::IData> data = file->openAsData();
+        std::unique_ptr<io::IData> data = file->OpenAsData();
         if (!data) {
-          context->getDiagnostics()->error(DiagMessage(filePath)
+          context->GetDiagnostics()->Error(DiagMessage(file_path)
                                            << "failed to open resources.arsc");
           return;
         }
 
         table = util::make_unique<ResourceTable>();
-        BinaryResourceParser parser(context, table.get(), Source(filePath),
+        BinaryResourceParser parser(context, table.get(), Source(file_path),
                                     data->data(), data->size());
-        if (!parser.parse()) {
+        if (!parser.Parse()) {
           return;
         }
       }
@@ -98,109 +94,109 @@
   }
 
   if (!table) {
-    Maybe<android::FileMap> file = file::mmapPath(filePath, &err);
+    Maybe<android::FileMap> file = file::MmapPath(file_path, &err);
     if (!file) {
-      context->getDiagnostics()->error(DiagMessage(filePath) << err);
+      context->GetDiagnostics()->Error(DiagMessage(file_path) << err);
       return;
     }
 
-    android::FileMap* fileMap = &file.value();
+    android::FileMap* file_map = &file.value();
 
     // Try as a compiled table.
-    pb::ResourceTable pbTable;
-    if (pbTable.ParseFromArray(fileMap->getDataPtr(),
-                               fileMap->getDataLength())) {
-      table = deserializeTableFromPb(pbTable, Source(filePath),
-                                     context->getDiagnostics());
+    pb::ResourceTable pb_table;
+    if (pb_table.ParseFromArray(file_map->getDataPtr(),
+                                file_map->getDataLength())) {
+      table = DeserializeTableFromPb(pb_table, Source(file_path),
+                                     context->GetDiagnostics());
     }
 
     if (!table) {
       // Try as a compiled file.
-      CompiledFileInputStream input(fileMap->getDataPtr(),
-                                    fileMap->getDataLength());
+      CompiledFileInputStream input(file_map->getDataPtr(),
+                                    file_map->getDataLength());
 
-      uint32_t numFiles = 0;
-      if (!input.ReadLittleEndian32(&numFiles)) {
+      uint32_t num_files = 0;
+      if (!input.ReadLittleEndian32(&num_files)) {
         return;
       }
 
-      for (uint32_t i = 0; i < numFiles; i++) {
-        pb::CompiledFile compiledFile;
-        if (!input.ReadCompiledFile(&compiledFile)) {
-          context->getDiagnostics()->warn(DiagMessage()
+      for (uint32_t i = 0; i < num_files; i++) {
+        pb::CompiledFile compiled_file;
+        if (!input.ReadCompiledFile(&compiled_file)) {
+          context->GetDiagnostics()->Warn(DiagMessage()
                                           << "failed to read compiled file");
           return;
         }
 
         uint64_t offset, len;
         if (!input.ReadDataMetaData(&offset, &len)) {
-          context->getDiagnostics()->warn(DiagMessage()
+          context->GetDiagnostics()->Warn(DiagMessage()
                                           << "failed to read meta data");
           return;
         }
 
         const void* data =
-            static_cast<const uint8_t*>(fileMap->getDataPtr()) + offset;
-        dumpCompiledFile(compiledFile, data, len, Source(filePath), context);
+            static_cast<const uint8_t*>(file_map->getDataPtr()) + offset;
+        DumpCompiledFile(compiled_file, data, len, Source(file_path), context);
       }
     }
   }
 
   if (table) {
-    DebugPrintTableOptions debugPrintTableOptions;
-    debugPrintTableOptions.showSources = true;
-    Debug::printTable(table.get(), debugPrintTableOptions);
+    DebugPrintTableOptions options;
+    options.show_sources = true;
+    Debug::PrintTable(table.get(), options);
   }
 }
 
 class DumpContext : public IAaptContext {
  public:
-  IDiagnostics* getDiagnostics() override { return &mDiagnostics; }
+  IDiagnostics* GetDiagnostics() override { return &diagnostics_; }
 
-  NameMangler* getNameMangler() override {
+  NameMangler* GetNameMangler() override {
     abort();
     return nullptr;
   }
 
-  const std::string& getCompilationPackage() override {
+  const std::string& GetCompilationPackage() override {
     static std::string empty;
     return empty;
   }
 
-  uint8_t getPackageId() override { return 0; }
+  uint8_t GetPackageId() override { return 0; }
 
-  SymbolTable* getExternalSymbols() override {
+  SymbolTable* GetExternalSymbols() override {
     abort();
     return nullptr;
   }
 
-  bool verbose() override { return mVerbose; }
+  bool IsVerbose() override { return verbose_; }
 
-  void setVerbose(bool val) { mVerbose = val; }
+  void SetVerbose(bool val) { verbose_ = val; }
 
-  int getMinSdkVersion() override { return 0; }
+  int GetMinSdkVersion() override { return 0; }
 
  private:
-  StdErrDiagnostics mDiagnostics;
-  bool mVerbose = false;
+  StdErrDiagnostics diagnostics_;
+  bool verbose_ = false;
 };
 
 /**
  * Entry point for dump command.
  */
-int dump(const std::vector<StringPiece>& args) {
+int Dump(const std::vector<StringPiece>& args) {
   bool verbose = false;
   Flags flags =
-      Flags().optionalSwitch("-v", "increase verbosity of output", &verbose);
-  if (!flags.parse("aapt2 dump", args, &std::cerr)) {
+      Flags().OptionalSwitch("-v", "increase verbosity of output", &verbose);
+  if (!flags.Parse("aapt2 dump", args, &std::cerr)) {
     return 1;
   }
 
   DumpContext context;
-  context.setVerbose(verbose);
+  context.SetVerbose(verbose);
 
-  for (const std::string& arg : flags.getArgs()) {
-    tryDumpFile(&context, arg);
+  for (const std::string& arg : flags.GetArgs()) {
+    TryDumpFile(&context, arg);
   }
   return 0;
 }
diff --git a/tools/aapt2/filter/ConfigFilter.cpp b/tools/aapt2/filter/ConfigFilter.cpp
index 5af996c..66aff82 100644
--- a/tools/aapt2/filter/ConfigFilter.cpp
+++ b/tools/aapt2/filter/ConfigFilter.cpp
@@ -15,44 +15,45 @@
  */
 
 #include "filter/ConfigFilter.h"
-#include "ConfigDescription.h"
 
-#include <androidfw/ResourceTypes.h>
+#include "androidfw/ResourceTypes.h"
+
+#include "ConfigDescription.h"
 
 namespace aapt {
 
-void AxisConfigFilter::addConfig(ConfigDescription config) {
-  uint32_t diffMask = ConfigDescription::defaultConfig().diff(config);
+void AxisConfigFilter::AddConfig(ConfigDescription config) {
+  uint32_t diff_mask = ConfigDescription::DefaultConfig().diff(config);
 
   // Ignore the version
-  diffMask &= ~android::ResTable_config::CONFIG_VERSION;
+  diff_mask &= ~android::ResTable_config::CONFIG_VERSION;
 
   // Ignore any densities. Those are best handled in --preferred-density
-  if ((diffMask & android::ResTable_config::CONFIG_DENSITY) != 0) {
+  if ((diff_mask & android::ResTable_config::CONFIG_DENSITY) != 0) {
     config.density = 0;
-    diffMask &= ~android::ResTable_config::CONFIG_DENSITY;
+    diff_mask &= ~android::ResTable_config::CONFIG_DENSITY;
   }
 
-  mConfigs.insert(std::make_pair(config, diffMask));
-  mConfigMask |= diffMask;
+  configs_.insert(std::make_pair(config, diff_mask));
+  config_mask_ |= diff_mask;
 }
 
-bool AxisConfigFilter::match(const ConfigDescription& config) const {
-  const uint32_t mask = ConfigDescription::defaultConfig().diff(config);
-  if ((mConfigMask & mask) == 0) {
+bool AxisConfigFilter::Match(const ConfigDescription& config) const {
+  const uint32_t mask = ConfigDescription::DefaultConfig().diff(config);
+  if ((config_mask_ & mask) == 0) {
     // The two configurations don't have any common axis.
     return true;
   }
 
-  uint32_t matchedAxis = 0;
-  for (const auto& entry : mConfigs) {
+  uint32_t matched_axis = 0;
+  for (const auto& entry : configs_) {
     const ConfigDescription& target = entry.first;
-    const uint32_t diffMask = entry.second;
+    const uint32_t diff_mask = entry.second;
     uint32_t diff = target.diff(config);
-    if ((diff & diffMask) == 0) {
+    if ((diff & diff_mask) == 0) {
       // Mark the axis that was matched.
-      matchedAxis |= diffMask;
-    } else if ((diff & diffMask) == android::ResTable_config::CONFIG_LOCALE) {
+      matched_axis |= diff_mask;
+    } else if ((diff & diff_mask) == android::ResTable_config::CONFIG_LOCALE) {
       // If the locales differ, but the languages are the same and
       // the locale we are matching only has a language specified,
       // we match.
@@ -60,10 +61,10 @@
           memcmp(config.language, target.language, sizeof(config.language)) ==
               0) {
         if (config.country[0] == 0) {
-          matchedAxis |= android::ResTable_config::CONFIG_LOCALE;
+          matched_axis |= android::ResTable_config::CONFIG_LOCALE;
         }
       }
-    } else if ((diff & diffMask) ==
+    } else if ((diff & diff_mask) ==
                android::ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE) {
       // Special case if the smallest screen width doesn't match. We check that
       // the
@@ -71,11 +72,11 @@
       // specified.
       if (config.smallestScreenWidthDp != 0 &&
           config.smallestScreenWidthDp < target.smallestScreenWidthDp) {
-        matchedAxis |= android::ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE;
+        matched_axis |= android::ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE;
       }
     }
   }
-  return matchedAxis == (mConfigMask & mask);
+  return matched_axis == (config_mask_ & mask);
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/filter/ConfigFilter.h b/tools/aapt2/filter/ConfigFilter.h
index c50160b..3f13416 100644
--- a/tools/aapt2/filter/ConfigFilter.h
+++ b/tools/aapt2/filter/ConfigFilter.h
@@ -17,11 +17,11 @@
 #ifndef AAPT_FILTER_CONFIGFILTER_H
 #define AAPT_FILTER_CONFIGFILTER_H
 
-#include "ConfigDescription.h"
-
 #include <set>
 #include <utility>
 
+#include "ConfigDescription.h"
+
 namespace aapt {
 
 /**
@@ -34,7 +34,7 @@
   /**
    * Returns true if the filter matches the configuration, false otherwise.
    */
-  virtual bool match(const ConfigDescription& config) const = 0;
+  virtual bool Match(const ConfigDescription& config) const = 0;
 };
 
 /**
@@ -50,13 +50,13 @@
  */
 class AxisConfigFilter : public IConfigFilter {
  public:
-  void addConfig(ConfigDescription config);
+  void AddConfig(ConfigDescription config);
 
-  bool match(const ConfigDescription& config) const override;
+  bool Match(const ConfigDescription& config) const override;
 
  private:
-  std::set<std::pair<ConfigDescription, uint32_t>> mConfigs;
-  uint32_t mConfigMask = 0;
+  std::set<std::pair<ConfigDescription, uint32_t>> configs_;
+  uint32_t config_mask_ = 0;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/filter/ConfigFilter_test.cpp b/tools/aapt2/filter/ConfigFilter_test.cpp
index edb40a8..586dd5f 100644
--- a/tools/aapt2/filter/ConfigFilter_test.cpp
+++ b/tools/aapt2/filter/ConfigFilter_test.cpp
@@ -15,99 +15,98 @@
  */
 
 #include "filter/ConfigFilter.h"
-#include "test/Common.h"
 
-#include <gtest/gtest.h>
+#include "test/Test.h"
 
 namespace aapt {
 
 TEST(ConfigFilterTest, EmptyFilterMatchesAnything) {
   AxisConfigFilter filter;
 
-  EXPECT_TRUE(filter.match(test::parseConfigOrDie("320dpi")));
-  EXPECT_TRUE(filter.match(test::parseConfigOrDie("fr")));
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("320dpi")));
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("fr")));
 }
 
 TEST(ConfigFilterTest, MatchesConfigWithUnrelatedAxis) {
   AxisConfigFilter filter;
-  filter.addConfig(test::parseConfigOrDie("fr"));
+  filter.AddConfig(test::ParseConfigOrDie("fr"));
 
-  EXPECT_TRUE(filter.match(test::parseConfigOrDie("320dpi")));
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("320dpi")));
 }
 
 TEST(ConfigFilterTest, MatchesConfigWithSameValueAxis) {
   AxisConfigFilter filter;
-  filter.addConfig(test::parseConfigOrDie("fr"));
+  filter.AddConfig(test::ParseConfigOrDie("fr"));
 
-  EXPECT_TRUE(filter.match(test::parseConfigOrDie("fr")));
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("fr")));
 }
 
 TEST(ConfigFilterTest, MatchesConfigWithSameValueAxisAndOtherUnrelatedAxis) {
   AxisConfigFilter filter;
-  filter.addConfig(test::parseConfigOrDie("fr"));
+  filter.AddConfig(test::ParseConfigOrDie("fr"));
 
-  EXPECT_TRUE(filter.match(test::parseConfigOrDie("fr-320dpi")));
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("fr-320dpi")));
 }
 
 TEST(ConfigFilterTest, MatchesConfigWithOneMatchingAxis) {
   AxisConfigFilter filter;
-  filter.addConfig(test::parseConfigOrDie("fr-rFR"));
-  filter.addConfig(test::parseConfigOrDie("sw360dp"));
-  filter.addConfig(test::parseConfigOrDie("normal"));
-  filter.addConfig(test::parseConfigOrDie("en-rUS"));
+  filter.AddConfig(test::ParseConfigOrDie("fr-rFR"));
+  filter.AddConfig(test::ParseConfigOrDie("sw360dp"));
+  filter.AddConfig(test::ParseConfigOrDie("normal"));
+  filter.AddConfig(test::ParseConfigOrDie("en-rUS"));
 
-  EXPECT_TRUE(filter.match(test::parseConfigOrDie("en")));
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("en")));
 }
 
 TEST(ConfigFilterTest, DoesNotMatchConfigWithDifferentValueAxis) {
   AxisConfigFilter filter;
-  filter.addConfig(test::parseConfigOrDie("fr"));
+  filter.AddConfig(test::ParseConfigOrDie("fr"));
 
-  EXPECT_FALSE(filter.match(test::parseConfigOrDie("de")));
+  EXPECT_FALSE(filter.Match(test::ParseConfigOrDie("de")));
 }
 
 TEST(ConfigFilterTest, DoesNotMatchWhenOneQualifierIsExplicitlyNotMatched) {
   AxisConfigFilter filter;
-  filter.addConfig(test::parseConfigOrDie("fr-rFR"));
-  filter.addConfig(test::parseConfigOrDie("en-rUS"));
-  filter.addConfig(test::parseConfigOrDie("normal"));
-  filter.addConfig(test::parseConfigOrDie("large"));
-  filter.addConfig(test::parseConfigOrDie("xxhdpi"));
-  filter.addConfig(test::parseConfigOrDie("sw320dp"));
+  filter.AddConfig(test::ParseConfigOrDie("fr-rFR"));
+  filter.AddConfig(test::ParseConfigOrDie("en-rUS"));
+  filter.AddConfig(test::ParseConfigOrDie("normal"));
+  filter.AddConfig(test::ParseConfigOrDie("large"));
+  filter.AddConfig(test::ParseConfigOrDie("xxhdpi"));
+  filter.AddConfig(test::ParseConfigOrDie("sw320dp"));
 
-  EXPECT_FALSE(filter.match(test::parseConfigOrDie("fr-sw600dp-v13")));
+  EXPECT_FALSE(filter.Match(test::ParseConfigOrDie("fr-sw600dp-v13")));
 }
 
 TEST(ConfigFilterTest, MatchesSmallestWidthWhenSmaller) {
   AxisConfigFilter filter;
-  filter.addConfig(test::parseConfigOrDie("sw600dp"));
+  filter.AddConfig(test::ParseConfigOrDie("sw600dp"));
 
-  EXPECT_TRUE(filter.match(test::parseConfigOrDie("fr-sw320dp-v13")));
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("fr-sw320dp-v13")));
 }
 
 TEST(ConfigFilterTest, MatchesConfigWithSameLanguageButNoRegionSpecified) {
   AxisConfigFilter filter;
-  filter.addConfig(test::parseConfigOrDie("de-rDE"));
+  filter.AddConfig(test::ParseConfigOrDie("de-rDE"));
 
-  EXPECT_TRUE(filter.match(test::parseConfigOrDie("de")));
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("de")));
 }
 
 TEST(ConfigFilterTest, IgnoresVersion) {
   AxisConfigFilter filter;
-  filter.addConfig(test::parseConfigOrDie("normal-v4"));
+  filter.AddConfig(test::ParseConfigOrDie("normal-v4"));
 
   // The configs don't match on any axis besides version, which should be
   // ignored.
-  EXPECT_TRUE(filter.match(test::parseConfigOrDie("sw600dp-v13")));
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("sw600dp-v13")));
 }
 
 TEST(ConfigFilterTest, MatchesConfigWithRegion) {
   AxisConfigFilter filter;
-  filter.addConfig(test::parseConfigOrDie("kok"));
-  filter.addConfig(test::parseConfigOrDie("kok-rIN"));
-  filter.addConfig(test::parseConfigOrDie("kok-v419"));
+  filter.AddConfig(test::ParseConfigOrDie("kok"));
+  filter.AddConfig(test::ParseConfigOrDie("kok-rIN"));
+  filter.AddConfig(test::ParseConfigOrDie("kok-v419"));
 
-  EXPECT_TRUE(filter.match(test::parseConfigOrDie("kok-rIN")));
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("kok-rIN")));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/flatten/Archive.cpp b/tools/aapt2/flatten/Archive.cpp
index ae08f65..47de0a3 100644
--- a/tools/aapt2/flatten/Archive.cpp
+++ b/tools/aapt2/flatten/Archive.cpp
@@ -15,131 +15,139 @@
  */
 
 #include "flatten/Archive.h"
-#include "util/Files.h"
-#include "util/StringPiece.h"
 
-#include <ziparchive/zip_writer.h>
 #include <cstdio>
 #include <memory>
 #include <string>
 #include <vector>
 
+#include "android-base/macros.h"
+#include "ziparchive/zip_writer.h"
+
+#include "util/Files.h"
+#include "util/StringPiece.h"
+
 namespace aapt {
 
 namespace {
 
-struct DirectoryWriter : public IArchiveWriter {
-  std::string mOutDir;
-  std::unique_ptr<FILE, decltype(fclose)*> mFile = {nullptr, fclose};
+class DirectoryWriter : public IArchiveWriter {
+ public:
+  DirectoryWriter() = default;
 
-  bool open(IDiagnostics* diag, const StringPiece& outDir) {
-    mOutDir = outDir.toString();
-    file::FileType type = file::getFileType(mOutDir);
+  bool Open(IDiagnostics* diag, const StringPiece& out_dir) {
+    dir_ = out_dir.ToString();
+    file::FileType type = file::GetFileType(dir_);
     if (type == file::FileType::kNonexistant) {
-      diag->error(DiagMessage() << "directory " << mOutDir
-                                << " does not exist");
+      diag->Error(DiagMessage() << "directory " << dir_ << " does not exist");
       return false;
     } else if (type != file::FileType::kDirectory) {
-      diag->error(DiagMessage() << mOutDir << " is not a directory");
+      diag->Error(DiagMessage() << dir_ << " is not a directory");
       return false;
     }
     return true;
   }
 
-  bool startEntry(const StringPiece& path, uint32_t flags) override {
-    if (mFile) {
+  bool StartEntry(const StringPiece& path, uint32_t flags) override {
+    if (file_) {
       return false;
     }
 
-    std::string fullPath = mOutDir;
-    file::appendPath(&fullPath, path);
-    file::mkdirs(file::getStem(fullPath));
+    std::string full_path = dir_;
+    file::AppendPath(&full_path, path);
+    file::mkdirs(file::GetStem(full_path));
 
-    mFile = {fopen(fullPath.data(), "wb"), fclose};
-    if (!mFile) {
+    file_ = {fopen(full_path.data(), "wb"), fclose};
+    if (!file_) {
       return false;
     }
     return true;
   }
 
-  bool writeEntry(const BigBuffer& buffer) override {
-    if (!mFile) {
+  bool WriteEntry(const BigBuffer& buffer) override {
+    if (!file_) {
       return false;
     }
 
     for (const BigBuffer::Block& b : buffer) {
-      if (fwrite(b.buffer.get(), 1, b.size, mFile.get()) != b.size) {
-        mFile.reset(nullptr);
+      if (fwrite(b.buffer.get(), 1, b.size, file_.get()) != b.size) {
+        file_.reset(nullptr);
         return false;
       }
     }
     return true;
   }
 
-  bool writeEntry(const void* data, size_t len) override {
-    if (fwrite(data, 1, len, mFile.get()) != len) {
-      mFile.reset(nullptr);
+  bool WriteEntry(const void* data, size_t len) override {
+    if (fwrite(data, 1, len, file_.get()) != len) {
+      file_.reset(nullptr);
       return false;
     }
     return true;
   }
 
-  bool finishEntry() override {
-    if (!mFile) {
+  bool FinishEntry() override {
+    if (!file_) {
       return false;
     }
-    mFile.reset(nullptr);
+    file_.reset(nullptr);
     return true;
   }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DirectoryWriter);
+
+  std::string dir_;
+  std::unique_ptr<FILE, decltype(fclose)*> file_ = {nullptr, fclose};
 };
 
-struct ZipFileWriter : public IArchiveWriter {
-  std::unique_ptr<FILE, decltype(fclose)*> mFile = {nullptr, fclose};
-  std::unique_ptr<ZipWriter> mWriter;
+class ZipFileWriter : public IArchiveWriter {
+ public:
+  ZipFileWriter() = default;
 
-  bool open(IDiagnostics* diag, const StringPiece& path) {
-    mFile = {fopen(path.data(), "w+b"), fclose};
-    if (!mFile) {
-      diag->error(DiagMessage() << "failed to open " << path << ": "
+  bool Open(IDiagnostics* diag, const StringPiece& path) {
+    file_ = {fopen(path.data(), "w+b"), fclose};
+    if (!file_) {
+      diag->Error(DiagMessage() << "failed to Open " << path << ": "
                                 << strerror(errno));
       return false;
     }
-    mWriter = util::make_unique<ZipWriter>(mFile.get());
+    writer_ = util::make_unique<ZipWriter>(file_.get());
     return true;
   }
 
-  bool startEntry(const StringPiece& path, uint32_t flags) override {
-    if (!mWriter) {
+  bool StartEntry(const StringPiece& path, uint32_t flags) override {
+    if (!writer_) {
       return false;
     }
 
-    size_t zipFlags = 0;
+    size_t zip_flags = 0;
     if (flags & ArchiveEntry::kCompress) {
-      zipFlags |= ZipWriter::kCompress;
+      zip_flags |= ZipWriter::kCompress;
     }
 
     if (flags & ArchiveEntry::kAlign) {
-      zipFlags |= ZipWriter::kAlign32;
+      zip_flags |= ZipWriter::kAlign32;
     }
 
-    int32_t result = mWriter->StartEntry(path.data(), zipFlags);
+    int32_t result = writer_->StartEntry(path.data(), zip_flags);
     if (result != 0) {
       return false;
     }
     return true;
   }
 
-  bool writeEntry(const void* data, size_t len) override {
-    int32_t result = mWriter->WriteBytes(data, len);
+  bool WriteEntry(const void* data, size_t len) override {
+    int32_t result = writer_->WriteBytes(data, len);
     if (result != 0) {
       return false;
     }
     return true;
   }
 
-  bool writeEntry(const BigBuffer& buffer) override {
+  bool WriteEntry(const BigBuffer& buffer) override {
     for (const BigBuffer::Block& b : buffer) {
-      int32_t result = mWriter->WriteBytes(b.buffer.get(), b.size);
+      int32_t result = writer_->WriteBytes(b.buffer.get(), b.size);
       if (result != 0) {
         return false;
       }
@@ -147,8 +155,8 @@
     return true;
   }
 
-  bool finishEntry() override {
-    int32_t result = mWriter->FinishEntry();
+  bool FinishEntry() override {
+    int32_t result = writer_->FinishEntry();
     if (result != 0) {
       return false;
     }
@@ -156,28 +164,34 @@
   }
 
   virtual ~ZipFileWriter() {
-    if (mWriter) {
-      mWriter->Finish();
+    if (writer_) {
+      writer_->Finish();
     }
   }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ZipFileWriter);
+
+  std::unique_ptr<FILE, decltype(fclose)*> file_ = {nullptr, fclose};
+  std::unique_ptr<ZipWriter> writer_;
 };
 
 }  // namespace
 
-std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter(
+std::unique_ptr<IArchiveWriter> CreateDirectoryArchiveWriter(
     IDiagnostics* diag, const StringPiece& path) {
   std::unique_ptr<DirectoryWriter> writer =
       util::make_unique<DirectoryWriter>();
-  if (!writer->open(diag, path)) {
+  if (!writer->Open(diag, path)) {
     return {};
   }
   return std::move(writer);
 }
 
-std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter(
+std::unique_ptr<IArchiveWriter> CreateZipFileArchiveWriter(
     IDiagnostics* diag, const StringPiece& path) {
   std::unique_ptr<ZipFileWriter> writer = util::make_unique<ZipFileWriter>();
-  if (!writer->open(diag, path)) {
+  if (!writer->Open(diag, path)) {
     return {};
   }
   return std::move(writer);
diff --git a/tools/aapt2/flatten/Archive.h b/tools/aapt2/flatten/Archive.h
index 46cd0ac..4fcb3ff 100644
--- a/tools/aapt2/flatten/Archive.h
+++ b/tools/aapt2/flatten/Archive.h
@@ -17,17 +17,18 @@
 #ifndef AAPT_FLATTEN_ARCHIVE_H
 #define AAPT_FLATTEN_ARCHIVE_H
 
-#include "Diagnostics.h"
-#include "util/BigBuffer.h"
-#include "util/Files.h"
-#include "util/StringPiece.h"
-
-#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <fstream>
 #include <memory>
 #include <string>
 #include <vector>
 
+#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
+
+#include "Diagnostics.h"
+#include "util/BigBuffer.h"
+#include "util/Files.h"
+#include "util/StringPiece.h"
+
 namespace aapt {
 
 struct ArchiveEntry {
@@ -38,28 +39,28 @@
 
   std::string path;
   uint32_t flags;
-  size_t uncompressedSize;
+  size_t uncompressed_size;
 };
 
 class IArchiveWriter : public google::protobuf::io::CopyingOutputStream {
  public:
   virtual ~IArchiveWriter() = default;
 
-  virtual bool startEntry(const StringPiece& path, uint32_t flags) = 0;
-  virtual bool writeEntry(const BigBuffer& buffer) = 0;
-  virtual bool writeEntry(const void* data, size_t len) = 0;
-  virtual bool finishEntry() = 0;
+  virtual bool StartEntry(const StringPiece& path, uint32_t flags) = 0;
+  virtual bool WriteEntry(const BigBuffer& buffer) = 0;
+  virtual bool WriteEntry(const void* data, size_t len) = 0;
+  virtual bool FinishEntry() = 0;
 
   // CopyingOutputStream implementations.
   bool Write(const void* buffer, int size) override {
-    return writeEntry(buffer, size);
+    return WriteEntry(buffer, size);
   }
 };
 
-std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter(
+std::unique_ptr<IArchiveWriter> CreateDirectoryArchiveWriter(
     IDiagnostics* diag, const StringPiece& path);
 
-std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter(
+std::unique_ptr<IArchiveWriter> CreateZipFileArchiveWriter(
     IDiagnostics* diag, const StringPiece& path);
 
 }  // namespace aapt
diff --git a/tools/aapt2/flatten/ChunkWriter.h b/tools/aapt2/flatten/ChunkWriter.h
index 852afd4..968d3ee 100644
--- a/tools/aapt2/flatten/ChunkWriter.h
+++ b/tools/aapt2/flatten/ChunkWriter.h
@@ -17,62 +17,62 @@
 #ifndef AAPT_FLATTEN_CHUNKWRITER_H
 #define AAPT_FLATTEN_CHUNKWRITER_H
 
+#include "android-base/macros.h"
+#include "androidfw/ResourceTypes.h"
+
 #include "util/BigBuffer.h"
 #include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
-
 namespace aapt {
 
 class ChunkWriter {
- private:
-  BigBuffer* mBuffer;
-  size_t mStartSize = 0;
-  android::ResChunk_header* mHeader = nullptr;
-
  public:
-  explicit inline ChunkWriter(BigBuffer* buffer) : mBuffer(buffer) {}
-
-  ChunkWriter(const ChunkWriter&) = delete;
-  ChunkWriter& operator=(const ChunkWriter&) = delete;
+  explicit inline ChunkWriter(BigBuffer* buffer) : buffer_(buffer) {}
   ChunkWriter(ChunkWriter&&) = default;
   ChunkWriter& operator=(ChunkWriter&&) = default;
 
   template <typename T>
-  inline T* startChunk(uint16_t type) {
-    mStartSize = mBuffer->size();
-    T* chunk = mBuffer->nextBlock<T>();
-    mHeader = &chunk->header;
-    mHeader->type = util::hostToDevice16(type);
-    mHeader->headerSize = util::hostToDevice16(sizeof(T));
+  inline T* StartChunk(uint16_t type) {
+    start_size_ = buffer_->size();
+    T* chunk = buffer_->NextBlock<T>();
+    header_ = &chunk->header;
+    header_->type = util::HostToDevice16(type);
+    header_->headerSize = util::HostToDevice16(sizeof(T));
     return chunk;
   }
 
   template <typename T>
-  inline T* nextBlock(size_t count = 1) {
-    return mBuffer->nextBlock<T>(count);
+  inline T* NextBlock(size_t count = 1) {
+    return buffer_->NextBlock<T>(count);
   }
 
-  inline BigBuffer* getBuffer() { return mBuffer; }
+  inline BigBuffer* buffer() { return buffer_; }
 
-  inline android::ResChunk_header* getChunkHeader() { return mHeader; }
+  inline android::ResChunk_header* chunk_header() { return header_; }
 
-  inline size_t size() { return mBuffer->size() - mStartSize; }
+  inline size_t size() { return buffer_->size() - start_size_; }
 
-  inline android::ResChunk_header* finish() {
-    mBuffer->align4();
-    mHeader->size = util::hostToDevice32(mBuffer->size() - mStartSize);
-    return mHeader;
+  inline android::ResChunk_header* Finish() {
+    buffer_->Align4();
+    header_->size = util::HostToDevice32(buffer_->size() - start_size_);
+    return header_;
   }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ChunkWriter);
+
+  BigBuffer* buffer_;
+  size_t start_size_ = 0;
+  android::ResChunk_header* header_ = nullptr;
 };
 
 template <>
-inline android::ResChunk_header* ChunkWriter::startChunk(uint16_t type) {
-  mStartSize = mBuffer->size();
-  mHeader = mBuffer->nextBlock<android::ResChunk_header>();
-  mHeader->type = util::hostToDevice16(type);
-  mHeader->headerSize = util::hostToDevice16(sizeof(android::ResChunk_header));
-  return mHeader;
+inline android::ResChunk_header* ChunkWriter::StartChunk(uint16_t type) {
+  start_size_ = buffer_->size();
+  header_ = buffer_->NextBlock<android::ResChunk_header>();
+  header_->type = util::HostToDevice16(type);
+  header_->headerSize = util::HostToDevice16(sizeof(android::ResChunk_header));
+  return header_;
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/flatten/ResourceTypeExtensions.h b/tools/aapt2/flatten/ResourceTypeExtensions.h
index 0b19240..6359b41 100644
--- a/tools/aapt2/flatten/ResourceTypeExtensions.h
+++ b/tools/aapt2/flatten/ResourceTypeExtensions.h
@@ -17,7 +17,7 @@
 #ifndef AAPT_RESOURCE_TYPE_EXTENSIONS_H
 #define AAPT_RESOURCE_TYPE_EXTENSIONS_H
 
-#include <androidfw/ResourceTypes.h>
+#include "androidfw/ResourceTypes.h"
 
 namespace aapt {
 
diff --git a/tools/aapt2/flatten/TableFlattener.cpp b/tools/aapt2/flatten/TableFlattener.cpp
index d4ea6c0..19d030e 100644
--- a/tools/aapt2/flatten/TableFlattener.cpp
+++ b/tools/aapt2/flatten/TableFlattener.cpp
@@ -14,21 +14,23 @@
  * limitations under the License.
  */
 
-#include "ResourceTable.h"
-#include "ResourceValues.h"
-#include "ValueVisitor.h"
-
-#include "flatten/ChunkWriter.h"
-#include "flatten/ResourceTypeExtensions.h"
 #include "flatten/TableFlattener.h"
-#include "util/BigBuffer.h"
 
-#include <android-base/macros.h>
 #include <algorithm>
 #include <numeric>
 #include <sstream>
 #include <type_traits>
 
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "ValueVisitor.h"
+#include "flatten/ChunkWriter.h"
+#include "flatten/ResourceTypeExtensions.h"
+#include "util/BigBuffer.h"
+
 using namespace android;
 
 namespace aapt {
@@ -36,7 +38,7 @@
 namespace {
 
 template <typename T>
-static bool cmpIds(const T* a, const T* b) {
+static bool cmp_ids(const T* a, const T* b) {
   return a->id.value() < b->id.value();
 }
 
@@ -46,14 +48,14 @@
   }
 
   size_t i;
-  const char16_t* srcData = src.data();
+  const char16_t* src_data = src.data();
   for (i = 0; i < len - 1 && i < src.size(); i++) {
-    dst[i] = util::hostToDevice16((uint16_t)srcData[i]);
+    dst[i] = util::HostToDevice16((uint16_t)src_data[i]);
   }
   dst[i] = 0;
 }
 
-static bool cmpStyleEntries(const Style::Entry& a, const Style::Entry& b) {
+static bool cmp_style_entries(const Style::Entry& a, const Style::Entry& b) {
   if (a.key.id) {
     if (b.key.id) {
       return a.key.id.value() < b.key.id.value();
@@ -70,75 +72,75 @@
   Value* value;
 
   // The entry string pool index to the entry's name.
-  uint32_t entryKey;
+  uint32_t entry_key;
 };
 
 class MapFlattenVisitor : public RawValueVisitor {
  public:
-  using RawValueVisitor::visit;
+  using RawValueVisitor::Visit;
 
-  MapFlattenVisitor(ResTable_entry_ext* outEntry, BigBuffer* buffer)
-      : mOutEntry(outEntry), mBuffer(buffer) {}
+  MapFlattenVisitor(ResTable_entry_ext* out_entry, BigBuffer* buffer)
+      : out_entry_(out_entry), buffer_(buffer) {}
 
-  void visit(Attribute* attr) override {
+  void Visit(Attribute* attr) override {
     {
       Reference key = Reference(ResourceId(ResTable_map::ATTR_TYPE));
-      BinaryPrimitive val(Res_value::TYPE_INT_DEC, attr->typeMask);
-      flattenEntry(&key, &val);
+      BinaryPrimitive val(Res_value::TYPE_INT_DEC, attr->type_mask);
+      FlattenEntry(&key, &val);
     }
 
-    if (attr->minInt != std::numeric_limits<int32_t>::min()) {
+    if (attr->min_int != std::numeric_limits<int32_t>::min()) {
       Reference key = Reference(ResourceId(ResTable_map::ATTR_MIN));
       BinaryPrimitive val(Res_value::TYPE_INT_DEC,
-                          static_cast<uint32_t>(attr->minInt));
-      flattenEntry(&key, &val);
+                          static_cast<uint32_t>(attr->min_int));
+      FlattenEntry(&key, &val);
     }
 
-    if (attr->maxInt != std::numeric_limits<int32_t>::max()) {
+    if (attr->max_int != std::numeric_limits<int32_t>::max()) {
       Reference key = Reference(ResourceId(ResTable_map::ATTR_MAX));
       BinaryPrimitive val(Res_value::TYPE_INT_DEC,
-                          static_cast<uint32_t>(attr->maxInt));
-      flattenEntry(&key, &val);
+                          static_cast<uint32_t>(attr->max_int));
+      FlattenEntry(&key, &val);
     }
 
     for (Attribute::Symbol& s : attr->symbols) {
       BinaryPrimitive val(Res_value::TYPE_INT_DEC, s.value);
-      flattenEntry(&s.symbol, &val);
+      FlattenEntry(&s.symbol, &val);
     }
   }
 
-  void visit(Style* style) override {
+  void Visit(Style* style) override {
     if (style->parent) {
-      const Reference& parentRef = style->parent.value();
-      assert(parentRef.id && "parent has no ID");
-      mOutEntry->parent.ident = util::hostToDevice32(parentRef.id.value().id);
+      const Reference& parent_ref = style->parent.value();
+      CHECK(bool(parent_ref.id)) << "parent has no ID";
+      out_entry_->parent.ident = util::HostToDevice32(parent_ref.id.value().id);
     }
 
     // Sort the style.
-    std::sort(style->entries.begin(), style->entries.end(), cmpStyleEntries);
+    std::sort(style->entries.begin(), style->entries.end(), cmp_style_entries);
 
     for (Style::Entry& entry : style->entries) {
-      flattenEntry(&entry.key, entry.value.get());
+      FlattenEntry(&entry.key, entry.value.get());
     }
   }
 
-  void visit(Styleable* styleable) override {
-    for (auto& attrRef : styleable->entries) {
+  void Visit(Styleable* styleable) override {
+    for (auto& attr_ref : styleable->entries) {
       BinaryPrimitive val(Res_value{});
-      flattenEntry(&attrRef, &val);
+      FlattenEntry(&attr_ref, &val);
     }
   }
 
-  void visit(Array* array) override {
+  void Visit(Array* array) override {
     for (auto& item : array->items) {
-      ResTable_map* outEntry = mBuffer->nextBlock<ResTable_map>();
-      flattenValue(item.get(), outEntry);
-      outEntry->value.size = util::hostToDevice16(sizeof(outEntry->value));
-      mEntryCount++;
+      ResTable_map* out_entry = buffer_->NextBlock<ResTable_map>();
+      FlattenValue(item.get(), out_entry);
+      out_entry->value.size = util::HostToDevice16(sizeof(out_entry->value));
+      entry_count_++;
     }
   }
 
-  void visit(Plural* plural) override {
+  void Visit(Plural* plural) override {
     const size_t count = plural->values.size();
     for (size_t i = 0; i < count; i++) {
       if (!plural->values[i]) {
@@ -172,12 +174,12 @@
           break;
 
         default:
-          assert(false);
+          LOG(FATAL) << "unhandled plural type";
           break;
       }
 
       Reference key(q);
-      flattenEntry(&key, plural->values[i].get());
+      FlattenEntry(&key, plural->values[i].get());
     }
   }
 
@@ -185,267 +187,264 @@
    * Call this after visiting a Value. This will finish any work that
    * needs to be done to prepare the entry.
    */
-  void finish() { mOutEntry->count = util::hostToDevice32(mEntryCount); }
+  void Finish() { out_entry_->count = util::HostToDevice32(entry_count_); }
 
  private:
-  void flattenKey(Reference* key, ResTable_map* outEntry) {
-    assert(key->id && "key has no ID");
-    outEntry->name.ident = util::hostToDevice32(key->id.value().id);
+  DISALLOW_COPY_AND_ASSIGN(MapFlattenVisitor);
+
+  void FlattenKey(Reference* key, ResTable_map* out_entry) {
+    CHECK(bool(key->id)) << "key has no ID";
+    out_entry->name.ident = util::HostToDevice32(key->id.value().id);
   }
 
-  void flattenValue(Item* value, ResTable_map* outEntry) {
-    bool result = value->flatten(&outEntry->value);
-    assert(result && "flatten failed");
+  void FlattenValue(Item* value, ResTable_map* out_entry) {
+    CHECK(value->Flatten(&out_entry->value)) << "flatten failed";
   }
 
-  void flattenEntry(Reference* key, Item* value) {
-    ResTable_map* outEntry = mBuffer->nextBlock<ResTable_map>();
-    flattenKey(key, outEntry);
-    flattenValue(value, outEntry);
-    outEntry->value.size = util::hostToDevice16(sizeof(outEntry->value));
-    mEntryCount++;
+  void FlattenEntry(Reference* key, Item* value) {
+    ResTable_map* out_entry = buffer_->NextBlock<ResTable_map>();
+    FlattenKey(key, out_entry);
+    FlattenValue(value, out_entry);
+    out_entry->value.size = util::HostToDevice16(sizeof(out_entry->value));
+    entry_count_++;
   }
 
-  ResTable_entry_ext* mOutEntry;
-  BigBuffer* mBuffer;
-  size_t mEntryCount = 0;
+  ResTable_entry_ext* out_entry_;
+  BigBuffer* buffer_;
+  size_t entry_count_ = 0;
 };
 
 class PackageFlattener {
  public:
   PackageFlattener(IDiagnostics* diag, ResourceTablePackage* package)
-      : mDiag(diag), mPackage(package) {}
+      : diag_(diag), package_(package) {}
 
-  bool flattenPackage(BigBuffer* buffer) {
-    ChunkWriter pkgWriter(buffer);
-    ResTable_package* pkgHeader =
-        pkgWriter.startChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE);
-    pkgHeader->id = util::hostToDevice32(mPackage->id.value());
+  bool FlattenPackage(BigBuffer* buffer) {
+    ChunkWriter pkg_writer(buffer);
+    ResTable_package* pkg_header =
+        pkg_writer.StartChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE);
+    pkg_header->id = util::HostToDevice32(package_->id.value());
 
-    if (mPackage->name.size() >= arraysize(pkgHeader->name)) {
-      mDiag->error(DiagMessage() << "package name '" << mPackage->name
+    if (package_->name.size() >= arraysize(pkg_header->name)) {
+      diag_->Error(DiagMessage() << "package name '" << package_->name
                                  << "' is too long");
       return false;
     }
 
     // Copy the package name in device endianness.
-    strcpy16_htod(pkgHeader->name, arraysize(pkgHeader->name),
-                  util::utf8ToUtf16(mPackage->name));
+    strcpy16_htod(pkg_header->name, arraysize(pkg_header->name),
+                  util::Utf8ToUtf16(package_->name));
 
     // Serialize the types. We do this now so that our type and key strings
     // are populated. We write those first.
-    BigBuffer typeBuffer(1024);
-    flattenTypes(&typeBuffer);
+    BigBuffer type_buffer(1024);
+    FlattenTypes(&type_buffer);
 
-    pkgHeader->typeStrings = util::hostToDevice32(pkgWriter.size());
-    StringPool::flattenUtf16(pkgWriter.getBuffer(), mTypePool);
+    pkg_header->typeStrings = util::HostToDevice32(pkg_writer.size());
+    StringPool::FlattenUtf16(pkg_writer.buffer(), type_pool_);
 
-    pkgHeader->keyStrings = util::hostToDevice32(pkgWriter.size());
-    StringPool::flattenUtf8(pkgWriter.getBuffer(), mKeyPool);
+    pkg_header->keyStrings = util::HostToDevice32(pkg_writer.size());
+    StringPool::FlattenUtf8(pkg_writer.buffer(), key_pool_);
 
     // Append the types.
-    buffer->appendBuffer(std::move(typeBuffer));
+    buffer->AppendBuffer(std::move(type_buffer));
 
-    pkgWriter.finish();
+    pkg_writer.Finish();
     return true;
   }
 
  private:
-  IDiagnostics* mDiag;
-  ResourceTablePackage* mPackage;
-  StringPool mTypePool;
-  StringPool mKeyPool;
+  DISALLOW_COPY_AND_ASSIGN(PackageFlattener);
 
   template <typename T, bool IsItem>
-  T* writeEntry(FlatEntry* entry, BigBuffer* buffer) {
+  T* WriteEntry(FlatEntry* entry, BigBuffer* buffer) {
     static_assert(std::is_same<ResTable_entry, T>::value ||
                       std::is_same<ResTable_entry_ext, T>::value,
                   "T must be ResTable_entry or ResTable_entry_ext");
 
-    T* result = buffer->nextBlock<T>();
-    ResTable_entry* outEntry = (ResTable_entry*)(result);
-    if (entry->entry->symbolStatus.state == SymbolState::kPublic) {
-      outEntry->flags |= ResTable_entry::FLAG_PUBLIC;
+    T* result = buffer->NextBlock<T>();
+    ResTable_entry* out_entry = (ResTable_entry*)result;
+    if (entry->entry->symbol_status.state == SymbolState::kPublic) {
+      out_entry->flags |= ResTable_entry::FLAG_PUBLIC;
     }
 
-    if (entry->value->isWeak()) {
-      outEntry->flags |= ResTable_entry::FLAG_WEAK;
+    if (entry->value->IsWeak()) {
+      out_entry->flags |= ResTable_entry::FLAG_WEAK;
     }
 
     if (!IsItem) {
-      outEntry->flags |= ResTable_entry::FLAG_COMPLEX;
+      out_entry->flags |= ResTable_entry::FLAG_COMPLEX;
     }
 
-    outEntry->flags = util::hostToDevice16(outEntry->flags);
-    outEntry->key.index = util::hostToDevice32(entry->entryKey);
-    outEntry->size = util::hostToDevice16(sizeof(T));
+    out_entry->flags = util::HostToDevice16(out_entry->flags);
+    out_entry->key.index = util::HostToDevice32(entry->entry_key);
+    out_entry->size = util::HostToDevice16(sizeof(T));
     return result;
   }
 
-  bool flattenValue(FlatEntry* entry, BigBuffer* buffer) {
-    if (Item* item = valueCast<Item>(entry->value)) {
-      writeEntry<ResTable_entry, true>(entry, buffer);
-      Res_value* outValue = buffer->nextBlock<Res_value>();
-      bool result = item->flatten(outValue);
-      assert(result && "flatten failed");
-      outValue->size = util::hostToDevice16(sizeof(*outValue));
+  bool FlattenValue(FlatEntry* entry, BigBuffer* buffer) {
+    if (Item* item = ValueCast<Item>(entry->value)) {
+      WriteEntry<ResTable_entry, true>(entry, buffer);
+      Res_value* outValue = buffer->NextBlock<Res_value>();
+      CHECK(item->Flatten(outValue)) << "flatten failed";
+      outValue->size = util::HostToDevice16(sizeof(*outValue));
     } else {
-      ResTable_entry_ext* outEntry =
-          writeEntry<ResTable_entry_ext, false>(entry, buffer);
-      MapFlattenVisitor visitor(outEntry, buffer);
-      entry->value->accept(&visitor);
-      visitor.finish();
+      ResTable_entry_ext* out_entry =
+          WriteEntry<ResTable_entry_ext, false>(entry, buffer);
+      MapFlattenVisitor visitor(out_entry, buffer);
+      entry->value->Accept(&visitor);
+      visitor.Finish();
     }
     return true;
   }
 
-  bool flattenConfig(const ResourceTableType* type,
+  bool FlattenConfig(const ResourceTableType* type,
                      const ConfigDescription& config,
                      std::vector<FlatEntry>* entries, BigBuffer* buffer) {
-    ChunkWriter typeWriter(buffer);
-    ResTable_type* typeHeader =
-        typeWriter.startChunk<ResTable_type>(RES_TABLE_TYPE_TYPE);
-    typeHeader->id = type->id.value();
-    typeHeader->config = config;
-    typeHeader->config.swapHtoD();
+    ChunkWriter type_writer(buffer);
+    ResTable_type* type_header =
+        type_writer.StartChunk<ResTable_type>(RES_TABLE_TYPE_TYPE);
+    type_header->id = type->id.value();
+    type_header->config = config;
+    type_header->config.swapHtoD();
 
-    auto maxAccum = [](uint32_t max,
-                       const std::unique_ptr<ResourceEntry>& a) -> uint32_t {
+    auto max_accum = [](uint32_t max,
+                        const std::unique_ptr<ResourceEntry>& a) -> uint32_t {
       return std::max(max, (uint32_t)a->id.value());
     };
 
     // Find the largest entry ID. That is how many entries we will have.
-    const uint32_t entryCount =
+    const uint32_t entry_count =
         std::accumulate(type->entries.begin(), type->entries.end(), 0,
-                        maxAccum) +
+                        max_accum) +
         1;
 
-    typeHeader->entryCount = util::hostToDevice32(entryCount);
-    uint32_t* indices = typeWriter.nextBlock<uint32_t>(entryCount);
+    type_header->entryCount = util::HostToDevice32(entry_count);
+    uint32_t* indices = type_writer.NextBlock<uint32_t>(entry_count);
 
-    assert((size_t)entryCount <= std::numeric_limits<uint16_t>::max() + 1);
-    memset(indices, 0xff, entryCount * sizeof(uint32_t));
+    CHECK((size_t)entry_count <= std::numeric_limits<uint16_t>::max());
+    memset(indices, 0xff, entry_count * sizeof(uint32_t));
 
-    typeHeader->entriesStart = util::hostToDevice32(typeWriter.size());
+    type_header->entriesStart = util::HostToDevice32(type_writer.size());
 
-    const size_t entryStart = typeWriter.getBuffer()->size();
-    for (FlatEntry& flatEntry : *entries) {
-      assert(flatEntry.entry->id.value() < entryCount);
-      indices[flatEntry.entry->id.value()] =
-          util::hostToDevice32(typeWriter.getBuffer()->size() - entryStart);
-      if (!flattenValue(&flatEntry, typeWriter.getBuffer())) {
-        mDiag->error(DiagMessage()
+    const size_t entry_start = type_writer.buffer()->size();
+    for (FlatEntry& flat_entry : *entries) {
+      CHECK(flat_entry.entry->id.value() < entry_count);
+      indices[flat_entry.entry->id.value()] =
+          util::HostToDevice32(type_writer.buffer()->size() - entry_start);
+      if (!FlattenValue(&flat_entry, type_writer.buffer())) {
+        diag_->Error(DiagMessage()
                      << "failed to flatten resource '"
-                     << ResourceNameRef(mPackage->name, type->type,
-                                        flatEntry.entry->name)
+                     << ResourceNameRef(package_->name, type->type,
+                                        flat_entry.entry->name)
                      << "' for configuration '" << config << "'");
         return false;
       }
     }
-    typeWriter.finish();
+    type_writer.Finish();
     return true;
   }
 
-  std::vector<ResourceTableType*> collectAndSortTypes() {
-    std::vector<ResourceTableType*> sortedTypes;
-    for (auto& type : mPackage->types) {
+  std::vector<ResourceTableType*> CollectAndSortTypes() {
+    std::vector<ResourceTableType*> sorted_types;
+    for (auto& type : package_->types) {
       if (type->type == ResourceType::kStyleable) {
         // Styleables aren't real Resource Types, they are represented in the
-        // R.java
-        // file.
+        // R.java file.
         continue;
       }
 
-      assert(type->id && "type must have an ID set");
+      CHECK(bool(type->id)) << "type must have an ID set";
 
-      sortedTypes.push_back(type.get());
+      sorted_types.push_back(type.get());
     }
-    std::sort(sortedTypes.begin(), sortedTypes.end(),
-              cmpIds<ResourceTableType>);
-    return sortedTypes;
+    std::sort(sorted_types.begin(), sorted_types.end(),
+              cmp_ids<ResourceTableType>);
+    return sorted_types;
   }
 
-  std::vector<ResourceEntry*> collectAndSortEntries(ResourceTableType* type) {
+  std::vector<ResourceEntry*> CollectAndSortEntries(ResourceTableType* type) {
     // Sort the entries by entry ID.
-    std::vector<ResourceEntry*> sortedEntries;
+    std::vector<ResourceEntry*> sorted_entries;
     for (auto& entry : type->entries) {
-      assert(entry->id && "entry must have an ID set");
-      sortedEntries.push_back(entry.get());
+      CHECK(bool(entry->id)) << "entry must have an ID set";
+      sorted_entries.push_back(entry.get());
     }
-    std::sort(sortedEntries.begin(), sortedEntries.end(),
-              cmpIds<ResourceEntry>);
-    return sortedEntries;
+    std::sort(sorted_entries.begin(), sorted_entries.end(),
+              cmp_ids<ResourceEntry>);
+    return sorted_entries;
   }
 
-  bool flattenTypeSpec(ResourceTableType* type,
-                       std::vector<ResourceEntry*>* sortedEntries,
+  bool FlattenTypeSpec(ResourceTableType* type,
+                       std::vector<ResourceEntry*>* sorted_entries,
                        BigBuffer* buffer) {
-    ChunkWriter typeSpecWriter(buffer);
-    ResTable_typeSpec* specHeader =
-        typeSpecWriter.startChunk<ResTable_typeSpec>(RES_TABLE_TYPE_SPEC_TYPE);
-    specHeader->id = type->id.value();
+    ChunkWriter type_spec_writer(buffer);
+    ResTable_typeSpec* spec_header =
+        type_spec_writer.StartChunk<ResTable_typeSpec>(
+            RES_TABLE_TYPE_SPEC_TYPE);
+    spec_header->id = type->id.value();
 
-    if (sortedEntries->empty()) {
-      typeSpecWriter.finish();
+    if (sorted_entries->empty()) {
+      type_spec_writer.Finish();
       return true;
     }
 
     // We can't just take the size of the vector. There may be holes in the
     // entry ID space.
     // Since the entries are sorted by ID, the last one will be the biggest.
-    const size_t numEntries = sortedEntries->back()->id.value() + 1;
+    const size_t num_entries = sorted_entries->back()->id.value() + 1;
 
-    specHeader->entryCount = util::hostToDevice32(numEntries);
+    spec_header->entryCount = util::HostToDevice32(num_entries);
 
     // Reserve space for the masks of each resource in this type. These
     // show for which configuration axis the resource changes.
-    uint32_t* configMasks = typeSpecWriter.nextBlock<uint32_t>(numEntries);
+    uint32_t* config_masks = type_spec_writer.NextBlock<uint32_t>(num_entries);
 
-    const size_t actualNumEntries = sortedEntries->size();
-    for (size_t entryIndex = 0; entryIndex < actualNumEntries; entryIndex++) {
-      ResourceEntry* entry = sortedEntries->at(entryIndex);
+    const size_t actual_num_entries = sorted_entries->size();
+    for (size_t entryIndex = 0; entryIndex < actual_num_entries; entryIndex++) {
+      ResourceEntry* entry = sorted_entries->at(entryIndex);
 
       // Populate the config masks for this entry.
 
-      if (entry->symbolStatus.state == SymbolState::kPublic) {
-        configMasks[entry->id.value()] |=
-            util::hostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
+      if (entry->symbol_status.state == SymbolState::kPublic) {
+        config_masks[entry->id.value()] |=
+            util::HostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
       }
 
-      const size_t configCount = entry->values.size();
-      for (size_t i = 0; i < configCount; i++) {
+      const size_t config_count = entry->values.size();
+      for (size_t i = 0; i < config_count; i++) {
         const ConfigDescription& config = entry->values[i]->config;
-        for (size_t j = i + 1; j < configCount; j++) {
-          configMasks[entry->id.value()] |=
-              util::hostToDevice32(config.diff(entry->values[j]->config));
+        for (size_t j = i + 1; j < config_count; j++) {
+          config_masks[entry->id.value()] |=
+              util::HostToDevice32(config.diff(entry->values[j]->config));
         }
       }
     }
-    typeSpecWriter.finish();
+    type_spec_writer.Finish();
     return true;
   }
 
-  bool flattenTypes(BigBuffer* buffer) {
+  bool FlattenTypes(BigBuffer* buffer) {
     // Sort the types by their IDs. They will be inserted into the StringPool in
     // this order.
-    std::vector<ResourceTableType*> sortedTypes = collectAndSortTypes();
+    std::vector<ResourceTableType*> sorted_types = CollectAndSortTypes();
 
-    size_t expectedTypeId = 1;
-    for (ResourceTableType* type : sortedTypes) {
+    size_t expected_type_id = 1;
+    for (ResourceTableType* type : sorted_types) {
       // If there is a gap in the type IDs, fill in the StringPool
       // with empty values until we reach the ID we expect.
-      while (type->id.value() > expectedTypeId) {
-        std::stringstream typeName;
-        typeName << "?" << expectedTypeId;
-        mTypePool.makeRef(typeName.str());
-        expectedTypeId++;
+      while (type->id.value() > expected_type_id) {
+        std::stringstream type_name;
+        type_name << "?" << expected_type_id;
+        type_pool_.MakeRef(type_name.str());
+        expected_type_id++;
       }
-      expectedTypeId++;
-      mTypePool.makeRef(toString(type->type));
+      expected_type_id++;
+      type_pool_.MakeRef(ToString(type->type));
 
-      std::vector<ResourceEntry*> sortedEntries = collectAndSortEntries(type);
+      std::vector<ResourceEntry*> sorted_entries = CollectAndSortEntries(type);
 
-      if (!flattenTypeSpec(type, &sortedEntries, buffer)) {
+      if (!FlattenTypeSpec(type, &sorted_entries, buffer)) {
         return false;
       }
 
@@ -455,35 +454,41 @@
       // each
       // configuration available. Here we reverse this to match the binary
       // table.
-      std::map<ConfigDescription, std::vector<FlatEntry>> configToEntryListMap;
-      for (ResourceEntry* entry : sortedEntries) {
-        const uint32_t keyIndex =
-            (uint32_t)mKeyPool.makeRef(entry->name).getIndex();
+      std::map<ConfigDescription, std::vector<FlatEntry>>
+          config_to_entry_list_map;
+      for (ResourceEntry* entry : sorted_entries) {
+        const uint32_t key_index =
+            (uint32_t)key_pool_.MakeRef(entry->name).index();
 
         // Group values by configuration.
-        for (auto& configValue : entry->values) {
-          configToEntryListMap[configValue->config].push_back(
-              FlatEntry{entry, configValue->value.get(), keyIndex});
+        for (auto& config_value : entry->values) {
+          config_to_entry_list_map[config_value->config].push_back(
+              FlatEntry{entry, config_value->value.get(), key_index});
         }
       }
 
       // Flatten a configuration value.
-      for (auto& entry : configToEntryListMap) {
-        if (!flattenConfig(type, entry.first, &entry.second, buffer)) {
+      for (auto& entry : config_to_entry_list_map) {
+        if (!FlattenConfig(type, entry.first, &entry.second, buffer)) {
           return false;
         }
       }
     }
     return true;
   }
+
+  IDiagnostics* diag_;
+  ResourceTablePackage* package_;
+  StringPool type_pool_;
+  StringPool key_pool_;
 };
 
 }  // namespace
 
-bool TableFlattener::consume(IAaptContext* context, ResourceTable* table) {
+bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) {
   // We must do this before writing the resources, since the string pool IDs may
   // change.
-  table->stringPool.sort(
+  table->string_pool.Sort(
       [](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
         int diff = a.context.priority - b.context.priority;
         if (diff < 0) return true;
@@ -493,30 +498,30 @@
         if (diff > 0) return false;
         return a.value < b.value;
       });
-  table->stringPool.prune();
+  table->string_pool.Prune();
 
   // Write the ResTable header.
-  ChunkWriter tableWriter(mBuffer);
-  ResTable_header* tableHeader =
-      tableWriter.startChunk<ResTable_header>(RES_TABLE_TYPE);
-  tableHeader->packageCount = util::hostToDevice32(table->packages.size());
+  ChunkWriter table_writer(buffer_);
+  ResTable_header* table_header =
+      table_writer.StartChunk<ResTable_header>(RES_TABLE_TYPE);
+  table_header->packageCount = util::HostToDevice32(table->packages.size());
 
   // Flatten the values string pool.
-  StringPool::flattenUtf8(tableWriter.getBuffer(), table->stringPool);
+  StringPool::FlattenUtf8(table_writer.buffer(), table->string_pool);
 
-  BigBuffer packageBuffer(1024);
+  BigBuffer package_buffer(1024);
 
   // Flatten each package.
   for (auto& package : table->packages) {
-    PackageFlattener flattener(context->getDiagnostics(), package.get());
-    if (!flattener.flattenPackage(&packageBuffer)) {
+    PackageFlattener flattener(context->GetDiagnostics(), package.get());
+    if (!flattener.FlattenPackage(&package_buffer)) {
       return false;
     }
   }
 
   // Finally merge all the packages into the main buffer.
-  tableWriter.getBuffer()->appendBuffer(std::move(packageBuffer));
-  tableWriter.finish();
+  table_writer.buffer()->AppendBuffer(std::move(package_buffer));
+  table_writer.Finish();
   return true;
 }
 
diff --git a/tools/aapt2/flatten/TableFlattener.h b/tools/aapt2/flatten/TableFlattener.h
index 91f9654..53f52c2 100644
--- a/tools/aapt2/flatten/TableFlattener.h
+++ b/tools/aapt2/flatten/TableFlattener.h
@@ -17,21 +17,24 @@
 #ifndef AAPT_FLATTEN_TABLEFLATTENER_H
 #define AAPT_FLATTEN_TABLEFLATTENER_H
 
+#include "android-base/macros.h"
+
+#include "ResourceTable.h"
 #include "process/IResourceTableConsumer.h"
+#include "util/BigBuffer.h"
 
 namespace aapt {
 
-class BigBuffer;
-class ResourceTable;
-
 class TableFlattener : public IResourceTableConsumer {
  public:
-  explicit TableFlattener(BigBuffer* buffer) : mBuffer(buffer) {}
+  explicit TableFlattener(BigBuffer* buffer) : buffer_(buffer) {}
 
-  bool consume(IAaptContext* context, ResourceTable* table) override;
+  bool Consume(IAaptContext* context, ResourceTable* table) override;
 
  private:
-  BigBuffer* mBuffer;
+  DISALLOW_COPY_AND_ASSIGN(TableFlattener);
+
+  BigBuffer* buffer_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/flatten/TableFlattener_test.cpp b/tools/aapt2/flatten/TableFlattener_test.cpp
index a7706bd..c726240 100644
--- a/tools/aapt2/flatten/TableFlattener_test.cpp
+++ b/tools/aapt2/flatten/TableFlattener_test.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "flatten/TableFlattener.h"
+
 #include "ResourceUtils.h"
 #include "test/Test.h"
 #include "unflatten/BinaryResourceParser.h"
@@ -27,162 +28,165 @@
 class TableFlattenerTest : public ::testing::Test {
  public:
   void SetUp() override {
-    mContext = test::ContextBuilder()
-                   .setCompilationPackage("com.app.test")
-                   .setPackageId(0x7f)
-                   .build();
+    context_ = test::ContextBuilder()
+                   .SetCompilationPackage("com.app.test")
+                   .SetPackageId(0x7f)
+                   .Build();
   }
 
-  ::testing::AssertionResult flatten(ResourceTable* table, ResTable* outTable) {
+  ::testing::AssertionResult Flatten(ResourceTable* table,
+                                     ResTable* out_table) {
     BigBuffer buffer(1024);
     TableFlattener flattener(&buffer);
-    if (!flattener.consume(mContext.get(), table)) {
+    if (!flattener.Consume(context_.get(), table)) {
       return ::testing::AssertionFailure() << "failed to flatten ResourceTable";
     }
 
-    std::unique_ptr<uint8_t[]> data = util::copy(buffer);
-    if (outTable->add(data.get(), buffer.size(), -1, true) != NO_ERROR) {
+    std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
+    if (out_table->add(data.get(), buffer.size(), -1, true) != NO_ERROR) {
       return ::testing::AssertionFailure() << "flattened ResTable is corrupt";
     }
     return ::testing::AssertionSuccess();
   }
 
-  ::testing::AssertionResult flatten(ResourceTable* table,
-                                     ResourceTable* outTable) {
+  ::testing::AssertionResult Flatten(ResourceTable* table,
+                                     ResourceTable* out_table) {
     BigBuffer buffer(1024);
     TableFlattener flattener(&buffer);
-    if (!flattener.consume(mContext.get(), table)) {
+    if (!flattener.Consume(context_.get(), table)) {
       return ::testing::AssertionFailure() << "failed to flatten ResourceTable";
     }
 
-    std::unique_ptr<uint8_t[]> data = util::copy(buffer);
-    BinaryResourceParser parser(mContext.get(), outTable, {}, data.get(),
+    std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
+    BinaryResourceParser parser(context_.get(), out_table, {}, data.get(),
                                 buffer.size());
-    if (!parser.parse()) {
+    if (!parser.Parse()) {
       return ::testing::AssertionFailure() << "flattened ResTable is corrupt";
     }
     return ::testing::AssertionSuccess();
   }
 
-  ::testing::AssertionResult exists(ResTable* table,
-                                    const StringPiece& expectedName,
-                                    const ResourceId& expectedId,
-                                    const ConfigDescription& expectedConfig,
-                                    const uint8_t expectedDataType,
-                                    const uint32_t expectedData,
-                                    const uint32_t expectedSpecFlags) {
-    const ResourceName expectedResName = test::parseNameOrDie(expectedName);
+  ::testing::AssertionResult Exists(ResTable* table,
+                                    const StringPiece& expected_name,
+                                    const ResourceId& expected_id,
+                                    const ConfigDescription& expected_config,
+                                    const uint8_t expected_data_type,
+                                    const uint32_t expected_data,
+                                    const uint32_t expected_spec_flags) {
+    const ResourceName expected_res_name = test::ParseNameOrDie(expected_name);
 
-    table->setParameters(&expectedConfig);
+    table->setParameters(&expected_config);
 
     ResTable_config config;
     Res_value val;
-    uint32_t specFlags;
-    if (table->getResource(expectedId.id, &val, false, 0, &specFlags, &config) <
-        0) {
+    uint32_t spec_flags;
+    if (table->getResource(expected_id.id, &val, false, 0, &spec_flags,
+                           &config) < 0) {
       return ::testing::AssertionFailure() << "could not find resource with";
     }
 
-    if (expectedDataType != val.dataType) {
+    if (expected_data_type != val.dataType) {
       return ::testing::AssertionFailure()
-             << "expected data type " << std::hex << (int)expectedDataType
+             << "expected data type " << std::hex << (int)expected_data_type
              << " but got data type " << (int)val.dataType << std::dec
              << " instead";
     }
 
-    if (expectedData != val.data) {
+    if (expected_data != val.data) {
       return ::testing::AssertionFailure()
-             << "expected data " << std::hex << expectedData << " but got data "
-             << val.data << std::dec << " instead";
+             << "expected data " << std::hex << expected_data
+             << " but got data " << val.data << std::dec << " instead";
     }
 
-    if (expectedSpecFlags != specFlags) {
+    if (expected_spec_flags != spec_flags) {
       return ::testing::AssertionFailure()
-             << "expected specFlags " << std::hex << expectedSpecFlags
-             << " but got specFlags " << specFlags << std::dec << " instead";
+             << "expected specFlags " << std::hex << expected_spec_flags
+             << " but got specFlags " << spec_flags << std::dec << " instead";
     }
 
-    ResTable::resource_name actualName;
-    if (!table->getResourceName(expectedId.id, false, &actualName)) {
+    ResTable::resource_name actual_name;
+    if (!table->getResourceName(expected_id.id, false, &actual_name)) {
       return ::testing::AssertionFailure() << "failed to find resource name";
     }
 
-    Maybe<ResourceName> resName = ResourceUtils::toResourceName(actualName);
+    Maybe<ResourceName> resName = ResourceUtils::ToResourceName(actual_name);
     if (!resName) {
       return ::testing::AssertionFailure()
-             << "expected name '" << expectedResName << "' but got '"
-             << StringPiece16(actualName.package, actualName.packageLen) << ":"
-             << StringPiece16(actualName.type, actualName.typeLen) << "/"
-             << StringPiece16(actualName.name, actualName.nameLen) << "'";
+             << "expected name '" << expected_res_name << "' but got '"
+             << StringPiece16(actual_name.package, actual_name.packageLen)
+             << ":" << StringPiece16(actual_name.type, actual_name.typeLen)
+             << "/" << StringPiece16(actual_name.name, actual_name.nameLen)
+             << "'";
     }
 
-    if (expectedConfig != config) {
+    if (expected_config != config) {
       return ::testing::AssertionFailure() << "expected config '"
-                                           << expectedConfig << "' but got '"
+                                           << expected_config << "' but got '"
                                            << ConfigDescription(config) << "'";
     }
     return ::testing::AssertionSuccess();
   }
 
  private:
-  std::unique_ptr<IAaptContext> mContext;
+  std::unique_ptr<IAaptContext> context_;
 };
 
 TEST_F(TableFlattenerTest, FlattenFullyLinkedTable) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.test", 0x7f)
-          .addSimple("com.app.test:id/one", ResourceId(0x7f020000))
-          .addSimple("com.app.test:id/two", ResourceId(0x7f020001))
-          .addValue("com.app.test:id/three", ResourceId(0x7f020002),
-                    test::buildReference("com.app.test:id/one",
+          .SetPackageId("com.app.test", 0x7f)
+          .AddSimple("com.app.test:id/one", ResourceId(0x7f020000))
+          .AddSimple("com.app.test:id/two", ResourceId(0x7f020001))
+          .AddValue("com.app.test:id/three", ResourceId(0x7f020002),
+                    test::BuildReference("com.app.test:id/one",
                                          ResourceId(0x7f020000)))
-          .addValue("com.app.test:integer/one", ResourceId(0x7f030000),
+          .AddValue("com.app.test:integer/one", ResourceId(0x7f030000),
                     util::make_unique<BinaryPrimitive>(
                         uint8_t(Res_value::TYPE_INT_DEC), 1u))
-          .addValue("com.app.test:integer/one", test::parseConfigOrDie("v1"),
+          .AddValue("com.app.test:integer/one", test::ParseConfigOrDie("v1"),
                     ResourceId(0x7f030000),
                     util::make_unique<BinaryPrimitive>(
                         uint8_t(Res_value::TYPE_INT_DEC), 2u))
-          .addString("com.app.test:string/test", ResourceId(0x7f040000), "foo")
-          .addString("com.app.test:layout/bar", ResourceId(0x7f050000),
+          .AddString("com.app.test:string/test", ResourceId(0x7f040000), "foo")
+          .AddString("com.app.test:layout/bar", ResourceId(0x7f050000),
                      "res/layout/bar.xml")
-          .build();
+          .Build();
 
-  ResTable resTable;
-  ASSERT_TRUE(flatten(table.get(), &resTable));
+  ResTable res_table;
+  ASSERT_TRUE(Flatten(table.get(), &res_table));
 
-  EXPECT_TRUE(exists(&resTable, "com.app.test:id/one", ResourceId(0x7f020000),
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:id/one", ResourceId(0x7f020000),
                      {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
 
-  EXPECT_TRUE(exists(&resTable, "com.app.test:id/two", ResourceId(0x7f020001),
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:id/two", ResourceId(0x7f020001),
                      {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
 
-  EXPECT_TRUE(exists(&resTable, "com.app.test:id/three", ResourceId(0x7f020002),
-                     {}, Res_value::TYPE_REFERENCE, 0x7f020000u, 0u));
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:id/three",
+                     ResourceId(0x7f020002), {}, Res_value::TYPE_REFERENCE,
+                     0x7f020000u, 0u));
 
-  EXPECT_TRUE(exists(&resTable, "com.app.test:integer/one",
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:integer/one",
                      ResourceId(0x7f030000), {}, Res_value::TYPE_INT_DEC, 1u,
                      ResTable_config::CONFIG_VERSION));
 
-  EXPECT_TRUE(exists(&resTable, "com.app.test:integer/one",
-                     ResourceId(0x7f030000), test::parseConfigOrDie("v1"),
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:integer/one",
+                     ResourceId(0x7f030000), test::ParseConfigOrDie("v1"),
                      Res_value::TYPE_INT_DEC, 2u,
                      ResTable_config::CONFIG_VERSION));
 
-  std::u16string fooStr = u"foo";
-  ssize_t idx = resTable.getTableStringBlock(0)->indexOfString(fooStr.data(),
-                                                               fooStr.size());
+  std::u16string foo_str = u"foo";
+  ssize_t idx = res_table.getTableStringBlock(0)->indexOfString(foo_str.data(),
+                                                                foo_str.size());
   ASSERT_GE(idx, 0);
-  EXPECT_TRUE(exists(&resTable, "com.app.test:string/test",
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:string/test",
                      ResourceId(0x7f040000), {}, Res_value::TYPE_STRING,
                      (uint32_t)idx, 0u));
 
-  std::u16string barPath = u"res/layout/bar.xml";
-  idx = resTable.getTableStringBlock(0)->indexOfString(barPath.data(),
-                                                       barPath.size());
+  std::u16string bar_path = u"res/layout/bar.xml";
+  idx = res_table.getTableStringBlock(0)->indexOfString(bar_path.data(),
+                                                        bar_path.size());
   ASSERT_GE(idx, 0);
-  EXPECT_TRUE(exists(&resTable, "com.app.test:layout/bar",
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:layout/bar",
                      ResourceId(0x7f050000), {}, Res_value::TYPE_STRING,
                      (uint32_t)idx, 0u));
 }
@@ -190,42 +194,43 @@
 TEST_F(TableFlattenerTest, FlattenEntriesWithGapsInIds) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.test", 0x7f)
-          .addSimple("com.app.test:id/one", ResourceId(0x7f020001))
-          .addSimple("com.app.test:id/three", ResourceId(0x7f020003))
-          .build();
+          .SetPackageId("com.app.test", 0x7f)
+          .AddSimple("com.app.test:id/one", ResourceId(0x7f020001))
+          .AddSimple("com.app.test:id/three", ResourceId(0x7f020003))
+          .Build();
 
-  ResTable resTable;
-  ASSERT_TRUE(flatten(table.get(), &resTable));
+  ResTable res_table;
+  ASSERT_TRUE(Flatten(table.get(), &res_table));
 
-  EXPECT_TRUE(exists(&resTable, "com.app.test:id/one", ResourceId(0x7f020001),
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:id/one", ResourceId(0x7f020001),
                      {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
-  EXPECT_TRUE(exists(&resTable, "com.app.test:id/three", ResourceId(0x7f020003),
-                     {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:id/three",
+                     ResourceId(0x7f020003), {}, Res_value::TYPE_INT_BOOLEAN,
+                     0u, 0u));
 }
 
 TEST_F(TableFlattenerTest, FlattenMinMaxAttributes) {
   Attribute attr(false);
-  attr.typeMask = android::ResTable_map::TYPE_INTEGER;
-  attr.minInt = 10;
-  attr.maxInt = 23;
+  attr.type_mask = android::ResTable_map::TYPE_INTEGER;
+  attr.min_int = 10;
+  attr.max_int = 23;
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .setPackageId("android", 0x01)
-          .addValue("android:attr/foo", ResourceId(0x01010000),
+          .SetPackageId("android", 0x01)
+          .AddValue("android:attr/foo", ResourceId(0x01010000),
                     util::make_unique<Attribute>(attr))
-          .build();
+          .Build();
 
   ResourceTable result;
-  ASSERT_TRUE(flatten(table.get(), &result));
+  ASSERT_TRUE(Flatten(table.get(), &result));
 
   Attribute* actualAttr =
-      test::getValue<Attribute>(&result, "android:attr/foo");
+      test::GetValue<Attribute>(&result, "android:attr/foo");
   ASSERT_NE(nullptr, actualAttr);
-  EXPECT_EQ(attr.isWeak(), actualAttr->isWeak());
-  EXPECT_EQ(attr.typeMask, actualAttr->typeMask);
-  EXPECT_EQ(attr.minInt, actualAttr->minInt);
-  EXPECT_EQ(attr.maxInt, actualAttr->maxInt);
+  EXPECT_EQ(attr.IsWeak(), actualAttr->IsWeak());
+  EXPECT_EQ(attr.type_mask, actualAttr->type_mask);
+  EXPECT_EQ(attr.min_int, actualAttr->min_int);
+  EXPECT_EQ(attr.max_int, actualAttr->max_int);
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/flatten/XmlFlattener.cpp b/tools/aapt2/flatten/XmlFlattener.cpp
index c296dde..366c373 100644
--- a/tools/aapt2/flatten/XmlFlattener.cpp
+++ b/tools/aapt2/flatten/XmlFlattener.cpp
@@ -15,17 +15,21 @@
  */
 
 #include "flatten/XmlFlattener.h"
+
+#include <algorithm>
+#include <map>
+#include <vector>
+
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+#include "androidfw/ResourceTypes.h"
+#include "utils/misc.h"
+
 #include "SdkConstants.h"
 #include "flatten/ChunkWriter.h"
 #include "flatten/ResourceTypeExtensions.h"
 #include "xml/XmlDom.h"
 
-#include <androidfw/ResourceTypes.h>
-#include <utils/misc.h>
-#include <algorithm>
-#include <map>
-#include <vector>
-
 using namespace android;
 
 namespace aapt {
@@ -34,216 +38,215 @@
 
 constexpr uint32_t kLowPriority = 0xffffffffu;
 
-struct XmlFlattenerVisitor : public xml::Visitor {
-  using xml::Visitor::visit;
+static bool cmp_xml_attribute_by_id(const xml::Attribute* a,
+                                    const xml::Attribute* b) {
+  if (a->compiled_attribute && a->compiled_attribute.value().id) {
+    if (b->compiled_attribute && b->compiled_attribute.value().id) {
+      return a->compiled_attribute.value().id.value() <
+             b->compiled_attribute.value().id.value();
+    }
+    return true;
+  } else if (!b->compiled_attribute) {
+    int diff = a->namespace_uri.compare(b->namespace_uri);
+    if (diff < 0) {
+      return true;
+    } else if (diff > 0) {
+      return false;
+    }
+    return a->name < b->name;
+  }
+  return false;
+}
 
-  BigBuffer* mBuffer;
-  XmlFlattenerOptions mOptions;
-  StringPool mPool;
-  std::map<uint8_t, StringPool> mPackagePools;
+class XmlFlattenerVisitor : public xml::Visitor {
+ public:
+  using xml::Visitor::Visit;
+
+  StringPool pool;
+  std::map<uint8_t, StringPool> package_pools;
 
   struct StringFlattenDest {
     StringPool::Ref ref;
     ResStringPool_ref* dest;
   };
-  std::vector<StringFlattenDest> mStringRefs;
 
-  // Scratch vector to filter attributes. We avoid allocations
-  // making this a member.
-  std::vector<xml::Attribute*> mFilteredAttrs;
+  std::vector<StringFlattenDest> string_refs;
 
   XmlFlattenerVisitor(BigBuffer* buffer, XmlFlattenerOptions options)
-      : mBuffer(buffer), mOptions(options) {}
+      : buffer_(buffer), options_(options) {}
 
-  void addString(const StringPiece& str, uint32_t priority,
-                 android::ResStringPool_ref* dest,
-                 bool treatEmptyStringAsNull = false) {
-    if (str.empty() && treatEmptyStringAsNull) {
-      // Some parts of the runtime treat null differently than empty string.
-      dest->index = util::deviceToHost32(-1);
-    } else {
-      mStringRefs.push_back(StringFlattenDest{
-          mPool.makeRef(str, StringPool::Context{priority}), dest});
-    }
-  }
-
-  void addString(const StringPool::Ref& ref, android::ResStringPool_ref* dest) {
-    mStringRefs.push_back(StringFlattenDest{ref, dest});
-  }
-
-  void writeNamespace(xml::Namespace* node, uint16_t type) {
-    ChunkWriter writer(mBuffer);
-
-    ResXMLTree_node* flatNode = writer.startChunk<ResXMLTree_node>(type);
-    flatNode->lineNumber = util::hostToDevice32(node->lineNumber);
-    flatNode->comment.index = util::hostToDevice32(-1);
-
-    ResXMLTree_namespaceExt* flatNs =
-        writer.nextBlock<ResXMLTree_namespaceExt>();
-    addString(node->namespacePrefix, kLowPriority, &flatNs->prefix);
-    addString(node->namespaceUri, kLowPriority, &flatNs->uri);
-
-    writer.finish();
-  }
-
-  void visit(xml::Namespace* node) override {
-    if (node->namespaceUri == xml::kSchemaTools) {
+  void Visit(xml::Namespace* node) override {
+    if (node->namespace_uri == xml::kSchemaTools) {
       // Skip dedicated tools namespace.
-      xml::Visitor::visit(node);
+      xml::Visitor::Visit(node);
     } else {
-      writeNamespace(node, android::RES_XML_START_NAMESPACE_TYPE);
-      xml::Visitor::visit(node);
-      writeNamespace(node, android::RES_XML_END_NAMESPACE_TYPE);
+      WriteNamespace(node, android::RES_XML_START_NAMESPACE_TYPE);
+      xml::Visitor::Visit(node);
+      WriteNamespace(node, android::RES_XML_END_NAMESPACE_TYPE);
     }
   }
 
-  void visit(xml::Text* node) override {
-    if (util::trimWhitespace(node->text).empty()) {
+  void Visit(xml::Text* node) override {
+    if (util::TrimWhitespace(node->text).empty()) {
       // Skip whitespace only text nodes.
       return;
     }
 
-    ChunkWriter writer(mBuffer);
-    ResXMLTree_node* flatNode =
-        writer.startChunk<ResXMLTree_node>(RES_XML_CDATA_TYPE);
-    flatNode->lineNumber = util::hostToDevice32(node->lineNumber);
-    flatNode->comment.index = util::hostToDevice32(-1);
+    ChunkWriter writer(buffer_);
+    ResXMLTree_node* flat_node =
+        writer.StartChunk<ResXMLTree_node>(RES_XML_CDATA_TYPE);
+    flat_node->lineNumber = util::HostToDevice32(node->line_number);
+    flat_node->comment.index = util::HostToDevice32(-1);
 
-    ResXMLTree_cdataExt* flatText = writer.nextBlock<ResXMLTree_cdataExt>();
-    addString(node->text, kLowPriority, &flatText->data);
+    ResXMLTree_cdataExt* flat_text = writer.NextBlock<ResXMLTree_cdataExt>();
+    AddString(node->text, kLowPriority, &flat_text->data);
 
-    writer.finish();
+    writer.Finish();
   }
 
-  void visit(xml::Element* node) override {
+  void Visit(xml::Element* node) override {
     {
-      ChunkWriter startWriter(mBuffer);
-      ResXMLTree_node* flatNode =
-          startWriter.startChunk<ResXMLTree_node>(RES_XML_START_ELEMENT_TYPE);
-      flatNode->lineNumber = util::hostToDevice32(node->lineNumber);
-      flatNode->comment.index = util::hostToDevice32(-1);
+      ChunkWriter start_writer(buffer_);
+      ResXMLTree_node* flat_node =
+          start_writer.StartChunk<ResXMLTree_node>(RES_XML_START_ELEMENT_TYPE);
+      flat_node->lineNumber = util::HostToDevice32(node->line_number);
+      flat_node->comment.index = util::HostToDevice32(-1);
 
-      ResXMLTree_attrExt* flatElem =
-          startWriter.nextBlock<ResXMLTree_attrExt>();
+      ResXMLTree_attrExt* flat_elem =
+          start_writer.NextBlock<ResXMLTree_attrExt>();
 
       // A missing namespace must be null, not an empty string. Otherwise the
-      // runtime
-      // complains.
-      addString(node->namespaceUri, kLowPriority, &flatElem->ns,
-                true /* treatEmptyStringAsNull */);
-      addString(node->name, kLowPriority, &flatElem->name,
-                true /* treatEmptyStringAsNull */);
+      // runtime complains.
+      AddString(node->namespace_uri, kLowPriority, &flat_elem->ns,
+                true /* treat_empty_string_as_null */);
+      AddString(node->name, kLowPriority, &flat_elem->name,
+                true /* treat_empty_string_as_null */);
 
-      flatElem->attributeStart = util::hostToDevice16(sizeof(*flatElem));
-      flatElem->attributeSize =
-          util::hostToDevice16(sizeof(ResXMLTree_attribute));
+      flat_elem->attributeStart = util::HostToDevice16(sizeof(*flat_elem));
+      flat_elem->attributeSize =
+          util::HostToDevice16(sizeof(ResXMLTree_attribute));
 
-      writeAttributes(node, flatElem, &startWriter);
+      WriteAttributes(node, flat_elem, &start_writer);
 
-      startWriter.finish();
+      start_writer.Finish();
     }
 
-    xml::Visitor::visit(node);
+    xml::Visitor::Visit(node);
 
     {
-      ChunkWriter endWriter(mBuffer);
-      ResXMLTree_node* flatEndNode =
-          endWriter.startChunk<ResXMLTree_node>(RES_XML_END_ELEMENT_TYPE);
-      flatEndNode->lineNumber = util::hostToDevice32(node->lineNumber);
-      flatEndNode->comment.index = util::hostToDevice32(-1);
+      ChunkWriter end_writer(buffer_);
+      ResXMLTree_node* flat_end_node =
+          end_writer.StartChunk<ResXMLTree_node>(RES_XML_END_ELEMENT_TYPE);
+      flat_end_node->lineNumber = util::HostToDevice32(node->line_number);
+      flat_end_node->comment.index = util::HostToDevice32(-1);
 
-      ResXMLTree_endElementExt* flatEndElem =
-          endWriter.nextBlock<ResXMLTree_endElementExt>();
-      addString(node->namespaceUri, kLowPriority, &flatEndElem->ns,
-                true /* treatEmptyStringAsNull */);
-      addString(node->name, kLowPriority, &flatEndElem->name);
+      ResXMLTree_endElementExt* flat_end_elem =
+          end_writer.NextBlock<ResXMLTree_endElementExt>();
+      AddString(node->namespace_uri, kLowPriority, &flat_end_elem->ns,
+                true /* treat_empty_string_as_null */);
+      AddString(node->name, kLowPriority, &flat_end_elem->name);
 
-      endWriter.finish();
+      end_writer.Finish();
     }
   }
 
-  static bool cmpXmlAttributeById(const xml::Attribute* a,
-                                  const xml::Attribute* b) {
-    if (a->compiledAttribute && a->compiledAttribute.value().id) {
-      if (b->compiledAttribute && b->compiledAttribute.value().id) {
-        return a->compiledAttribute.value().id.value() <
-               b->compiledAttribute.value().id.value();
-      }
-      return true;
-    } else if (!b->compiledAttribute) {
-      int diff = a->namespaceUri.compare(b->namespaceUri);
-      if (diff < 0) {
-        return true;
-      } else if (diff > 0) {
-        return false;
-      }
-      return a->name < b->name;
+ private:
+  DISALLOW_COPY_AND_ASSIGN(XmlFlattenerVisitor);
+
+  void AddString(const StringPiece& str, uint32_t priority,
+                 android::ResStringPool_ref* dest,
+                 bool treat_empty_string_as_null = false) {
+    if (str.empty() && treat_empty_string_as_null) {
+      // Some parts of the runtime treat null differently than empty string.
+      dest->index = util::DeviceToHost32(-1);
+    } else {
+      string_refs.push_back(StringFlattenDest{
+          pool.MakeRef(str, StringPool::Context(priority)), dest});
     }
-    return false;
   }
 
-  void writeAttributes(xml::Element* node, ResXMLTree_attrExt* flatElem,
+  void AddString(const StringPool::Ref& ref, android::ResStringPool_ref* dest) {
+    string_refs.push_back(StringFlattenDest{ref, dest});
+  }
+
+  void WriteNamespace(xml::Namespace* node, uint16_t type) {
+    ChunkWriter writer(buffer_);
+
+    ResXMLTree_node* flatNode = writer.StartChunk<ResXMLTree_node>(type);
+    flatNode->lineNumber = util::HostToDevice32(node->line_number);
+    flatNode->comment.index = util::HostToDevice32(-1);
+
+    ResXMLTree_namespaceExt* flat_ns =
+        writer.NextBlock<ResXMLTree_namespaceExt>();
+    AddString(node->namespace_prefix, kLowPriority, &flat_ns->prefix);
+    AddString(node->namespace_uri, kLowPriority, &flat_ns->uri);
+
+    writer.Finish();
+  }
+
+  void WriteAttributes(xml::Element* node, ResXMLTree_attrExt* flat_elem,
                        ChunkWriter* writer) {
-    mFilteredAttrs.clear();
-    mFilteredAttrs.reserve(node->attributes.size());
+    filtered_attrs_.clear();
+    filtered_attrs_.reserve(node->attributes.size());
 
     // Filter the attributes.
     for (xml::Attribute& attr : node->attributes) {
-      if (mOptions.maxSdkLevel && attr.compiledAttribute &&
-          attr.compiledAttribute.value().id) {
-        size_t sdkLevel =
-            findAttributeSdkLevel(attr.compiledAttribute.value().id.value());
-        if (sdkLevel > mOptions.maxSdkLevel.value()) {
+      if (options_.max_sdk_level && attr.compiled_attribute &&
+          attr.compiled_attribute.value().id) {
+        size_t sdk_level =
+            FindAttributeSdkLevel(attr.compiled_attribute.value().id.value());
+        if (sdk_level > options_.max_sdk_level.value()) {
           continue;
         }
       }
-      if (attr.namespaceUri == xml::kSchemaTools) {
+      if (attr.namespace_uri == xml::kSchemaTools) {
         continue;
       }
-      mFilteredAttrs.push_back(&attr);
+      filtered_attrs_.push_back(&attr);
     }
 
-    if (mFilteredAttrs.empty()) {
+    if (filtered_attrs_.empty()) {
       return;
     }
 
     const ResourceId kIdAttr(0x010100d0);
 
-    std::sort(mFilteredAttrs.begin(), mFilteredAttrs.end(),
-              cmpXmlAttributeById);
+    std::sort(filtered_attrs_.begin(), filtered_attrs_.end(),
+              cmp_xml_attribute_by_id);
 
-    flatElem->attributeCount = util::hostToDevice16(mFilteredAttrs.size());
+    flat_elem->attributeCount = util::HostToDevice16(filtered_attrs_.size());
 
-    ResXMLTree_attribute* flatAttr =
-        writer->nextBlock<ResXMLTree_attribute>(mFilteredAttrs.size());
-    uint16_t attributeIndex = 1;
-    for (const xml::Attribute* xmlAttr : mFilteredAttrs) {
+    ResXMLTree_attribute* flat_attr =
+        writer->NextBlock<ResXMLTree_attribute>(filtered_attrs_.size());
+    uint16_t attribute_index = 1;
+    for (const xml::Attribute* xml_attr : filtered_attrs_) {
       // Assign the indices for specific attributes.
-      if (xmlAttr->compiledAttribute && xmlAttr->compiledAttribute.value().id &&
-          xmlAttr->compiledAttribute.value().id.value() == kIdAttr) {
-        flatElem->idIndex = util::hostToDevice16(attributeIndex);
-      } else if (xmlAttr->namespaceUri.empty()) {
-        if (xmlAttr->name == "class") {
-          flatElem->classIndex = util::hostToDevice16(attributeIndex);
-        } else if (xmlAttr->name == "style") {
-          flatElem->styleIndex = util::hostToDevice16(attributeIndex);
+      if (xml_attr->compiled_attribute &&
+          xml_attr->compiled_attribute.value().id &&
+          xml_attr->compiled_attribute.value().id.value() == kIdAttr) {
+        flat_elem->idIndex = util::HostToDevice16(attribute_index);
+      } else if (xml_attr->namespace_uri.empty()) {
+        if (xml_attr->name == "class") {
+          flat_elem->classIndex = util::HostToDevice16(attribute_index);
+        } else if (xml_attr->name == "style") {
+          flat_elem->styleIndex = util::HostToDevice16(attribute_index);
         }
       }
-      attributeIndex++;
+      attribute_index++;
 
       // Add the namespaceUri to the list of StringRefs to encode. Use null if
       // the namespace
       // is empty (doesn't exist).
-      addString(xmlAttr->namespaceUri, kLowPriority, &flatAttr->ns,
-                true /* treatEmptyStringAsNull */);
+      AddString(xml_attr->namespace_uri, kLowPriority, &flat_attr->ns,
+                true /* treat_empty_string_as_null */);
 
-      flatAttr->rawValue.index = util::hostToDevice32(-1);
+      flat_attr->rawValue.index = util::HostToDevice32(-1);
 
-      if (!xmlAttr->compiledAttribute ||
-          !xmlAttr->compiledAttribute.value().id) {
+      if (!xml_attr->compiled_attribute ||
+          !xml_attr->compiled_attribute.value().id) {
         // The attribute has no associated ResourceID, so the string order
         // doesn't matter.
-        addString(xmlAttr->name, kLowPriority, &flatAttr->name);
+        AddString(xml_attr->name, kLowPriority, &flat_attr->name);
       } else {
         // Attribute names are stored without packages, but we use
         // their StringPool index to lookup their resource IDs.
@@ -252,99 +255,106 @@
         // pools that we later combine.
         //
         // Lookup the StringPool for this package and make the reference there.
-        const xml::AaptAttribute& aaptAttr = xmlAttr->compiledAttribute.value();
+        const xml::AaptAttribute& aapt_attr =
+            xml_attr->compiled_attribute.value();
 
-        StringPool::Ref nameRef =
-            mPackagePools[aaptAttr.id.value().packageId()].makeRef(
-                xmlAttr->name, StringPool::Context{aaptAttr.id.value().id});
+        StringPool::Ref name_ref =
+            package_pools[aapt_attr.id.value().package_id()].MakeRef(
+                xml_attr->name, StringPool::Context(aapt_attr.id.value().id));
 
         // Add it to the list of strings to flatten.
-        addString(nameRef, &flatAttr->name);
+        AddString(name_ref, &flat_attr->name);
       }
 
-      if (mOptions.keepRawValues || !xmlAttr->compiledValue) {
+      if (options_.keep_raw_values || !xml_attr->compiled_value) {
         // Keep raw values if the value is not compiled or
         // if we're building a static library (need symbols).
-        addString(xmlAttr->value, kLowPriority, &flatAttr->rawValue);
+        AddString(xml_attr->value, kLowPriority, &flat_attr->rawValue);
       }
 
-      if (xmlAttr->compiledValue) {
-        bool result = xmlAttr->compiledValue->flatten(&flatAttr->typedValue);
-        assert(result);
+      if (xml_attr->compiled_value) {
+        CHECK(xml_attr->compiled_value->Flatten(&flat_attr->typedValue));
       } else {
         // Flatten as a regular string type.
-        flatAttr->typedValue.dataType = android::Res_value::TYPE_STRING;
-        addString(xmlAttr->value, kLowPriority,
-                  (ResStringPool_ref*)&flatAttr->typedValue.data);
+        flat_attr->typedValue.dataType = android::Res_value::TYPE_STRING;
+        AddString(xml_attr->value, kLowPriority,
+                  (ResStringPool_ref*)&flat_attr->typedValue.data);
       }
 
-      flatAttr->typedValue.size =
-          util::hostToDevice16(sizeof(flatAttr->typedValue));
-      flatAttr++;
+      flat_attr->typedValue.size =
+          util::HostToDevice16(sizeof(flat_attr->typedValue));
+      flat_attr++;
     }
   }
+
+  BigBuffer* buffer_;
+  XmlFlattenerOptions options_;
+
+  // Scratch vector to filter attributes. We avoid allocations
+  // making this a member.
+  std::vector<xml::Attribute*> filtered_attrs_;
 };
 
 }  // namespace
 
-bool XmlFlattener::flatten(IAaptContext* context, xml::Node* node) {
-  BigBuffer nodeBuffer(1024);
-  XmlFlattenerVisitor visitor(&nodeBuffer, mOptions);
-  node->accept(&visitor);
+bool XmlFlattener::Flatten(IAaptContext* context, xml::Node* node) {
+  BigBuffer node_buffer(1024);
+  XmlFlattenerVisitor visitor(&node_buffer, options_);
+  node->Accept(&visitor);
 
   // Merge the package pools into the main pool.
-  for (auto& packagePoolEntry : visitor.mPackagePools) {
-    visitor.mPool.merge(std::move(packagePoolEntry.second));
+  for (auto& package_pool_entry : visitor.package_pools) {
+    visitor.pool.Merge(std::move(package_pool_entry.second));
   }
 
   // Sort the string pool so that attribute resource IDs show up first.
-  visitor.mPool.sort(
+  visitor.pool.Sort(
       [](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
         return a.context.priority < b.context.priority;
       });
 
   // Now we flatten the string pool references into the correct places.
-  for (const auto& refEntry : visitor.mStringRefs) {
-    refEntry.dest->index = util::hostToDevice32(refEntry.ref.getIndex());
+  for (const auto& ref_entry : visitor.string_refs) {
+    ref_entry.dest->index = util::HostToDevice32(ref_entry.ref.index());
   }
 
   // Write the XML header.
-  ChunkWriter xmlHeaderWriter(mBuffer);
-  xmlHeaderWriter.startChunk<ResXMLTree_header>(RES_XML_TYPE);
+  ChunkWriter xml_header_writer(buffer_);
+  xml_header_writer.StartChunk<ResXMLTree_header>(RES_XML_TYPE);
 
   // Flatten the StringPool.
-  StringPool::flattenUtf8(mBuffer, visitor.mPool);
+  StringPool::FlattenUtf8(buffer_, visitor.pool);
 
   {
     // Write the array of resource IDs, indexed by StringPool order.
-    ChunkWriter resIdMapWriter(mBuffer);
-    resIdMapWriter.startChunk<ResChunk_header>(RES_XML_RESOURCE_MAP_TYPE);
-    for (const auto& str : visitor.mPool) {
+    ChunkWriter res_id_map_writer(buffer_);
+    res_id_map_writer.StartChunk<ResChunk_header>(RES_XML_RESOURCE_MAP_TYPE);
+    for (const auto& str : visitor.pool) {
       ResourceId id = {str->context.priority};
-      if (id.id == kLowPriority || !id.isValid()) {
+      if (id.id == kLowPriority || !id.is_valid()) {
         // When we see the first non-resource ID,
         // we're done.
         break;
       }
 
-      *resIdMapWriter.nextBlock<uint32_t>() = id.id;
+      *res_id_map_writer.NextBlock<uint32_t>() = id.id;
     }
-    resIdMapWriter.finish();
+    res_id_map_writer.Finish();
   }
 
   // Move the nodeBuffer and append it to the out buffer.
-  mBuffer->appendBuffer(std::move(nodeBuffer));
+  buffer_->AppendBuffer(std::move(node_buffer));
 
   // Finish the xml header.
-  xmlHeaderWriter.finish();
+  xml_header_writer.Finish();
   return true;
 }
 
-bool XmlFlattener::consume(IAaptContext* context, xml::XmlResource* resource) {
+bool XmlFlattener::Consume(IAaptContext* context, xml::XmlResource* resource) {
   if (!resource->root) {
     return false;
   }
-  return flatten(context, resource->root.get());
+  return Flatten(context, resource->root.get());
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/flatten/XmlFlattener.h b/tools/aapt2/flatten/XmlFlattener.h
index d8d592b..f5129fd 100644
--- a/tools/aapt2/flatten/XmlFlattener.h
+++ b/tools/aapt2/flatten/XmlFlattener.h
@@ -17,6 +17,8 @@
 #ifndef AAPT_FLATTEN_XMLFLATTENER_H
 #define AAPT_FLATTEN_XMLFLATTENER_H
 
+#include "android-base/macros.h"
+
 #include "process/IResourceTableConsumer.h"
 #include "util/BigBuffer.h"
 #include "xml/XmlDom.h"
@@ -27,26 +29,28 @@
   /**
    * Keep attribute raw string values along with typed values.
    */
-  bool keepRawValues = false;
+  bool keep_raw_values = false;
 
   /**
    * If set, the max SDK level of attribute to flatten. All others are ignored.
    */
-  Maybe<size_t> maxSdkLevel;
+  Maybe<size_t> max_sdk_level;
 };
 
 class XmlFlattener : public IXmlResourceConsumer {
  public:
   XmlFlattener(BigBuffer* buffer, XmlFlattenerOptions options)
-      : mBuffer(buffer), mOptions(options) {}
+      : buffer_(buffer), options_(options) {}
 
-  bool consume(IAaptContext* context, xml::XmlResource* resource) override;
+  bool Consume(IAaptContext* context, xml::XmlResource* resource) override;
 
  private:
-  BigBuffer* mBuffer;
-  XmlFlattenerOptions mOptions;
+  DISALLOW_COPY_AND_ASSIGN(XmlFlattener);
 
-  bool flatten(IAaptContext* context, xml::Node* node);
+  bool Flatten(IAaptContext* context, xml::Node* node);
+
+  BigBuffer* buffer_;
+  XmlFlattenerOptions options_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/flatten/XmlFlattener_test.cpp b/tools/aapt2/flatten/XmlFlattener_test.cpp
index e0159cb..2c83bb3 100644
--- a/tools/aapt2/flatten/XmlFlattener_test.cpp
+++ b/tools/aapt2/flatten/XmlFlattener_test.cpp
@@ -15,61 +15,62 @@
  */
 
 #include "flatten/XmlFlattener.h"
+
+#include "androidfw/ResourceTypes.h"
+
 #include "link/Linkers.h"
 #include "test/Test.h"
 #include "util/BigBuffer.h"
 #include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
-
 namespace aapt {
 
 class XmlFlattenerTest : public ::testing::Test {
  public:
   void SetUp() override {
-    mContext =
+    context_ =
         test::ContextBuilder()
-            .setCompilationPackage("com.app.test")
-            .setNameManglerPolicy(NameManglerPolicy{"com.app.test"})
-            .addSymbolSource(
+            .SetCompilationPackage("com.app.test")
+            .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"})
+            .AddSymbolSource(
                 test::StaticSymbolSourceBuilder()
-                    .addSymbol("android:attr/id", ResourceId(0x010100d0),
-                               test::AttributeBuilder().build())
-                    .addSymbol("com.app.test:id/id", ResourceId(0x7f020000))
-                    .addSymbol("android:attr/paddingStart",
+                    .AddSymbol("android:attr/id", ResourceId(0x010100d0),
+                               test::AttributeBuilder().Build())
+                    .AddSymbol("com.app.test:id/id", ResourceId(0x7f020000))
+                    .AddSymbol("android:attr/paddingStart",
                                ResourceId(0x010103b3),
-                               test::AttributeBuilder().build())
-                    .addSymbol("android:attr/colorAccent",
+                               test::AttributeBuilder().Build())
+                    .AddSymbol("android:attr/colorAccent",
                                ResourceId(0x01010435),
-                               test::AttributeBuilder().build())
-                    .build())
-            .build();
+                               test::AttributeBuilder().Build())
+                    .Build())
+            .Build();
   }
 
-  ::testing::AssertionResult flatten(xml::XmlResource* doc,
-                                     android::ResXMLTree* outTree,
+  ::testing::AssertionResult Flatten(xml::XmlResource* doc,
+                                     android::ResXMLTree* out_tree,
                                      const XmlFlattenerOptions& options = {}) {
     using namespace android;  // For NO_ERROR on windows because it is a macro.
 
     BigBuffer buffer(1024);
     XmlFlattener flattener(&buffer, options);
-    if (!flattener.consume(mContext.get(), doc)) {
+    if (!flattener.Consume(context_.get(), doc)) {
       return ::testing::AssertionFailure() << "failed to flatten XML Tree";
     }
 
-    std::unique_ptr<uint8_t[]> data = util::copy(buffer);
-    if (outTree->setTo(data.get(), buffer.size(), true) != NO_ERROR) {
+    std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
+    if (out_tree->setTo(data.get(), buffer.size(), true) != NO_ERROR) {
       return ::testing::AssertionFailure() << "flattened XML is corrupt";
     }
     return ::testing::AssertionSuccess();
   }
 
  protected:
-  std::unique_ptr<IAaptContext> mContext;
+  std::unique_ptr<IAaptContext> context_;
 };
 
 TEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) {
-  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
             <View xmlns:test="http://com.test"
                   attr="hey">
               <Layout test:hello="hi" />
@@ -77,27 +78,27 @@
             </View>)EOF");
 
   android::ResXMLTree tree;
-  ASSERT_TRUE(flatten(doc.get(), &tree));
+  ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   ASSERT_EQ(tree.next(), android::ResXMLTree::START_NAMESPACE);
 
   size_t len;
-  const char16_t* namespacePrefix = tree.getNamespacePrefix(&len);
-  EXPECT_EQ(StringPiece16(namespacePrefix, len), u"test");
+  const char16_t* namespace_prefix = tree.getNamespacePrefix(&len);
+  EXPECT_EQ(StringPiece16(namespace_prefix, len), u"test");
 
-  const char16_t* namespaceUri = tree.getNamespaceUri(&len);
-  ASSERT_EQ(StringPiece16(namespaceUri, len), u"http://com.test");
+  const char16_t* namespace_uri = tree.getNamespaceUri(&len);
+  ASSERT_EQ(StringPiece16(namespace_uri, len), u"http://com.test");
 
   ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
 
   ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
-  const char16_t* tagName = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(tagName, len), u"View");
+  const char16_t* tag_name = tree.getElementName(&len);
+  EXPECT_EQ(StringPiece16(tag_name, len), u"View");
 
   ASSERT_EQ(1u, tree.getAttributeCount());
   ASSERT_EQ(tree.getAttributeNamespace(0, &len), nullptr);
-  const char16_t* attrName = tree.getAttributeName(0, &len);
-  EXPECT_EQ(StringPiece16(attrName, len), u"attr");
+  const char16_t* attr_name = tree.getAttributeName(0, &len);
+  EXPECT_EQ(StringPiece16(attr_name, len), u"attr");
 
   EXPECT_EQ(0, tree.indexOfAttribute(nullptr, 0, u"attr",
                                      StringPiece16(u"attr").size()));
@@ -105,22 +106,22 @@
   ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
 
   ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
-  tagName = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(tagName, len), u"Layout");
+  tag_name = tree.getElementName(&len);
+  EXPECT_EQ(StringPiece16(tag_name, len), u"Layout");
 
   ASSERT_EQ(1u, tree.getAttributeCount());
-  const char16_t* attrNamespace = tree.getAttributeNamespace(0, &len);
-  EXPECT_EQ(StringPiece16(attrNamespace, len), u"http://com.test");
+  const char16_t* attr_namespace = tree.getAttributeNamespace(0, &len);
+  EXPECT_EQ(StringPiece16(attr_namespace, len), u"http://com.test");
 
-  attrName = tree.getAttributeName(0, &len);
-  EXPECT_EQ(StringPiece16(attrName, len), u"hello");
+  attr_name = tree.getAttributeName(0, &len);
+  EXPECT_EQ(StringPiece16(attr_name, len), u"hello");
 
   ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG);
   ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
 
   ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
-  tagName = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(tagName, len), u"Layout");
+  tag_name = tree.getElementName(&len);
+  EXPECT_EQ(StringPiece16(tag_name, len), u"Layout");
   ASSERT_EQ(0u, tree.getAttributeCount());
 
   ASSERT_EQ(tree.next(), android::ResXMLTree::TEXT);
@@ -129,39 +130,39 @@
 
   ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG);
   ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
-  tagName = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(tagName, len), u"Layout");
+  tag_name = tree.getElementName(&len);
+  EXPECT_EQ(StringPiece16(tag_name, len), u"Layout");
 
   ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG);
   ASSERT_EQ(tree.getElementNamespace(&len), nullptr);
-  tagName = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(tagName, len), u"View");
+  tag_name = tree.getElementName(&len);
+  EXPECT_EQ(StringPiece16(tag_name, len), u"View");
 
   ASSERT_EQ(tree.next(), android::ResXMLTree::END_NAMESPACE);
-  namespacePrefix = tree.getNamespacePrefix(&len);
-  EXPECT_EQ(StringPiece16(namespacePrefix, len), u"test");
+  namespace_prefix = tree.getNamespacePrefix(&len);
+  EXPECT_EQ(StringPiece16(namespace_prefix, len), u"test");
 
-  namespaceUri = tree.getNamespaceUri(&len);
-  ASSERT_EQ(StringPiece16(namespaceUri, len), u"http://com.test");
+  namespace_uri = tree.getNamespaceUri(&len);
+  ASSERT_EQ(StringPiece16(namespace_uri, len), u"http://com.test");
 
   ASSERT_EQ(tree.next(), android::ResXMLTree::END_DOCUMENT);
 }
 
 TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripSdk21) {
-  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
             <View xmlns:android="http://schemas.android.com/apk/res/android"
                 android:paddingStart="1dp"
                 android:colorAccent="#ffffff"/>)EOF");
 
   XmlReferenceLinker linker;
-  ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
-  ASSERT_TRUE(linker.getSdkLevels().count(17) == 1);
-  ASSERT_TRUE(linker.getSdkLevels().count(21) == 1);
+  ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
+  ASSERT_TRUE(linker.sdk_levels().count(17) == 1);
+  ASSERT_TRUE(linker.sdk_levels().count(21) == 1);
 
   android::ResXMLTree tree;
   XmlFlattenerOptions options;
-  options.maxSdkLevel = 17;
-  ASSERT_TRUE(flatten(doc.get(), &tree, options));
+  options.max_sdk_level = 17;
+  ASSERT_TRUE(Flatten(doc.get(), &tree, options));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
     ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
@@ -173,23 +174,23 @@
 }
 
 TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripOnlyTools) {
-  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
             <View xmlns:tools="http://schemas.android.com/tools"
                 xmlns:foo="http://schemas.android.com/foo"
                 foo:bar="Foo"
                 tools:ignore="MissingTranslation"/>)EOF");
 
   android::ResXMLTree tree;
-  ASSERT_TRUE(flatten(doc.get(), &tree));
+  ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   ASSERT_EQ(tree.next(), android::ResXMLTree::START_NAMESPACE);
 
   size_t len;
-  const char16_t* namespacePrefix = tree.getNamespacePrefix(&len);
-  EXPECT_EQ(StringPiece16(namespacePrefix, len), u"foo");
+  const char16_t* namespace_prefix = tree.getNamespacePrefix(&len);
+  EXPECT_EQ(StringPiece16(namespace_prefix, len), u"foo");
 
-  const char16_t* namespaceUri = tree.getNamespaceUri(&len);
-  ASSERT_EQ(StringPiece16(namespaceUri, len),
+  const char16_t* namespace_uri = tree.getNamespaceUri(&len);
+  ASSERT_EQ(StringPiece16(namespace_uri, len),
             u"http://schemas.android.com/foo");
 
   ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
@@ -200,14 +201,14 @@
 }
 
 TEST_F(XmlFlattenerTest, AssignSpecialAttributeIndices) {
-  std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
             <View xmlns:android="http://schemas.android.com/apk/res/android"
                   android:id="@id/id"
                   class="str"
                   style="@id/id"/>)EOF");
 
   android::ResXMLTree tree;
-  ASSERT_TRUE(flatten(doc.get(), &tree));
+  ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
     ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
@@ -225,10 +226,10 @@
  */
 TEST_F(XmlFlattenerTest, NoNamespaceIsNotTheSameAsEmptyNamespace) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDom("<View package=\"android\"/>");
+      test::BuildXmlDom("<View package=\"android\"/>");
 
   android::ResXMLTree tree;
-  ASSERT_TRUE(flatten(doc.get(), &tree));
+  ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
     ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
@@ -242,10 +243,10 @@
 
 TEST_F(XmlFlattenerTest, EmptyStringValueInAttributeIsNotNull) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDom("<View package=\"\"/>");
+      test::BuildXmlDom("<View package=\"\"/>");
 
   android::ResXMLTree tree;
-  ASSERT_TRUE(flatten(doc.get(), &tree));
+  ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
     ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
diff --git a/tools/aapt2/io/Data.h b/tools/aapt2/io/Data.h
index 0479228b..fdc044d 100644
--- a/tools/aapt2/io/Data.h
+++ b/tools/aapt2/io/Data.h
@@ -17,10 +17,11 @@
 #ifndef AAPT_IO_DATA_H
 #define AAPT_IO_DATA_H
 
-#include <android-base/macros.h>
-#include <utils/FileMap.h>
 #include <memory>
 
+#include "android-base/macros.h"
+#include "utils/FileMap.h"
+
 namespace aapt {
 namespace io {
 
@@ -39,20 +40,20 @@
 class DataSegment : public IData {
  public:
   explicit DataSegment(std::unique_ptr<IData> data, size_t offset, size_t len)
-      : mData(std::move(data)), mOffset(offset), mLen(len) {}
+      : data_(std::move(data)), offset_(offset), len_(len) {}
 
   const void* data() const override {
-    return static_cast<const uint8_t*>(mData->data()) + mOffset;
+    return static_cast<const uint8_t*>(data_->data()) + offset_;
   }
 
-  size_t size() const override { return mLen; }
+  size_t size() const override { return len_; }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(DataSegment);
 
-  std::unique_ptr<IData> mData;
-  size_t mOffset;
-  size_t mLen;
+  std::unique_ptr<IData> data_;
+  size_t offset_;
+  size_t len_;
 };
 
 /**
@@ -63,14 +64,14 @@
 class MmappedData : public IData {
  public:
   explicit MmappedData(android::FileMap&& map)
-      : mMap(std::forward<android::FileMap>(map)) {}
+      : map_(std::forward<android::FileMap>(map)) {}
 
-  const void* data() const override { return mMap.getDataPtr(); }
+  const void* data() const override { return map_.getDataPtr(); }
 
-  size_t size() const override { return mMap.getDataLength(); }
+  size_t size() const override { return map_.getDataLength(); }
 
  private:
-  android::FileMap mMap;
+  android::FileMap map_;
 };
 
 /**
@@ -81,15 +82,15 @@
 class MallocData : public IData {
  public:
   MallocData(std::unique_ptr<const uint8_t[]> data, size_t size)
-      : mData(std::move(data)), mSize(size) {}
+      : data_(std::move(data)), size_(size) {}
 
-  const void* data() const override { return mData.get(); }
+  const void* data() const override { return data_.get(); }
 
-  size_t size() const override { return mSize; }
+  size_t size() const override { return size_; }
 
  private:
-  std::unique_ptr<const uint8_t[]> mData;
-  size_t mSize;
+  std::unique_ptr<const uint8_t[]> data_;
+  size_t size_;
 };
 
 /**
diff --git a/tools/aapt2/io/File.cpp b/tools/aapt2/io/File.cpp
index 739c0d2..ee73728 100644
--- a/tools/aapt2/io/File.cpp
+++ b/tools/aapt2/io/File.cpp
@@ -21,23 +21,23 @@
 namespace aapt {
 namespace io {
 
-IFile* IFile::createFileSegment(size_t offset, size_t len) {
-   FileSegment* fileSegment = new FileSegment(this, offset, len);
-   mSegments.push_back(std::unique_ptr<IFile>(fileSegment));
-   return fileSegment;
+IFile* IFile::CreateFileSegment(size_t offset, size_t len) {
+  FileSegment* file_segment = new FileSegment(this, offset, len);
+  segments_.push_back(std::unique_ptr<IFile>(file_segment));
+  return file_segment;
 }
 
-std::unique_ptr<IData> FileSegment::openAsData() {
-    std::unique_ptr<IData> data = mFile->openAsData();
-    if (!data) {
-        return {};
-    }
-
-    if (mOffset <= data->size() - mLen) {
-        return util::make_unique<DataSegment>(std::move(data), mOffset, mLen);
-    }
+std::unique_ptr<IData> FileSegment::OpenAsData() {
+  std::unique_ptr<IData> data = file_->OpenAsData();
+  if (!data) {
     return {};
+  }
+
+  if (offset_ <= data->size() - len_) {
+    return util::make_unique<DataSegment>(std::move(data), offset_, len_);
+  }
+  return {};
 }
 
-} // namespace io
-} // namespace aapt
+}  // namespace io
+}  // namespace aapt
diff --git a/tools/aapt2/io/File.h b/tools/aapt2/io/File.h
index 012f446..644f59f 100644
--- a/tools/aapt2/io/File.h
+++ b/tools/aapt2/io/File.h
@@ -17,15 +17,16 @@
 #ifndef AAPT_IO_FILE_H
 #define AAPT_IO_FILE_H
 
-#include "Source.h"
-#include "io/Data.h"
-#include "util/Util.h"
-
-#include <android-base/macros.h>
 #include <list>
 #include <memory>
 #include <vector>
 
+#include "android-base/macros.h"
+
+#include "Source.h"
+#include "io/Data.h"
+#include "util/Util.h"
+
 namespace aapt {
 namespace io {
 
@@ -49,7 +50,7 @@
    *
    * Returns nullptr on failure.
    */
-  virtual std::unique_ptr<IData> openAsData() = 0;
+  virtual std::unique_ptr<IData> OpenAsData() = 0;
 
   /**
    * Returns the source of this file. This is for presentation to the user and
@@ -58,9 +59,9 @@
    * the files within
    * a ZIP archive from the path to the containing ZIP archive.
    */
-  virtual const Source& getSource() const = 0;
+  virtual const Source& GetSource() const = 0;
 
-  IFile* createFileSegment(size_t offset, size_t len);
+  IFile* CreateFileSegment(size_t offset, size_t len);
 
  private:
   // Any segments created from this IFile need to be owned by this IFile, so
@@ -68,7 +69,7 @@
   // in a list. This will never be read, so we prefer better insertion
   // performance
   // than cache locality, hence the list.
-  std::list<std::unique_ptr<IFile>> mSegments;
+  std::list<std::unique_ptr<IFile>> segments_;
 };
 
 /**
@@ -78,26 +79,26 @@
 class FileSegment : public IFile {
  public:
   explicit FileSegment(IFile* file, size_t offset, size_t len)
-      : mFile(file), mOffset(offset), mLen(len) {}
+      : file_(file), offset_(offset), len_(len) {}
 
-  std::unique_ptr<IData> openAsData() override;
+  std::unique_ptr<IData> OpenAsData() override;
 
-  const Source& getSource() const override { return mFile->getSource(); }
+  const Source& GetSource() const override { return file_->GetSource(); }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(FileSegment);
 
-  IFile* mFile;
-  size_t mOffset;
-  size_t mLen;
+  IFile* file_;
+  size_t offset_;
+  size_t len_;
 };
 
 class IFileCollectionIterator {
  public:
   virtual ~IFileCollectionIterator() = default;
 
-  virtual bool hasNext() = 0;
-  virtual IFile* next() = 0;
+  virtual bool HasNext() = 0;
+  virtual IFile* Next() = 0;
 };
 
 /**
@@ -109,8 +110,8 @@
  public:
   virtual ~IFileCollection() = default;
 
-  virtual IFile* findFile(const StringPiece& path) = 0;
-  virtual std::unique_ptr<IFileCollectionIterator> iterator() = 0;
+  virtual IFile* FindFile(const StringPiece& path) = 0;
+  virtual std::unique_ptr<IFileCollectionIterator> Iterator() = 0;
 };
 
 }  // namespace io
diff --git a/tools/aapt2/io/FileSystem.cpp b/tools/aapt2/io/FileSystem.cpp
index e758d8a4..828f34e 100644
--- a/tools/aapt2/io/FileSystem.cpp
+++ b/tools/aapt2/io/FileSystem.cpp
@@ -14,65 +14,62 @@
  * limitations under the License.
  */
 
-#include "Source.h"
 #include "io/FileSystem.h"
+
+#include "utils/FileMap.h"
+
+#include "Source.h"
 #include "util/Files.h"
 #include "util/Maybe.h"
 #include "util/StringPiece.h"
 #include "util/Util.h"
 
-#include <utils/FileMap.h>
-
 namespace aapt {
 namespace io {
 
-RegularFile::RegularFile(const Source& source) : mSource(source) {
-}
+RegularFile::RegularFile(const Source& source) : source_(source) {}
 
-std::unique_ptr<IData> RegularFile::openAsData() {
-    android::FileMap map;
-    if (Maybe<android::FileMap> map = file::mmapPath(mSource.path, nullptr)) {
-        if (map.value().getDataPtr() && map.value().getDataLength() > 0) {
-            return util::make_unique<MmappedData>(std::move(map.value()));
-        }
-        return util::make_unique<EmptyData>();
+std::unique_ptr<IData> RegularFile::OpenAsData() {
+  android::FileMap map;
+  if (Maybe<android::FileMap> map = file::MmapPath(source_.path, nullptr)) {
+    if (map.value().getDataPtr() && map.value().getDataLength() > 0) {
+      return util::make_unique<MmappedData>(std::move(map.value()));
     }
-    return {};
+    return util::make_unique<EmptyData>();
+  }
+  return {};
 }
 
-const Source& RegularFile::getSource() const {
-    return mSource;
+const Source& RegularFile::GetSource() const { return source_; }
+
+FileCollectionIterator::FileCollectionIterator(FileCollection* collection)
+    : current_(collection->files_.begin()), end_(collection->files_.end()) {}
+
+bool FileCollectionIterator::HasNext() { return current_ != end_; }
+
+IFile* FileCollectionIterator::Next() {
+  IFile* result = current_->second.get();
+  ++current_;
+  return result;
 }
 
-FileCollectionIterator::FileCollectionIterator(FileCollection* collection) :
-        mCurrent(collection->mFiles.begin()), mEnd(collection->mFiles.end()) {
+IFile* FileCollection::InsertFile(const StringPiece& path) {
+  return (files_[path.ToString()] =
+              util::make_unique<RegularFile>(Source(path)))
+      .get();
 }
 
-bool FileCollectionIterator::hasNext() {
-    return mCurrent != mEnd;
+IFile* FileCollection::FindFile(const StringPiece& path) {
+  auto iter = files_.find(path.ToString());
+  if (iter != files_.end()) {
+    return iter->second.get();
+  }
+  return nullptr;
 }
 
-IFile* FileCollectionIterator::next() {
-    IFile* result = mCurrent->second.get();
-    ++mCurrent;
-    return result;
+std::unique_ptr<IFileCollectionIterator> FileCollection::Iterator() {
+  return util::make_unique<FileCollectionIterator>(this);
 }
 
-IFile* FileCollection::insertFile(const StringPiece& path) {
-    return (mFiles[path.toString()] = util::make_unique<RegularFile>(Source(path))).get();
-}
-
-IFile* FileCollection::findFile(const StringPiece& path) {
-    auto iter = mFiles.find(path.toString());
-    if (iter != mFiles.end()) {
-        return iter->second.get();
-    }
-    return nullptr;
-}
-
-std::unique_ptr<IFileCollectionIterator> FileCollection::iterator() {
-    return util::make_unique<FileCollectionIterator>(this);
-}
-
-} // namespace io
-} // namespace aapt
+}  // namespace io
+}  // namespace aapt
diff --git a/tools/aapt2/io/FileSystem.h b/tools/aapt2/io/FileSystem.h
index 8584d48..84f851f 100644
--- a/tools/aapt2/io/FileSystem.h
+++ b/tools/aapt2/io/FileSystem.h
@@ -17,10 +17,10 @@
 #ifndef AAPT_IO_FILESYSTEM_H
 #define AAPT_IO_FILESYSTEM_H
 
-#include "io/File.h"
-
 #include <map>
 
+#include "io/File.h"
+
 namespace aapt {
 namespace io {
 
@@ -31,11 +31,11 @@
  public:
   explicit RegularFile(const Source& source);
 
-  std::unique_ptr<IData> openAsData() override;
-  const Source& getSource() const override;
+  std::unique_ptr<IData> OpenAsData() override;
+  const Source& GetSource() const override;
 
  private:
-  Source mSource;
+  Source source_;
 };
 
 class FileCollection;
@@ -44,11 +44,11 @@
  public:
   explicit FileCollectionIterator(FileCollection* collection);
 
-  bool hasNext() override;
-  io::IFile* next() override;
+  bool HasNext() override;
+  io::IFile* Next() override;
 
  private:
-  std::map<std::string, std::unique_ptr<IFile>>::const_iterator mCurrent, mEnd;
+  std::map<std::string, std::unique_ptr<IFile>>::const_iterator current_, end_;
 };
 
 /**
@@ -59,13 +59,13 @@
   /**
    * Adds a file located at path. Returns the IFile representation of that file.
    */
-  IFile* insertFile(const StringPiece& path);
-  IFile* findFile(const StringPiece& path) override;
-  std::unique_ptr<IFileCollectionIterator> iterator() override;
+  IFile* InsertFile(const StringPiece& path);
+  IFile* FindFile(const StringPiece& path) override;
+  std::unique_ptr<IFileCollectionIterator> Iterator() override;
 
  private:
   friend class FileCollectionIterator;
-  std::map<std::string, std::unique_ptr<IFile>> mFiles;
+  std::map<std::string, std::unique_ptr<IFile>> files_;
 };
 
 }  // namespace io
diff --git a/tools/aapt2/io/Io.cpp b/tools/aapt2/io/Io.cpp
index 963c21c..cab4b65 100644
--- a/tools/aapt2/io/Io.cpp
+++ b/tools/aapt2/io/Io.cpp
@@ -22,23 +22,23 @@
 namespace aapt {
 namespace io {
 
-bool copy(OutputStream* out, InputStream* in) {
-    const void* inBuffer;
-    int inLen;
-    while (in->Next(&inBuffer, &inLen)) {
-        void* outBuffer;
-        int outLen;
-        if (!out->Next(&outBuffer, &outLen)) {
-            return !out->HadError();
-        }
-
-        const int bytesToCopy = std::min(inLen, outLen);
-        memcpy(outBuffer, inBuffer, bytesToCopy);
-        out->BackUp(outLen - bytesToCopy);
-        in->BackUp(inLen - bytesToCopy);
+bool Copy(OutputStream* out, InputStream* in) {
+  const void* in_buffer;
+  int in_len;
+  while (in->Next(&in_buffer, &in_len)) {
+    void* out_buffer;
+    int out_len;
+    if (!out->Next(&out_buffer, &out_len)) {
+      return !out->HadError();
     }
-    return !in->HadError();
+
+    const int bytes_to_copy = std::min(in_len, out_len);
+    memcpy(out_buffer, in_buffer, bytes_to_copy);
+    out->BackUp(out_len - bytes_to_copy);
+    in->BackUp(in_len - bytes_to_copy);
+  }
+  return !in->HadError();
 }
 
-} // namespace io
-} // namespace aapt
+}  // namespace io
+}  // namespace aapt
diff --git a/tools/aapt2/io/Io.h b/tools/aapt2/io/Io.h
index 49b9fc3..33cdc7b 100644
--- a/tools/aapt2/io/Io.h
+++ b/tools/aapt2/io/Io.h
@@ -17,9 +17,10 @@
 #ifndef AAPT_IO_IO_H
 #define AAPT_IO_IO_H
 
-#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <string>
 
+#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
+
 namespace aapt {
 namespace io {
 
@@ -29,7 +30,7 @@
  *
  * The code style here matches the protobuf style.
  */
-class InputStream : public google::protobuf::io::ZeroCopyInputStream {
+class InputStream : public ::google::protobuf::io::ZeroCopyInputStream {
  public:
   virtual std::string GetError() const { return {}; }
 
@@ -42,7 +43,7 @@
  *
  * The code style here matches the protobuf style.
  */
-class OutputStream : public google::protobuf::io::ZeroCopyOutputStream {
+class OutputStream : public ::google::protobuf::io::ZeroCopyOutputStream {
  public:
   virtual std::string GetError() const { return {}; }
 
@@ -54,7 +55,7 @@
  * If there was an error, check the individual streams' HadError/GetError
  * methods.
  */
-bool copy(OutputStream* out, InputStream* in);
+bool Copy(OutputStream* out, InputStream* in);
 
 }  // namespace io
 }  // namespace aapt
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
index b3e7a02..f4a128e 100644
--- a/tools/aapt2/io/ZipArchive.cpp
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -14,129 +14,128 @@
  * limitations under the License.
  */
 
-#include "Source.h"
 #include "io/ZipArchive.h"
-#include "util/Util.h"
 
-#include <utils/FileMap.h>
-#include <ziparchive/zip_archive.h>
+#include "utils/FileMap.h"
+#include "ziparchive/zip_archive.h"
+
+#include "Source.h"
+#include "util/Util.h"
 
 namespace aapt {
 namespace io {
 
-ZipFile::ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, const Source& source) :
-        mZipHandle(handle), mZipEntry(entry), mSource(source) {
-}
+ZipFile::ZipFile(ZipArchiveHandle handle, const ZipEntry& entry,
+                 const Source& source)
+    : zip_handle_(handle), zip_entry_(entry), source_(source) {}
 
-std::unique_ptr<IData> ZipFile::openAsData() {
-    if (mZipEntry.method == kCompressStored) {
-        int fd = GetFileDescriptor(mZipHandle);
+std::unique_ptr<IData> ZipFile::OpenAsData() {
+  if (zip_entry_.method == kCompressStored) {
+    int fd = GetFileDescriptor(zip_handle_);
 
-        android::FileMap fileMap;
-        bool result = fileMap.create(nullptr, fd, mZipEntry.offset,
-                                     mZipEntry.uncompressed_length, true);
-        if (!result) {
-            return {};
-        }
-        return util::make_unique<MmappedData>(std::move(fileMap));
-
-    } else {
-        std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(
-                new uint8_t[mZipEntry.uncompressed_length]);
-        int32_t result = ExtractToMemory(mZipHandle, &mZipEntry, data.get(),
-                                         static_cast<uint32_t>(mZipEntry.uncompressed_length));
-        if (result != 0) {
-            return {};
-        }
-        return util::make_unique<MallocData>(std::move(data), mZipEntry.uncompressed_length);
+    android::FileMap file_map;
+    bool result = file_map.create(nullptr, fd, zip_entry_.offset,
+                                  zip_entry_.uncompressed_length, true);
+    if (!result) {
+      return {};
     }
-}
+    return util::make_unique<MmappedData>(std::move(file_map));
 
-const Source& ZipFile::getSource() const {
-    return mSource;
-}
-
-ZipFileCollectionIterator::ZipFileCollectionIterator(ZipFileCollection* collection) :
-        mCurrent(collection->mFiles.begin()), mEnd(collection->mFiles.end()) {
-}
-
-bool ZipFileCollectionIterator::hasNext() {
-    return mCurrent != mEnd;
-}
-
-IFile* ZipFileCollectionIterator::next() {
-    IFile* result = mCurrent->second.get();
-    ++mCurrent;
-    return result;
-}
-
-ZipFileCollection::ZipFileCollection() : mHandle(nullptr) {
-}
-
-std::unique_ptr<ZipFileCollection> ZipFileCollection::create(const StringPiece& path,
-                                                             std::string* outError) {
-    constexpr static const int32_t kEmptyArchive = -6;
-
-    std::unique_ptr<ZipFileCollection> collection = std::unique_ptr<ZipFileCollection>(
-            new ZipFileCollection());
-
-    int32_t result = OpenArchive(path.data(), &collection->mHandle);
+  } else {
+    std::unique_ptr<uint8_t[]> data =
+        std::unique_ptr<uint8_t[]>(new uint8_t[zip_entry_.uncompressed_length]);
+    int32_t result =
+        ExtractToMemory(zip_handle_, &zip_entry_, data.get(),
+                        static_cast<uint32_t>(zip_entry_.uncompressed_length));
     if (result != 0) {
-        // If a zip is empty, result will be an error code. This is fine and we should
-        // return an empty ZipFileCollection.
-        if (result == kEmptyArchive) {
-            return collection;
-        }
-
-        if (outError) *outError = ErrorCodeString(result);
-        return {};
+      return {};
     }
-
-    void* cookie = nullptr;
-    result = StartIteration(collection->mHandle, &cookie, nullptr, nullptr);
-    if (result != 0) {
-        if (outError) *outError = ErrorCodeString(result);
-        return {};
-    }
-
-    using IterationEnder = std::unique_ptr<void, decltype(EndIteration)*>;
-    IterationEnder iterationEnder(cookie, EndIteration);
-
-    ZipString zipEntryName;
-    ZipEntry zipData;
-    while ((result = Next(cookie, &zipData, &zipEntryName)) == 0) {
-        std::string zipEntryPath = std::string(reinterpret_cast<const char*>(zipEntryName.name),
-                                               zipEntryName.name_length);
-        std::string nestedPath = path.toString() + "@" + zipEntryPath;
-        collection->mFiles[zipEntryPath] = util::make_unique<ZipFile>(collection->mHandle,
-                                                                      zipData,
-                                                                      Source(nestedPath));
-    }
-
-    if (result != -1) {
-        if (outError) *outError = ErrorCodeString(result);
-        return {};
-    }
-    return collection;
+    return util::make_unique<MallocData>(std::move(data),
+                                         zip_entry_.uncompressed_length);
+  }
 }
 
-IFile* ZipFileCollection::findFile(const StringPiece& path) {
-    auto iter = mFiles.find(path.toString());
-    if (iter != mFiles.end()) {
-        return iter->second.get();
-    }
-    return nullptr;
+const Source& ZipFile::GetSource() const { return source_; }
+
+ZipFileCollectionIterator::ZipFileCollectionIterator(
+    ZipFileCollection* collection)
+    : current_(collection->files_.begin()), end_(collection->files_.end()) {}
+
+bool ZipFileCollectionIterator::HasNext() { return current_ != end_; }
+
+IFile* ZipFileCollectionIterator::Next() {
+  IFile* result = current_->second.get();
+  ++current_;
+  return result;
 }
 
-std::unique_ptr<IFileCollectionIterator> ZipFileCollection::iterator() {
-    return util::make_unique<ZipFileCollectionIterator>(this);
+ZipFileCollection::ZipFileCollection() : handle_(nullptr) {}
+
+std::unique_ptr<ZipFileCollection> ZipFileCollection::Create(
+    const StringPiece& path, std::string* out_error) {
+  constexpr static const int32_t kEmptyArchive = -6;
+
+  std::unique_ptr<ZipFileCollection> collection =
+      std::unique_ptr<ZipFileCollection>(new ZipFileCollection());
+
+  int32_t result = OpenArchive(path.data(), &collection->handle_);
+  if (result != 0) {
+    // If a zip is empty, result will be an error code. This is fine and we
+    // should
+    // return an empty ZipFileCollection.
+    if (result == kEmptyArchive) {
+      return collection;
+    }
+
+    if (out_error) *out_error = ErrorCodeString(result);
+    return {};
+  }
+
+  void* cookie = nullptr;
+  result = StartIteration(collection->handle_, &cookie, nullptr, nullptr);
+  if (result != 0) {
+    if (out_error) *out_error = ErrorCodeString(result);
+    return {};
+  }
+
+  using IterationEnder = std::unique_ptr<void, decltype(EndIteration)*>;
+  IterationEnder iteration_ender(cookie, EndIteration);
+
+  ZipString zip_entry_name;
+  ZipEntry zip_data;
+  while ((result = Next(cookie, &zip_data, &zip_entry_name)) == 0) {
+    std::string zip_entry_path =
+        std::string(reinterpret_cast<const char*>(zip_entry_name.name),
+                    zip_entry_name.name_length);
+    std::string nested_path = path.ToString() + "@" + zip_entry_path;
+    collection->files_[zip_entry_path] = util::make_unique<ZipFile>(
+        collection->handle_, zip_data, Source(nested_path));
+  }
+
+  if (result != -1) {
+    if (out_error) *out_error = ErrorCodeString(result);
+    return {};
+  }
+  return collection;
+}
+
+IFile* ZipFileCollection::FindFile(const StringPiece& path) {
+  auto iter = files_.find(path.ToString());
+  if (iter != files_.end()) {
+    return iter->second.get();
+  }
+  return nullptr;
+}
+
+std::unique_ptr<IFileCollectionIterator> ZipFileCollection::Iterator() {
+  return util::make_unique<ZipFileCollectionIterator>(this);
 }
 
 ZipFileCollection::~ZipFileCollection() {
-    if (mHandle) {
-        CloseArchive(mHandle);
-    }
+  if (handle_) {
+    CloseArchive(handle_);
+  }
 }
 
-} // namespace io
-} // namespace aapt
+}  // namespace io
+}  // namespace aapt
diff --git a/tools/aapt2/io/ZipArchive.h b/tools/aapt2/io/ZipArchive.h
index e04525f..85ca1ae 100644
--- a/tools/aapt2/io/ZipArchive.h
+++ b/tools/aapt2/io/ZipArchive.h
@@ -17,12 +17,13 @@
 #ifndef AAPT_IO_ZIPARCHIVE_H
 #define AAPT_IO_ZIPARCHIVE_H
 
+#include "ziparchive/zip_archive.h"
+
+#include <map>
+
 #include "io/File.h"
 #include "util/StringPiece.h"
 
-#include <ziparchive/zip_archive.h>
-#include <map>
-
 namespace aapt {
 namespace io {
 
@@ -36,13 +37,13 @@
  public:
   ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, const Source& source);
 
-  std::unique_ptr<IData> openAsData() override;
-  const Source& getSource() const override;
+  std::unique_ptr<IData> OpenAsData() override;
+  const Source& GetSource() const override;
 
  private:
-  ZipArchiveHandle mZipHandle;
-  ZipEntry mZipEntry;
-  Source mSource;
+  ZipArchiveHandle zip_handle_;
+  ZipEntry zip_entry_;
+  Source source_;
 };
 
 class ZipFileCollection;
@@ -51,11 +52,11 @@
  public:
   explicit ZipFileCollectionIterator(ZipFileCollection* collection);
 
-  bool hasNext() override;
-  io::IFile* next() override;
+  bool HasNext() override;
+  io::IFile* Next() override;
 
  private:
-  std::map<std::string, std::unique_ptr<IFile>>::const_iterator mCurrent, mEnd;
+  std::map<std::string, std::unique_ptr<IFile>>::const_iterator current_, end_;
 };
 
 /**
@@ -63,11 +64,11 @@
  */
 class ZipFileCollection : public IFileCollection {
  public:
-  static std::unique_ptr<ZipFileCollection> create(const StringPiece& path,
+  static std::unique_ptr<ZipFileCollection> Create(const StringPiece& path,
                                                    std::string* outError);
 
-  io::IFile* findFile(const StringPiece& path) override;
-  std::unique_ptr<IFileCollectionIterator> iterator() override;
+  io::IFile* FindFile(const StringPiece& path) override;
+  std::unique_ptr<IFileCollectionIterator> Iterator() override;
 
   ~ZipFileCollection() override;
 
@@ -75,8 +76,8 @@
   friend class ZipFileCollectionIterator;
   ZipFileCollection();
 
-  ZipArchiveHandle mHandle;
-  std::map<std::string, std::unique_ptr<IFile>> mFiles;
+  ZipArchiveHandle handle_;
+  std::map<std::string, std::unique_ptr<IFile>> files_;
 };
 
 }  // namespace io
diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp
index 23ff8ab..2951e5c 100644
--- a/tools/aapt2/java/AnnotationProcessor.cpp
+++ b/tools/aapt2/java/AnnotationProcessor.cpp
@@ -15,69 +15,71 @@
  */
 
 #include "java/AnnotationProcessor.h"
-#include "util/Util.h"
 
 #include <algorithm>
 
+#include "util/Util.h"
+
 namespace aapt {
 
-void AnnotationProcessor::appendCommentLine(std::string& comment) {
-    static const std::string sDeprecated = "@deprecated";
-    static const std::string sSystemApi = "@SystemApi";
+void AnnotationProcessor::AppendCommentLine(std::string& comment) {
+  static const std::string sDeprecated = "@deprecated";
+  static const std::string sSystemApi = "@SystemApi";
 
-    if (comment.find(sDeprecated) != std::string::npos) {
-        mAnnotationBitMask |= kDeprecated;
-    }
+  if (comment.find(sDeprecated) != std::string::npos) {
+    annotation_bit_mask_ |= kDeprecated;
+  }
 
-    std::string::size_type idx = comment.find(sSystemApi);
-    if (idx != std::string::npos) {
-        mAnnotationBitMask |= kSystemApi;
-        comment.erase(comment.begin() + idx, comment.begin() + idx + sSystemApi.size());
-    }
+  std::string::size_type idx = comment.find(sSystemApi);
+  if (idx != std::string::npos) {
+    annotation_bit_mask_ |= kSystemApi;
+    comment.erase(comment.begin() + idx,
+                  comment.begin() + idx + sSystemApi.size());
+  }
 
-    if (util::trimWhitespace(comment).empty()) {
-        return;
-    }
+  if (util::TrimWhitespace(comment).empty()) {
+    return;
+  }
 
-    if (!mHasComments) {
-        mHasComments = true;
-        mComment << "/**";
-    }
+  if (!has_comments_) {
+    has_comments_ = true;
+    comment_ << "/**";
+  }
 
-    mComment << "\n * " << std::move(comment);
+  comment_ << "\n * " << std::move(comment);
 }
 
-void AnnotationProcessor::appendComment(const StringPiece& comment) {
-    // We need to process line by line to clean-up whitespace and append prefixes.
-    for (StringPiece line : util::tokenize(comment, '\n')) {
-        line = util::trimWhitespace(line);
-        if (!line.empty()) {
-            std::string lineCopy = line.toString();
-            appendCommentLine(lineCopy);
-        }
+void AnnotationProcessor::AppendComment(const StringPiece& comment) {
+  // We need to process line by line to clean-up whitespace and append prefixes.
+  for (StringPiece line : util::Tokenize(comment, '\n')) {
+    line = util::TrimWhitespace(line);
+    if (!line.empty()) {
+      std::string lineCopy = line.ToString();
+      AppendCommentLine(lineCopy);
     }
+  }
 }
 
-void AnnotationProcessor::appendNewLine() {
-    mComment << "\n *";
+void AnnotationProcessor::AppendNewLine() { comment_ << "\n *"; }
+
+void AnnotationProcessor::WriteToStream(std::ostream* out,
+                                        const StringPiece& prefix) const {
+  if (has_comments_) {
+    std::string result = comment_.str();
+    for (StringPiece line : util::Tokenize(result, '\n')) {
+      *out << prefix << line << "\n";
+    }
+    *out << prefix << " */"
+         << "\n";
+  }
+
+  if (annotation_bit_mask_ & kDeprecated) {
+    *out << prefix << "@Deprecated\n";
+  }
+
+  if (annotation_bit_mask_ & kSystemApi) {
+    *out << prefix << "@android.annotation.SystemApi\n";
+  }
 }
 
-void AnnotationProcessor::writeToStream(std::ostream* out, const StringPiece& prefix) const {
-    if (mHasComments) {
-        std::string result = mComment.str();
-        for (StringPiece line : util::tokenize(result, '\n')) {
-           *out << prefix << line << "\n";
-        }
-        *out << prefix << " */" << "\n";
-    }
-
-    if (mAnnotationBitMask & kDeprecated) {
-        *out << prefix << "@Deprecated\n";
-    }
-
-    if (mAnnotationBitMask & kSystemApi) {
-        *out << prefix << "@android.annotation.SystemApi\n";
-    }
-}
-
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/java/AnnotationProcessor.h b/tools/aapt2/java/AnnotationProcessor.h
index 5419608..666a7f3 100644
--- a/tools/aapt2/java/AnnotationProcessor.h
+++ b/tools/aapt2/java/AnnotationProcessor.h
@@ -17,11 +17,11 @@
 #ifndef AAPT_JAVA_ANNOTATIONPROCESSOR_H
 #define AAPT_JAVA_ANNOTATIONPROCESSOR_H
 
-#include "util/StringPiece.h"
-
 #include <sstream>
 #include <string>
 
+#include "util/StringPiece.h"
+
 namespace aapt {
 
 /**
@@ -58,15 +58,15 @@
    * configurations,
    * we need to collect all the comments.
    */
-  void appendComment(const StringPiece& comment);
+  void AppendComment(const StringPiece& comment);
 
-  void appendNewLine();
+  void AppendNewLine();
 
   /**
    * Writes the comments and annotations to the stream, with the given prefix
    * before each line.
    */
-  void writeToStream(std::ostream* out, const StringPiece& prefix) const;
+  void WriteToStream(std::ostream* out, const StringPiece& prefix) const;
 
  private:
   enum : uint32_t {
@@ -74,12 +74,12 @@
     kSystemApi = 0x02,
   };
 
-  std::stringstream mComment;
+  std::stringstream comment_;
   std::stringstream mAnnotations;
-  bool mHasComments = false;
-  uint32_t mAnnotationBitMask = 0;
+  bool has_comments_ = false;
+  uint32_t annotation_bit_mask_ = 0;
 
-  void appendCommentLine(std::string& line);
+  void AppendCommentLine(std::string& line);
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/java/AnnotationProcessor_test.cpp b/tools/aapt2/java/AnnotationProcessor_test.cpp
index 5a39add..3e43c42 100644
--- a/tools/aapt2/java/AnnotationProcessor_test.cpp
+++ b/tools/aapt2/java/AnnotationProcessor_test.cpp
@@ -15,38 +15,39 @@
  */
 
 #include "java/AnnotationProcessor.h"
+
 #include "test/Test.h"
 
 namespace aapt {
 
 TEST(AnnotationProcessorTest, EmitsDeprecated) {
-    const char* comment = "Some comment, and it should contain a marker word, "
-                          "something that marks this resource as nor needed. "
-                          "{@deprecated That's the marker! }";
+  const char* comment =
+      "Some comment, and it should contain a marker word, "
+      "something that marks this resource as nor needed. "
+      "{@deprecated That's the marker! }";
 
-    AnnotationProcessor processor;
-    processor.appendComment(comment);
+  AnnotationProcessor processor;
+  processor.AppendComment(comment);
 
-    std::stringstream result;
-    processor.writeToStream(&result, "");
-    std::string annotations = result.str();
+  std::stringstream result;
+  processor.WriteToStream(&result, "");
+  std::string annotations = result.str();
 
-    EXPECT_NE(std::string::npos, annotations.find("@Deprecated"));
+  EXPECT_NE(std::string::npos, annotations.find("@Deprecated"));
 }
 
 TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationAndRemovesFromComment) {
-    AnnotationProcessor processor;
-    processor.appendComment("@SystemApi This is a system API");
+  AnnotationProcessor processor;
+  processor.AppendComment("@SystemApi This is a system API");
 
-    std::stringstream result;
-    processor.writeToStream(&result, "");
-    std::string annotations = result.str();
+  std::stringstream result;
+  processor.WriteToStream(&result, "");
+  std::string annotations = result.str();
 
-    EXPECT_NE(std::string::npos, annotations.find("@android.annotation.SystemApi"));
-    EXPECT_EQ(std::string::npos, annotations.find("@SystemApi"));
-    EXPECT_NE(std::string::npos, annotations.find("This is a system API"));
+  EXPECT_NE(std::string::npos,
+            annotations.find("@android.annotation.SystemApi"));
+  EXPECT_EQ(std::string::npos, annotations.find("@SystemApi"));
+  EXPECT_NE(std::string::npos, annotations.find("This is a system API"));
 }
 
-} // namespace aapt
-
-
+}  // namespace aapt
diff --git a/tools/aapt2/java/ClassDefinition.cpp b/tools/aapt2/java/ClassDefinition.cpp
index 08f2c8b..f1f1f92 100644
--- a/tools/aapt2/java/ClassDefinition.cpp
+++ b/tools/aapt2/java/ClassDefinition.cpp
@@ -15,61 +15,59 @@
  */
 
 #include "java/ClassDefinition.h"
-#include "util/StringPiece.h"
 
-#include <ostream>
+#include "util/StringPiece.h"
 
 namespace aapt {
 
 bool ClassDefinition::empty() const {
-    for (const std::unique_ptr<ClassMember>& member : mMembers) {
-        if (!member->empty()) {
-            return false;
-        }
+  for (const std::unique_ptr<ClassMember>& member : members_) {
+    if (!member->empty()) {
+      return false;
     }
-    return true;
+  }
+  return true;
 }
 
-void ClassDefinition::writeToStream(const StringPiece& prefix, bool final,
+void ClassDefinition::WriteToStream(const StringPiece& prefix, bool final,
                                     std::ostream* out) const {
-    if (mMembers.empty() && !mCreateIfEmpty) {
-        return;
-    }
+  if (members_.empty() && !create_if_empty_) {
+    return;
+  }
 
-    ClassMember::writeToStream(prefix, final, out);
+  ClassMember::WriteToStream(prefix, final, out);
 
-    *out << prefix << "public ";
-    if (mQualifier == ClassQualifier::Static) {
-        *out << "static ";
-    }
-    *out << "final class " << mName << " {\n";
+  *out << prefix << "public ";
+  if (qualifier_ == ClassQualifier::Static) {
+    *out << "static ";
+  }
+  *out << "final class " << name_ << " {\n";
 
-    std::string newPrefix = prefix.toString();
-    newPrefix.append(kIndent);
+  std::string new_prefix = prefix.ToString();
+  new_prefix.append(kIndent);
 
-    for (const std::unique_ptr<ClassMember>& member : mMembers) {
-        member->writeToStream(newPrefix, final, out);
-        *out << "\n";
-    }
+  for (const std::unique_ptr<ClassMember>& member : members_) {
+    member->WriteToStream(new_prefix, final, out);
+    *out << "\n";
+  }
 
-    *out << prefix << "}";
+  *out << prefix << "}";
 }
 
 constexpr static const char* sWarningHeader =
-        "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n"
-        " *\n"
-        " * This class was automatically generated by the\n"
-        " * aapt tool from the resource data it found. It\n"
-        " * should not be modified by hand.\n"
-        " */\n\n";
+    "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n"
+    " *\n"
+    " * This class was automatically generated by the\n"
+    " * aapt tool from the resource data it found. It\n"
+    " * should not be modified by hand.\n"
+    " */\n\n";
 
-bool ClassDefinition::writeJavaFile(const ClassDefinition* def,
-                                    const StringPiece& package,
-                                    bool final,
+bool ClassDefinition::WriteJavaFile(const ClassDefinition* def,
+                                    const StringPiece& package, bool final,
                                     std::ostream* out) {
-    *out << sWarningHeader << "package " << package << ";\n\n";
-    def->writeToStream("", final, out);
-    return bool(*out);
+  *out << sWarningHeader << "package " << package << ";\n\n";
+  def->WriteToStream("", final, out);
+  return bool(*out);
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/java/ClassDefinition.h b/tools/aapt2/java/ClassDefinition.h
index bd7e7b2..d8b61d9 100644
--- a/tools/aapt2/java/ClassDefinition.h
+++ b/tools/aapt2/java/ClassDefinition.h
@@ -17,15 +17,16 @@
 #ifndef AAPT_JAVA_CLASSDEFINITION_H
 #define AAPT_JAVA_CLASSDEFINITION_H
 
+#include <ostream>
+#include <string>
+
+#include "android-base/macros.h"
+
 #include "Resource.h"
 #include "java/AnnotationProcessor.h"
 #include "util/StringPiece.h"
 #include "util/Util.h"
 
-#include <android-base/macros.h>
-#include <sstream>
-#include <string>
-
 namespace aapt {
 
 // The number of attributes to emit per line in a Styleable array.
@@ -36,38 +37,38 @@
  public:
   virtual ~ClassMember() = default;
 
-  AnnotationProcessor* getCommentBuilder() { return &mProcessor; }
+  AnnotationProcessor* GetCommentBuilder() { return &processor_; }
 
   virtual bool empty() const = 0;
 
-  virtual void writeToStream(const StringPiece& prefix, bool final,
+  virtual void WriteToStream(const StringPiece& prefix, bool final,
                              std::ostream* out) const {
-    mProcessor.writeToStream(out, prefix);
+    processor_.WriteToStream(out, prefix);
   }
 
  private:
-  AnnotationProcessor mProcessor;
+  AnnotationProcessor processor_;
 };
 
 template <typename T>
 class PrimitiveMember : public ClassMember {
  public:
   PrimitiveMember(const StringPiece& name, const T& val)
-      : mName(name.toString()), mVal(val) {}
+      : name_(name.ToString()), val_(val) {}
 
   bool empty() const override { return false; }
 
-  void writeToStream(const StringPiece& prefix, bool final,
+  void WriteToStream(const StringPiece& prefix, bool final,
                      std::ostream* out) const override {
-    ClassMember::writeToStream(prefix, final, out);
+    ClassMember::WriteToStream(prefix, final, out);
 
     *out << prefix << "public static " << (final ? "final " : "") << "int "
-         << mName << "=" << mVal << ";";
+         << name_ << "=" << val_ << ";";
   }
 
  private:
-  std::string mName;
-  T mVal;
+  std::string name_;
+  T val_;
 
   DISALLOW_COPY_AND_ASSIGN(PrimitiveMember);
 };
@@ -79,21 +80,21 @@
 class PrimitiveMember<std::string> : public ClassMember {
  public:
   PrimitiveMember(const StringPiece& name, const std::string& val)
-      : mName(name.toString()), mVal(val) {}
+      : name_(name.ToString()), val_(val) {}
 
   bool empty() const override { return false; }
 
-  void writeToStream(const StringPiece& prefix, bool final,
+  void WriteToStream(const StringPiece& prefix, bool final,
                      std::ostream* out) const override {
-    ClassMember::writeToStream(prefix, final, out);
+    ClassMember::WriteToStream(prefix, final, out);
 
     *out << prefix << "public static " << (final ? "final " : "") << "String "
-         << mName << "=\"" << mVal << "\";";
+         << name_ << "=\"" << val_ << "\";";
   }
 
  private:
-  std::string mName;
-  std::string mVal;
+  std::string name_;
+  std::string val_;
 
   DISALLOW_COPY_AND_ASSIGN(PrimitiveMember);
 };
@@ -106,20 +107,20 @@
 class PrimitiveArrayMember : public ClassMember {
  public:
   explicit PrimitiveArrayMember(const StringPiece& name)
-      : mName(name.toString()) {}
+      : name_(name.ToString()) {}
 
-  void addElement(const T& val) { mElements.push_back(val); }
+  void AddElement(const T& val) { elements_.push_back(val); }
 
   bool empty() const override { return false; }
 
-  void writeToStream(const StringPiece& prefix, bool final,
+  void WriteToStream(const StringPiece& prefix, bool final,
                      std::ostream* out) const override {
-    ClassMember::writeToStream(prefix, final, out);
+    ClassMember::WriteToStream(prefix, final, out);
 
-    *out << prefix << "public static final int[] " << mName << "={";
+    *out << prefix << "public static final int[] " << name_ << "={";
 
-    const auto begin = mElements.begin();
-    const auto end = mElements.end();
+    const auto begin = elements_.begin();
+    const auto end = elements_.end();
     for (auto current = begin; current != end; ++current) {
       if (std::distance(begin, current) % kAttribsPerLine == 0) {
         *out << "\n" << prefix << kIndent << kIndent;
@@ -134,8 +135,8 @@
   }
 
  private:
-  std::string mName;
-  std::vector<T> mElements;
+  std::string name_;
+  std::vector<T> elements_;
 
   DISALLOW_COPY_AND_ASSIGN(PrimitiveArrayMember);
 };
@@ -146,29 +147,29 @@
 
 class ClassDefinition : public ClassMember {
  public:
-  static bool writeJavaFile(const ClassDefinition* def,
+  static bool WriteJavaFile(const ClassDefinition* def,
                             const StringPiece& package, bool final,
                             std::ostream* out);
 
   ClassDefinition(const StringPiece& name, ClassQualifier qualifier,
                   bool createIfEmpty)
-      : mName(name.toString()),
-        mQualifier(qualifier),
-        mCreateIfEmpty(createIfEmpty) {}
+      : name_(name.ToString()),
+        qualifier_(qualifier),
+        create_if_empty_(createIfEmpty) {}
 
-  void addMember(std::unique_ptr<ClassMember> member) {
-    mMembers.push_back(std::move(member));
+  void AddMember(std::unique_ptr<ClassMember> member) {
+    members_.push_back(std::move(member));
   }
 
   bool empty() const override;
-  void writeToStream(const StringPiece& prefix, bool final,
+  void WriteToStream(const StringPiece& prefix, bool final,
                      std::ostream* out) const override;
 
  private:
-  std::string mName;
-  ClassQualifier mQualifier;
-  bool mCreateIfEmpty;
-  std::vector<std::unique_ptr<ClassMember>> mMembers;
+  std::string name_;
+  ClassQualifier qualifier_;
+  bool create_if_empty_;
+  std::vector<std::unique_ptr<ClassMember>> members_;
 
   DISALLOW_COPY_AND_ASSIGN(ClassDefinition);
 };
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index fbaefb1..6e7c7078 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -14,16 +14,7 @@
  * limitations under the License.
  */
 
-#include "NameMangler.h"
-#include "Resource.h"
-#include "ResourceTable.h"
-#include "ResourceValues.h"
-#include "ValueVisitor.h"
-#include "java/AnnotationProcessor.h"
-#include "java/ClassDefinition.h"
 #include "java/JavaClassGenerator.h"
-#include "process/SymbolTable.h"
-#include "util/StringPiece.h"
 
 #include <algorithm>
 #include <ostream>
@@ -31,42 +22,49 @@
 #include <sstream>
 #include <tuple>
 
+#include "android-base/logging.h"
+
+#include "NameMangler.h"
+#include "Resource.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "ValueVisitor.h"
+#include "java/AnnotationProcessor.h"
+#include "java/ClassDefinition.h"
+#include "process/SymbolTable.h"
+#include "util/StringPiece.h"
+
 namespace aapt {
 
-JavaClassGenerator::JavaClassGenerator(IAaptContext* context, ResourceTable* table,
-                                       const JavaClassGeneratorOptions& options) :
-        mContext(context), mTable(table), mOptions(options) {
-}
-
 static const std::set<StringPiece> sJavaIdentifiers = {
-    "abstract", "assert", "boolean", "break", "byte",
-    "case", "catch", "char", "class", "const", "continue",
-    "default", "do", "double", "else", "enum", "extends",
-    "final", "finally", "float", "for", "goto", "if",
-    "implements", "import", "instanceof", "int", "interface",
-    "long", "native", "new", "package", "private", "protected",
-    "public", "return", "short", "static", "strictfp", "super",
-    "switch", "synchronized", "this", "throw", "throws",
-    "transient", "try", "void", "volatile", "while", "true",
-    "false", "null"
-};
+    "abstract",   "assert",       "boolean",   "break",      "byte",
+    "case",       "catch",        "char",      "class",      "const",
+    "continue",   "default",      "do",        "double",     "else",
+    "enum",       "extends",      "final",     "finally",    "float",
+    "for",        "goto",         "if",        "implements", "import",
+    "instanceof", "int",          "interface", "long",       "native",
+    "new",        "package",      "private",   "protected",  "public",
+    "return",     "short",        "static",    "strictfp",   "super",
+    "switch",     "synchronized", "this",      "throw",      "throws",
+    "transient",  "try",          "void",      "volatile",   "while",
+    "true",       "false",        "null"};
 
-static bool isValidSymbol(const StringPiece& symbol) {
-    return sJavaIdentifiers.find(symbol) == sJavaIdentifiers.end();
+static bool IsValidSymbol(const StringPiece& symbol) {
+  return sJavaIdentifiers.find(symbol) == sJavaIdentifiers.end();
 }
 
 /*
  * Java symbols can not contain . or -, but those are valid in a resource name.
  * Replace those with '_'.
  */
-static std::string transform(const StringPiece& symbol) {
-    std::string output = symbol.toString();
-    for (char& c : output) {
-        if (c == '.' || c == '-') {
-            c = '_';
-        }
+static std::string Transform(const StringPiece& symbol) {
+  std::string output = symbol.ToString();
+  for (char& c : output) {
+    if (c == '.' || c == '-') {
+      c = '_';
     }
-    return output;
+  }
+  return output;
 }
 
 /**
@@ -80,475 +78,519 @@
  * Foo_android_bar
  * Foo_bar
  */
-static std::string transformNestedAttr(const ResourceNameRef& attrName,
-                                       const std::string& styleableClassName,
-                                       const StringPiece& packageNameToGenerate) {
-    std::string output = styleableClassName;
+static std::string TransformNestedAttr(
+    const ResourceNameRef& attr_name, const std::string& styleable_class_name,
+    const StringPiece& package_name_to_generate) {
+  std::string output = styleable_class_name;
 
-    // We may reference IDs from other packages, so prefix the entry name with
-    // the package.
-    if (!attrName.package.empty() && packageNameToGenerate != attrName.package) {
-        output += "_" + transform(attrName.package);
-    }
-    output += "_" + transform(attrName.entry);
-    return output;
+  // We may reference IDs from other packages, so prefix the entry name with
+  // the package.
+  if (!attr_name.package.empty() &&
+      package_name_to_generate != attr_name.package) {
+    output += "_" + Transform(attr_name.package);
+  }
+  output += "_" + Transform(attr_name.entry);
+  return output;
 }
 
-static void addAttributeFormatDoc(AnnotationProcessor* processor, Attribute* attr) {
-    const uint32_t typeMask = attr->typeMask;
-    if (typeMask & android::ResTable_map::TYPE_REFERENCE) {
-        processor->appendComment(
-                "<p>May be a reference to another resource, in the form\n"
-                "\"<code>@[+][<i>package</i>:]<i>type</i>/<i>name</i></code>\" or a theme\n"
-                "attribute in the form\n"
-                "\"<code>?[<i>package</i>:]<i>type</i>/<i>name</i></code>\".");
+static void AddAttributeFormatDoc(AnnotationProcessor* processor,
+                                  Attribute* attr) {
+  const uint32_t type_mask = attr->type_mask;
+  if (type_mask & android::ResTable_map::TYPE_REFERENCE) {
+    processor->AppendComment(
+        "<p>May be a reference to another resource, in the form\n"
+        "\"<code>@[+][<i>package</i>:]<i>type</i>/<i>name</i></code>\" or a "
+        "theme\n"
+        "attribute in the form\n"
+        "\"<code>?[<i>package</i>:]<i>type</i>/<i>name</i></code>\".");
+  }
+
+  if (type_mask & android::ResTable_map::TYPE_STRING) {
+    processor->AppendComment(
+        "<p>May be a string value, using '\\\\;' to escape characters such as\n"
+        "'\\\\n' or '\\\\uxxxx' for a unicode character;");
+  }
+
+  if (type_mask & android::ResTable_map::TYPE_INTEGER) {
+    processor->AppendComment(
+        "<p>May be an integer value, such as \"<code>100</code>\".");
+  }
+
+  if (type_mask & android::ResTable_map::TYPE_BOOLEAN) {
+    processor->AppendComment(
+        "<p>May be a boolean value, such as \"<code>true</code>\" or\n"
+        "\"<code>false</code>\".");
+  }
+
+  if (type_mask & android::ResTable_map::TYPE_COLOR) {
+    processor->AppendComment(
+        "<p>May be a color value, in the form of "
+        "\"<code>#<i>rgb</i></code>\",\n"
+        "\"<code>#<i>argb</i></code>\", \"<code>#<i>rrggbb</i></code\", or \n"
+        "\"<code>#<i>aarrggbb</i></code>\".");
+  }
+
+  if (type_mask & android::ResTable_map::TYPE_FLOAT) {
+    processor->AppendComment(
+        "<p>May be a floating point value, such as \"<code>1.2</code>\".");
+  }
+
+  if (type_mask & android::ResTable_map::TYPE_DIMENSION) {
+    processor->AppendComment(
+        "<p>May be a dimension value, which is a floating point number "
+        "appended with a\n"
+        "unit such as \"<code>14.5sp</code>\".\n"
+        "Available units are: px (pixels), dp (density-independent pixels),\n"
+        "sp (scaled pixels based on preferred font size), in (inches), and\n"
+        "mm (millimeters).");
+  }
+
+  if (type_mask & android::ResTable_map::TYPE_FRACTION) {
+    processor->AppendComment(
+        "<p>May be a fractional value, which is a floating point number "
+        "appended with\n"
+        "either % or %p, such as \"<code>14.5%</code>\".\n"
+        "The % suffix always means a percentage of the base size;\n"
+        "the optional %p suffix provides a size relative to some parent "
+        "container.");
+  }
+
+  if (type_mask &
+      (android::ResTable_map::TYPE_FLAGS | android::ResTable_map::TYPE_ENUM)) {
+    if (type_mask & android::ResTable_map::TYPE_FLAGS) {
+      processor->AppendComment(
+          "<p>Must be one or more (separated by '|') of the following "
+          "constant values.</p>");
+    } else {
+      processor->AppendComment(
+          "<p>Must be one of the following constant values.</p>");
     }
 
-    if (typeMask & android::ResTable_map::TYPE_STRING) {
-        processor->appendComment(
-                "<p>May be a string value, using '\\\\;' to escape characters such as\n"
-                "'\\\\n' or '\\\\uxxxx' for a unicode character;");
+    processor->AppendComment(
+        "<table>\n<colgroup align=\"left\" />\n"
+        "<colgroup align=\"left\" />\n"
+        "<colgroup align=\"left\" />\n"
+        "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>\n");
+    for (const Attribute::Symbol& symbol : attr->symbols) {
+      std::stringstream line;
+      line << "<tr><td>" << symbol.symbol.name.value().entry << "</td>"
+           << "<td>" << std::hex << symbol.value << std::dec << "</td>"
+           << "<td>" << util::TrimWhitespace(symbol.symbol.GetComment())
+           << "</td></tr>";
+      processor->AppendComment(line.str());
     }
-
-    if (typeMask & android::ResTable_map::TYPE_INTEGER) {
-        processor->appendComment("<p>May be an integer value, such as \"<code>100</code>\".");
-    }
-
-    if (typeMask & android::ResTable_map::TYPE_BOOLEAN) {
-        processor->appendComment(
-                "<p>May be a boolean value, such as \"<code>true</code>\" or\n"
-                "\"<code>false</code>\".");
-    }
-
-    if (typeMask & android::ResTable_map::TYPE_COLOR) {
-        processor->appendComment(
-                "<p>May be a color value, in the form of \"<code>#<i>rgb</i></code>\",\n"
-                "\"<code>#<i>argb</i></code>\", \"<code>#<i>rrggbb</i></code\", or \n"
-                "\"<code>#<i>aarrggbb</i></code>\".");
-    }
-
-    if (typeMask & android::ResTable_map::TYPE_FLOAT) {
-        processor->appendComment(
-                "<p>May be a floating point value, such as \"<code>1.2</code>\".");
-    }
-
-    if (typeMask & android::ResTable_map::TYPE_DIMENSION) {
-        processor->appendComment(
-                "<p>May be a dimension value, which is a floating point number appended with a\n"
-                "unit such as \"<code>14.5sp</code>\".\n"
-                "Available units are: px (pixels), dp (density-independent pixels),\n"
-                "sp (scaled pixels based on preferred font size), in (inches), and\n"
-                "mm (millimeters).");
-    }
-
-    if (typeMask & android::ResTable_map::TYPE_FRACTION) {
-        processor->appendComment(
-                "<p>May be a fractional value, which is a floating point number appended with\n"
-                "either % or %p, such as \"<code>14.5%</code>\".\n"
-                "The % suffix always means a percentage of the base size;\n"
-                "the optional %p suffix provides a size relative to some parent container.");
-    }
-
-    if (typeMask & (android::ResTable_map::TYPE_FLAGS | android::ResTable_map::TYPE_ENUM)) {
-        if (typeMask & android::ResTable_map::TYPE_FLAGS) {
-            processor->appendComment(
-                    "<p>Must be one or more (separated by '|') of the following "
-                    "constant values.</p>");
-        } else {
-            processor->appendComment("<p>Must be one of the following constant values.</p>");
-        }
-
-        processor->appendComment("<table>\n<colgroup align=\"left\" />\n"
-                                 "<colgroup align=\"left\" />\n"
-                                 "<colgroup align=\"left\" />\n"
-                                 "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>\n");
-        for (const Attribute::Symbol& symbol : attr->symbols) {
-            std::stringstream line;
-            line << "<tr><td>" << symbol.symbol.name.value().entry << "</td>"
-            << "<td>" << std::hex << symbol.value << std::dec << "</td>"
-            << "<td>" << util::trimWhitespace(symbol.symbol.getComment()) << "</td></tr>";
-            processor->appendComment(line.str());
-        }
-        processor->appendComment("</table>");
-    }
+    processor->AppendComment("</table>");
+  }
 }
 
-bool JavaClassGenerator::skipSymbol(SymbolState state) {
-    switch (mOptions.types) {
+JavaClassGenerator::JavaClassGenerator(IAaptContext* context,
+                                       ResourceTable* table,
+                                       const JavaClassGeneratorOptions& options)
+    : context_(context), table_(table), options_(options) {}
+
+bool JavaClassGenerator::SkipSymbol(SymbolState state) {
+  switch (options_.types) {
     case JavaClassGeneratorOptions::SymbolTypes::kAll:
-        return false;
+      return false;
     case JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate:
-        return state == SymbolState::kUndefined;
+      return state == SymbolState::kUndefined;
     case JavaClassGeneratorOptions::SymbolTypes::kPublic:
-        return state != SymbolState::kPublic;
-    }
-    return true;
+      return state != SymbolState::kPublic;
+  }
+  return true;
 }
 
 struct StyleableAttr {
-    const Reference* attrRef;
-    std::string fieldName;
-    std::unique_ptr<SymbolTable::Symbol> symbol;
+  const Reference* attr_ref;
+  std::string field_name;
+  std::unique_ptr<SymbolTable::Symbol> symbol;
 };
 
-static bool lessStyleableAttr(const StyleableAttr& lhs, const StyleableAttr& rhs) {
-    const ResourceId lhsId = lhs.attrRef->id ? lhs.attrRef->id.value() : ResourceId(0);
-    const ResourceId rhsId = rhs.attrRef->id ? rhs.attrRef->id.value() : ResourceId(0);
-    if (lhsId < rhsId) {
-        return true;
-    } else if (lhsId > rhsId) {
-        return false;
+static bool less_styleable_attr(const StyleableAttr& lhs,
+                                const StyleableAttr& rhs) {
+  const ResourceId lhs_id =
+      lhs.attr_ref->id ? lhs.attr_ref->id.value() : ResourceId(0);
+  const ResourceId rhs_id =
+      rhs.attr_ref->id ? rhs.attr_ref->id.value() : ResourceId(0);
+  if (lhs_id < rhs_id) {
+    return true;
+  } else if (lhs_id > rhs_id) {
+    return false;
+  } else {
+    return lhs.attr_ref->name.value() < rhs.attr_ref->name.value();
+  }
+}
+
+void JavaClassGenerator::AddMembersToStyleableClass(
+    const StringPiece& package_name_to_generate, const std::string& entry_name,
+    const Styleable* styleable, ClassDefinition* out_styleable_class_def) {
+  const std::string class_name = Transform(entry_name);
+
+  std::unique_ptr<ResourceArrayMember> styleable_array_def =
+      util::make_unique<ResourceArrayMember>(class_name);
+
+  // This must be sorted by resource ID.
+  std::vector<StyleableAttr> sorted_attributes;
+  sorted_attributes.reserve(styleable->entries.size());
+  for (const auto& attr : styleable->entries) {
+    // If we are not encoding final attributes, the styleable entry may have no
+    // ID if we are building a static library.
+    CHECK(!options_.use_final || attr.id) << "no ID set for Styleable entry";
+    CHECK(bool(attr.name)) << "no name set for Styleable entry";
+
+    // We will need the unmangled, transformed name in the comments and the
+    // field,
+    // so create it once and cache it in this StyleableAttr data structure.
+    StyleableAttr styleable_attr = {};
+    styleable_attr.attr_ref = &attr;
+    styleable_attr.field_name = TransformNestedAttr(
+        attr.name.value(), class_name, package_name_to_generate);
+
+    Reference mangled_reference;
+    mangled_reference.id = attr.id;
+    mangled_reference.name = attr.name;
+    if (mangled_reference.name.value().package.empty()) {
+      mangled_reference.name.value().package =
+          context_->GetCompilationPackage();
+    }
+
+    if (Maybe<ResourceName> mangled_name =
+            context_->GetNameMangler()->MangleName(
+                mangled_reference.name.value())) {
+      mangled_reference.name = mangled_name;
+    }
+
+    // Look up the symbol so that we can write out in the comments what are
+    // possible
+    // legal values for this attribute.
+    const SymbolTable::Symbol* symbol =
+        context_->GetExternalSymbols()->FindByReference(mangled_reference);
+    if (symbol && symbol->attribute) {
+      // Copy the symbol data structure because the returned instance can be
+      // destroyed.
+      styleable_attr.symbol = util::make_unique<SymbolTable::Symbol>(*symbol);
+    }
+    sorted_attributes.push_back(std::move(styleable_attr));
+  }
+
+  // Sort the attributes by ID.
+  std::sort(sorted_attributes.begin(), sorted_attributes.end(),
+            less_styleable_attr);
+
+  const size_t attr_count = sorted_attributes.size();
+  if (attr_count > 0) {
+    // Build the comment string for the Styleable. It includes details about the
+    // child attributes.
+    std::stringstream styleable_comment;
+    if (!styleable->GetComment().empty()) {
+      styleable_comment << styleable->GetComment() << "\n";
     } else {
-        return lhs.attrRef->name.value() < rhs.attrRef->name.value();
+      styleable_comment << "Attributes that can be used with a " << class_name
+                        << ".\n";
     }
+
+    styleable_comment << "<p>Includes the following attributes:</p>\n"
+                         "<table>\n"
+                         "<colgroup align=\"left\" />\n"
+                         "<colgroup align=\"left\" />\n"
+                         "<tr><th>Attribute</th><th>Description</th></tr>\n";
+
+    for (const StyleableAttr& entry : sorted_attributes) {
+      if (!entry.symbol) {
+        continue;
+      }
+
+      if (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic &&
+          !entry.symbol->is_public) {
+        // Don't write entries for non-public attributes.
+        continue;
+      }
+
+      StringPiece attr_comment_line = entry.symbol->attribute->GetComment();
+      if (attr_comment_line.contains("@removed")) {
+        // Removed attributes are public but hidden from the documentation, so
+        // don't emit
+        // them as part of the class documentation.
+        continue;
+      }
+
+      const ResourceName& attr_name = entry.attr_ref->name.value();
+      styleable_comment << "<tr><td>";
+      styleable_comment << "<code>{@link #" << entry.field_name << " "
+                        << (!attr_name.package.empty()
+                                ? attr_name.package
+                                : context_->GetCompilationPackage())
+                        << ":" << attr_name.entry << "}</code>";
+      styleable_comment << "</td>";
+
+      styleable_comment << "<td>";
+
+      // Only use the comment up until the first '.'. This is to stay compatible
+      // with
+      // the way old AAPT did it (presumably to keep it short and to avoid
+      // including
+      // annotations like @hide which would affect this Styleable).
+      auto iter =
+          std::find(attr_comment_line.begin(), attr_comment_line.end(), u'.');
+      if (iter != attr_comment_line.end()) {
+        attr_comment_line =
+            attr_comment_line.substr(0, (iter - attr_comment_line.begin()) + 1);
+      }
+      styleable_comment << attr_comment_line << "</td></tr>\n";
+    }
+    styleable_comment << "</table>\n";
+
+    for (const StyleableAttr& entry : sorted_attributes) {
+      if (!entry.symbol) {
+        continue;
+      }
+
+      if (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic &&
+          !entry.symbol->is_public) {
+        // Don't write entries for non-public attributes.
+        continue;
+      }
+      styleable_comment << "@see #" << entry.field_name << "\n";
+    }
+
+    styleable_array_def->GetCommentBuilder()->AppendComment(
+        styleable_comment.str());
+  }
+
+  // Add the ResourceIds to the array member.
+  for (const StyleableAttr& styleable_attr : sorted_attributes) {
+    styleable_array_def->AddElement(styleable_attr.attr_ref->id
+                                        ? styleable_attr.attr_ref->id.value()
+                                        : ResourceId(0));
+  }
+
+  // Add the Styleable array to the Styleable class.
+  out_styleable_class_def->AddMember(std::move(styleable_array_def));
+
+  // Now we emit the indices into the array.
+  for (size_t i = 0; i < attr_count; i++) {
+    const StyleableAttr& styleable_attr = sorted_attributes[i];
+
+    if (!styleable_attr.symbol) {
+      continue;
+    }
+
+    if (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic &&
+        !styleable_attr.symbol->is_public) {
+      // Don't write entries for non-public attributes.
+      continue;
+    }
+
+    StringPiece comment = styleable_attr.attr_ref->GetComment();
+    if (styleable_attr.symbol->attribute && comment.empty()) {
+      comment = styleable_attr.symbol->attribute->GetComment();
+    }
+
+    if (comment.contains("@removed")) {
+      // Removed attributes are public but hidden from the documentation, so
+      // don't emit them
+      // as part of the class documentation.
+      continue;
+    }
+
+    const ResourceName& attr_name = styleable_attr.attr_ref->name.value();
+
+    StringPiece package_name = attr_name.package;
+    if (package_name.empty()) {
+      package_name = context_->GetCompilationPackage();
+    }
+
+    std::unique_ptr<IntMember> index_member = util::make_unique<IntMember>(
+        sorted_attributes[i].field_name, static_cast<uint32_t>(i));
+
+    AnnotationProcessor* attr_processor = index_member->GetCommentBuilder();
+
+    if (!comment.empty()) {
+      attr_processor->AppendComment("<p>\n@attr description");
+      attr_processor->AppendComment(comment);
+    } else {
+      std::stringstream default_comment;
+      default_comment << "<p>This symbol is the offset where the "
+                      << "{@link " << package_name << ".R.attr#"
+                      << Transform(attr_name.entry) << "}\n"
+                      << "attribute's value can be found in the "
+                      << "{@link #" << class_name << "} array.";
+      attr_processor->AppendComment(default_comment.str());
+    }
+
+    attr_processor->AppendNewLine();
+
+    AddAttributeFormatDoc(attr_processor,
+                          styleable_attr.symbol->attribute.get());
+    attr_processor->AppendNewLine();
+
+    std::stringstream doclava_name;
+    doclava_name << "@attr name " << package_name << ":" << attr_name.entry;
+
+    attr_processor->AppendComment(doclava_name.str());
+
+    out_styleable_class_def->AddMember(std::move(index_member));
+  }
 }
 
-void JavaClassGenerator::addMembersToStyleableClass(const StringPiece& packageNameToGenerate,
-                                                    const std::string& entryName,
-                                                    const Styleable* styleable,
-                                                    ClassDefinition* outStyleableClassDef) {
-    const std::string className = transform(entryName);
-
-    std::unique_ptr<ResourceArrayMember> styleableArrayDef =
-            util::make_unique<ResourceArrayMember>(className);
-
-    // This must be sorted by resource ID.
-    std::vector<StyleableAttr> sortedAttributes;
-    sortedAttributes.reserve(styleable->entries.size());
-    for (const auto& attr : styleable->entries) {
-        // If we are not encoding final attributes, the styleable entry may have no ID
-        // if we are building a static library.
-        assert((!mOptions.useFinal || attr.id) && "no ID set for Styleable entry");
-        assert(attr.name && "no name set for Styleable entry");
-
-        // We will need the unmangled, transformed name in the comments and the field,
-        // so create it once and cache it in this StyleableAttr data structure.
-        StyleableAttr styleableAttr = {};
-        styleableAttr.attrRef = &attr;
-        styleableAttr.fieldName = transformNestedAttr(attr.name.value(), className,
-                                                      packageNameToGenerate);
-
-        Reference mangledReference;
-        mangledReference.id = attr.id;
-        mangledReference.name = attr.name;
-        if (mangledReference.name.value().package.empty()) {
-            mangledReference.name.value().package = mContext->getCompilationPackage();
-        }
-
-        if (Maybe<ResourceName> mangledName =
-                mContext->getNameMangler()->mangleName(mangledReference.name.value())) {
-            mangledReference.name = mangledName;
-        }
-
-        // Look up the symbol so that we can write out in the comments what are possible
-        // legal values for this attribute.
-        const SymbolTable::Symbol* symbol = mContext->getExternalSymbols()->findByReference(
-                mangledReference);
-        if (symbol && symbol->attribute) {
-            // Copy the symbol data structure because the returned instance can be destroyed.
-            styleableAttr.symbol = util::make_unique<SymbolTable::Symbol>(*symbol);
-        }
-        sortedAttributes.push_back(std::move(styleableAttr));
+bool JavaClassGenerator::AddMembersToTypeClass(
+    const StringPiece& package_name_to_generate,
+    const ResourceTablePackage* package, const ResourceTableType* type,
+    ClassDefinition* out_type_class_def) {
+  for (const auto& entry : type->entries) {
+    if (SkipSymbol(entry->symbol_status.state)) {
+      continue;
     }
 
-    // Sort the attributes by ID.
-    std::sort(sortedAttributes.begin(), sortedAttributes.end(), lessStyleableAttr);
-
-    const size_t attrCount = sortedAttributes.size();
-    if (attrCount > 0) {
-        // Build the comment string for the Styleable. It includes details about the
-        // child attributes.
-        std::stringstream styleableComment;
-        if (!styleable->getComment().empty()) {
-            styleableComment << styleable->getComment() << "\n";
-        } else {
-            styleableComment << "Attributes that can be used with a " << className << ".\n";
-        }
-
-        styleableComment <<
-                "<p>Includes the following attributes:</p>\n"
-                "<table>\n"
-                "<colgroup align=\"left\" />\n"
-                "<colgroup align=\"left\" />\n"
-                "<tr><th>Attribute</th><th>Description</th></tr>\n";
-
-        for (const StyleableAttr& entry : sortedAttributes) {
-            if (!entry.symbol) {
-                continue;
-            }
-
-            if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic &&
-                    !entry.symbol->isPublic) {
-                // Don't write entries for non-public attributes.
-                continue;
-            }
-
-            StringPiece attrCommentLine = entry.symbol->attribute->getComment();
-            if (attrCommentLine.contains("@removed")) {
-                // Removed attributes are public but hidden from the documentation, so don't emit
-                // them as part of the class documentation.
-                continue;
-            }
-
-            const ResourceName& attrName = entry.attrRef->name.value();
-            styleableComment << "<tr><td>";
-            styleableComment << "<code>{@link #"
-                             << entry.fieldName << " "
-                             << (!attrName.package.empty()
-                                    ? attrName.package : mContext->getCompilationPackage())
-                             << ":" << attrName.entry
-                             << "}</code>";
-            styleableComment << "</td>";
-
-            styleableComment << "<td>";
-
-            // Only use the comment up until the first '.'. This is to stay compatible with
-            // the way old AAPT did it (presumably to keep it short and to avoid including
-            // annotations like @hide which would affect this Styleable).
-            auto iter = std::find(attrCommentLine.begin(), attrCommentLine.end(), u'.');
-            if (iter != attrCommentLine.end()) {
-                attrCommentLine = attrCommentLine.substr(
-                        0, (iter - attrCommentLine.begin()) + 1);
-            }
-            styleableComment << attrCommentLine << "</td></tr>\n";
-        }
-        styleableComment << "</table>\n";
-
-        for (const StyleableAttr& entry : sortedAttributes) {
-            if (!entry.symbol) {
-                continue;
-            }
-
-            if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic &&
-                    !entry.symbol->isPublic) {
-                // Don't write entries for non-public attributes.
-                continue;
-            }
-            styleableComment << "@see #" << entry.fieldName << "\n";
-        }
-
-        styleableArrayDef->getCommentBuilder()->appendComment(styleableComment.str());
+    ResourceId id;
+    if (package->id && type->id && entry->id) {
+      id = ResourceId(package->id.value(), type->id.value(), entry->id.value());
     }
 
-    // Add the ResourceIds to the array member.
-    for (const StyleableAttr& styleableAttr : sortedAttributes) {
-        styleableArrayDef->addElement(
-                styleableAttr.attrRef->id ? styleableAttr.attrRef->id.value() : ResourceId(0));
+    std::string unmangled_package;
+    std::string unmangled_name = entry->name;
+    if (NameMangler::Unmangle(&unmangled_name, &unmangled_package)) {
+      // The entry name was mangled, and we successfully unmangled it.
+      // Check that we want to emit this symbol.
+      if (package->name != unmangled_package) {
+        // Skip the entry if it doesn't belong to the package we're writing.
+        continue;
+      }
+    } else if (package_name_to_generate != package->name) {
+      // We are processing a mangled package name,
+      // but this is a non-mangled resource.
+      continue;
     }
 
-    // Add the Styleable array to the Styleable class.
-    outStyleableClassDef->addMember(std::move(styleableArrayDef));
-
-    // Now we emit the indices into the array.
-    for (size_t i = 0; i < attrCount; i++) {
-        const StyleableAttr& styleableAttr = sortedAttributes[i];
-
-        if (!styleableAttr.symbol) {
-            continue;
-        }
-
-        if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic &&
-                !styleableAttr.symbol->isPublic) {
-            // Don't write entries for non-public attributes.
-            continue;
-        }
-
-        StringPiece comment = styleableAttr.attrRef->getComment();
-        if (styleableAttr.symbol->attribute && comment.empty()) {
-            comment = styleableAttr.symbol->attribute->getComment();
-        }
-
-        if (comment.contains("@removed")) {
-            // Removed attributes are public but hidden from the documentation, so don't emit them
-            // as part of the class documentation.
-            continue;
-        }
-
-        const ResourceName& attrName = styleableAttr.attrRef->name.value();
-
-        StringPiece packageName = attrName.package;
-        if (packageName.empty()) {
-            packageName = mContext->getCompilationPackage();
-        }
-
-        std::unique_ptr<IntMember> indexMember = util::make_unique<IntMember>(
-                sortedAttributes[i].fieldName, static_cast<uint32_t>(i));
-
-        AnnotationProcessor* attrProcessor = indexMember->getCommentBuilder();
-
-        if (!comment.empty()) {
-            attrProcessor->appendComment("<p>\n@attr description");
-            attrProcessor->appendComment(comment);
-        } else {
-            std::stringstream defaultComment;
-            defaultComment
-                    << "<p>This symbol is the offset where the "
-                    << "{@link " << packageName << ".R.attr#" << transform(attrName.entry) << "}\n"
-                    << "attribute's value can be found in the "
-                    << "{@link #" << className << "} array.";
-            attrProcessor->appendComment(defaultComment.str());
-        }
-
-        attrProcessor->appendNewLine();
-
-        addAttributeFormatDoc(attrProcessor, styleableAttr.symbol->attribute.get());
-        attrProcessor->appendNewLine();
-
-        std::stringstream doclavaName;
-        doclavaName << "@attr name " << packageName << ":" << attrName.entry;;
-        attrProcessor->appendComment(doclavaName.str());
-
-        outStyleableClassDef->addMember(std::move(indexMember));
+    if (!IsValidSymbol(unmangled_name)) {
+      ResourceNameRef resource_name(package_name_to_generate, type->type,
+                                    unmangled_name);
+      std::stringstream err;
+      err << "invalid symbol name '" << resource_name << "'";
+      error_ = err.str();
+      return false;
     }
+
+    if (type->type == ResourceType::kStyleable) {
+      CHECK(!entry->values.empty());
+
+      const Styleable* styleable =
+          static_cast<const Styleable*>(entry->values.front()->value.get());
+
+      // Comments are handled within this method.
+      AddMembersToStyleableClass(package_name_to_generate, unmangled_name,
+                                 styleable, out_type_class_def);
+    } else {
+      std::unique_ptr<ResourceMember> resource_member =
+          util::make_unique<ResourceMember>(Transform(unmangled_name), id);
+
+      // Build the comments and annotations for this entry.
+      AnnotationProcessor* processor = resource_member->GetCommentBuilder();
+
+      // Add the comments from any <public> tags.
+      if (entry->symbol_status.state != SymbolState::kUndefined) {
+        processor->AppendComment(entry->symbol_status.comment);
+      }
+
+      // Add the comments from all configurations of this entry.
+      for (const auto& config_value : entry->values) {
+        processor->AppendComment(config_value->value->GetComment());
+      }
+
+      // If this is an Attribute, append the format Javadoc.
+      if (!entry->values.empty()) {
+        if (Attribute* attr =
+                ValueCast<Attribute>(entry->values.front()->value.get())) {
+          // We list out the available values for the given attribute.
+          AddAttributeFormatDoc(processor, attr);
+        }
+      }
+
+      out_type_class_def->AddMember(std::move(resource_member));
+    }
+  }
+  return true;
 }
 
-bool JavaClassGenerator::addMembersToTypeClass(const StringPiece& packageNameToGenerate,
-                                               const ResourceTablePackage* package,
-                                               const ResourceTableType* type,
-                                               ClassDefinition* outTypeClassDef) {
-
-    for (const auto& entry : type->entries) {
-        if (skipSymbol(entry->symbolStatus.state)) {
-            continue;
-        }
-
-        ResourceId id;
-        if (package->id && type->id && entry->id) {
-            id = ResourceId(package->id.value(), type->id.value(), entry->id.value());
-        }
-
-        std::string unmangledPackage;
-        std::string unmangledName = entry->name;
-        if (NameMangler::unmangle(&unmangledName, &unmangledPackage)) {
-            // The entry name was mangled, and we successfully unmangled it.
-            // Check that we want to emit this symbol.
-            if (package->name != unmangledPackage) {
-                // Skip the entry if it doesn't belong to the package we're writing.
-                continue;
-            }
-        } else if (packageNameToGenerate != package->name) {
-            // We are processing a mangled package name,
-            // but this is a non-mangled resource.
-            continue;
-        }
-
-        if (!isValidSymbol(unmangledName)) {
-            ResourceNameRef resourceName(packageNameToGenerate, type->type, unmangledName);
-            std::stringstream err;
-            err << "invalid symbol name '" << resourceName << "'";
-            mError = err.str();
-            return false;
-        }
-
-        if (type->type == ResourceType::kStyleable) {
-            assert(!entry->values.empty());
-
-            const Styleable* styleable = static_cast<const Styleable*>(
-                    entry->values.front()->value.get());
-
-            // Comments are handled within this method.
-            addMembersToStyleableClass(packageNameToGenerate, unmangledName, styleable,
-                                       outTypeClassDef);
-        } else {
-            std::unique_ptr<ResourceMember> resourceMember =
-                    util::make_unique<ResourceMember>(transform(unmangledName), id);
-
-            // Build the comments and annotations for this entry.
-            AnnotationProcessor* processor = resourceMember->getCommentBuilder();
-
-            // Add the comments from any <public> tags.
-            if (entry->symbolStatus.state != SymbolState::kUndefined) {
-                processor->appendComment(entry->symbolStatus.comment);
-            }
-
-            // Add the comments from all configurations of this entry.
-            for (const auto& configValue : entry->values) {
-                processor->appendComment(configValue->value->getComment());
-            }
-
-            // If this is an Attribute, append the format Javadoc.
-            if (!entry->values.empty()) {
-                if (Attribute* attr = valueCast<Attribute>(entry->values.front()->value.get())) {
-                    // We list out the available values for the given attribute.
-                    addAttributeFormatDoc(processor, attr);
-                }
-            }
-
-            outTypeClassDef->addMember(std::move(resourceMember));
-        }
-    }
-    return true;
+bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
+                                  std::ostream* out) {
+  return Generate(package_name_to_generate, package_name_to_generate, out);
 }
 
-bool JavaClassGenerator::generate(const StringPiece& packageNameToGenerate, std::ostream* out) {
-    return generate(packageNameToGenerate, packageNameToGenerate, out);
+static void AppendJavaDocAnnotations(
+    const std::vector<std::string>& annotations,
+    AnnotationProcessor* processor) {
+  for (const std::string& annotation : annotations) {
+    std::string proper_annotation = "@";
+    proper_annotation += annotation;
+    processor->AppendComment(proper_annotation);
+  }
 }
 
-static void appendJavaDocAnnotations(const std::vector<std::string>& annotations,
-                                     AnnotationProcessor* processor) {
-    for (const std::string& annotation : annotations) {
-        std::string properAnnotation = "@";
-        properAnnotation += annotation;
-        processor->appendComment(properAnnotation);
-    }
-}
+bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
+                                  const StringPiece& out_package_name,
+                                  std::ostream* out) {
+  ClassDefinition r_class("R", ClassQualifier::None, true);
 
-bool JavaClassGenerator::generate(const StringPiece& packageNameToGenerate,
-                                  const StringPiece& outPackageName, std::ostream* out) {
+  for (const auto& package : table_->packages) {
+    for (const auto& type : package->types) {
+      if (type->type == ResourceType::kAttrPrivate) {
+        continue;
+      }
 
-    ClassDefinition rClass("R", ClassQualifier::None, true);
+      const bool force_creation_if_empty =
+          (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic);
 
-    for (const auto& package : mTable->packages) {
-        for (const auto& type : package->types) {
-            if (type->type == ResourceType::kAttrPrivate) {
-                continue;
-            }
+      std::unique_ptr<ClassDefinition> class_def =
+          util::make_unique<ClassDefinition>(ToString(type->type),
+                                             ClassQualifier::Static,
+                                             force_creation_if_empty);
 
-            const bool forceCreationIfEmpty =
-                    (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic);
-
-            std::unique_ptr<ClassDefinition> classDef = util::make_unique<ClassDefinition>(
-                    toString(type->type), ClassQualifier::Static, forceCreationIfEmpty);
-
-            bool result = addMembersToTypeClass(packageNameToGenerate, package.get(), type.get(),
-                                                classDef.get());
-            if (!result) {
-                return false;
-            }
-
-            if (type->type == ResourceType::kAttr) {
-                // Also include private attributes in this same class.
-                ResourceTableType* privType = package->findType(ResourceType::kAttrPrivate);
-                if (privType) {
-                    result = addMembersToTypeClass(packageNameToGenerate, package.get(), privType,
-                                                   classDef.get());
-                    if (!result) {
-                        return false;
-                    }
-                }
-            }
-
-            if (type->type == ResourceType::kStyleable &&
-                    mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic) {
-                // When generating a public R class, we don't want Styleable to be part of the API.
-                // It is only emitted for documentation purposes.
-                classDef->getCommentBuilder()->appendComment("@doconly");
-            }
-
-            appendJavaDocAnnotations(mOptions.javadocAnnotations, classDef->getCommentBuilder());
-
-            rClass.addMember(std::move(classDef));
-        }
-    }
-
-    appendJavaDocAnnotations(mOptions.javadocAnnotations, rClass.getCommentBuilder());
-
-    if (!ClassDefinition::writeJavaFile(&rClass, outPackageName, mOptions.useFinal, out)) {
+      bool result = AddMembersToTypeClass(
+          package_name_to_generate, package.get(), type.get(), class_def.get());
+      if (!result) {
         return false;
-    }
+      }
 
-    out->flush();
-    return true;
+      if (type->type == ResourceType::kAttr) {
+        // Also include private attributes in this same class.
+        ResourceTableType* priv_type =
+            package->FindType(ResourceType::kAttrPrivate);
+        if (priv_type) {
+          result =
+              AddMembersToTypeClass(package_name_to_generate, package.get(),
+                                    priv_type, class_def.get());
+          if (!result) {
+            return false;
+          }
+        }
+      }
+
+      if (type->type == ResourceType::kStyleable &&
+          options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic) {
+        // When generating a public R class, we don't want Styleable to be part
+        // of the API.
+        // It is only emitted for documentation purposes.
+        class_def->GetCommentBuilder()->AppendComment("@doconly");
+      }
+
+      AppendJavaDocAnnotations(options_.javadoc_annotations,
+                               class_def->GetCommentBuilder());
+
+      r_class.AddMember(std::move(class_def));
+    }
+  }
+
+  AppendJavaDocAnnotations(options_.javadoc_annotations,
+                           r_class.GetCommentBuilder());
+
+  if (!ClassDefinition::WriteJavaFile(&r_class, out_package_name,
+                                      options_.use_final, out)) {
+    return false;
+  }
+
+  out->flush();
+  return true;
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/java/JavaClassGenerator.h b/tools/aapt2/java/JavaClassGenerator.h
index 2fdf268..190e73b 100644
--- a/tools/aapt2/java/JavaClassGenerator.h
+++ b/tools/aapt2/java/JavaClassGenerator.h
@@ -17,14 +17,14 @@
 #ifndef AAPT_JAVA_CLASS_GENERATOR_H
 #define AAPT_JAVA_CLASS_GENERATOR_H
 
+#include <ostream>
+#include <string>
+
 #include "ResourceTable.h"
 #include "ResourceValues.h"
 #include "process/IResourceTableConsumer.h"
 #include "util/StringPiece.h"
 
-#include <ostream>
-#include <string>
-
 namespace aapt {
 
 class AnnotationProcessor;
@@ -35,7 +35,7 @@
    * Specifies whether to use the 'final' modifier
    * on resource entries. Default is true.
    */
-  bool useFinal = true;
+  bool use_final = true;
 
   enum class SymbolTypes {
     kAll,
@@ -49,7 +49,7 @@
    * A list of JavaDoc annotations to add to the comments of all generated
    * classes.
    */
-  std::vector<std::string> javadocAnnotations;
+  std::vector<std::string> javadoc_annotations;
 };
 
 /*
@@ -69,34 +69,34 @@
    * We need to generate these symbols in a separate file.
    * Returns true on success.
    */
-  bool generate(const StringPiece& packageNameToGenerate, std::ostream* out);
+  bool Generate(const StringPiece& packageNameToGenerate, std::ostream* out);
 
-  bool generate(const StringPiece& packageNameToGenerate,
+  bool Generate(const StringPiece& packageNameToGenerate,
                 const StringPiece& outputPackageName, std::ostream* out);
 
   const std::string& getError() const;
 
  private:
-  bool addMembersToTypeClass(const StringPiece& packageNameToGenerate,
+  bool AddMembersToTypeClass(const StringPiece& packageNameToGenerate,
                              const ResourceTablePackage* package,
                              const ResourceTableType* type,
                              ClassDefinition* outTypeClassDef);
 
-  void addMembersToStyleableClass(const StringPiece& packageNameToGenerate,
+  void AddMembersToStyleableClass(const StringPiece& packageNameToGenerate,
                                   const std::string& entryName,
                                   const Styleable* styleable,
                                   ClassDefinition* outStyleableClassDef);
 
-  bool skipSymbol(SymbolState state);
+  bool SkipSymbol(SymbolState state);
 
-  IAaptContext* mContext;
-  ResourceTable* mTable;
-  JavaClassGeneratorOptions mOptions;
-  std::string mError;
+  IAaptContext* context_;
+  ResourceTable* table_;
+  JavaClassGeneratorOptions options_;
+  std::string error_;
 };
 
 inline const std::string& JavaClassGenerator::getError() const {
-  return mError;
+  return error_;
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp
index ed7c6bd..3d3d24e 100644
--- a/tools/aapt2/java/JavaClassGenerator_test.cpp
+++ b/tools/aapt2/java/JavaClassGenerator_test.cpp
@@ -15,154 +15,181 @@
  */
 
 #include "java/JavaClassGenerator.h"
-#include "test/Test.h"
-#include "util/Util.h"
 
 #include <sstream>
 #include <string>
 
+#include "test/Test.h"
+#include "util/Util.h"
+
 namespace aapt {
 
 TEST(JavaClassGeneratorTest, FailWhenEntryIsJavaKeyword) {
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("android", 0x01)
-            .addSimple("android:id/class", ResourceId(0x01020000))
-            .build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("android", 0x01)
+          .AddSimple("android:id/class", ResourceId(0x01020000))
+          .Build();
 
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder()
-            .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
-            .setNameManglerPolicy(NameManglerPolicy{ "android" })
-            .build();
-    JavaClassGenerator generator(context.get(), table.get(), {});
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder()
+          .AddSymbolSource(
+              util::make_unique<ResourceTableSymbolSource>(table.get()))
+          .SetNameManglerPolicy(NameManglerPolicy{"android"})
+          .Build();
+  JavaClassGenerator generator(context.get(), table.get(), {});
 
-    std::stringstream out;
-    EXPECT_FALSE(generator.generate("android", &out));
+  std::stringstream out;
+  EXPECT_FALSE(generator.Generate("android", &out));
 }
 
 TEST(JavaClassGeneratorTest, TransformInvalidJavaIdentifierCharacter) {
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("android", 0x01)
-            .addSimple("android:id/hey-man", ResourceId(0x01020000))
-            .addValue("android:attr/cool.attr", ResourceId(0x01010000),
-                      test::AttributeBuilder(false).build())
-            .addValue("android:styleable/hey.dude", ResourceId(0x01030000),
-                      test::StyleableBuilder()
-                              .addItem("android:attr/cool.attr", ResourceId(0x01010000))
-                              .build())
-            .build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("android", 0x01)
+          .AddSimple("android:id/hey-man", ResourceId(0x01020000))
+          .AddValue("android:attr/cool.attr", ResourceId(0x01010000),
+                    test::AttributeBuilder(false).Build())
+          .AddValue(
+              "android:styleable/hey.dude", ResourceId(0x01030000),
+              test::StyleableBuilder()
+                  .AddItem("android:attr/cool.attr", ResourceId(0x01010000))
+                  .Build())
+          .Build();
 
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder()
-            .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
-            .setNameManglerPolicy(NameManglerPolicy{ "android" })
-            .build();
-    JavaClassGenerator generator(context.get(), table.get(), {});
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder()
+          .AddSymbolSource(
+              util::make_unique<ResourceTableSymbolSource>(table.get()))
+          .SetNameManglerPolicy(NameManglerPolicy{"android"})
+          .Build();
+  JavaClassGenerator generator(context.get(), table.get(), {});
 
-    std::stringstream out;
-    EXPECT_TRUE(generator.generate("android", &out));
+  std::stringstream out;
+  EXPECT_TRUE(generator.Generate("android", &out));
 
-    std::string output = out.str();
+  std::string output = out.str();
 
-    EXPECT_NE(std::string::npos,
-              output.find("public static final int hey_man=0x01020000;"));
+  EXPECT_NE(std::string::npos,
+            output.find("public static final int hey_man=0x01020000;"));
 
-    EXPECT_NE(std::string::npos,
-              output.find("public static final int[] hey_dude={"));
+  EXPECT_NE(std::string::npos,
+            output.find("public static final int[] hey_dude={"));
 
-    EXPECT_NE(std::string::npos,
-              output.find("public static final int hey_dude_cool_attr=0;"));
+  EXPECT_NE(std::string::npos,
+            output.find("public static final int hey_dude_cool_attr=0;"));
 }
 
 TEST(JavaClassGeneratorTest, CorrectPackageNameIsUsed) {
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("android", 0x01)
-            .addSimple("android:id/one", ResourceId(0x01020000))
-            .addSimple("android:id/com.foo$two", ResourceId(0x01020001))
-            .build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("android", 0x01)
+          .AddSimple("android:id/one", ResourceId(0x01020000))
+          .AddSimple("android:id/com.foo$two", ResourceId(0x01020001))
+          .Build();
 
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder()
-            .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
-            .setNameManglerPolicy(NameManglerPolicy{ "android" })
-            .build();
-    JavaClassGenerator generator(context.get(), table.get(), {});
-    std::stringstream out;
-    ASSERT_TRUE(generator.generate("android", "com.android.internal", &out));
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder()
+          .AddSymbolSource(
+              util::make_unique<ResourceTableSymbolSource>(table.get()))
+          .SetNameManglerPolicy(NameManglerPolicy{"android"})
+          .Build();
+  JavaClassGenerator generator(context.get(), table.get(), {});
+  std::stringstream out;
+  ASSERT_TRUE(generator.Generate("android", "com.android.internal", &out));
 
-    std::string output = out.str();
-    EXPECT_NE(std::string::npos, output.find("package com.android.internal;"));
-    EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;"));
-    EXPECT_EQ(std::string::npos, output.find("two"));
-    EXPECT_EQ(std::string::npos, output.find("com_foo$two"));
+  std::string output = out.str();
+  EXPECT_NE(std::string::npos, output.find("package com.android.internal;"));
+  EXPECT_NE(std::string::npos,
+            output.find("public static final int one=0x01020000;"));
+  EXPECT_EQ(std::string::npos, output.find("two"));
+  EXPECT_EQ(std::string::npos, output.find("com_foo$two"));
 }
 
 TEST(JavaClassGeneratorTest, AttrPrivateIsWrittenAsAttr) {
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("android", 0x01)
-            .addSimple("android:attr/two", ResourceId(0x01010001))
-            .addSimple("android:^attr-private/one", ResourceId(0x01010000))
-            .build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("android", 0x01)
+          .AddSimple("android:attr/two", ResourceId(0x01010001))
+          .AddSimple("android:^attr-private/one", ResourceId(0x01010000))
+          .Build();
 
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder()
-            .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
-            .setNameManglerPolicy(NameManglerPolicy{ "android" })
-            .build();
-    JavaClassGenerator generator(context.get(), table.get(), {});
-    std::stringstream out;
-    ASSERT_TRUE(generator.generate("android", &out));
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder()
+          .AddSymbolSource(
+              util::make_unique<ResourceTableSymbolSource>(table.get()))
+          .SetNameManglerPolicy(NameManglerPolicy{"android"})
+          .Build();
+  JavaClassGenerator generator(context.get(), table.get(), {});
+  std::stringstream out;
+  ASSERT_TRUE(generator.Generate("android", &out));
 
-    std::string output = out.str();
-    EXPECT_NE(std::string::npos, output.find("public static final class attr"));
-    EXPECT_EQ(std::string::npos, output.find("public static final class ^attr-private"));
+  std::string output = out.str();
+  EXPECT_NE(std::string::npos, output.find("public static final class attr"));
+  EXPECT_EQ(std::string::npos,
+            output.find("public static final class ^attr-private"));
 }
 
 TEST(JavaClassGeneratorTest, OnlyWritePublicResources) {
-    StdErrDiagnostics diag;
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("android", 0x01)
-            .addSimple("android:id/one", ResourceId(0x01020000))
-            .addSimple("android:id/two", ResourceId(0x01020001))
-            .addSimple("android:id/three", ResourceId(0x01020002))
-            .setSymbolState("android:id/one", ResourceId(0x01020000), SymbolState::kPublic)
-            .setSymbolState("android:id/two", ResourceId(0x01020001), SymbolState::kPrivate)
-            .build();
+  StdErrDiagnostics diag;
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("android", 0x01)
+          .AddSimple("android:id/one", ResourceId(0x01020000))
+          .AddSimple("android:id/two", ResourceId(0x01020001))
+          .AddSimple("android:id/three", ResourceId(0x01020002))
+          .SetSymbolState("android:id/one", ResourceId(0x01020000),
+                          SymbolState::kPublic)
+          .SetSymbolState("android:id/two", ResourceId(0x01020001),
+                          SymbolState::kPrivate)
+          .Build();
 
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder()
-            .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
-            .setNameManglerPolicy(NameManglerPolicy{ "android" })
-            .build();
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder()
+          .AddSymbolSource(
+              util::make_unique<ResourceTableSymbolSource>(table.get()))
+          .SetNameManglerPolicy(NameManglerPolicy{"android"})
+          .Build();
 
-    JavaClassGeneratorOptions options;
-    options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic;
-    {
-        JavaClassGenerator generator(context.get(), table.get(), options);
-        std::stringstream out;
-        ASSERT_TRUE(generator.generate("android", &out));
-        std::string output = out.str();
-        EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;"));
-        EXPECT_EQ(std::string::npos, output.find("two"));
-        EXPECT_EQ(std::string::npos, output.find("three"));
-    }
+  JavaClassGeneratorOptions options;
+  options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic;
+  {
+    JavaClassGenerator generator(context.get(), table.get(), options);
+    std::stringstream out;
+    ASSERT_TRUE(generator.Generate("android", &out));
+    std::string output = out.str();
+    EXPECT_NE(std::string::npos,
+              output.find("public static final int one=0x01020000;"));
+    EXPECT_EQ(std::string::npos, output.find("two"));
+    EXPECT_EQ(std::string::npos, output.find("three"));
+  }
 
-    options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate;
-    {
-        JavaClassGenerator generator(context.get(), table.get(), options);
-        std::stringstream out;
-        ASSERT_TRUE(generator.generate("android", &out));
-        std::string output = out.str();
-        EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;"));
-        EXPECT_NE(std::string::npos, output.find("public static final int two=0x01020001;"));
-        EXPECT_EQ(std::string::npos, output.find("three"));
-    }
+  options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate;
+  {
+    JavaClassGenerator generator(context.get(), table.get(), options);
+    std::stringstream out;
+    ASSERT_TRUE(generator.Generate("android", &out));
+    std::string output = out.str();
+    EXPECT_NE(std::string::npos,
+              output.find("public static final int one=0x01020000;"));
+    EXPECT_NE(std::string::npos,
+              output.find("public static final int two=0x01020001;"));
+    EXPECT_EQ(std::string::npos, output.find("three"));
+  }
 
-    options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
-    {
-        JavaClassGenerator generator(context.get(), table.get(), options);
-        std::stringstream out;
-        ASSERT_TRUE(generator.generate("android", &out));
-        std::string output = out.str();
-        EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;"));
-        EXPECT_NE(std::string::npos, output.find("public static final int two=0x01020001;"));
-        EXPECT_NE(std::string::npos, output.find("public static final int three=0x01020002;"));
-    }
+  options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
+  {
+    JavaClassGenerator generator(context.get(), table.get(), options);
+    std::stringstream out;
+    ASSERT_TRUE(generator.Generate("android", &out));
+    std::string output = out.str();
+    EXPECT_NE(std::string::npos,
+              output.find("public static final int one=0x01020000;"));
+    EXPECT_NE(std::string::npos,
+              output.find("public static final int two=0x01020001;"));
+    EXPECT_NE(std::string::npos,
+              output.find("public static final int three=0x01020002;"));
+  }
 }
 
 /*
@@ -172,12 +199,15 @@
                             ResourceId{ 0x01, 0x02, 0x0000 }));
     ResourceTable table;
     table.setPackage(u"com.lib");
-    ASSERT_TRUE(table.addResource(ResourceName{ {}, ResourceType::kId, u"test" }, {},
-                                  Source{ "lib.xml", 33 }, util::make_unique<Id>()));
+    ASSERT_TRUE(table.addResource(ResourceName{ {}, ResourceType::kId, u"test"
+}, {},
+                                  Source{ "lib.xml", 33 },
+util::make_unique<Id>()));
     ASSERT_TRUE(mTable->merge(std::move(table)));
 
     Linker linker(mTable,
-                  std::make_shared<MockResolver>(mTable, std::map<ResourceName, ResourceId>()),
+                  std::make_shared<MockResolver>(mTable, std::map<ResourceName,
+ResourceId>()),
                   {});
     ASSERT_TRUE(linker.linkAndValidate());
 
@@ -197,126 +227,139 @@
 }*/
 
 TEST(JavaClassGeneratorTest, EmitOtherPackagesAttributesInStyleable) {
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-                .setPackageId("android", 0x01)
-                .setPackageId("com.lib", 0x02)
-                .addValue("android:attr/bar", ResourceId(0x01010000),
-                          test::AttributeBuilder(false).build())
-                .addValue("com.lib:attr/bar", ResourceId(0x02010000),
-                           test::AttributeBuilder(false).build())
-                .addValue("android:styleable/foo", ResourceId(0x01030000),
-                          test::StyleableBuilder()
-                                  .addItem("android:attr/bar", ResourceId(0x01010000))
-                                  .addItem("com.lib:attr/bar", ResourceId(0x02010000))
-                                  .build())
-                .build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("android", 0x01)
+          .SetPackageId("com.lib", 0x02)
+          .AddValue("android:attr/bar", ResourceId(0x01010000),
+                    test::AttributeBuilder(false).Build())
+          .AddValue("com.lib:attr/bar", ResourceId(0x02010000),
+                    test::AttributeBuilder(false).Build())
+          .AddValue("android:styleable/foo", ResourceId(0x01030000),
+                    test::StyleableBuilder()
+                        .AddItem("android:attr/bar", ResourceId(0x01010000))
+                        .AddItem("com.lib:attr/bar", ResourceId(0x02010000))
+                        .Build())
+          .Build();
 
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder()
-            .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
-            .setNameManglerPolicy(NameManglerPolicy{ "android" })
-            .build();
-    JavaClassGenerator generator(context.get(), table.get(), {});
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder()
+          .AddSymbolSource(
+              util::make_unique<ResourceTableSymbolSource>(table.get()))
+          .SetNameManglerPolicy(NameManglerPolicy{"android"})
+          .Build();
+  JavaClassGenerator generator(context.get(), table.get(), {});
 
-    std::stringstream out;
-    EXPECT_TRUE(generator.generate("android", &out));
+  std::stringstream out;
+  EXPECT_TRUE(generator.Generate("android", &out));
 
-    std::string output = out.str();
-    EXPECT_NE(std::string::npos, output.find("int foo_bar="));
-    EXPECT_NE(std::string::npos, output.find("int foo_com_lib_bar="));
+  std::string output = out.str();
+  EXPECT_NE(std::string::npos, output.find("int foo_bar="));
+  EXPECT_NE(std::string::npos, output.find("int foo_com_lib_bar="));
 }
 
 TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) {
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("android", 0x01)
-            .addSimple("android:id/foo", ResourceId(0x01010000))
-            .build();
-    test::getValue<Id>(table.get(), "android:id/foo")
-            ->setComment(std::string("This is a comment\n@deprecated"));
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("android", 0x01)
+          .AddSimple("android:id/foo", ResourceId(0x01010000))
+          .Build();
+  test::GetValue<Id>(table.get(), "android:id/foo")
+      ->SetComment(std::string("This is a comment\n@deprecated"));
 
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder()
-            .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
-            .setNameManglerPolicy(NameManglerPolicy{ "android" })
-            .build();
-    JavaClassGenerator generator(context.get(), table.get(), {});
-    std::stringstream out;
-    ASSERT_TRUE(generator.generate("android", &out));
-    std::string actual = out.str();
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder()
+          .AddSymbolSource(
+              util::make_unique<ResourceTableSymbolSource>(table.get()))
+          .SetNameManglerPolicy(NameManglerPolicy{"android"})
+          .Build();
+  JavaClassGenerator generator(context.get(), table.get(), {});
+  std::stringstream out;
+  ASSERT_TRUE(generator.Generate("android", &out));
+  std::string actual = out.str();
 
-    const char* expectedText =
-R"EOF(/**
+  const char* expectedText =
+      R"EOF(/**
      * This is a comment
      * @deprecated
      */
     @Deprecated
     public static final int foo=0x01010000;)EOF";
 
-    EXPECT_NE(std::string::npos, actual.find(expectedText));
+  EXPECT_NE(std::string::npos, actual.find(expectedText));
 }
 
-TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) {
+TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) {}
 
-}
+TEST(JavaClassGeneratorTest,
+     CommentsForStyleablesAndNestedAttributesArePresent) {
+  Attribute attr(false);
+  attr.SetComment(StringPiece("This is an attribute"));
 
-TEST(JavaClassGeneratorTest, CommentsForStyleablesAndNestedAttributesArePresent) {
-    Attribute attr(false);
-    attr.setComment(StringPiece("This is an attribute"));
+  Styleable styleable;
+  styleable.entries.push_back(
+      Reference(test::ParseNameOrDie("android:attr/one")));
+  styleable.SetComment(StringPiece("This is a styleable"));
 
-    Styleable styleable;
-    styleable.entries.push_back(Reference(test::parseNameOrDie("android:attr/one")));
-    styleable.setComment(StringPiece("This is a styleable"));
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("android", 0x01)
+          .AddValue("android:attr/one", util::make_unique<Attribute>(attr))
+          .AddValue("android:styleable/Container",
+                    std::unique_ptr<Styleable>(styleable.Clone(nullptr)))
+          .Build();
 
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("android", 0x01)
-            .addValue("android:attr/one", util::make_unique<Attribute>(attr))
-            .addValue("android:styleable/Container",
-                      std::unique_ptr<Styleable>(styleable.clone(nullptr)))
-            .build();
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder()
+          .AddSymbolSource(
+              util::make_unique<ResourceTableSymbolSource>(table.get()))
+          .SetNameManglerPolicy(NameManglerPolicy{"android"})
+          .Build();
+  JavaClassGeneratorOptions options;
+  options.use_final = false;
+  JavaClassGenerator generator(context.get(), table.get(), options);
+  std::stringstream out;
+  ASSERT_TRUE(generator.Generate("android", &out));
+  std::string actual = out.str();
 
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder()
-            .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
-            .setNameManglerPolicy(NameManglerPolicy{ "android" })
-            .build();
-    JavaClassGeneratorOptions options;
-    options.useFinal = false;
-    JavaClassGenerator generator(context.get(), table.get(), options);
-    std::stringstream out;
-    ASSERT_TRUE(generator.generate("android", &out));
-    std::string actual = out.str();
-
-    EXPECT_NE(std::string::npos, actual.find("attr name android:one"));
-    EXPECT_NE(std::string::npos, actual.find("attr description"));
-    EXPECT_NE(std::string::npos, actual.find(attr.getComment().data()));
-    EXPECT_NE(std::string::npos, actual.find(styleable.getComment().data()));
+  EXPECT_NE(std::string::npos, actual.find("attr name android:one"));
+  EXPECT_NE(std::string::npos, actual.find("attr description"));
+  EXPECT_NE(std::string::npos, actual.find(attr.GetComment().data()));
+  EXPECT_NE(std::string::npos, actual.find(styleable.GetComment().data()));
 }
 
 TEST(JavaClassGeneratorTest, CommentsForRemovedAttributesAreNotPresentInClass) {
-    Attribute attr(false);
-    attr.setComment(StringPiece("removed"));
+  Attribute attr(false);
+  attr.SetComment(StringPiece("removed"));
 
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("android", 0x01)
-            .addValue("android:attr/one", util::make_unique<Attribute>(attr))
-            .build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("android", 0x01)
+          .AddValue("android:attr/one", util::make_unique<Attribute>(attr))
+          .Build();
 
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder()
-            .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
-            .setNameManglerPolicy(NameManglerPolicy{ "android" })
-            .build();
-    JavaClassGeneratorOptions options;
-    options.useFinal = false;
-    JavaClassGenerator generator(context.get(), table.get(), options);
-    std::stringstream out;
-    ASSERT_TRUE(generator.generate("android", &out));
-    std::string actual = out.str();
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder()
+          .AddSymbolSource(
+              util::make_unique<ResourceTableSymbolSource>(table.get()))
+          .SetNameManglerPolicy(NameManglerPolicy{"android"})
+          .Build();
+  JavaClassGeneratorOptions options;
+  options.use_final = false;
+  JavaClassGenerator generator(context.get(), table.get(), options);
+  std::stringstream out;
+  ASSERT_TRUE(generator.Generate("android", &out));
+  std::string actual = out.str();
 
-    EXPECT_EQ(std::string::npos, actual.find("@attr name android:one"));
-    EXPECT_EQ(std::string::npos, actual.find("@attr description"));
+  EXPECT_EQ(std::string::npos, actual.find("@attr name android:one"));
+  EXPECT_EQ(std::string::npos, actual.find("@attr description"));
 
-    // We should find @removed only in the attribute javadoc and not anywhere else (i.e. the class
-    // javadoc).
-    const size_t pos = actual.find("removed");
-    EXPECT_NE(std::string::npos, pos);
-    EXPECT_EQ(std::string::npos, actual.find("removed", pos + 1));
+  // We should find @removed only in the attribute javadoc and not anywhere else
+  // (i.e. the class
+  // javadoc).
+  const size_t pos = actual.find("removed");
+  EXPECT_NE(std::string::npos, pos);
+  EXPECT_EQ(std::string::npos, actual.find("removed", pos + 1));
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/java/ManifestClassGenerator.cpp b/tools/aapt2/java/ManifestClassGenerator.cpp
index 5ff11b1..db84f29 100644
--- a/tools/aapt2/java/ManifestClassGenerator.cpp
+++ b/tools/aapt2/java/ManifestClassGenerator.cpp
@@ -14,111 +14,120 @@
  * limitations under the License.
  */
 
-#include "Source.h"
-#include "java/AnnotationProcessor.h"
-#include "java/ClassDefinition.h"
 #include "java/ManifestClassGenerator.h"
-#include "util/Maybe.h"
-#include "xml/XmlDom.h"
 
 #include <algorithm>
 
+#include "Source.h"
+#include "java/AnnotationProcessor.h"
+#include "java/ClassDefinition.h"
+#include "util/Maybe.h"
+#include "xml/XmlDom.h"
+
 namespace aapt {
 
-static Maybe<StringPiece> extractJavaIdentifier(IDiagnostics* diag, const Source& source,
+static Maybe<StringPiece> ExtractJavaIdentifier(IDiagnostics* diag,
+                                                const Source& source,
                                                 const StringPiece& value) {
-    const StringPiece sep = ".";
-    auto iter = std::find_end(value.begin(), value.end(), sep.begin(), sep.end());
+  const StringPiece sep = ".";
+  auto iter = std::find_end(value.begin(), value.end(), sep.begin(), sep.end());
 
-    StringPiece result;
-    if (iter != value.end()) {
-        result.assign(iter + sep.size(), value.end() - (iter + sep.size()));
-    } else {
-        result = value;
-    }
+  StringPiece result;
+  if (iter != value.end()) {
+    result.assign(iter + sep.size(), value.end() - (iter + sep.size()));
+  } else {
+    result = value;
+  }
 
-    if (result.empty()) {
-        diag->error(DiagMessage(source) << "empty symbol");
-        return {};
-    }
+  if (result.empty()) {
+    diag->Error(DiagMessage(source) << "empty symbol");
+    return {};
+  }
 
-    iter = util::findNonAlphaNumericAndNotInSet(result, "_");
-    if (iter != result.end()) {
-        diag->error(DiagMessage(source)
-                    << "invalid character '" << StringPiece(iter, 1)
-                    << "' in '" << result << "'");
-        return {};
-    }
+  iter = util::FindNonAlphaNumericAndNotInSet(result, "_");
+  if (iter != result.end()) {
+    diag->Error(DiagMessage(source) << "invalid character '"
+                                    << StringPiece(iter, 1) << "' in '"
+                                    << result << "'");
+    return {};
+  }
 
-    if (*result.begin() >= '0' && *result.begin() <= '9') {
-        diag->error(DiagMessage(source) << "symbol can not start with a digit");
-        return {};
-    }
+  if (*result.begin() >= '0' && *result.begin() <= '9') {
+    diag->Error(DiagMessage(source) << "symbol can not start with a digit");
+    return {};
+  }
 
-    return result;
+  return result;
 }
 
-static bool writeSymbol(const Source& source, IDiagnostics* diag, xml::Element* el,
-                        ClassDefinition* classDef) {
-    xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, "name");
-    if (!attr) {
-        diag->error(DiagMessage(source) << "<" << el->name << "> must define 'android:name'");
-        return false;
-    }
+static bool WriteSymbol(const Source& source, IDiagnostics* diag,
+                        xml::Element* el, ClassDefinition* class_def) {
+  xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name");
+  if (!attr) {
+    diag->Error(DiagMessage(source) << "<" << el->name
+                                    << "> must define 'android:name'");
+    return false;
+  }
 
-    Maybe<StringPiece> result = extractJavaIdentifier(diag, source.withLine(el->lineNumber),
-                                                      attr->value);
-    if (!result) {
-        return false;
-    }
+  Maybe<StringPiece> result = ExtractJavaIdentifier(
+      diag, source.WithLine(el->line_number), attr->value);
+  if (!result) {
+    return false;
+  }
 
-    std::unique_ptr<StringMember> stringMember = util::make_unique<StringMember>(
-            result.value(), attr->value);
-    stringMember->getCommentBuilder()->appendComment(el->comment);
+  std::unique_ptr<StringMember> string_member =
+      util::make_unique<StringMember>(result.value(), attr->value);
+  string_member->GetCommentBuilder()->AppendComment(el->comment);
 
-    classDef->addMember(std::move(stringMember));
-    return true;
+  class_def->AddMember(std::move(string_member));
+  return true;
 }
 
-std::unique_ptr<ClassDefinition> generateManifestClass(IDiagnostics* diag, xml::XmlResource* res) {
-    xml::Element* el = xml::findRootElement(res->root.get());
-    if (!el) {
-        diag->error(DiagMessage(res->file.source) << "no root tag defined");
-        return {};
+std::unique_ptr<ClassDefinition> GenerateManifestClass(IDiagnostics* diag,
+                                                       xml::XmlResource* res) {
+  xml::Element* el = xml::FindRootElement(res->root.get());
+  if (!el) {
+    diag->Error(DiagMessage(res->file.source) << "no root tag defined");
+    return {};
+  }
+
+  if (el->name != "manifest" && !el->namespace_uri.empty()) {
+    diag->Error(DiagMessage(res->file.source)
+                << "no <manifest> root tag defined");
+    return {};
+  }
+
+  std::unique_ptr<ClassDefinition> permission_class =
+      util::make_unique<ClassDefinition>("permission", ClassQualifier::Static,
+                                         false);
+  std::unique_ptr<ClassDefinition> permission_group_class =
+      util::make_unique<ClassDefinition>("permission_group",
+                                         ClassQualifier::Static, false);
+
+  bool error = false;
+  std::vector<xml::Element*> children = el->GetChildElements();
+  for (xml::Element* child_el : children) {
+    if (child_el->namespace_uri.empty()) {
+      if (child_el->name == "permission") {
+        error |= !WriteSymbol(res->file.source, diag, child_el,
+                              permission_class.get());
+      } else if (child_el->name == "permission-group") {
+        error |= !WriteSymbol(res->file.source, diag, child_el,
+                              permission_group_class.get());
+      }
     }
+  }
 
-    if (el->name != "manifest" && !el->namespaceUri.empty()) {
-        diag->error(DiagMessage(res->file.source) << "no <manifest> root tag defined");
-        return {};
-    }
+  if (error) {
+    return {};
+  }
 
-    std::unique_ptr<ClassDefinition> permissionClass =
-            util::make_unique<ClassDefinition>("permission", ClassQualifier::Static, false);
-    std::unique_ptr<ClassDefinition> permissionGroupClass =
-            util::make_unique<ClassDefinition>("permission_group", ClassQualifier::Static, false);
-
-    bool error = false;
-
-    std::vector<xml::Element*> children = el->getChildElements();
-    for (xml::Element* childEl : children) {
-        if (childEl->namespaceUri.empty()) {
-            if (childEl->name == "permission") {
-                error |= !writeSymbol(res->file.source, diag, childEl, permissionClass.get());
-            } else if (childEl->name == "permission-group") {
-                error |= !writeSymbol(res->file.source, diag, childEl, permissionGroupClass.get());
-            }
-        }
-    }
-
-    if (error) {
-        return {};
-    }
-
-    std::unique_ptr<ClassDefinition> manifestClass =
-            util::make_unique<ClassDefinition>("Manifest", ClassQualifier::None, false);
-    manifestClass->addMember(std::move(permissionClass));
-    manifestClass->addMember(std::move(permissionGroupClass));
-    return manifestClass;
+  std::unique_ptr<ClassDefinition> manifest_class =
+      util::make_unique<ClassDefinition>("Manifest", ClassQualifier::None,
+                                         false);
+  manifest_class->AddMember(std::move(permission_class));
+  manifest_class->AddMember(std::move(permission_group_class));
+  return manifest_class;
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/java/ManifestClassGenerator.h b/tools/aapt2/java/ManifestClassGenerator.h
index 1817648..b12202a 100644
--- a/tools/aapt2/java/ManifestClassGenerator.h
+++ b/tools/aapt2/java/ManifestClassGenerator.h
@@ -19,14 +19,11 @@
 
 #include "Diagnostics.h"
 #include "java/ClassDefinition.h"
-#include "util/StringPiece.h"
 #include "xml/XmlDom.h"
 
-#include <iostream>
-
 namespace aapt {
 
-std::unique_ptr<ClassDefinition> generateManifestClass(IDiagnostics* diag,
+std::unique_ptr<ClassDefinition> GenerateManifestClass(IDiagnostics* diag,
                                                        xml::XmlResource* res);
 
 }  // namespace aapt
diff --git a/tools/aapt2/java/ManifestClassGenerator_test.cpp b/tools/aapt2/java/ManifestClassGenerator_test.cpp
index eecb544..5ebf508 100644
--- a/tools/aapt2/java/ManifestClassGenerator_test.cpp
+++ b/tools/aapt2/java/ManifestClassGenerator_test.cpp
@@ -15,30 +15,33 @@
  */
 
 #include "java/ManifestClassGenerator.h"
+
 #include "test/Test.h"
 
 namespace aapt {
 
-static ::testing::AssertionResult getManifestClassText(IAaptContext* context, xml::XmlResource* res,
-                                                       std::string* outStr) {
-    std::unique_ptr<ClassDefinition> manifestClass = generateManifestClass(
-            context->getDiagnostics(), res);
-    if (!manifestClass) {
-        return ::testing::AssertionFailure() << "manifestClass == nullptr";
-    }
+static ::testing::AssertionResult GetManifestClassText(IAaptContext* context,
+                                                       xml::XmlResource* res,
+                                                       std::string* out_str) {
+  std::unique_ptr<ClassDefinition> manifest_class =
+      GenerateManifestClass(context->GetDiagnostics(), res);
+  if (!manifest_class) {
+    return ::testing::AssertionFailure() << "manifest_class == nullptr";
+  }
 
-    std::stringstream out;
-    if (!manifestClass->writeJavaFile(manifestClass.get(), "android", true, &out)) {
-        return ::testing::AssertionFailure() << "failed to write java file";
-    }
+  std::stringstream out;
+  if (!manifest_class->WriteJavaFile(manifest_class.get(), "android", true,
+                                     &out)) {
+    return ::testing::AssertionFailure() << "failed to write java file";
+  }
 
-    *outStr = out.str();
-    return ::testing::AssertionSuccess();
+  *out_str = out.str();
+  return ::testing::AssertionSuccess();
 }
 
 TEST(ManifestClassGeneratorTest, NameIsProperlyGeneratedFromSymbol) {
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
-    std::unique_ptr<xml::XmlResource> manifest = test::buildXmlDom(R"EOF(
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"EOF(
         <manifest xmlns:android="http://schemas.android.com/apk/res/android">
           <permission android:name="android.permission.ACCESS_INTERNET" />
           <permission android:name="android.DO_DANGEROUS_THINGS" />
@@ -46,46 +49,51 @@
           <permission-group android:name="foo.bar.PERMISSION" />
         </manifest>)EOF");
 
-    std::string actual;
-    ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual));
+  std::string actual;
+  ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
 
-    const size_t permissionClassPos = actual.find("public static final class permission {");
-    const size_t permissionGroupClassPos =
-            actual.find("public static final class permission_group {");
-    ASSERT_NE(std::string::npos, permissionClassPos);
-    ASSERT_NE(std::string::npos, permissionGroupClassPos);
+  const size_t permission_class_pos =
+      actual.find("public static final class permission {");
+  const size_t permission_croup_class_pos =
+      actual.find("public static final class permission_group {");
+  ASSERT_NE(std::string::npos, permission_class_pos);
+  ASSERT_NE(std::string::npos, permission_croup_class_pos);
 
-    //
-    // Make sure these permissions are in the permission class.
-    //
+  //
+  // Make sure these permissions are in the permission class.
+  //
 
-    size_t pos = actual.find("public static final String ACCESS_INTERNET="
-                             "\"android.permission.ACCESS_INTERNET\";");
-    EXPECT_GT(pos, permissionClassPos);
-    EXPECT_LT(pos, permissionGroupClassPos);
+  size_t pos = actual.find(
+      "public static final String ACCESS_INTERNET="
+      "\"android.permission.ACCESS_INTERNET\";");
+  EXPECT_GT(pos, permission_class_pos);
+  EXPECT_LT(pos, permission_croup_class_pos);
 
-    pos = actual.find("public static final String DO_DANGEROUS_THINGS="
-                      "\"android.DO_DANGEROUS_THINGS\";");
-    EXPECT_GT(pos, permissionClassPos);
-    EXPECT_LT(pos, permissionGroupClassPos);
+  pos = actual.find(
+      "public static final String DO_DANGEROUS_THINGS="
+      "\"android.DO_DANGEROUS_THINGS\";");
+  EXPECT_GT(pos, permission_class_pos);
+  EXPECT_LT(pos, permission_croup_class_pos);
 
-    pos = actual.find("public static final String HUH=\"com.test.sample.permission.HUH\";");
-    EXPECT_GT(pos, permissionClassPos);
-    EXPECT_LT(pos, permissionGroupClassPos);
+  pos = actual.find(
+      "public static final String HUH=\"com.test.sample.permission.HUH\";");
+  EXPECT_GT(pos, permission_class_pos);
+  EXPECT_LT(pos, permission_croup_class_pos);
 
-    //
-    // Make sure these permissions are in the permission_group class
-    //
+  //
+  // Make sure these permissions are in the permission_group class
+  //
 
-    pos = actual.find("public static final String PERMISSION="
-                      "\"foo.bar.PERMISSION\";");
-    EXPECT_GT(pos, permissionGroupClassPos);
-    EXPECT_LT(pos, std::string::npos);
+  pos = actual.find(
+      "public static final String PERMISSION="
+      "\"foo.bar.PERMISSION\";");
+  EXPECT_GT(pos, permission_croup_class_pos);
+  EXPECT_LT(pos, std::string::npos);
 }
 
 TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) {
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
-    std::unique_ptr<xml::XmlResource> manifest = test::buildXmlDom(R"EOF(
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"EOF(
         <manifest xmlns:android="http://schemas.android.com/apk/res/android">
           <!-- Required to access the internet.
                Added in API 1. -->
@@ -98,36 +106,36 @@
           <permission android:name="android.permission.SECRET" />
         </manifest>)EOF");
 
-    std::string actual;
-    ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual));
+  std::string actual;
+  ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
 
-    const char* expectedAccessInternet =
-R"EOF(    /**
+  const char* expected_access_internet =
+      R"EOF(    /**
      * Required to access the internet.
      * Added in API 1.
      */
     public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)EOF";
 
-    EXPECT_NE(std::string::npos, actual.find(expectedAccessInternet));
+  EXPECT_NE(std::string::npos, actual.find(expected_access_internet));
 
-    const char* expectedPlayOutside =
-R"EOF(    /**
+  const char* expected_play_outside =
+      R"EOF(    /**
      * @deprecated This permission is for playing outside.
      */
     @Deprecated
     public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)EOF";
 
-    EXPECT_NE(std::string::npos, actual.find(expectedPlayOutside));
+  EXPECT_NE(std::string::npos, actual.find(expected_play_outside));
 
-    const char* expectedSecret =
-R"EOF(    /**
+  const char* expected_secret =
+      R"EOF(    /**
      * This is a private permission for system only!
      * @hide
      */
     @android.annotation.SystemApi
     public static final String SECRET="android.permission.SECRET";)EOF";
 
-    EXPECT_NE(std::string::npos, actual.find(expectedSecret));
+  EXPECT_NE(std::string::npos, actual.find(expected_secret));
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp
index 902ec4c..624a559 100644
--- a/tools/aapt2/java/ProguardRules.cpp
+++ b/tools/aapt2/java/ProguardRules.cpp
@@ -15,254 +15,281 @@
  */
 
 #include "java/ProguardRules.h"
-#include "util/Util.h"
-#include "xml/XmlDom.h"
 
 #include <memory>
 #include <string>
 
+#include "android-base/macros.h"
+
+#include "util/Util.h"
+#include "xml/XmlDom.h"
+
 namespace aapt {
 namespace proguard {
 
 class BaseVisitor : public xml::Visitor {
-public:
-    BaseVisitor(const Source& source, KeepSet* keepSet) : mSource(source), mKeepSet(keepSet) {
+ public:
+  BaseVisitor(const Source& source, KeepSet* keep_set)
+      : source_(source), keep_set_(keep_set) {}
+
+  virtual void Visit(xml::Text*) override{};
+
+  virtual void Visit(xml::Namespace* node) override {
+    for (const auto& child : node->children) {
+      child->Accept(this);
     }
+  }
 
-    virtual void visit(xml::Text*) override {};
-
-    virtual void visit(xml::Namespace* node) override {
-        for (const auto& child : node->children) {
-            child->accept(this);
+  virtual void Visit(xml::Element* node) override {
+    if (!node->namespace_uri.empty()) {
+      Maybe<xml::ExtractedPackage> maybe_package =
+          xml::ExtractPackageFromNamespace(node->namespace_uri);
+      if (maybe_package) {
+        // This is a custom view, let's figure out the class name from this.
+        std::string package = maybe_package.value().package + "." + node->name;
+        if (util::IsJavaClassName(package)) {
+          AddClass(node->line_number, package);
         }
+      }
+    } else if (util::IsJavaClassName(node->name)) {
+      AddClass(node->line_number, node->name);
     }
 
-    virtual void visit(xml::Element* node) override {
-        if (!node->namespaceUri.empty()) {
-            Maybe<xml::ExtractedPackage> maybePackage = xml::extractPackageFromNamespace(
-                    node->namespaceUri);
-            if (maybePackage) {
-                // This is a custom view, let's figure out the class name from this.
-                std::string package = maybePackage.value().package + "." + node->name;
-                if (util::isJavaClassName(package)) {
-                    addClass(node->lineNumber, package);
-                }
-            }
-        } else if (util::isJavaClassName(node->name)) {
-            addClass(node->lineNumber, node->name);
-        }
-
-        for (const auto& child: node->children) {
-            child->accept(this);
-        }
+    for (const auto& child : node->children) {
+      child->Accept(this);
     }
+  }
 
-protected:
-    void addClass(size_t lineNumber, const std::string& className) {
-        mKeepSet->addClass(Source(mSource.path, lineNumber), className);
-    }
+ protected:
+  void AddClass(size_t line_number, const std::string& class_name) {
+    keep_set_->AddClass(Source(source_.path, line_number), class_name);
+  }
 
-    void addMethod(size_t lineNumber, const std::string& methodName) {
-        mKeepSet->addMethod(Source(mSource.path, lineNumber), methodName);
-    }
+  void AddMethod(size_t line_number, const std::string& method_name) {
+    keep_set_->AddMethod(Source(source_.path, line_number), method_name);
+  }
 
-private:
-    Source mSource;
-    KeepSet* mKeepSet;
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BaseVisitor);
+
+  Source source_;
+  KeepSet* keep_set_;
 };
 
-struct LayoutVisitor : public BaseVisitor {
-    LayoutVisitor(const Source& source, KeepSet* keepSet) : BaseVisitor(source, keepSet) {
+class LayoutVisitor : public BaseVisitor {
+ public:
+  LayoutVisitor(const Source& source, KeepSet* keep_set)
+      : BaseVisitor(source, keep_set) {}
+
+  virtual void Visit(xml::Element* node) override {
+    bool check_class = false;
+    bool check_name = false;
+    if (node->namespace_uri.empty()) {
+      check_class = node->name == "view" || node->name == "fragment";
+    } else if (node->namespace_uri == xml::kSchemaAndroid) {
+      check_name = node->name == "fragment";
     }
 
-    virtual void visit(xml::Element* node) override {
-        bool checkClass = false;
-        bool checkName = false;
-        if (node->namespaceUri.empty()) {
-            checkClass = node->name == "view" || node->name == "fragment";
-        } else if (node->namespaceUri == xml::kSchemaAndroid) {
-            checkName = node->name == "fragment";
-        }
-
-        for (const auto& attr : node->attributes) {
-            if (checkClass && attr.namespaceUri.empty() && attr.name == "class" &&
-                    util::isJavaClassName(attr.value)) {
-                addClass(node->lineNumber, attr.value);
-            } else if (checkName && attr.namespaceUri == xml::kSchemaAndroid &&
-                    attr.name == "name" && util::isJavaClassName(attr.value)) {
-                addClass(node->lineNumber, attr.value);
-            } else if (attr.namespaceUri == xml::kSchemaAndroid && attr.name == "onClick") {
-                addMethod(node->lineNumber, attr.value);
-            }
-        }
-
-        BaseVisitor::visit(node);
+    for (const auto& attr : node->attributes) {
+      if (check_class && attr.namespace_uri.empty() && attr.name == "class" &&
+          util::IsJavaClassName(attr.value)) {
+        AddClass(node->line_number, attr.value);
+      } else if (check_name && attr.namespace_uri == xml::kSchemaAndroid &&
+                 attr.name == "name" && util::IsJavaClassName(attr.value)) {
+        AddClass(node->line_number, attr.value);
+      } else if (attr.namespace_uri == xml::kSchemaAndroid &&
+                 attr.name == "onClick") {
+        AddMethod(node->line_number, attr.value);
+      }
     }
+
+    BaseVisitor::Visit(node);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(LayoutVisitor);
 };
 
-struct XmlResourceVisitor : public BaseVisitor {
-    XmlResourceVisitor(const Source& source, KeepSet* keepSet) : BaseVisitor(source, keepSet) {
+class XmlResourceVisitor : public BaseVisitor {
+ public:
+  XmlResourceVisitor(const Source& source, KeepSet* keep_set)
+      : BaseVisitor(source, keep_set) {}
+
+  virtual void Visit(xml::Element* node) override {
+    bool check_fragment = false;
+    if (node->namespace_uri.empty()) {
+      check_fragment =
+          node->name == "PreferenceScreen" || node->name == "header";
     }
 
-    virtual void visit(xml::Element* node) override {
-        bool checkFragment = false;
-        if (node->namespaceUri.empty()) {
-            checkFragment = node->name == "PreferenceScreen" || node->name == "header";
-        }
-
-        if (checkFragment) {
-            xml::Attribute* attr = node->findAttribute(xml::kSchemaAndroid, "fragment");
-            if (attr && util::isJavaClassName(attr->value)) {
-                addClass(node->lineNumber, attr->value);
-            }
-        }
-
-        BaseVisitor::visit(node);
+    if (check_fragment) {
+      xml::Attribute* attr =
+          node->FindAttribute(xml::kSchemaAndroid, "fragment");
+      if (attr && util::IsJavaClassName(attr->value)) {
+        AddClass(node->line_number, attr->value);
+      }
     }
+
+    BaseVisitor::Visit(node);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(XmlResourceVisitor);
 };
 
-struct TransitionVisitor : public BaseVisitor {
-    TransitionVisitor(const Source& source, KeepSet* keepSet) : BaseVisitor(source, keepSet) {
+class TransitionVisitor : public BaseVisitor {
+ public:
+  TransitionVisitor(const Source& source, KeepSet* keep_set)
+      : BaseVisitor(source, keep_set) {}
+
+  virtual void Visit(xml::Element* node) override {
+    bool check_class =
+        node->namespace_uri.empty() &&
+        (node->name == "transition" || node->name == "pathMotion");
+    if (check_class) {
+      xml::Attribute* attr = node->FindAttribute({}, "class");
+      if (attr && util::IsJavaClassName(attr->value)) {
+        AddClass(node->line_number, attr->value);
+      }
     }
 
-    virtual void visit(xml::Element* node) override {
-        bool checkClass = node->namespaceUri.empty() &&
-                (node->name == "transition" || node->name == "pathMotion");
-        if (checkClass) {
-            xml::Attribute* attr = node->findAttribute({}, "class");
-            if (attr && util::isJavaClassName(attr->value)) {
-                addClass(node->lineNumber, attr->value);
-            }
-        }
+    BaseVisitor::Visit(node);
+  }
 
-        BaseVisitor::visit(node);
-    }
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TransitionVisitor);
 };
 
-struct ManifestVisitor : public BaseVisitor {
-    ManifestVisitor(const Source& source, KeepSet* keepSet, bool mainDexOnly)
-            : BaseVisitor(source, keepSet), mMainDexOnly(mainDexOnly) {
-    }
+class ManifestVisitor : public BaseVisitor {
+ public:
+  ManifestVisitor(const Source& source, KeepSet* keep_set, bool main_dex_only)
+      : BaseVisitor(source, keep_set), main_dex_only_(main_dex_only) {}
 
-    virtual void visit(xml::Element* node) override {
-        if (node->namespaceUri.empty()) {
-            bool getName = false;
-            if (node->name == "manifest") {
-                xml::Attribute* attr = node->findAttribute({}, "package");
-                if (attr) {
-                    mPackage = attr->value;
-                }
-            } else if (node->name == "application") {
-                getName = true;
-                xml::Attribute* attr = node->findAttribute(xml::kSchemaAndroid, "backupAgent");
-                if (attr) {
-                    Maybe<std::string> result = util::getFullyQualifiedClassName(mPackage,
-                                                                                 attr->value);
-                    if (result) {
-                        addClass(node->lineNumber, result.value());
-                    }
-                }
-                if (mMainDexOnly) {
-                    xml::Attribute* defaultProcess = node->findAttribute(xml::kSchemaAndroid,
-                                                                         "process");
-                    if (defaultProcess) {
-                        mDefaultProcess = defaultProcess->value;
-                    }
-                }
-            } else if (node->name == "activity" || node->name == "service" ||
-                    node->name == "receiver" || node->name == "provider") {
-                getName = true;
-
-                if (mMainDexOnly) {
-                    xml::Attribute* componentProcess = node->findAttribute(xml::kSchemaAndroid,
-                                                                           "process");
-
-                    const std::string& process = componentProcess ? componentProcess->value
-                            : mDefaultProcess;
-                    getName = !process.empty() && process[0] != ':';
-                }
-            } else if (node-> name == "instrumentation") {
-                getName = true;
-            }
-
-            if (getName) {
-                xml::Attribute* attr = node->findAttribute(xml::kSchemaAndroid, "name");
-                getName = attr != nullptr;
-
-                if (getName) {
-                    Maybe<std::string> result = util::getFullyQualifiedClassName(mPackage,
-                                                                                 attr->value);
-                    if (result) {
-                        addClass(node->lineNumber, result.value());
-                    }
-                }
-            }
+  virtual void Visit(xml::Element* node) override {
+    if (node->namespace_uri.empty()) {
+      bool get_name = false;
+      if (node->name == "manifest") {
+        xml::Attribute* attr = node->FindAttribute({}, "package");
+        if (attr) {
+          package_ = attr->value;
         }
-        BaseVisitor::visit(node);
-    }
+      } else if (node->name == "application") {
+        get_name = true;
+        xml::Attribute* attr =
+            node->FindAttribute(xml::kSchemaAndroid, "backupAgent");
+        if (attr) {
+          Maybe<std::string> result =
+              util::GetFullyQualifiedClassName(package_, attr->value);
+          if (result) {
+            AddClass(node->line_number, result.value());
+          }
+        }
+        if (main_dex_only_) {
+          xml::Attribute* default_process =
+              node->FindAttribute(xml::kSchemaAndroid, "process");
+          if (default_process) {
+            default_process_ = default_process->value;
+          }
+        }
+      } else if (node->name == "activity" || node->name == "service" ||
+                 node->name == "receiver" || node->name == "provider") {
+        get_name = true;
 
-private:
-    std::string mPackage;
-    const bool mMainDexOnly;
-    std::string mDefaultProcess;
+        if (main_dex_only_) {
+          xml::Attribute* component_process =
+              node->FindAttribute(xml::kSchemaAndroid, "process");
+
+          const std::string& process =
+              component_process ? component_process->value : default_process_;
+          get_name = !process.empty() && process[0] != ':';
+        }
+      } else if (node->name == "instrumentation") {
+        get_name = true;
+      }
+
+      if (get_name) {
+        xml::Attribute* attr = node->FindAttribute(xml::kSchemaAndroid, "name");
+        get_name = attr != nullptr;
+
+        if (get_name) {
+          Maybe<std::string> result =
+              util::GetFullyQualifiedClassName(package_, attr->value);
+          if (result) {
+            AddClass(node->line_number, result.value());
+          }
+        }
+      }
+    }
+    BaseVisitor::Visit(node);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ManifestVisitor);
+
+  std::string package_;
+  const bool main_dex_only_;
+  std::string default_process_;
 };
 
-bool collectProguardRulesForManifest(const Source& source, xml::XmlResource* res,
-                                     KeepSet* keepSet, bool mainDexOnly) {
-    ManifestVisitor visitor(source, keepSet, mainDexOnly);
-    if (res->root) {
-        res->root->accept(&visitor);
-        return true;
-    }
+bool CollectProguardRulesForManifest(const Source& source,
+                                     xml::XmlResource* res, KeepSet* keep_set,
+                                     bool main_dex_only) {
+  ManifestVisitor visitor(source, keep_set, main_dex_only);
+  if (res->root) {
+    res->root->Accept(&visitor);
+    return true;
+  }
+  return false;
+}
+
+bool CollectProguardRules(const Source& source, xml::XmlResource* res,
+                          KeepSet* keep_set) {
+  if (!res->root) {
     return false;
+  }
+
+  switch (res->file.name.type) {
+    case ResourceType::kLayout: {
+      LayoutVisitor visitor(source, keep_set);
+      res->root->Accept(&visitor);
+      break;
+    }
+
+    case ResourceType::kXml: {
+      XmlResourceVisitor visitor(source, keep_set);
+      res->root->Accept(&visitor);
+      break;
+    }
+
+    case ResourceType::kTransition: {
+      TransitionVisitor visitor(source, keep_set);
+      res->root->Accept(&visitor);
+      break;
+    }
+
+    default:
+      break;
+  }
+  return true;
 }
 
-bool collectProguardRules(const Source& source, xml::XmlResource* res, KeepSet* keepSet) {
-    if (!res->root) {
-        return false;
+bool WriteKeepSet(std::ostream* out, const KeepSet& keep_set) {
+  for (const auto& entry : keep_set.keep_set_) {
+    for (const Source& source : entry.second) {
+      *out << "# Referenced at " << source << "\n";
     }
+    *out << "-keep class " << entry.first << " { <init>(...); }\n" << std::endl;
+  }
 
-    switch (res->file.name.type) {
-        case ResourceType::kLayout: {
-            LayoutVisitor visitor(source, keepSet);
-            res->root->accept(&visitor);
-            break;
-        }
-
-        case ResourceType::kXml: {
-            XmlResourceVisitor visitor(source, keepSet);
-            res->root->accept(&visitor);
-            break;
-        }
-
-        case ResourceType::kTransition: {
-            TransitionVisitor visitor(source, keepSet);
-            res->root->accept(&visitor);
-            break;
-        }
-
-        default:
-            break;
+  for (const auto& entry : keep_set.keep_method_set_) {
+    for (const Source& source : entry.second) {
+      *out << "# Referenced at " << source << "\n";
     }
-    return true;
+    *out << "-keepclassmembers class * { *** " << entry.first << "(...); }\n"
+         << std::endl;
+  }
+  return true;
 }
 
-bool writeKeepSet(std::ostream* out, const KeepSet& keepSet) {
-    for (const auto& entry : keepSet.mKeepSet) {
-        for (const Source& source : entry.second) {
-            *out << "# Referenced at " << source << "\n";
-        }
-        *out << "-keep class " << entry.first << " { <init>(...); }\n" << std::endl;
-    }
-
-    for (const auto& entry : keepSet.mKeepMethodSet) {
-        for (const Source& source : entry.second) {
-            *out << "# Referenced at " << source << "\n";
-        }
-        *out << "-keepclassmembers class * { *** " << entry.first << "(...); }\n" << std::endl;
-    }
-    return true;
-}
-
-} // namespace proguard
-} // namespace aapt
+}  // namespace proguard
+}  // namespace aapt
diff --git a/tools/aapt2/java/ProguardRules.h b/tools/aapt2/java/ProguardRules.h
index 7578ec2..3c349ba 100644
--- a/tools/aapt2/java/ProguardRules.h
+++ b/tools/aapt2/java/ProguardRules.h
@@ -17,42 +17,42 @@
 #ifndef AAPT_PROGUARD_RULES_H
 #define AAPT_PROGUARD_RULES_H
 
-#include "Resource.h"
-#include "Source.h"
-#include "xml/XmlDom.h"
-
 #include <map>
 #include <ostream>
 #include <set>
 #include <string>
 
+#include "Resource.h"
+#include "Source.h"
+#include "xml/XmlDom.h"
+
 namespace aapt {
 namespace proguard {
 
 class KeepSet {
  public:
-  inline void addClass(const Source& source, const std::string& className) {
-    mKeepSet[className].insert(source);
+  inline void AddClass(const Source& source, const std::string& class_name) {
+    keep_set_[class_name].insert(source);
   }
 
-  inline void addMethod(const Source& source, const std::string& methodName) {
-    mKeepMethodSet[methodName].insert(source);
+  inline void AddMethod(const Source& source, const std::string& method_name) {
+    keep_method_set_[method_name].insert(source);
   }
 
  private:
-  friend bool writeKeepSet(std::ostream* out, const KeepSet& keepSet);
+  friend bool WriteKeepSet(std::ostream* out, const KeepSet& keep_set);
 
-  std::map<std::string, std::set<Source>> mKeepSet;
-  std::map<std::string, std::set<Source>> mKeepMethodSet;
+  std::map<std::string, std::set<Source>> keep_set_;
+  std::map<std::string, std::set<Source>> keep_method_set_;
 };
 
-bool collectProguardRulesForManifest(const Source& source,
-                                     xml::XmlResource* res, KeepSet* keepSet,
-                                     bool mainDexOnly = false);
-bool collectProguardRules(const Source& source, xml::XmlResource* res,
-                          KeepSet* keepSet);
+bool CollectProguardRulesForManifest(const Source& source,
+                                     xml::XmlResource* res, KeepSet* keep_set,
+                                     bool main_dex_only = false);
+bool CollectProguardRules(const Source& source, xml::XmlResource* res,
+                          KeepSet* keep_set);
 
-bool writeKeepSet(std::ostream* out, const KeepSet& keepSet);
+bool WriteKeepSet(std::ostream* out, const KeepSet& keep_set);
 
 }  // namespace proguard
 }  // namespace aapt
diff --git a/tools/aapt2/jni/Aapt2.java b/tools/aapt2/jni/Aapt2.java
new file mode 100644
index 0000000..aed23de
--- /dev/null
+++ b/tools/aapt2/jni/Aapt2.java
@@ -0,0 +1,44 @@
+package com.android.tools.aapt2;
+
+import java.util.List;
+
+/**
+ * {@code aapt2} JNI interface. To use the {@code aapt2} native interface, the
+ * shared library must first be loaded and then a new instance of this class can
+ * be used to access the library.
+ */
+public class Aapt2 {
+
+  /**
+   * Invokes {@code aapt2} to perform resource compilation.
+   *
+   * @param arguments arguments for compilation (see {@code Compile.cpp})
+   */
+  public static void compile(List<String> arguments) {
+    nativeCompile(arguments);
+  }
+
+  /**
+   * Invokes {@code aapt2} to perform linking.
+   *
+   * @param arguments arguments for linking (see {@code Link.cpp})
+   */
+  public static void link(List<String> arguments) {
+    nativeLink(arguments);
+  }
+
+  /**
+   * JNI call.
+   *
+   * @param arguments arguments for compilation (see {@code Compile.cpp})
+   */
+  private static native void nativeCompile(List<String> arguments);
+
+  /**
+   * JNI call.
+   *
+   * @param arguments arguments for linking (see {@code Link.cpp})
+   */
+  private static native void nativeLink(List<String> arguments);
+}
+
diff --git a/tools/aapt2/jni/Makefile b/tools/aapt2/jni/Makefile
new file mode 100644
index 0000000..a9e628f
--- /dev/null
+++ b/tools/aapt2/jni/Makefile
@@ -0,0 +1,25 @@
+#
+# This Makefile will generate the JNI headers for the Aapt2 class.
+#
+
+AAPT2_PKG=com.android.tools.aapt2
+AAPT2_DIR=$(shell echo -n com/android/tools/aapt2 | tr . /)
+OUT=out
+OUT_CLASSES=$(OUT)/classes
+OUT_HEADERS=.
+
+AAPT2_JAVA=Aapt2.java
+AAPT2_CLASSES=$(OUT_CLASSES)/$(AAPT2_DIR)/Aapt2.class
+
+AAPT2_HEADERS=$(OUT_HEADERS)/Aapt2.h
+
+all: $(AAPT2_HEADERS)
+
+$(AAPT2_HEADERS): $(AAPT2_JAVA) $(AAPT2_CLASSES)
+	mkdir -p $(OUT_HEADERS)
+	$(JAVA_HOME)/bin/javah -d $(OUT_HEADERS) -cp $(OUT_CLASSES) $(AAPT2_PKG).Aapt2
+
+$(AAPT2_CLASSES): $(AAPT2_JAVA)
+	mkdir -p $(OUT_CLASSES)
+	javac -d $(OUT_CLASSES) $(AAPT2_JAVA)
+
diff --git a/tools/aapt2/jni/aapt2_jni.cpp b/tools/aapt2/jni/aapt2_jni.cpp
new file mode 100644
index 0000000..211ada8
--- /dev/null
+++ b/tools/aapt2/jni/aapt2_jni.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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 "com_android_tools_aapt2_Aapt2.h"
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "android-base/logging.h"
+#include "nativehelper/ScopedUtfChars.h"
+
+#include "util/Util.h"
+
+namespace aapt {
+extern int Compile(const std::vector<StringPiece> &args);
+extern int Link(const std::vector<StringPiece> &args);
+}
+
+/*
+ * Converts a java List<String> into C++ vector<ScopedUtfChars>.
+ */
+static std::vector<ScopedUtfChars> list_to_utfchars(JNIEnv *env, jobject obj) {
+  std::vector<ScopedUtfChars> converted;
+
+  // Call size() method on the list to know how many elements there are.
+  jclass list_cls = env->GetObjectClass(obj);
+  jmethodID size_method_id = env->GetMethodID(list_cls, "size", "()I");
+  CHECK(size_method_id != 0);
+  jint size = env->CallIntMethod(obj, size_method_id);
+  CHECK(size >= 0);
+
+  // Now, iterate all strings in the list
+  // (note: generic erasure means get() return an Object)
+  jmethodID get_method_id =
+      env->GetMethodID(list_cls, "get", "()Ljava/lang/Object;");
+  for (jint i = 0; i < size; i++) {
+    // Call get(i) to get the string in the ith position.
+    jobject string_obj_uncast = env->CallObjectMethod(obj, get_method_id, i);
+    CHECK(string_obj_uncast != nullptr);
+    jstring string_obj = static_cast<jstring>(string_obj_uncast);
+    converted.push_back(ScopedUtfChars(env, string_obj));
+  }
+
+  return converted;
+}
+
+/*
+ * Extracts all StringPiece from the ScopedUtfChars instances.
+ *
+ * The returned pieces can only be used while the original ones have not been
+ * destroyed.
+ */
+static std::vector<aapt::StringPiece> extract_pieces(
+    const std::vector<ScopedUtfChars> &strings) {
+  std::vector<aapt::StringPiece> pieces;
+
+  std::for_each(
+      strings.begin(), strings.end(),
+      [&pieces](const ScopedUtfChars &p) { pieces.push_back(p.c_str()); });
+
+  return pieces;
+}
+
+JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2_nativeCompile(
+    JNIEnv *env, jclass aapt_obj, jobject arguments_obj) {
+  std::vector<ScopedUtfChars> compile_args_jni =
+      list_to_utfchars(env, arguments_obj);
+  std::vector<aapt::StringPiece> compile_args =
+      extract_pieces(compile_args_jni);
+  aapt::Compile(compile_args);
+}
+
+JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2_nativeLink(
+    JNIEnv *env, jclass aapt_obj, jobject arguments_obj) {
+  std::vector<ScopedUtfChars> link_args_jni =
+      list_to_utfchars(env, arguments_obj);
+  std::vector<aapt::StringPiece> link_args = extract_pieces(link_args_jni);
+  aapt::Link(link_args);
+}
diff --git a/tools/aapt2/jni/com_android_tools_aapt2_Aapt2.h b/tools/aapt2/jni/com_android_tools_aapt2_Aapt2.h
new file mode 100644
index 0000000..443b98f
--- /dev/null
+++ b/tools/aapt2/jni/com_android_tools_aapt2_Aapt2.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_android_tools_aapt2_Aapt2 */
+
+#ifndef _Included_com_android_tools_aapt2_Aapt2
+#define _Included_com_android_tools_aapt2_Aapt2
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     com_android_tools_aapt2_Aapt2
+ * Method:    nativeCompile
+ * Signature: (Ljava/util/List;)V
+ */
+JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2_nativeCompile
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     com_android_tools_aapt2_Aapt2
+ * Method:    nativeLink
+ * Signature: (Ljava/util/List;)V
+ */
+JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2_nativeLink
+  (JNIEnv *, jclass, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp
index 5ba9819..77471ea 100644
--- a/tools/aapt2/link/AutoVersioner.cpp
+++ b/tools/aapt2/link/AutoVersioner.cpp
@@ -14,34 +14,36 @@
  * limitations under the License.
  */
 
+#include "link/Linkers.h"
+
+#include <algorithm>
+
+#include "android-base/logging.h"
+
 #include "ConfigDescription.h"
 #include "ResourceTable.h"
 #include "SdkConstants.h"
 #include "ValueVisitor.h"
-#include "link/Linkers.h"
-
-#include <algorithm>
-#include <cassert>
 
 namespace aapt {
 
-bool shouldGenerateVersionedResource(const ResourceEntry* entry,
+bool ShouldGenerateVersionedResource(const ResourceEntry* entry,
                                      const ConfigDescription& config,
-                                     const int sdkVersionToGenerate) {
+                                     const int sdk_version_to_generate) {
   // We assume the caller is trying to generate a version greater than the
   // current configuration.
-  assert(sdkVersionToGenerate > config.sdkVersion);
+  CHECK(sdk_version_to_generate > config.sdkVersion);
 
-  const auto endIter = entry->values.end();
+  const auto end_iter = entry->values.end();
   auto iter = entry->values.begin();
-  for (; iter != endIter; ++iter) {
+  for (; iter != end_iter; ++iter) {
     if ((*iter)->config == config) {
       break;
     }
   }
 
   // The source config came from this list, so it should be here.
-  assert(iter != entry->values.end());
+  CHECK(iter != entry->values.end());
   ++iter;
 
   // The next configuration either only varies in sdkVersion, or it is
@@ -53,12 +55,12 @@
   // than other
   // qualifiers, so we need to iterate through the entire list to be sure there
   // are no higher sdk level versions of this resource.
-  ConfigDescription tempConfig(config);
-  for (; iter != endIter; ++iter) {
-    tempConfig.sdkVersion = (*iter)->config.sdkVersion;
-    if (tempConfig == (*iter)->config) {
+  ConfigDescription temp_config(config);
+  for (; iter != end_iter; ++iter) {
+    temp_config.sdkVersion = (*iter)->config.sdkVersion;
+    if (temp_config == (*iter)->config) {
       // The two configs are the same, check the sdk version.
-      return sdkVersionToGenerate < (*iter)->config.sdkVersion;
+      return sdk_version_to_generate < (*iter)->config.sdkVersion;
     }
   }
 
@@ -66,7 +68,7 @@
   return true;
 }
 
-bool AutoVersioner::consume(IAaptContext* context, ResourceTable* table) {
+bool AutoVersioner::Consume(IAaptContext* context, ResourceTable* table) {
   for (auto& package : table->packages) {
     for (auto& type : package->types) {
       if (type->type != ResourceType::kStyle) {
@@ -75,36 +77,37 @@
 
       for (auto& entry : type->entries) {
         for (size_t i = 0; i < entry->values.size(); i++) {
-          ResourceConfigValue* configValue = entry->values[i].get();
-          if (configValue->config.sdkVersion >= SDK_LOLLIPOP_MR1) {
+          ResourceConfigValue* config_value = entry->values[i].get();
+          if (config_value->config.sdkVersion >= SDK_LOLLIPOP_MR1) {
             // If this configuration is only used on L-MR1 then we don't need
             // to do anything since we use private attributes since that
             // version.
             continue;
           }
 
-          if (Style* style = valueCast<Style>(configValue->value.get())) {
-            Maybe<size_t> minSdkStripped;
+          if (Style* style = ValueCast<Style>(config_value->value.get())) {
+            Maybe<size_t> min_sdk_stripped;
             std::vector<Style::Entry> stripped;
 
             auto iter = style->entries.begin();
             while (iter != style->entries.end()) {
-              assert(iter->key.id && "IDs must be assigned and linked");
+              CHECK(bool(iter->key.id)) << "IDs must be assigned and linked";
 
               // Find the SDK level that is higher than the configuration
               // allows.
-              const size_t sdkLevel =
-                  findAttributeSdkLevel(iter->key.id.value());
-              if (sdkLevel >
-                  std::max<size_t>(configValue->config.sdkVersion, 1)) {
+              const size_t sdk_level =
+                  FindAttributeSdkLevel(iter->key.id.value());
+              if (sdk_level >
+                  std::max<size_t>(config_value->config.sdkVersion, 1)) {
                 // Record that we are about to strip this.
                 stripped.emplace_back(std::move(*iter));
 
                 // We use the smallest SDK level to generate the new style.
-                if (minSdkStripped) {
-                  minSdkStripped = std::min(minSdkStripped.value(), sdkLevel);
+                if (min_sdk_stripped) {
+                  min_sdk_stripped =
+                      std::min(min_sdk_stripped.value(), sdk_level);
                 } else {
-                  minSdkStripped = sdkLevel;
+                  min_sdk_stripped = sdk_level;
                 }
 
                 // Erase this from this style.
@@ -114,31 +117,31 @@
               ++iter;
             }
 
-            if (minSdkStripped && !stripped.empty()) {
+            if (min_sdk_stripped && !stripped.empty()) {
               // We found attributes from a higher SDK level. Check that
               // there is no other defined resource for the version we want to
               // generate.
-              if (shouldGenerateVersionedResource(entry.get(),
-                                                  configValue->config,
-                                                  minSdkStripped.value())) {
+              if (ShouldGenerateVersionedResource(entry.get(),
+                                                  config_value->config,
+                                                  min_sdk_stripped.value())) {
                 // Let's create a new Style for this versioned resource.
-                ConfigDescription newConfig(configValue->config);
-                newConfig.sdkVersion = minSdkStripped.value();
+                ConfigDescription new_config(config_value->config);
+                new_config.sdkVersion = min_sdk_stripped.value();
 
-                std::unique_ptr<Style> newStyle(
-                    style->clone(&table->stringPool));
-                newStyle->setComment(style->getComment());
-                newStyle->setSource(style->getSource());
+                std::unique_ptr<Style> new_style(
+                    style->Clone(&table->string_pool));
+                new_style->SetComment(style->GetComment());
+                new_style->SetSource(style->GetSource());
 
                 // Move the previously stripped attributes into this style.
-                newStyle->entries.insert(
-                    newStyle->entries.end(),
+                new_style->entries.insert(
+                    new_style->entries.end(),
                     std::make_move_iterator(stripped.begin()),
                     std::make_move_iterator(stripped.end()));
 
                 // Insert the new Resource into the correct place.
-                entry->findOrCreateValue(newConfig, {})->value =
-                    std::move(newStyle);
+                entry->FindOrCreateValue(new_config, {})->value =
+                    std::move(new_style);
               }
             }
           }
diff --git a/tools/aapt2/link/AutoVersioner_test.cpp b/tools/aapt2/link/AutoVersioner_test.cpp
index 04bf9cd..755af0a 100644
--- a/tools/aapt2/link/AutoVersioner_test.cpp
+++ b/tools/aapt2/link/AutoVersioner_test.cpp
@@ -14,121 +14,124 @@
  * limitations under the License.
  */
 
-#include "ConfigDescription.h"
 #include "link/Linkers.h"
+
+#include "ConfigDescription.h"
 #include "test/Test.h"
 
 namespace aapt {
 
 TEST(AutoVersionerTest, GenerateVersionedResources) {
-  const ConfigDescription defaultConfig = {};
-  const ConfigDescription landConfig = test::parseConfigOrDie("land");
-  const ConfigDescription sw600dpLandConfig =
-      test::parseConfigOrDie("sw600dp-land");
+  const ConfigDescription land_config = test::ParseConfigOrDie("land");
+  const ConfigDescription sw600dp_land_config =
+      test::ParseConfigOrDie("sw600dp-land");
 
   ResourceEntry entry("foo");
+  entry.values.push_back(util::make_unique<ResourceConfigValue>(
+      ConfigDescription::DefaultConfig(), ""));
   entry.values.push_back(
-      util::make_unique<ResourceConfigValue>(defaultConfig, ""));
+      util::make_unique<ResourceConfigValue>(land_config, ""));
   entry.values.push_back(
-      util::make_unique<ResourceConfigValue>(landConfig, ""));
-  entry.values.push_back(
-      util::make_unique<ResourceConfigValue>(sw600dpLandConfig, ""));
+      util::make_unique<ResourceConfigValue>(sw600dp_land_config, ""));
 
-  EXPECT_TRUE(shouldGenerateVersionedResource(&entry, defaultConfig, 17));
-  EXPECT_TRUE(shouldGenerateVersionedResource(&entry, landConfig, 17));
+  EXPECT_TRUE(ShouldGenerateVersionedResource(
+      &entry, ConfigDescription::DefaultConfig(), 17));
+  EXPECT_TRUE(ShouldGenerateVersionedResource(&entry, land_config, 17));
 }
 
 TEST(AutoVersionerTest, GenerateVersionedResourceWhenHigherVersionExists) {
-  const ConfigDescription defaultConfig = {};
-  const ConfigDescription sw600dpV13Config =
-      test::parseConfigOrDie("sw600dp-v13");
-  const ConfigDescription v21Config = test::parseConfigOrDie("v21");
+  const ConfigDescription sw600dp_v13_config =
+      test::ParseConfigOrDie("sw600dp-v13");
+  const ConfigDescription v21_config = test::ParseConfigOrDie("v21");
 
   ResourceEntry entry("foo");
+  entry.values.push_back(util::make_unique<ResourceConfigValue>(
+      ConfigDescription::DefaultConfig(), ""));
   entry.values.push_back(
-      util::make_unique<ResourceConfigValue>(defaultConfig, ""));
+      util::make_unique<ResourceConfigValue>(sw600dp_v13_config, ""));
   entry.values.push_back(
-      util::make_unique<ResourceConfigValue>(sw600dpV13Config, ""));
-  entry.values.push_back(util::make_unique<ResourceConfigValue>(v21Config, ""));
+      util::make_unique<ResourceConfigValue>(v21_config, ""));
 
-  EXPECT_TRUE(shouldGenerateVersionedResource(&entry, defaultConfig, 17));
-  EXPECT_FALSE(shouldGenerateVersionedResource(&entry, defaultConfig, 22));
+  EXPECT_TRUE(ShouldGenerateVersionedResource(
+      &entry, ConfigDescription::DefaultConfig(), 17));
+  EXPECT_FALSE(ShouldGenerateVersionedResource(
+      &entry, ConfigDescription::DefaultConfig(), 22));
 }
 
 TEST(AutoVersionerTest, VersionStylesForTable) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .setPackageId("app", 0x7f)
-          .addValue(
-              "app:style/Foo", test::parseConfigOrDie("v4"),
+          .SetPackageId("app", 0x7f)
+          .AddValue(
+              "app:style/Foo", test::ParseConfigOrDie("v4"),
               ResourceId(0x7f020000),
               test::StyleBuilder()
-                  .addItem("android:attr/onClick", ResourceId(0x0101026f),
+                  .AddItem("android:attr/onClick", ResourceId(0x0101026f),
                            util::make_unique<Id>())
-                  .addItem("android:attr/paddingStart", ResourceId(0x010103b3),
+                  .AddItem("android:attr/paddingStart", ResourceId(0x010103b3),
                            util::make_unique<Id>())
-                  .addItem("android:attr/requiresSmallestWidthDp",
+                  .AddItem("android:attr/requiresSmallestWidthDp",
                            ResourceId(0x01010364), util::make_unique<Id>())
-                  .addItem("android:attr/colorAccent", ResourceId(0x01010435),
+                  .AddItem("android:attr/colorAccent", ResourceId(0x01010435),
                            util::make_unique<Id>())
-                  .build())
-          .addValue(
-              "app:style/Foo", test::parseConfigOrDie("v21"),
+                  .Build())
+          .AddValue(
+              "app:style/Foo", test::ParseConfigOrDie("v21"),
               ResourceId(0x7f020000),
               test::StyleBuilder()
-                  .addItem("android:attr/paddingEnd", ResourceId(0x010103b4),
+                  .AddItem("android:attr/paddingEnd", ResourceId(0x010103b4),
                            util::make_unique<Id>())
-                  .build())
-          .build();
+                  .Build())
+          .Build();
 
   std::unique_ptr<IAaptContext> context = test::ContextBuilder()
-                                              .setCompilationPackage("app")
-                                              .setPackageId(0x7f)
-                                              .build();
+                                              .SetCompilationPackage("app")
+                                              .SetPackageId(0x7f)
+                                              .Build();
 
   AutoVersioner versioner;
-  ASSERT_TRUE(versioner.consume(context.get(), table.get()));
+  ASSERT_TRUE(versioner.Consume(context.get(), table.get()));
 
-  Style* style = test::getValueForConfig<Style>(table.get(), "app:style/Foo",
-                                                test::parseConfigOrDie("v4"));
+  Style* style = test::GetValueForConfig<Style>(table.get(), "app:style/Foo",
+                                                test::ParseConfigOrDie("v4"));
   ASSERT_NE(style, nullptr);
   ASSERT_EQ(style->entries.size(), 1u);
   AAPT_ASSERT_TRUE(style->entries.front().key.name);
   EXPECT_EQ(style->entries.front().key.name.value(),
-            test::parseNameOrDie("android:attr/onClick"));
+            test::ParseNameOrDie("android:attr/onClick"));
 
-  style = test::getValueForConfig<Style>(table.get(), "app:style/Foo",
-                                         test::parseConfigOrDie("v13"));
+  style = test::GetValueForConfig<Style>(table.get(), "app:style/Foo",
+                                         test::ParseConfigOrDie("v13"));
   ASSERT_NE(style, nullptr);
   ASSERT_EQ(style->entries.size(), 2u);
   AAPT_ASSERT_TRUE(style->entries[0].key.name);
   EXPECT_EQ(style->entries[0].key.name.value(),
-            test::parseNameOrDie("android:attr/onClick"));
+            test::ParseNameOrDie("android:attr/onClick"));
   AAPT_ASSERT_TRUE(style->entries[1].key.name);
   EXPECT_EQ(style->entries[1].key.name.value(),
-            test::parseNameOrDie("android:attr/requiresSmallestWidthDp"));
+            test::ParseNameOrDie("android:attr/requiresSmallestWidthDp"));
 
-  style = test::getValueForConfig<Style>(table.get(), "app:style/Foo",
-                                         test::parseConfigOrDie("v17"));
+  style = test::GetValueForConfig<Style>(table.get(), "app:style/Foo",
+                                         test::ParseConfigOrDie("v17"));
   ASSERT_NE(style, nullptr);
   ASSERT_EQ(style->entries.size(), 3u);
   AAPT_ASSERT_TRUE(style->entries[0].key.name);
   EXPECT_EQ(style->entries[0].key.name.value(),
-            test::parseNameOrDie("android:attr/onClick"));
+            test::ParseNameOrDie("android:attr/onClick"));
   AAPT_ASSERT_TRUE(style->entries[1].key.name);
   EXPECT_EQ(style->entries[1].key.name.value(),
-            test::parseNameOrDie("android:attr/requiresSmallestWidthDp"));
+            test::ParseNameOrDie("android:attr/requiresSmallestWidthDp"));
   AAPT_ASSERT_TRUE(style->entries[2].key.name);
   EXPECT_EQ(style->entries[2].key.name.value(),
-            test::parseNameOrDie("android:attr/paddingStart"));
+            test::ParseNameOrDie("android:attr/paddingStart"));
 
-  style = test::getValueForConfig<Style>(table.get(), "app:style/Foo",
-                                         test::parseConfigOrDie("v21"));
+  style = test::GetValueForConfig<Style>(table.get(), "app:style/Foo",
+                                         test::ParseConfigOrDie("v21"));
   ASSERT_NE(style, nullptr);
   ASSERT_EQ(style->entries.size(), 1u);
   AAPT_ASSERT_TRUE(style->entries.front().key.name);
   EXPECT_EQ(style->entries.front().key.name.value(),
-            test::parseNameOrDie("android:attr/paddingEnd"));
+            test::ParseNameOrDie("android:attr/paddingEnd"));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index a42d868..b525758 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -14,6 +14,17 @@
  * limitations under the License.
  */
 
+#include <sys/stat.h>
+
+#include <fstream>
+#include <queue>
+#include <unordered_map>
+#include <vector>
+
+#include "android-base/errors.h"
+#include "android-base/file.h"
+#include "google/protobuf/io/coded_stream.h"
+
 #include "AppInfo.h"
 #include "Debug.h"
 #include "Flags.h"
@@ -32,7 +43,6 @@
 #include "java/ProguardRules.h"
 #include "link/Linkers.h"
 #include "link/ManifestFixer.h"
-#include "link/ProductFilter.h"
 #include "link/ReferenceLinker.h"
 #include "link/TableMerger.h"
 #include "process/IResourceTableConsumer.h"
@@ -44,179 +54,179 @@
 #include "util/StringPiece.h"
 #include "xml/XmlDom.h"
 
-#include <android-base/file.h>
-#include <google/protobuf/io/coded_stream.h>
-
-#include <sys/stat.h>
-#include <fstream>
-#include <queue>
-#include <unordered_map>
-#include <vector>
-
-using google::protobuf::io::CopyingOutputStreamAdaptor;
+using ::google::protobuf::io::CopyingOutputStreamAdaptor;
 
 namespace aapt {
 
 struct LinkOptions {
-  std::string outputPath;
-  std::string manifestPath;
-  std::vector<std::string> includePaths;
-  std::vector<std::string> overlayFiles;
+  std::string output_path;
+  std::string manifest_path;
+  std::vector<std::string> include_paths;
+  std::vector<std::string> overlay_files;
+  bool output_to_directory = false;
+  bool auto_add_overlay = false;
 
   // Java/Proguard options.
-  Maybe<std::string> generateJavaClassPath;
-  Maybe<std::string> customJavaPackage;
-  std::set<std::string> extraJavaPackages;
-  Maybe<std::string> generateProguardRulesPath;
-  Maybe<std::string> generateMainDexProguardRulesPath;
+  Maybe<std::string> generate_java_class_path;
+  Maybe<std::string> custom_java_package;
+  std::set<std::string> extra_java_packages;
+  Maybe<std::string> generate_proguard_rules_path;
+  Maybe<std::string> generate_main_dex_proguard_rules_path;
+  bool generate_non_final_ids = false;
+  std::vector<std::string> javadoc_annotations;
+  Maybe<std::string> private_symbols;
 
-  bool noAutoVersion = false;
-  bool noVersionVectors = false;
-  bool noResourceDeduping = false;
-  bool staticLib = false;
-  bool noStaticLibPackages = false;
-  bool generateNonFinalIds = false;
-  std::vector<std::string> javadocAnnotations;
-  bool outputToDirectory = false;
-  bool noXmlNamespaces = false;
-  bool autoAddOverlay = false;
-  bool doNotCompressAnything = false;
-  std::unordered_set<std::string> extensionsToNotCompress;
-  Maybe<std::string> privateSymbols;
-  ManifestFixerOptions manifestFixerOptions;
+  // Optimizations/features.
+  bool no_auto_version = false;
+  bool no_version_vectors = false;
+  bool no_resource_deduping = false;
+  bool no_xml_namespaces = false;
+  bool do_not_compress_anything = false;
+  std::unordered_set<std::string> extensions_to_not_compress;
+
+  // Static lib options.
+  bool static_lib = false;
+  bool no_static_lib_packages = false;
+
+  // AndroidManifest.xml massaging options.
+  ManifestFixerOptions manifest_fixer_options;
+
+  // Products to use/filter on.
   std::unordered_set<std::string> products;
 
   // Split APK options.
-  TableSplitterOptions tableSplitterOptions;
-  std::vector<SplitConstraints> splitConstraints;
-  std::vector<std::string> splitPaths;
+  TableSplitterOptions table_splitter_options;
+  std::vector<SplitConstraints> split_constraints;
+  std::vector<std::string> split_paths;
 
   // Stable ID options.
-  std::unordered_map<ResourceName, ResourceId> stableIdMap;
-  Maybe<std::string> resourceIdMapPath;
+  std::unordered_map<ResourceName, ResourceId> stable_id_map;
+  Maybe<std::string> resource_id_map_path;
 };
 
 class LinkContext : public IAaptContext {
  public:
-  LinkContext() : mNameMangler({}) {}
+  LinkContext() : name_mangler_({}) {}
 
-  IDiagnostics* getDiagnostics() override { return &mDiagnostics; }
+  IDiagnostics* GetDiagnostics() override { return &diagnostics_; }
 
-  NameMangler* getNameMangler() override { return &mNameMangler; }
+  NameMangler* GetNameMangler() override { return &name_mangler_; }
 
-  void setNameManglerPolicy(const NameManglerPolicy& policy) {
-    mNameMangler = NameMangler(policy);
+  void SetNameManglerPolicy(const NameManglerPolicy& policy) {
+    name_mangler_ = NameMangler(policy);
   }
 
-  const std::string& getCompilationPackage() override {
-    return mCompilationPackage;
+  const std::string& GetCompilationPackage() override {
+    return compilation_package_;
   }
 
-  void setCompilationPackage(const StringPiece& packageName) {
-    mCompilationPackage = packageName.toString();
+  void SetCompilationPackage(const StringPiece& package_name) {
+    compilation_package_ = package_name.ToString();
   }
 
-  uint8_t getPackageId() override { return mPackageId; }
+  uint8_t GetPackageId() override { return package_id_; }
 
-  void setPackageId(uint8_t id) { mPackageId = id; }
+  void SetPackageId(uint8_t id) { package_id_ = id; }
 
-  SymbolTable* getExternalSymbols() override { return &mSymbols; }
+  SymbolTable* GetExternalSymbols() override { return &symbols_; }
 
-  bool verbose() override { return mVerbose; }
+  bool IsVerbose() override { return verbose_; }
 
-  void setVerbose(bool val) { mVerbose = val; }
+  void SetVerbose(bool val) { verbose_ = val; }
 
-  int getMinSdkVersion() override { return mMinSdkVersion; }
+  int GetMinSdkVersion() override { return min_sdk_version_; }
 
-  void setMinSdkVersion(int minSdk) { mMinSdkVersion = minSdk; }
+  void SetMinSdkVersion(int minSdk) { min_sdk_version_ = minSdk; }
 
  private:
-  StdErrDiagnostics mDiagnostics;
-  NameMangler mNameMangler;
-  std::string mCompilationPackage;
-  uint8_t mPackageId = 0x0;
-  SymbolTable mSymbols;
-  bool mVerbose = false;
-  int mMinSdkVersion = 0;
+  DISALLOW_COPY_AND_ASSIGN(LinkContext);
+
+  StdErrDiagnostics diagnostics_;
+  NameMangler name_mangler_;
+  std::string compilation_package_;
+  uint8_t package_id_ = 0x0;
+  SymbolTable symbols_;
+  bool verbose_ = false;
+  int min_sdk_version_ = 0;
 };
 
-static bool copyFileToArchive(io::IFile* file, const std::string& outPath,
-                              uint32_t compressionFlags, IArchiveWriter* writer,
-                              IAaptContext* context) {
-  std::unique_ptr<io::IData> data = file->openAsData();
+static bool CopyFileToArchive(io::IFile* file, const std::string& out_path,
+                              uint32_t compression_flags,
+                              IArchiveWriter* writer, IAaptContext* context) {
+  std::unique_ptr<io::IData> data = file->OpenAsData();
   if (!data) {
-    context->getDiagnostics()->error(DiagMessage(file->getSource())
+    context->GetDiagnostics()->Error(DiagMessage(file->GetSource())
                                      << "failed to open file");
     return false;
   }
 
   const uint8_t* buffer = reinterpret_cast<const uint8_t*>(data->data());
-  const size_t bufferSize = data->size();
+  const size_t buffer_size = data->size();
 
-  if (context->verbose()) {
-    context->getDiagnostics()->note(DiagMessage() << "writing " << outPath
+  if (context->IsVerbose()) {
+    context->GetDiagnostics()->Note(DiagMessage() << "writing " << out_path
                                                   << " to archive");
   }
 
-  if (writer->startEntry(outPath, compressionFlags)) {
-    if (writer->writeEntry(buffer, bufferSize)) {
-      if (writer->finishEntry()) {
+  if (writer->StartEntry(out_path, compression_flags)) {
+    if (writer->WriteEntry(buffer, buffer_size)) {
+      if (writer->FinishEntry()) {
         return true;
       }
     }
   }
 
-  context->getDiagnostics()->error(DiagMessage() << "failed to write file "
-                                                 << outPath);
+  context->GetDiagnostics()->Error(DiagMessage() << "failed to write file "
+                                                 << out_path);
   return false;
 }
 
-static bool flattenXml(xml::XmlResource* xmlRes, const StringPiece& path,
-                       Maybe<size_t> maxSdkLevel, bool keepRawValues,
+static bool FlattenXml(xml::XmlResource* xml_res, const StringPiece& path,
+                       Maybe<size_t> max_sdk_level, bool keep_raw_values,
                        IArchiveWriter* writer, IAaptContext* context) {
   BigBuffer buffer(1024);
   XmlFlattenerOptions options = {};
-  options.keepRawValues = keepRawValues;
-  options.maxSdkLevel = maxSdkLevel;
+  options.keep_raw_values = keep_raw_values;
+  options.max_sdk_level = max_sdk_level;
   XmlFlattener flattener(&buffer, options);
-  if (!flattener.consume(context, xmlRes)) {
+  if (!flattener.Consume(context, xml_res)) {
     return false;
   }
 
-  if (context->verbose()) {
+  if (context->IsVerbose()) {
     DiagMessage msg;
     msg << "writing " << path << " to archive";
-    if (maxSdkLevel) {
-      msg << " maxSdkLevel=" << maxSdkLevel.value()
-          << " keepRawValues=" << keepRawValues;
+    if (max_sdk_level) {
+      msg << " maxSdkLevel=" << max_sdk_level.value()
+          << " keepRawValues=" << keep_raw_values;
     }
-    context->getDiagnostics()->note(msg);
+    context->GetDiagnostics()->Note(msg);
   }
 
-  if (writer->startEntry(path, ArchiveEntry::kCompress)) {
-    if (writer->writeEntry(buffer)) {
-      if (writer->finishEntry()) {
+  if (writer->StartEntry(path, ArchiveEntry::kCompress)) {
+    if (writer->WriteEntry(buffer)) {
+      if (writer->FinishEntry()) {
         return true;
       }
     }
   }
-  context->getDiagnostics()->error(DiagMessage() << "failed to write " << path
+  context->GetDiagnostics()->Error(DiagMessage() << "failed to write " << path
                                                  << " to archive");
   return false;
 }
 
-static std::unique_ptr<ResourceTable> loadTableFromPb(const Source& source,
+static std::unique_ptr<ResourceTable> LoadTableFromPb(const Source& source,
                                                       const void* data,
                                                       size_t len,
                                                       IDiagnostics* diag) {
-  pb::ResourceTable pbTable;
-  if (!pbTable.ParseFromArray(data, len)) {
-    diag->error(DiagMessage(source) << "invalid compiled table");
+  pb::ResourceTable pb_table;
+  if (!pb_table.ParseFromArray(data, len)) {
+    diag->Error(DiagMessage(source) << "invalid compiled table");
     return {};
   }
 
   std::unique_ptr<ResourceTable> table =
-      deserializeTableFromPb(pbTable, source, diag);
+      DeserializeTableFromPb(pb_table, source, diag);
   if (!table) {
     return {};
   }
@@ -226,33 +236,33 @@
 /**
  * Inflates an XML file from the source path.
  */
-static std::unique_ptr<xml::XmlResource> loadXml(const std::string& path,
+static std::unique_ptr<xml::XmlResource> LoadXml(const std::string& path,
                                                  IDiagnostics* diag) {
   std::ifstream fin(path, std::ifstream::binary);
   if (!fin) {
-    diag->error(DiagMessage(path) << strerror(errno));
+    diag->Error(DiagMessage(path) << strerror(errno));
     return {};
   }
-  return xml::inflate(&fin, diag, Source(path));
+  return xml::Inflate(&fin, diag, Source(path));
 }
 
 struct ResourceFileFlattenerOptions {
-  bool noAutoVersion = false;
-  bool noVersionVectors = false;
-  bool noXmlNamespaces = false;
-  bool keepRawValues = false;
-  bool doNotCompressAnything = false;
-  bool updateProguardSpec = false;
-  std::unordered_set<std::string> extensionsToNotCompress;
+  bool no_auto_version = false;
+  bool no_version_vectors = false;
+  bool no_xml_namespaces = false;
+  bool keep_raw_values = false;
+  bool do_not_compress_anything = false;
+  bool update_proguard_spec = false;
+  std::unordered_set<std::string> extensions_to_not_compress;
 };
 
 class ResourceFileFlattener {
  public:
   ResourceFileFlattener(const ResourceFileFlattenerOptions& options,
-                        IAaptContext* context, proguard::KeepSet* keepSet)
-      : mOptions(options), mContext(context), mKeepSet(keepSet) {}
+                        IAaptContext* context, proguard::KeepSet* keep_set)
+      : options_(options), context_(context), keep_set_(keep_set) {}
 
-  bool flatten(ResourceTable* table, IArchiveWriter* archiveWriter);
+  bool Flatten(ResourceTable* table, IArchiveWriter* archive_writer);
 
  private:
   struct FileOperation {
@@ -262,118 +272,119 @@
     const ResourceEntry* entry;
 
     // The file to copy as-is.
-    io::IFile* fileToCopy;
+    io::IFile* file_to_copy;
 
     // The XML to process and flatten.
-    std::unique_ptr<xml::XmlResource> xmlToFlatten;
+    std::unique_ptr<xml::XmlResource> xml_to_flatten;
 
     // The destination to write this file to.
-    std::string dstPath;
-    bool skipVersion = false;
+    std::string dst_path;
+    bool skip_version = false;
   };
 
-  uint32_t getCompressionFlags(const StringPiece& str);
+  uint32_t GetCompressionFlags(const StringPiece& str);
 
-  bool linkAndVersionXmlFile(ResourceTable* table, FileOperation* fileOp,
-                             std::queue<FileOperation>* outFileOpQueue);
+  bool LinkAndVersionXmlFile(ResourceTable* table, FileOperation* file_op,
+                             std::queue<FileOperation>* out_file_op_queue);
 
-  ResourceFileFlattenerOptions mOptions;
-  IAaptContext* mContext;
-  proguard::KeepSet* mKeepSet;
+  ResourceFileFlattenerOptions options_;
+  IAaptContext* context_;
+  proguard::KeepSet* keep_set_;
 };
 
-uint32_t ResourceFileFlattener::getCompressionFlags(const StringPiece& str) {
-  if (mOptions.doNotCompressAnything) {
+uint32_t ResourceFileFlattener::GetCompressionFlags(const StringPiece& str) {
+  if (options_.do_not_compress_anything) {
     return 0;
   }
 
-  for (const std::string& extension : mOptions.extensionsToNotCompress) {
-    if (util::stringEndsWith(str, extension)) {
+  for (const std::string& extension : options_.extensions_to_not_compress) {
+    if (util::EndsWith(str, extension)) {
       return 0;
     }
   }
   return ArchiveEntry::kCompress;
 }
 
-bool ResourceFileFlattener::linkAndVersionXmlFile(
-    ResourceTable* table, FileOperation* fileOp,
-    std::queue<FileOperation>* outFileOpQueue) {
-  xml::XmlResource* doc = fileOp->xmlToFlatten.get();
+bool ResourceFileFlattener::LinkAndVersionXmlFile(
+    ResourceTable* table, FileOperation* file_op,
+    std::queue<FileOperation>* out_file_op_queue) {
+  xml::XmlResource* doc = file_op->xml_to_flatten.get();
   const Source& src = doc->file.source;
 
-  if (mContext->verbose()) {
-    mContext->getDiagnostics()->note(DiagMessage() << "linking " << src.path);
+  if (context_->IsVerbose()) {
+    context_->GetDiagnostics()->Note(DiagMessage() << "linking " << src.path);
   }
 
-  XmlReferenceLinker xmlLinker;
-  if (!xmlLinker.consume(mContext, doc)) {
+  XmlReferenceLinker xml_linker;
+  if (!xml_linker.Consume(context_, doc)) {
     return false;
   }
 
-  if (mOptions.updateProguardSpec &&
-      !proguard::collectProguardRules(src, doc, mKeepSet)) {
+  if (options_.update_proguard_spec &&
+      !proguard::CollectProguardRules(src, doc, keep_set_)) {
     return false;
   }
 
-  if (mOptions.noXmlNamespaces) {
-    XmlNamespaceRemover namespaceRemover;
-    if (!namespaceRemover.consume(mContext, doc)) {
+  if (options_.no_xml_namespaces) {
+    XmlNamespaceRemover namespace_remover;
+    if (!namespace_remover.Consume(context_, doc)) {
       return false;
     }
   }
 
-  if (!mOptions.noAutoVersion) {
-    if (mOptions.noVersionVectors) {
+  if (!options_.no_auto_version) {
+    if (options_.no_version_vectors) {
       // Skip this if it is a vector or animated-vector.
-      xml::Element* el = xml::findRootElement(doc);
-      if (el && el->namespaceUri.empty()) {
+      xml::Element* el = xml::FindRootElement(doc);
+      if (el && el->namespace_uri.empty()) {
         if (el->name == "vector" || el->name == "animated-vector") {
           // We are NOT going to version this file.
-          fileOp->skipVersion = true;
+          file_op->skip_version = true;
           return true;
         }
       }
     }
 
-    const ConfigDescription& config = fileOp->config;
+    const ConfigDescription& config = file_op->config;
 
     // Find the first SDK level used that is higher than this defined config and
     // not superseded by a lower or equal SDK level resource.
-    const int minSdkVersion = mContext->getMinSdkVersion();
-    for (int sdkLevel : xmlLinker.getSdkLevels()) {
-      if (sdkLevel > minSdkVersion && sdkLevel > config.sdkVersion) {
-        if (!shouldGenerateVersionedResource(fileOp->entry, config, sdkLevel)) {
+    const int min_sdk_version = context_->GetMinSdkVersion();
+    for (int sdk_level : xml_linker.sdk_levels()) {
+      if (sdk_level > min_sdk_version && sdk_level > config.sdkVersion) {
+        if (!ShouldGenerateVersionedResource(file_op->entry, config,
+                                             sdk_level)) {
           // If we shouldn't generate a versioned resource, stop checking.
           break;
         }
 
-        ResourceFile versionedFileDesc = doc->file;
-        versionedFileDesc.config.sdkVersion = (uint16_t)sdkLevel;
+        ResourceFile versioned_file_desc = doc->file;
+        versioned_file_desc.config.sdkVersion = (uint16_t)sdk_level;
 
-        FileOperation newFileOp;
-        newFileOp.xmlToFlatten = util::make_unique<xml::XmlResource>(
-            versionedFileDesc, doc->root->clone());
-        newFileOp.config = versionedFileDesc.config;
-        newFileOp.entry = fileOp->entry;
-        newFileOp.dstPath = ResourceUtils::buildResourceFileName(
-            versionedFileDesc, mContext->getNameMangler());
+        FileOperation new_file_op;
+        new_file_op.xml_to_flatten = util::make_unique<xml::XmlResource>(
+            versioned_file_desc, doc->root->Clone());
+        new_file_op.config = versioned_file_desc.config;
+        new_file_op.entry = file_op->entry;
+        new_file_op.dst_path = ResourceUtils::BuildResourceFileName(
+            versioned_file_desc, context_->GetNameMangler());
 
-        if (mContext->verbose()) {
-          mContext->getDiagnostics()->note(
-              DiagMessage(versionedFileDesc.source)
+        if (context_->IsVerbose()) {
+          context_->GetDiagnostics()->Note(
+              DiagMessage(versioned_file_desc.source)
               << "auto-versioning resource from config '" << config << "' -> '"
-              << versionedFileDesc.config << "'");
+              << versioned_file_desc.config << "'");
         }
 
-        bool added = table->addFileReferenceAllowMangled(
-            versionedFileDesc.name, versionedFileDesc.config,
-            versionedFileDesc.source, newFileOp.dstPath, nullptr,
-            mContext->getDiagnostics());
+        bool added = table->AddFileReferenceAllowMangled(
+            versioned_file_desc.name, versioned_file_desc.config,
+            versioned_file_desc.source, new_file_op.dst_path, nullptr,
+            context_->GetDiagnostics());
         if (!added) {
           return false;
         }
 
-        outFileOpQueue->push(std::move(newFileOp));
+        out_file_op_queue->push(std::move(new_file_op));
         break;
       }
     }
@@ -386,100 +397,96 @@
  * will
  * corrupt the iteration order.
  */
-bool ResourceFileFlattener::flatten(ResourceTable* table,
-                                    IArchiveWriter* archiveWriter) {
+bool ResourceFileFlattener::Flatten(ResourceTable* table,
+                                    IArchiveWriter* archive_writer) {
   bool error = false;
   std::map<std::pair<ConfigDescription, StringPiece>, FileOperation>
-      configSortedFiles;
+      config_sorted_files;
 
   for (auto& pkg : table->packages) {
     for (auto& type : pkg->types) {
       // Sort by config and name, so that we get better locality in the zip
       // file.
-      configSortedFiles.clear();
-      std::queue<FileOperation> fileOperations;
+      config_sorted_files.clear();
+      std::queue<FileOperation> file_operations;
 
       // Populate the queue with all files in the ResourceTable.
       for (auto& entry : type->entries) {
-        for (auto& configValue : entry->values) {
-          FileReference* fileRef =
-              valueCast<FileReference>(configValue->value.get());
-          if (!fileRef) {
+        for (auto& config_value : entry->values) {
+          FileReference* file_ref =
+              ValueCast<FileReference>(config_value->value.get());
+          if (!file_ref) {
             continue;
           }
 
-          io::IFile* file = fileRef->file;
+          io::IFile* file = file_ref->file;
           if (!file) {
-            mContext->getDiagnostics()->error(DiagMessage(fileRef->getSource())
+            context_->GetDiagnostics()->Error(DiagMessage(file_ref->GetSource())
                                               << "file not found");
             return false;
           }
 
-          FileOperation fileOp;
-          fileOp.entry = entry.get();
-          fileOp.dstPath = *fileRef->path;
-          fileOp.config = configValue->config;
+          FileOperation file_op;
+          file_op.entry = entry.get();
+          file_op.dst_path = *file_ref->path;
+          file_op.config = config_value->config;
 
-          const StringPiece srcPath = file->getSource().path;
+          const StringPiece src_path = file->GetSource().path;
           if (type->type != ResourceType::kRaw &&
-              (util::stringEndsWith(srcPath, ".xml.flat") ||
-               util::stringEndsWith(srcPath, ".xml"))) {
-            std::unique_ptr<io::IData> data = file->openAsData();
+              (util::EndsWith(src_path, ".xml.flat") ||
+               util::EndsWith(src_path, ".xml"))) {
+            std::unique_ptr<io::IData> data = file->OpenAsData();
             if (!data) {
-              mContext->getDiagnostics()->error(DiagMessage(file->getSource())
+              context_->GetDiagnostics()->Error(DiagMessage(file->GetSource())
                                                 << "failed to open file");
               return false;
             }
 
-            fileOp.xmlToFlatten =
-                xml::inflate(data->data(), data->size(),
-                             mContext->getDiagnostics(), file->getSource());
+            file_op.xml_to_flatten =
+                xml::Inflate(data->data(), data->size(),
+                             context_->GetDiagnostics(), file->GetSource());
 
-            if (!fileOp.xmlToFlatten) {
+            if (!file_op.xml_to_flatten) {
               return false;
             }
 
-            fileOp.xmlToFlatten->file.config = configValue->config;
-            fileOp.xmlToFlatten->file.source = fileRef->getSource();
-            fileOp.xmlToFlatten->file.name =
+            file_op.xml_to_flatten->file.config = config_value->config;
+            file_op.xml_to_flatten->file.source = file_ref->GetSource();
+            file_op.xml_to_flatten->file.name =
                 ResourceName(pkg->name, type->type, entry->name);
 
             // Enqueue the XML files to be processed.
-            fileOperations.push(std::move(fileOp));
+            file_operations.push(std::move(file_op));
           } else {
-            fileOp.fileToCopy = file;
+            file_op.file_to_copy = file;
 
             // NOTE(adamlesinski): Explicitly construct a StringPiece here, or
-            // else
-            // we end up copying the string in the std::make_pair() method, then
-            // creating a StringPiece from the copy, which would cause us to end
-            // up
-            // referencing garbage in the map.
-            const StringPiece entryName(entry->name);
-            configSortedFiles[std::make_pair(configValue->config, entryName)] =
-                std::move(fileOp);
+            // else we end up copying the string in the std::make_pair() method,
+            // then creating a StringPiece from the copy, which would cause us
+            // to end up referencing garbage in the map.
+            const StringPiece entry_name(entry->name);
+            config_sorted_files[std::make_pair(
+                config_value->config, entry_name)] = std::move(file_op);
           }
         }
       }
 
       // Now process the XML queue
-      for (; !fileOperations.empty(); fileOperations.pop()) {
-        FileOperation& fileOp = fileOperations.front();
+      for (; !file_operations.empty(); file_operations.pop()) {
+        FileOperation& file_op = file_operations.front();
 
-        if (!linkAndVersionXmlFile(table, &fileOp, &fileOperations)) {
+        if (!LinkAndVersionXmlFile(table, &file_op, &file_operations)) {
           error = true;
           continue;
         }
 
         // NOTE(adamlesinski): Explicitly construct a StringPiece here, or else
         // we end up copying the string in the std::make_pair() method, then
-        // creating
-        // a StringPiece from the copy, which would cause us to end up
-        // referencing
-        // garbage in the map.
-        const StringPiece entryName(fileOp.entry->name);
-        configSortedFiles[std::make_pair(fileOp.config, entryName)] =
-            std::move(fileOp);
+        // creating a StringPiece from the copy, which would cause us to end up
+        // referencing garbage in the map.
+        const StringPiece entry_name(file_op.entry->name);
+        config_sorted_files[std::make_pair(file_op.config, entry_name)] =
+            std::move(file_op);
       }
 
       if (error) {
@@ -487,28 +494,28 @@
       }
 
       // Now flatten the sorted values.
-      for (auto& mapEntry : configSortedFiles) {
-        const ConfigDescription& config = mapEntry.first.first;
-        const FileOperation& fileOp = mapEntry.second;
+      for (auto& map_entry : config_sorted_files) {
+        const ConfigDescription& config = map_entry.first.first;
+        const FileOperation& file_op = map_entry.second;
 
-        if (fileOp.xmlToFlatten) {
-          Maybe<size_t> maxSdkLevel;
-          if (!mOptions.noAutoVersion && !fileOp.skipVersion) {
-            maxSdkLevel =
+        if (file_op.xml_to_flatten) {
+          Maybe<size_t> max_sdk_level;
+          if (!options_.no_auto_version && !file_op.skip_version) {
+            max_sdk_level =
                 std::max<size_t>(std::max<size_t>(config.sdkVersion, 1u),
-                                 mContext->getMinSdkVersion());
+                                 context_->GetMinSdkVersion());
           }
 
-          bool result =
-              flattenXml(fileOp.xmlToFlatten.get(), fileOp.dstPath, maxSdkLevel,
-                         mOptions.keepRawValues, archiveWriter, mContext);
+          bool result = FlattenXml(
+              file_op.xml_to_flatten.get(), file_op.dst_path, max_sdk_level,
+              options_.keep_raw_values, archive_writer, context_);
           if (!result) {
             error = true;
           }
         } else {
-          bool result = copyFileToArchive(fileOp.fileToCopy, fileOp.dstPath,
-                                          getCompressionFlags(fileOp.dstPath),
-                                          archiveWriter, mContext);
+          bool result = CopyFileToArchive(
+              file_op.file_to_copy, file_op.dst_path,
+              GetCompressionFlags(file_op.dst_path), archive_writer, context_);
           if (!result) {
             error = true;
           }
@@ -519,136 +526,136 @@
   return !error;
 }
 
-static bool writeStableIdMapToPath(
+static bool WriteStableIdMapToPath(
     IDiagnostics* diag,
-    const std::unordered_map<ResourceName, ResourceId>& idMap,
-    const std::string& idMapPath) {
-  std::ofstream fout(idMapPath, std::ofstream::binary);
+    const std::unordered_map<ResourceName, ResourceId>& id_map,
+    const std::string& id_map_path) {
+  std::ofstream fout(id_map_path, std::ofstream::binary);
   if (!fout) {
-    diag->error(DiagMessage(idMapPath) << strerror(errno));
+    diag->Error(DiagMessage(id_map_path) << strerror(errno));
     return false;
   }
 
-  for (const auto& entry : idMap) {
+  for (const auto& entry : id_map) {
     const ResourceName& name = entry.first;
     const ResourceId& id = entry.second;
     fout << name << " = " << id << "\n";
   }
 
   if (!fout) {
-    diag->error(DiagMessage(idMapPath) << "failed writing to file: "
-                                       << strerror(errno));
+    diag->Error(DiagMessage(id_map_path)
+                << "failed writing to file: "
+                << android::base::SystemErrorCodeToString(errno));
     return false;
   }
 
   return true;
 }
 
-static bool loadStableIdMap(
+static bool LoadStableIdMap(
     IDiagnostics* diag, const std::string& path,
-    std::unordered_map<ResourceName, ResourceId>* outIdMap) {
+    std::unordered_map<ResourceName, ResourceId>* out_id_map) {
   std::string content;
   if (!android::base::ReadFileToString(path, &content)) {
-    diag->error(DiagMessage(path) << "failed reading stable ID file");
+    diag->Error(DiagMessage(path) << "failed reading stable ID file");
     return false;
   }
 
-  outIdMap->clear();
-  size_t lineNo = 0;
-  for (StringPiece line : util::tokenize(content, '\n')) {
-    lineNo++;
-    line = util::trimWhitespace(line);
+  out_id_map->clear();
+  size_t line_no = 0;
+  for (StringPiece line : util::Tokenize(content, '\n')) {
+    line_no++;
+    line = util::TrimWhitespace(line);
     if (line.empty()) {
       continue;
     }
 
     auto iter = std::find(line.begin(), line.end(), '=');
     if (iter == line.end()) {
-      diag->error(DiagMessage(Source(path, lineNo)) << "missing '='");
+      diag->Error(DiagMessage(Source(path, line_no)) << "missing '='");
       return false;
     }
 
     ResourceNameRef name;
-    StringPiece resNameStr =
-        util::trimWhitespace(line.substr(0, std::distance(line.begin(), iter)));
-    if (!ResourceUtils::parseResourceName(resNameStr, &name)) {
-      diag->error(DiagMessage(Source(path, lineNo)) << "invalid resource name '"
-                                                    << resNameStr << "'");
+    StringPiece res_name_str =
+        util::TrimWhitespace(line.substr(0, std::distance(line.begin(), iter)));
+    if (!ResourceUtils::ParseResourceName(res_name_str, &name)) {
+      diag->Error(DiagMessage(Source(path, line_no))
+                  << "invalid resource name '" << res_name_str << "'");
       return false;
     }
 
-    const size_t resIdStartIdx = std::distance(line.begin(), iter) + 1;
-    const size_t resIdStrLen = line.size() - resIdStartIdx;
-    StringPiece resIdStr =
-        util::trimWhitespace(line.substr(resIdStartIdx, resIdStrLen));
+    const size_t res_id_start_idx = std::distance(line.begin(), iter) + 1;
+    const size_t res_id_str_len = line.size() - res_id_start_idx;
+    StringPiece res_id_str =
+        util::TrimWhitespace(line.substr(res_id_start_idx, res_id_str_len));
 
-    Maybe<ResourceId> maybeId = ResourceUtils::parseResourceId(resIdStr);
-    if (!maybeId) {
-      diag->error(DiagMessage(Source(path, lineNo)) << "invalid resource ID '"
-                                                    << resIdStr << "'");
+    Maybe<ResourceId> maybe_id = ResourceUtils::ParseResourceId(res_id_str);
+    if (!maybe_id) {
+      diag->Error(DiagMessage(Source(path, line_no)) << "invalid resource ID '"
+                                                     << res_id_str << "'");
       return false;
     }
 
-    (*outIdMap)[name.toResourceName()] = maybeId.value();
+    (*out_id_map)[name.ToResourceName()] = maybe_id.value();
   }
   return true;
 }
 
-static bool parseSplitParameter(const StringPiece& arg, IDiagnostics* diag,
-                                std::string* outPath,
-                                SplitConstraints* outSplit) {
-  std::vector<std::string> parts = util::split(arg, ':');
+static bool ParseSplitParameter(const StringPiece& arg, IDiagnostics* diag,
+                                std::string* out_path,
+                                SplitConstraints* out_split) {
+  std::vector<std::string> parts = util::Split(arg, ':');
   if (parts.size() != 2) {
-    diag->error(DiagMessage() << "invalid split parameter '" << arg << "'");
-    diag->note(
+    diag->Error(DiagMessage() << "invalid split parameter '" << arg << "'");
+    diag->Note(
         DiagMessage()
         << "should be --split path/to/output.apk:<config>[,<config>...]");
     return false;
   }
-  *outPath = parts[0];
+  *out_path = parts[0];
   std::vector<ConfigDescription> configs;
-  for (const StringPiece& configStr : util::tokenize(parts[1], ',')) {
+  for (const StringPiece& config_str : util::Tokenize(parts[1], ',')) {
     configs.push_back({});
-    if (!ConfigDescription::parse(configStr, &configs.back())) {
-      diag->error(DiagMessage() << "invalid config '" << configStr
+    if (!ConfigDescription::Parse(config_str, &configs.back())) {
+      diag->Error(DiagMessage() << "invalid config '" << config_str
                                 << "' in split parameter '" << arg << "'");
       return false;
     }
   }
-  outSplit->configs.insert(configs.begin(), configs.end());
+  out_split->configs.insert(configs.begin(), configs.end());
   return true;
 }
 
 class LinkCommand {
  public:
   LinkCommand(LinkContext* context, const LinkOptions& options)
-      : mOptions(options),
-        mContext(context),
-        mFinalTable(),
-        mFileCollection(util::make_unique<io::FileCollection>()) {}
+      : options_(options),
+        context_(context),
+        final_table_(),
+        file_collection_(util::make_unique<io::FileCollection>()) {}
 
   /**
    * Creates a SymbolTable that loads symbols from the various APKs and caches
-   * the
-   * results for faster lookup.
+   * the results for faster lookup.
    */
-  bool loadSymbolsFromIncludePaths() {
-    std::unique_ptr<AssetManagerSymbolSource> assetSource =
+  bool LoadSymbolsFromIncludePaths() {
+    std::unique_ptr<AssetManagerSymbolSource> asset_source =
         util::make_unique<AssetManagerSymbolSource>();
-    for (const std::string& path : mOptions.includePaths) {
-      if (mContext->verbose()) {
-        mContext->getDiagnostics()->note(DiagMessage(path)
+    for (const std::string& path : options_.include_paths) {
+      if (context_->IsVerbose()) {
+        context_->GetDiagnostics()->Note(DiagMessage(path)
                                          << "loading include path");
       }
 
       // First try to load the file as a static lib.
-      std::string errorStr;
-      std::unique_ptr<ResourceTable> staticInclude =
-          loadStaticLibrary(path, &errorStr);
-      if (staticInclude) {
-        if (!mOptions.staticLib) {
+      std::string error_str;
+      std::unique_ptr<ResourceTable> static_include =
+          LoadStaticLibrary(path, &error_str);
+      if (static_include) {
+        if (!options_.static_lib) {
           // Can't include static libraries when not building a static library.
-          mContext->getDiagnostics()->error(
+          context_->GetDiagnostics()->Error(
               DiagMessage(path)
               << "can't include static library when building app");
           return false;
@@ -657,92 +664,92 @@
         // If we are using --no-static-lib-packages, we need to rename the
         // package of this
         // table to our compilation package.
-        if (mOptions.noStaticLibPackages) {
+        if (options_.no_static_lib_packages) {
           if (ResourceTablePackage* pkg =
-                  staticInclude->findPackageById(0x7f)) {
-            pkg->name = mContext->getCompilationPackage();
+                  static_include->FindPackageById(0x7f)) {
+            pkg->name = context_->GetCompilationPackage();
           }
         }
 
-        mContext->getExternalSymbols()->appendSource(
-            util::make_unique<ResourceTableSymbolSource>(staticInclude.get()));
+        context_->GetExternalSymbols()->AppendSource(
+            util::make_unique<ResourceTableSymbolSource>(static_include.get()));
 
-        mStaticTableIncludes.push_back(std::move(staticInclude));
+        static_table_includes_.push_back(std::move(static_include));
 
-      } else if (!errorStr.empty()) {
+      } else if (!error_str.empty()) {
         // We had an error with reading, so fail.
-        mContext->getDiagnostics()->error(DiagMessage(path) << errorStr);
+        context_->GetDiagnostics()->Error(DiagMessage(path) << error_str);
         return false;
       }
 
-      if (!assetSource->addAssetPath(path)) {
-        mContext->getDiagnostics()->error(DiagMessage(path)
+      if (!asset_source->AddAssetPath(path)) {
+        context_->GetDiagnostics()->Error(DiagMessage(path)
                                           << "failed to load include path");
         return false;
       }
     }
 
-    mContext->getExternalSymbols()->appendSource(std::move(assetSource));
+    context_->GetExternalSymbols()->AppendSource(std::move(asset_source));
     return true;
   }
 
-  Maybe<AppInfo> extractAppInfoFromManifest(xml::XmlResource* xmlRes,
+  Maybe<AppInfo> ExtractAppInfoFromManifest(xml::XmlResource* xml_res,
                                             IDiagnostics* diag) {
     // Make sure the first element is <manifest> with package attribute.
-    if (xml::Element* manifestEl = xml::findRootElement(xmlRes->root.get())) {
-      AppInfo appInfo;
+    if (xml::Element* manifest_el = xml::FindRootElement(xml_res->root.get())) {
+      AppInfo app_info;
 
-      if (!manifestEl->namespaceUri.empty() || manifestEl->name != "manifest") {
-        diag->error(DiagMessage(xmlRes->file.source)
+      if (!manifest_el->namespace_uri.empty() ||
+          manifest_el->name != "manifest") {
+        diag->Error(DiagMessage(xml_res->file.source)
                     << "root tag must be <manifest>");
         return {};
       }
 
-      xml::Attribute* packageAttr = manifestEl->findAttribute({}, "package");
-      if (!packageAttr) {
-        diag->error(DiagMessage(xmlRes->file.source)
+      xml::Attribute* package_attr = manifest_el->FindAttribute({}, "package");
+      if (!package_attr) {
+        diag->Error(DiagMessage(xml_res->file.source)
                     << "<manifest> must have a 'package' attribute");
         return {};
       }
 
-      appInfo.package = packageAttr->value;
+      app_info.package = package_attr->value;
 
-      if (xml::Attribute* versionCodeAttr =
-              manifestEl->findAttribute(xml::kSchemaAndroid, "versionCode")) {
-        Maybe<uint32_t> maybeCode =
-            ResourceUtils::parseInt(versionCodeAttr->value);
-        if (!maybeCode) {
-          diag->error(
-              DiagMessage(xmlRes->file.source.withLine(manifestEl->lineNumber))
-              << "invalid android:versionCode '" << versionCodeAttr->value
-              << "'");
+      if (xml::Attribute* version_code_attr =
+              manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode")) {
+        Maybe<uint32_t> maybe_code =
+            ResourceUtils::ParseInt(version_code_attr->value);
+        if (!maybe_code) {
+          diag->Error(DiagMessage(xml_res->file.source.WithLine(
+                          manifest_el->line_number))
+                      << "invalid android:versionCode '"
+                      << version_code_attr->value << "'");
           return {};
         }
-        appInfo.versionCode = maybeCode.value();
+        app_info.version_code = maybe_code.value();
       }
 
-      if (xml::Attribute* revisionCodeAttr =
-              manifestEl->findAttribute(xml::kSchemaAndroid, "revisionCode")) {
-        Maybe<uint32_t> maybeCode =
-            ResourceUtils::parseInt(revisionCodeAttr->value);
-        if (!maybeCode) {
-          diag->error(
-              DiagMessage(xmlRes->file.source.withLine(manifestEl->lineNumber))
-              << "invalid android:revisionCode '" << revisionCodeAttr->value
-              << "'");
+      if (xml::Attribute* revision_code_attr =
+              manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode")) {
+        Maybe<uint32_t> maybe_code =
+            ResourceUtils::ParseInt(revision_code_attr->value);
+        if (!maybe_code) {
+          diag->Error(DiagMessage(xml_res->file.source.WithLine(
+                          manifest_el->line_number))
+                      << "invalid android:revisionCode '"
+                      << revision_code_attr->value << "'");
           return {};
         }
-        appInfo.revisionCode = maybeCode.value();
+        app_info.revision_code = maybe_code.value();
       }
 
-      if (xml::Element* usesSdkEl = manifestEl->findChild({}, "uses-sdk")) {
-        if (xml::Attribute* minSdk = usesSdkEl->findAttribute(
+      if (xml::Element* uses_sdk_el = manifest_el->FindChild({}, "uses-sdk")) {
+        if (xml::Attribute* min_sdk = uses_sdk_el->FindAttribute(
                 xml::kSchemaAndroid, "minSdkVersion")) {
-          appInfo.minSdkVersion = minSdk->value;
+          app_info.min_sdk_version = min_sdk->value;
         }
       }
-
-      return appInfo;
+      return app_info;
     }
     return {};
   }
@@ -751,38 +758,36 @@
    * Precondition: ResourceTable doesn't have any IDs assigned yet, nor is it
    * linked.
    * Postcondition: ResourceTable has only one package left. All others are
-   * stripped, or there
-   *                is an error and false is returned.
+   * stripped, or there is an error and false is returned.
    */
-  bool verifyNoExternalPackages() {
-    auto isExtPackageFunc =
+  bool VerifyNoExternalPackages() {
+    auto is_ext_package_func =
         [&](const std::unique_ptr<ResourceTablePackage>& pkg) -> bool {
-      return mContext->getCompilationPackage() != pkg->name || !pkg->id ||
-             pkg->id.value() != mContext->getPackageId();
+      return context_->GetCompilationPackage() != pkg->name || !pkg->id ||
+             pkg->id.value() != context_->GetPackageId();
     };
 
     bool error = false;
-    for (const auto& package : mFinalTable.packages) {
-      if (isExtPackageFunc(package)) {
+    for (const auto& package : final_table_.packages) {
+      if (is_ext_package_func(package)) {
         // We have a package that is not related to the one we're building!
         for (const auto& type : package->types) {
           for (const auto& entry : type->entries) {
-            ResourceNameRef resName(package->name, type->type, entry->name);
+            ResourceNameRef res_name(package->name, type->type, entry->name);
 
-            for (const auto& configValue : entry->values) {
+            for (const auto& config_value : entry->values) {
               // Special case the occurrence of an ID that is being generated
-              // for the
-              // 'android' package. This is due to legacy reasons.
-              if (valueCast<Id>(configValue->value.get()) &&
+              // for the 'android' package. This is due to legacy reasons.
+              if (ValueCast<Id>(config_value->value.get()) &&
                   package->name == "android") {
-                mContext->getDiagnostics()->warn(
-                    DiagMessage(configValue->value->getSource())
-                    << "generated id '" << resName << "' for external package '"
-                    << package->name << "'");
+                context_->GetDiagnostics()->Warn(
+                    DiagMessage(config_value->value->GetSource())
+                    << "generated id '" << res_name
+                    << "' for external package '" << package->name << "'");
               } else {
-                mContext->getDiagnostics()->error(
-                    DiagMessage(configValue->value->getSource())
-                    << "defined resource '" << resName
+                context_->GetDiagnostics()->Error(
+                    DiagMessage(config_value->value->GetSource())
+                    << "defined resource '" << res_name
                     << "' for external package '" << package->name << "'");
                 error = true;
               }
@@ -792,21 +797,21 @@
       }
     }
 
-    auto newEndIter =
-        std::remove_if(mFinalTable.packages.begin(), mFinalTable.packages.end(),
-                       isExtPackageFunc);
-    mFinalTable.packages.erase(newEndIter, mFinalTable.packages.end());
+    auto new_end_iter =
+        std::remove_if(final_table_.packages.begin(),
+                       final_table_.packages.end(), is_ext_package_func);
+    final_table_.packages.erase(new_end_iter, final_table_.packages.end());
     return !error;
   }
 
   /**
    * Returns true if no IDs have been set, false otherwise.
    */
-  bool verifyNoIdsSet() {
-    for (const auto& package : mFinalTable.packages) {
+  bool VerifyNoIdsSet() {
+    for (const auto& package : final_table_.packages) {
       for (const auto& type : package->types) {
         if (type->id) {
-          mContext->getDiagnostics()->error(
+          context_->GetDiagnostics()->Error(
               DiagMessage() << "type " << type->type << " has ID " << std::hex
                             << (int)type->id.value() << std::dec
                             << " assigned");
@@ -815,9 +820,9 @@
 
         for (const auto& entry : type->entries) {
           if (entry->id) {
-            ResourceNameRef resName(package->name, type->type, entry->name);
-            mContext->getDiagnostics()->error(
-                DiagMessage() << "entry " << resName << " has ID " << std::hex
+            ResourceNameRef res_name(package->name, type->type, entry->name);
+            context_->GetDiagnostics()->Error(
+                DiagMessage() << "entry " << res_name << " has ID " << std::hex
                               << (int)entry->id.value() << std::dec
                               << " assigned");
             return false;
@@ -828,265 +833,261 @@
     return true;
   }
 
-  std::unique_ptr<IArchiveWriter> makeArchiveWriter(const StringPiece& out) {
-    if (mOptions.outputToDirectory) {
-      return createDirectoryArchiveWriter(mContext->getDiagnostics(), out);
+  std::unique_ptr<IArchiveWriter> MakeArchiveWriter(const StringPiece& out) {
+    if (options_.output_to_directory) {
+      return CreateDirectoryArchiveWriter(context_->GetDiagnostics(), out);
     } else {
-      return createZipFileArchiveWriter(mContext->getDiagnostics(), out);
+      return CreateZipFileArchiveWriter(context_->GetDiagnostics(), out);
     }
   }
 
-  bool flattenTable(ResourceTable* table, IArchiveWriter* writer) {
+  bool FlattenTable(ResourceTable* table, IArchiveWriter* writer) {
     BigBuffer buffer(1024);
     TableFlattener flattener(&buffer);
-    if (!flattener.consume(mContext, table)) {
+    if (!flattener.Consume(context_, table)) {
       return false;
     }
 
-    if (writer->startEntry("resources.arsc", ArchiveEntry::kAlign)) {
-      if (writer->writeEntry(buffer)) {
-        if (writer->finishEntry()) {
+    if (writer->StartEntry("resources.arsc", ArchiveEntry::kAlign)) {
+      if (writer->WriteEntry(buffer)) {
+        if (writer->FinishEntry()) {
           return true;
         }
       }
     }
 
-    mContext->getDiagnostics()->error(
+    context_->GetDiagnostics()->Error(
         DiagMessage() << "failed to write resources.arsc to archive");
     return false;
   }
 
-  bool flattenTableToPb(ResourceTable* table, IArchiveWriter* writer) {
+  bool FlattenTableToPb(ResourceTable* table, IArchiveWriter* writer) {
     // Create the file/zip entry.
-    if (!writer->startEntry("resources.arsc.flat", 0)) {
-      mContext->getDiagnostics()->error(DiagMessage() << "failed to open");
+    if (!writer->StartEntry("resources.arsc.flat", 0)) {
+      context_->GetDiagnostics()->Error(DiagMessage() << "failed to open");
       return false;
     }
 
     // Make sure CopyingOutputStreamAdaptor is deleted before we call
-    // writer->finishEntry().
+    // writer->FinishEntry().
     {
       // Wrap our IArchiveWriter with an adaptor that implements the
-      // ZeroCopyOutputStream
-      // interface.
+      // ZeroCopyOutputStream interface.
       CopyingOutputStreamAdaptor adaptor(writer);
 
-      std::unique_ptr<pb::ResourceTable> pbTable = serializeTableToPb(table);
-      if (!pbTable->SerializeToZeroCopyStream(&adaptor)) {
-        mContext->getDiagnostics()->error(DiagMessage() << "failed to write");
+      std::unique_ptr<pb::ResourceTable> pb_table = SerializeTableToPb(table);
+      if (!pb_table->SerializeToZeroCopyStream(&adaptor)) {
+        context_->GetDiagnostics()->Error(DiagMessage() << "failed to write");
         return false;
       }
     }
 
-    if (!writer->finishEntry()) {
-      mContext->getDiagnostics()->error(DiagMessage()
+    if (!writer->FinishEntry()) {
+      context_->GetDiagnostics()->Error(DiagMessage()
                                         << "failed to finish entry");
       return false;
     }
     return true;
   }
 
-  bool writeJavaFile(ResourceTable* table,
-                     const StringPiece& packageNameToGenerate,
-                     const StringPiece& outPackage,
-                     const JavaClassGeneratorOptions& javaOptions) {
-    if (!mOptions.generateJavaClassPath) {
+  bool WriteJavaFile(ResourceTable* table,
+                     const StringPiece& package_name_to_generate,
+                     const StringPiece& out_package,
+                     const JavaClassGeneratorOptions& java_options) {
+    if (!options_.generate_java_class_path) {
       return true;
     }
 
-    std::string outPath = mOptions.generateJavaClassPath.value();
-    file::appendPath(&outPath, file::packageToPath(outPackage));
-    if (!file::mkdirs(outPath)) {
-      mContext->getDiagnostics()->error(
-          DiagMessage() << "failed to create directory '" << outPath << "'");
+    std::string out_path = options_.generate_java_class_path.value();
+    file::AppendPath(&out_path, file::PackageToPath(out_package));
+    if (!file::mkdirs(out_path)) {
+      context_->GetDiagnostics()->Error(
+          DiagMessage() << "failed to create directory '" << out_path << "'");
       return false;
     }
 
-    file::appendPath(&outPath, "R.java");
+    file::AppendPath(&out_path, "R.java");
 
-    std::ofstream fout(outPath, std::ofstream::binary);
+    std::ofstream fout(out_path, std::ofstream::binary);
     if (!fout) {
-      mContext->getDiagnostics()->error(DiagMessage()
-                                        << "failed writing to '" << outPath
-                                        << "': " << strerror(errno));
+      context_->GetDiagnostics()->Error(
+          DiagMessage() << "failed writing to '" << out_path << "': "
+                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
 
-    JavaClassGenerator generator(mContext, table, javaOptions);
-    if (!generator.generate(packageNameToGenerate, outPackage, &fout)) {
-      mContext->getDiagnostics()->error(DiagMessage(outPath)
+    JavaClassGenerator generator(context_, table, java_options);
+    if (!generator.Generate(package_name_to_generate, out_package, &fout)) {
+      context_->GetDiagnostics()->Error(DiagMessage(out_path)
                                         << generator.getError());
       return false;
     }
 
     if (!fout) {
-      mContext->getDiagnostics()->error(DiagMessage()
-                                        << "failed writing to '" << outPath
-                                        << "': " << strerror(errno));
+      context_->GetDiagnostics()->Error(
+          DiagMessage() << "failed writing to '" << out_path << "': "
+                        << android::base::SystemErrorCodeToString(errno));
     }
     return true;
   }
 
-  bool writeManifestJavaFile(xml::XmlResource* manifestXml) {
-    if (!mOptions.generateJavaClassPath) {
+  bool WriteManifestJavaFile(xml::XmlResource* manifest_xml) {
+    if (!options_.generate_java_class_path) {
       return true;
     }
 
-    std::unique_ptr<ClassDefinition> manifestClass =
-        generateManifestClass(mContext->getDiagnostics(), manifestXml);
+    std::unique_ptr<ClassDefinition> manifest_class =
+        GenerateManifestClass(context_->GetDiagnostics(), manifest_xml);
 
-    if (!manifestClass) {
+    if (!manifest_class) {
       // Something bad happened, but we already logged it, so exit.
       return false;
     }
 
-    if (manifestClass->empty()) {
+    if (manifest_class->empty()) {
       // Empty Manifest class, no need to generate it.
       return true;
     }
 
     // Add any JavaDoc annotations to the generated class.
-    for (const std::string& annotation : mOptions.javadocAnnotations) {
-      std::string properAnnotation = "@";
-      properAnnotation += annotation;
-      manifestClass->getCommentBuilder()->appendComment(properAnnotation);
+    for (const std::string& annotation : options_.javadoc_annotations) {
+      std::string proper_annotation = "@";
+      proper_annotation += annotation;
+      manifest_class->GetCommentBuilder()->AppendComment(proper_annotation);
     }
 
-    const std::string& packageUtf8 = mContext->getCompilationPackage();
+    const std::string& package_utf8 = context_->GetCompilationPackage();
 
-    std::string outPath = mOptions.generateJavaClassPath.value();
-    file::appendPath(&outPath, file::packageToPath(packageUtf8));
+    std::string out_path = options_.generate_java_class_path.value();
+    file::AppendPath(&out_path, file::PackageToPath(package_utf8));
 
-    if (!file::mkdirs(outPath)) {
-      mContext->getDiagnostics()->error(
-          DiagMessage() << "failed to create directory '" << outPath << "'");
+    if (!file::mkdirs(out_path)) {
+      context_->GetDiagnostics()->Error(
+          DiagMessage() << "failed to create directory '" << out_path << "'");
       return false;
     }
 
-    file::appendPath(&outPath, "Manifest.java");
+    file::AppendPath(&out_path, "Manifest.java");
 
-    std::ofstream fout(outPath, std::ofstream::binary);
+    std::ofstream fout(out_path, std::ofstream::binary);
     if (!fout) {
-      mContext->getDiagnostics()->error(DiagMessage()
-                                        << "failed writing to '" << outPath
-                                        << "': " << strerror(errno));
+      context_->GetDiagnostics()->Error(
+          DiagMessage() << "failed writing to '" << out_path << "': "
+                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
 
-    if (!ClassDefinition::writeJavaFile(manifestClass.get(), packageUtf8, true,
-                                        &fout)) {
-      mContext->getDiagnostics()->error(DiagMessage()
-                                        << "failed writing to '" << outPath
-                                        << "': " << strerror(errno));
+    if (!ClassDefinition::WriteJavaFile(manifest_class.get(), package_utf8,
+                                        true, &fout)) {
+      context_->GetDiagnostics()->Error(
+          DiagMessage() << "failed writing to '" << out_path << "': "
+                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
     return true;
   }
 
-  bool writeProguardFile(const Maybe<std::string>& out,
-                         const proguard::KeepSet& keepSet) {
+  bool WriteProguardFile(const Maybe<std::string>& out,
+                         const proguard::KeepSet& keep_set) {
     if (!out) {
       return true;
     }
 
-    const std::string& outPath = out.value();
-    std::ofstream fout(outPath, std::ofstream::binary);
+    const std::string& out_path = out.value();
+    std::ofstream fout(out_path, std::ofstream::binary);
     if (!fout) {
-      mContext->getDiagnostics()->error(DiagMessage()
-                                        << "failed to open '" << outPath
-                                        << "': " << strerror(errno));
+      context_->GetDiagnostics()->Error(
+          DiagMessage() << "failed to open '" << out_path << "': "
+                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
 
-    proguard::writeKeepSet(&fout, keepSet);
+    proguard::WriteKeepSet(&fout, keep_set);
     if (!fout) {
-      mContext->getDiagnostics()->error(DiagMessage()
-                                        << "failed writing to '" << outPath
-                                        << "': " << strerror(errno));
+      context_->GetDiagnostics()->Error(
+          DiagMessage() << "failed writing to '" << out_path << "': "
+                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
     return true;
   }
 
-  std::unique_ptr<ResourceTable> loadStaticLibrary(const std::string& input,
-                                                   std::string* outError) {
+  std::unique_ptr<ResourceTable> LoadStaticLibrary(const std::string& input,
+                                                   std::string* out_error) {
     std::unique_ptr<io::ZipFileCollection> collection =
-        io::ZipFileCollection::create(input, outError);
+        io::ZipFileCollection::Create(input, out_error);
     if (!collection) {
       return {};
     }
-    return loadTablePbFromCollection(collection.get());
+    return LoadTablePbFromCollection(collection.get());
   }
 
-  std::unique_ptr<ResourceTable> loadTablePbFromCollection(
+  std::unique_ptr<ResourceTable> LoadTablePbFromCollection(
       io::IFileCollection* collection) {
-    io::IFile* file = collection->findFile("resources.arsc.flat");
+    io::IFile* file = collection->FindFile("resources.arsc.flat");
     if (!file) {
       return {};
     }
 
-    std::unique_ptr<io::IData> data = file->openAsData();
-    return loadTableFromPb(file->getSource(), data->data(), data->size(),
-                           mContext->getDiagnostics());
+    std::unique_ptr<io::IData> data = file->OpenAsData();
+    return LoadTableFromPb(file->GetSource(), data->data(), data->size(),
+                           context_->GetDiagnostics());
   }
 
-  bool mergeStaticLibrary(const std::string& input, bool override) {
-    if (mContext->verbose()) {
-      mContext->getDiagnostics()->note(DiagMessage()
+  bool MergeStaticLibrary(const std::string& input, bool override) {
+    if (context_->IsVerbose()) {
+      context_->GetDiagnostics()->Note(DiagMessage()
                                        << "merging static library " << input);
     }
 
-    std::string errorStr;
+    std::string error_str;
     std::unique_ptr<io::ZipFileCollection> collection =
-        io::ZipFileCollection::create(input, &errorStr);
+        io::ZipFileCollection::Create(input, &error_str);
     if (!collection) {
-      mContext->getDiagnostics()->error(DiagMessage(input) << errorStr);
+      context_->GetDiagnostics()->Error(DiagMessage(input) << error_str);
       return false;
     }
 
     std::unique_ptr<ResourceTable> table =
-        loadTablePbFromCollection(collection.get());
+        LoadTablePbFromCollection(collection.get());
     if (!table) {
-      mContext->getDiagnostics()->error(DiagMessage(input)
+      context_->GetDiagnostics()->Error(DiagMessage(input)
                                         << "invalid static library");
       return false;
     }
 
-    ResourceTablePackage* pkg = table->findPackageById(0x7f);
+    ResourceTablePackage* pkg = table->FindPackageById(0x7f);
     if (!pkg) {
-      mContext->getDiagnostics()->error(DiagMessage(input)
+      context_->GetDiagnostics()->Error(DiagMessage(input)
                                         << "static library has no package");
       return false;
     }
 
     bool result;
-    if (mOptions.noStaticLibPackages) {
+    if (options_.no_static_lib_packages) {
       // Merge all resources as if they were in the compilation package. This is
-      // the old
-      // behaviour of aapt.
+      // the old behavior of aapt.
 
       // Add the package to the set of --extra-packages so we emit an R.java for
-      // each
-      // library package.
+      // each library package.
       if (!pkg->name.empty()) {
-        mOptions.extraJavaPackages.insert(pkg->name);
+        options_.extra_java_packages.insert(pkg->name);
       }
 
       pkg->name = "";
       if (override) {
-        result = mTableMerger->mergeOverlay(Source(input), table.get(),
-                                            collection.get());
+        result = table_merger_->MergeOverlay(Source(input), table.get(),
+                                             collection.get());
       } else {
         result =
-            mTableMerger->merge(Source(input), table.get(), collection.get());
+            table_merger_->Merge(Source(input), table.get(), collection.get());
       }
 
     } else {
       // This is the proper way to merge libraries, where the package name is
-      // preserved
-      // and resource names are mangled.
-      result = mTableMerger->mergeAndMangle(Source(input), pkg->name,
-                                            table.get(), collection.get());
+      // preserved and resource names are mangled.
+      result = table_merger_->MergeAndMangle(Source(input), pkg->name,
+                                             table.get(), collection.get());
     }
 
     if (!result) {
@@ -1094,52 +1095,52 @@
     }
 
     // Make sure to move the collection into the set of IFileCollections.
-    mCollections.push_back(std::move(collection));
+    collections_.push_back(std::move(collection));
     return true;
   }
 
-  bool mergeResourceTable(io::IFile* file, bool override) {
-    if (mContext->verbose()) {
-      mContext->getDiagnostics()->note(
-          DiagMessage() << "merging resource table " << file->getSource());
+  bool MergeResourceTable(io::IFile* file, bool override) {
+    if (context_->IsVerbose()) {
+      context_->GetDiagnostics()->Note(
+          DiagMessage() << "merging resource table " << file->GetSource());
     }
 
-    std::unique_ptr<io::IData> data = file->openAsData();
+    std::unique_ptr<io::IData> data = file->OpenAsData();
     if (!data) {
-      mContext->getDiagnostics()->error(DiagMessage(file->getSource())
+      context_->GetDiagnostics()->Error(DiagMessage(file->GetSource())
                                         << "failed to open file");
       return false;
     }
 
     std::unique_ptr<ResourceTable> table =
-        loadTableFromPb(file->getSource(), data->data(), data->size(),
-                        mContext->getDiagnostics());
+        LoadTableFromPb(file->GetSource(), data->data(), data->size(),
+                        context_->GetDiagnostics());
     if (!table) {
       return false;
     }
 
     bool result = false;
     if (override) {
-      result = mTableMerger->mergeOverlay(file->getSource(), table.get());
+      result = table_merger_->MergeOverlay(file->GetSource(), table.get());
     } else {
-      result = mTableMerger->merge(file->getSource(), table.get());
+      result = table_merger_->Merge(file->GetSource(), table.get());
     }
     return result;
   }
 
-  bool mergeCompiledFile(io::IFile* file, ResourceFile* fileDesc,
+  bool MergeCompiledFile(io::IFile* file, ResourceFile* file_desc,
                          bool override) {
-    if (mContext->verbose()) {
-      mContext->getDiagnostics()->note(
-          DiagMessage() << "merging '" << fileDesc->name
-                        << "' from compiled file " << file->getSource());
+    if (context_->IsVerbose()) {
+      context_->GetDiagnostics()->Note(
+          DiagMessage() << "merging '" << file_desc->name
+                        << "' from compiled file " << file->GetSource());
     }
 
     bool result = false;
     if (override) {
-      result = mTableMerger->mergeFileOverlay(*fileDesc, file);
+      result = table_merger_->MergeFileOverlay(*file_desc, file);
     } else {
-      result = mTableMerger->mergeFile(*fileDesc, file);
+      result = table_merger_->MergeFile(*file_desc, file);
     }
 
     if (!result) {
@@ -1147,24 +1148,24 @@
     }
 
     // Add the exports of this file to the table.
-    for (SourcedResourceName& exportedSymbol : fileDesc->exportedSymbols) {
-      if (exportedSymbol.name.package.empty()) {
-        exportedSymbol.name.package = mContext->getCompilationPackage();
+    for (SourcedResourceName& exported_symbol : file_desc->exported_symbols) {
+      if (exported_symbol.name.package.empty()) {
+        exported_symbol.name.package = context_->GetCompilationPackage();
       }
 
-      ResourceNameRef resName = exportedSymbol.name;
+      ResourceNameRef res_name = exported_symbol.name;
 
-      Maybe<ResourceName> mangledName =
-          mContext->getNameMangler()->mangleName(exportedSymbol.name);
-      if (mangledName) {
-        resName = mangledName.value();
+      Maybe<ResourceName> mangled_name =
+          context_->GetNameMangler()->MangleName(exported_symbol.name);
+      if (mangled_name) {
+        res_name = mangled_name.value();
       }
 
       std::unique_ptr<Id> id = util::make_unique<Id>();
-      id->setSource(fileDesc->source.withLine(exportedSymbol.line));
-      bool result = mFinalTable.addResourceAllowMangled(
-          resName, ConfigDescription::defaultConfig(), std::string(),
-          std::move(id), mContext->getDiagnostics());
+      id->SetSource(file_desc->source.WithLine(exported_symbol.line));
+      bool result = final_table_.AddResourceAllowMangled(
+          res_name, ConfigDescription::DefaultConfig(), std::string(),
+          std::move(id), context_->GetDiagnostics());
       if (!result) {
         return false;
       }
@@ -1176,35 +1177,34 @@
    * Takes a path to load as a ZIP file and merges the files within into the
    * master ResourceTable.
    * If override is true, conflicting resources are allowed to override each
-   * other, in order of
-   * last seen.
+   * other, in order of last seen.
    *
    * An io::IFileCollection is created from the ZIP file and added to the set of
    * io::IFileCollections that are open.
    */
-  bool mergeArchive(const std::string& input, bool override) {
-    if (mContext->verbose()) {
-      mContext->getDiagnostics()->note(DiagMessage() << "merging archive "
+  bool MergeArchive(const std::string& input, bool override) {
+    if (context_->IsVerbose()) {
+      context_->GetDiagnostics()->Note(DiagMessage() << "merging archive "
                                                      << input);
     }
 
-    std::string errorStr;
+    std::string error_str;
     std::unique_ptr<io::ZipFileCollection> collection =
-        io::ZipFileCollection::create(input, &errorStr);
+        io::ZipFileCollection::Create(input, &error_str);
     if (!collection) {
-      mContext->getDiagnostics()->error(DiagMessage(input) << errorStr);
+      context_->GetDiagnostics()->Error(DiagMessage(input) << error_str);
       return false;
     }
 
     bool error = false;
-    for (auto iter = collection->iterator(); iter->hasNext();) {
-      if (!mergeFile(iter->next(), override)) {
+    for (auto iter = collection->Iterator(); iter->HasNext();) {
+      if (!MergeFile(iter->Next(), override)) {
         error = true;
       }
     }
 
     // Make sure to move the collection into the set of IFileCollections.
-    mCollections.push_back(std::move(collection));
+    collections_.push_back(std::move(collection));
     return !error;
   }
 
@@ -1220,18 +1220,16 @@
    *
    * Otherwise the files is processed on its own.
    */
-  bool mergePath(const std::string& path, bool override) {
-    if (util::stringEndsWith(path, ".flata") ||
-        util::stringEndsWith(path, ".jar") ||
-        util::stringEndsWith(path, ".jack") ||
-        util::stringEndsWith(path, ".zip")) {
-      return mergeArchive(path, override);
-    } else if (util::stringEndsWith(path, ".apk")) {
-      return mergeStaticLibrary(path, override);
+  bool MergePath(const std::string& path, bool override) {
+    if (util::EndsWith(path, ".flata") || util::EndsWith(path, ".jar") ||
+        util::EndsWith(path, ".jack") || util::EndsWith(path, ".zip")) {
+      return MergeArchive(path, override);
+    } else if (util::EndsWith(path, ".apk")) {
+      return MergeStaticLibrary(path, override);
     }
 
-    io::IFile* file = mFileCollection->insertFile(path);
-    return mergeFile(file, override);
+    io::IFile* file = file_collection_->InsertFile(path);
+    return MergeFile(file, override);
   }
 
   /**
@@ -1250,55 +1248,66 @@
    * coming from a zip,
    * where we could have other files like classes.dex.
    */
-  bool mergeFile(io::IFile* file, bool override) {
-    const Source& src = file->getSource();
-    if (util::stringEndsWith(src.path, ".arsc.flat")) {
-      return mergeResourceTable(file, override);
+  bool MergeFile(io::IFile* file, bool override) {
+    const Source& src = file->GetSource();
+    if (util::EndsWith(src.path, ".arsc.flat")) {
+      return MergeResourceTable(file, override);
 
-    } else if (util::stringEndsWith(src.path, ".flat")) {
+    } else if (util::EndsWith(src.path, ".flat")) {
       // Try opening the file and looking for an Export header.
-      std::unique_ptr<io::IData> data = file->openAsData();
+      std::unique_ptr<io::IData> data = file->OpenAsData();
       if (!data) {
-        mContext->getDiagnostics()->error(DiagMessage(src) << "failed to open");
+        context_->GetDiagnostics()->Error(DiagMessage(src) << "failed to open");
         return false;
       }
 
-      CompiledFileInputStream inputStream(data->data(), data->size());
-      uint32_t numFiles = 0;
-      if (!inputStream.ReadLittleEndian32(&numFiles)) {
-        mContext->getDiagnostics()->error(DiagMessage(src)
+      CompiledFileInputStream input_stream(data->data(), data->size());
+      uint32_t num_files = 0;
+      if (!input_stream.ReadLittleEndian32(&num_files)) {
+        context_->GetDiagnostics()->Error(DiagMessage(src)
                                           << "failed read num files");
         return false;
       }
 
-      for (uint32_t i = 0; i < numFiles; i++) {
-        pb::CompiledFile compiledFile;
-        if (!inputStream.ReadCompiledFile(&compiledFile)) {
-          mContext->getDiagnostics()->error(
+      for (uint32_t i = 0; i < num_files; i++) {
+        pb::CompiledFile compiled_file;
+        if (!input_stream.ReadCompiledFile(&compiled_file)) {
+          context_->GetDiagnostics()->Error(
               DiagMessage(src) << "failed to read compiled file header");
           return false;
         }
 
         uint64_t offset, len;
-        if (!inputStream.ReadDataMetaData(&offset, &len)) {
-          mContext->getDiagnostics()->error(DiagMessage(src)
+        if (!input_stream.ReadDataMetaData(&offset, &len)) {
+          context_->GetDiagnostics()->Error(DiagMessage(src)
                                             << "failed to read data meta data");
           return false;
         }
 
-        std::unique_ptr<ResourceFile> resourceFile =
-            deserializeCompiledFileFromPb(compiledFile, file->getSource(),
-                                          mContext->getDiagnostics());
-        if (!resourceFile) {
+        std::unique_ptr<ResourceFile> resource_file =
+            DeserializeCompiledFileFromPb(compiled_file, file->GetSource(),
+                                          context_->GetDiagnostics());
+        if (!resource_file) {
           return false;
         }
 
-        if (!mergeCompiledFile(file->createFileSegment(offset, len),
-                               resourceFile.get(), override)) {
+        if (!MergeCompiledFile(file->CreateFileSegment(offset, len),
+                               resource_file.get(), override)) {
           return false;
         }
       }
       return true;
+    } else if (util::EndsWith(src.path, ".xml") ||
+               util::EndsWith(src.path, ".png")) {
+      // Since AAPT compiles these file types and appends .flat to them, seeing
+      // their raw extensions is a sign that they weren't compiled.
+      const StringPiece file_type =
+          util::EndsWith(src.path, ".xml") ? "XML" : "PNG";
+      context_->GetDiagnostics()->Error(DiagMessage(src)
+                                        << "uncompiled " << file_type
+                                        << " file passed as argument. Must be "
+                                           "compiled first into .flat file.");
+      return false;
     }
 
     // Ignore non .flat files. This could be classes.dex or something else that
@@ -1307,95 +1316,95 @@
     return true;
   }
 
-  std::unique_ptr<xml::XmlResource> generateSplitManifest(
-      const AppInfo& appInfo, const SplitConstraints& constraints) {
+  std::unique_ptr<xml::XmlResource> GenerateSplitManifest(
+      const AppInfo& app_info, const SplitConstraints& constraints) {
     std::unique_ptr<xml::XmlResource> doc =
         util::make_unique<xml::XmlResource>();
 
-    std::unique_ptr<xml::Namespace> namespaceAndroid =
+    std::unique_ptr<xml::Namespace> namespace_android =
         util::make_unique<xml::Namespace>();
-    namespaceAndroid->namespaceUri = xml::kSchemaAndroid;
-    namespaceAndroid->namespacePrefix = "android";
+    namespace_android->namespace_uri = xml::kSchemaAndroid;
+    namespace_android->namespace_prefix = "android";
 
-    std::unique_ptr<xml::Element> manifestEl =
+    std::unique_ptr<xml::Element> manifest_el =
         util::make_unique<xml::Element>();
-    manifestEl->name = "manifest";
-    manifestEl->attributes.push_back(
-        xml::Attribute{"", "package", appInfo.package});
+    manifest_el->name = "manifest";
+    manifest_el->attributes.push_back(
+        xml::Attribute{"", "package", app_info.package});
 
-    if (appInfo.versionCode) {
-      manifestEl->attributes.push_back(
+    if (app_info.version_code) {
+      manifest_el->attributes.push_back(
           xml::Attribute{xml::kSchemaAndroid, "versionCode",
-                         std::to_string(appInfo.versionCode.value())});
+                         std::to_string(app_info.version_code.value())});
     }
 
-    if (appInfo.revisionCode) {
-      manifestEl->attributes.push_back(
+    if (app_info.revision_code) {
+      manifest_el->attributes.push_back(
           xml::Attribute{xml::kSchemaAndroid, "revisionCode",
-                         std::to_string(appInfo.revisionCode.value())});
+                         std::to_string(app_info.revision_code.value())});
     }
 
-    std::stringstream splitName;
-    splitName << "config." << util::joiner(constraints.configs, "_");
+    std::stringstream split_name;
+    split_name << "config." << util::Joiner(constraints.configs, "_");
 
-    manifestEl->attributes.push_back(
-        xml::Attribute{"", "split", splitName.str()});
+    manifest_el->attributes.push_back(
+        xml::Attribute{"", "split", split_name.str()});
 
-    std::unique_ptr<xml::Element> applicationEl =
+    std::unique_ptr<xml::Element> application_el =
         util::make_unique<xml::Element>();
-    applicationEl->name = "application";
-    applicationEl->attributes.push_back(
+    application_el->name = "application";
+    application_el->attributes.push_back(
         xml::Attribute{xml::kSchemaAndroid, "hasCode", "false"});
 
-    manifestEl->addChild(std::move(applicationEl));
-    namespaceAndroid->addChild(std::move(manifestEl));
-    doc->root = std::move(namespaceAndroid);
+    manifest_el->AppendChild(std::move(application_el));
+    namespace_android->AppendChild(std::move(manifest_el));
+    doc->root = std::move(namespace_android);
     return doc;
   }
 
   /**
    * Writes the AndroidManifest, ResourceTable, and all XML files referenced by
-   * the ResourceTable
-   * to the IArchiveWriter.
+   * the ResourceTable to the IArchiveWriter.
    */
-  bool writeApk(IArchiveWriter* writer, proguard::KeepSet* keepSet,
+  bool WriteApk(IArchiveWriter* writer, proguard::KeepSet* keep_set,
                 xml::XmlResource* manifest, ResourceTable* table) {
-    const bool keepRawValues = mOptions.staticLib;
-    bool result = flattenXml(manifest, "AndroidManifest.xml", {}, keepRawValues,
-                             writer, mContext);
+    const bool keep_raw_values = options_.static_lib;
+    bool result = FlattenXml(manifest, "AndroidManifest.xml", {},
+                             keep_raw_values, writer, context_);
     if (!result) {
       return false;
     }
 
-    ResourceFileFlattenerOptions fileFlattenerOptions;
-    fileFlattenerOptions.keepRawValues = keepRawValues;
-    fileFlattenerOptions.doNotCompressAnything = mOptions.doNotCompressAnything;
-    fileFlattenerOptions.extensionsToNotCompress =
-        mOptions.extensionsToNotCompress;
-    fileFlattenerOptions.noAutoVersion = mOptions.noAutoVersion;
-    fileFlattenerOptions.noVersionVectors = mOptions.noVersionVectors;
-    fileFlattenerOptions.noXmlNamespaces = mOptions.noXmlNamespaces;
-    fileFlattenerOptions.updateProguardSpec =
-        static_cast<bool>(mOptions.generateProguardRulesPath);
+    ResourceFileFlattenerOptions file_flattener_options;
+    file_flattener_options.keep_raw_values = keep_raw_values;
+    file_flattener_options.do_not_compress_anything =
+        options_.do_not_compress_anything;
+    file_flattener_options.extensions_to_not_compress =
+        options_.extensions_to_not_compress;
+    file_flattener_options.no_auto_version = options_.no_auto_version;
+    file_flattener_options.no_version_vectors = options_.no_version_vectors;
+    file_flattener_options.no_xml_namespaces = options_.no_xml_namespaces;
+    file_flattener_options.update_proguard_spec =
+        static_cast<bool>(options_.generate_proguard_rules_path);
 
-    ResourceFileFlattener fileFlattener(fileFlattenerOptions, mContext,
-                                        keepSet);
+    ResourceFileFlattener file_flattener(file_flattener_options, context_,
+                                         keep_set);
 
-    if (!fileFlattener.flatten(table, writer)) {
-      mContext->getDiagnostics()->error(DiagMessage()
+    if (!file_flattener.Flatten(table, writer)) {
+      context_->GetDiagnostics()->Error(DiagMessage()
                                         << "failed linking file resources");
       return false;
     }
 
-    if (mOptions.staticLib) {
-      if (!flattenTableToPb(table, writer)) {
-        mContext->getDiagnostics()->error(
+    if (options_.static_lib) {
+      if (!FlattenTableToPb(table, writer)) {
+        context_->GetDiagnostics()->Error(
             DiagMessage() << "failed to write resources.arsc.flat");
         return false;
       }
     } else {
-      if (!flattenTable(table, writer)) {
-        mContext->getDiagnostics()->error(DiagMessage()
+      if (!FlattenTable(table, writer)) {
+        context_->GetDiagnostics()->Error(DiagMessage()
                                           << "failed to write resources.arsc");
         return false;
       }
@@ -1403,118 +1412,118 @@
     return true;
   }
 
-  int run(const std::vector<std::string>& inputFiles) {
+  int Run(const std::vector<std::string>& input_files) {
     // Load the AndroidManifest.xml
-    std::unique_ptr<xml::XmlResource> manifestXml =
-        loadXml(mOptions.manifestPath, mContext->getDiagnostics());
-    if (!manifestXml) {
+    std::unique_ptr<xml::XmlResource> manifest_xml =
+        LoadXml(options_.manifest_path, context_->GetDiagnostics());
+    if (!manifest_xml) {
       return 1;
     }
 
     // First extract the Package name without modifying it (via
     // --rename-manifest-package).
-    if (Maybe<AppInfo> maybeAppInfo = extractAppInfoFromManifest(
-            manifestXml.get(), mContext->getDiagnostics())) {
-      const AppInfo& appInfo = maybeAppInfo.value();
-      mContext->setCompilationPackage(appInfo.package);
+    if (Maybe<AppInfo> maybe_app_info = ExtractAppInfoFromManifest(
+            manifest_xml.get(), context_->GetDiagnostics())) {
+      const AppInfo& app_info = maybe_app_info.value();
+      context_->SetCompilationPackage(app_info.package);
     }
 
-    ManifestFixer manifestFixer(mOptions.manifestFixerOptions);
-    if (!manifestFixer.consume(mContext, manifestXml.get())) {
+    ManifestFixer manifest_fixer(options_.manifest_fixer_options);
+    if (!manifest_fixer.Consume(context_, manifest_xml.get())) {
       return 1;
     }
 
-    Maybe<AppInfo> maybeAppInfo = extractAppInfoFromManifest(
-        manifestXml.get(), mContext->getDiagnostics());
-    if (!maybeAppInfo) {
+    Maybe<AppInfo> maybe_app_info = ExtractAppInfoFromManifest(
+        manifest_xml.get(), context_->GetDiagnostics());
+    if (!maybe_app_info) {
       return 1;
     }
 
-    const AppInfo& appInfo = maybeAppInfo.value();
-    if (appInfo.minSdkVersion) {
-      if (Maybe<int> maybeMinSdkVersion =
-              ResourceUtils::parseSdkVersion(appInfo.minSdkVersion.value())) {
-        mContext->setMinSdkVersion(maybeMinSdkVersion.value());
+    const AppInfo& app_info = maybe_app_info.value();
+    if (app_info.min_sdk_version) {
+      if (Maybe<int> maybe_min_sdk_version = ResourceUtils::ParseSdkVersion(
+              app_info.min_sdk_version.value())) {
+        context_->SetMinSdkVersion(maybe_min_sdk_version.value());
       }
     }
 
-    mContext->setNameManglerPolicy(
-        NameManglerPolicy{mContext->getCompilationPackage()});
-    if (mContext->getCompilationPackage() == "android") {
-      mContext->setPackageId(0x01);
+    context_->SetNameManglerPolicy(
+        NameManglerPolicy{context_->GetCompilationPackage()});
+    if (context_->GetCompilationPackage() == "android") {
+      context_->SetPackageId(0x01);
     } else {
-      mContext->setPackageId(0x7f);
+      context_->SetPackageId(0x7f);
     }
 
-    if (!loadSymbolsFromIncludePaths()) {
+    if (!LoadSymbolsFromIncludePaths()) {
       return 1;
     }
 
-    TableMergerOptions tableMergerOptions;
-    tableMergerOptions.autoAddOverlay = mOptions.autoAddOverlay;
-    mTableMerger = util::make_unique<TableMerger>(mContext, &mFinalTable,
-                                                  tableMergerOptions);
+    TableMergerOptions table_merger_options;
+    table_merger_options.auto_add_overlay = options_.auto_add_overlay;
+    table_merger_ = util::make_unique<TableMerger>(context_, &final_table_,
+                                                   table_merger_options);
 
-    if (mContext->verbose()) {
-      mContext->getDiagnostics()->note(DiagMessage()
+    if (context_->IsVerbose()) {
+      context_->GetDiagnostics()->Note(DiagMessage()
                                        << "linking package '"
-                                       << mContext->getCompilationPackage()
+                                       << context_->GetCompilationPackage()
                                        << "' with package ID " << std::hex
-                                       << (int)mContext->getPackageId());
+                                       << (int)context_->GetPackageId());
     }
 
-    for (const std::string& input : inputFiles) {
-      if (!mergePath(input, false)) {
-        mContext->getDiagnostics()->error(DiagMessage()
+    for (const std::string& input : input_files) {
+      if (!MergePath(input, false)) {
+        context_->GetDiagnostics()->Error(DiagMessage()
                                           << "failed parsing input");
         return 1;
       }
     }
 
-    for (const std::string& input : mOptions.overlayFiles) {
-      if (!mergePath(input, true)) {
-        mContext->getDiagnostics()->error(DiagMessage()
+    for (const std::string& input : options_.overlay_files) {
+      if (!MergePath(input, true)) {
+        context_->GetDiagnostics()->Error(DiagMessage()
                                           << "failed parsing overlays");
         return 1;
       }
     }
 
-    if (!verifyNoExternalPackages()) {
+    if (!VerifyNoExternalPackages()) {
       return 1;
     }
 
-    if (!mOptions.staticLib) {
+    if (!options_.static_lib) {
       PrivateAttributeMover mover;
-      if (!mover.consume(mContext, &mFinalTable)) {
-        mContext->getDiagnostics()->error(
+      if (!mover.Consume(context_, &final_table_)) {
+        context_->GetDiagnostics()->Error(
             DiagMessage() << "failed moving private attributes");
         return 1;
       }
 
       // Assign IDs if we are building a regular app.
-      IdAssigner idAssigner(&mOptions.stableIdMap);
-      if (!idAssigner.consume(mContext, &mFinalTable)) {
-        mContext->getDiagnostics()->error(DiagMessage()
+      IdAssigner id_assigner(&options_.stable_id_map);
+      if (!id_assigner.Consume(context_, &final_table_)) {
+        context_->GetDiagnostics()->Error(DiagMessage()
                                           << "failed assigning IDs");
         return 1;
       }
 
       // Now grab each ID and emit it as a file.
-      if (mOptions.resourceIdMapPath) {
-        for (auto& package : mFinalTable.packages) {
+      if (options_.resource_id_map_path) {
+        for (auto& package : final_table_.packages) {
           for (auto& type : package->types) {
             for (auto& entry : type->entries) {
               ResourceName name(package->name, type->type, entry->name);
               // The IDs are guaranteed to exist.
-              mOptions.stableIdMap[std::move(name)] = ResourceId(
+              options_.stable_id_map[std::move(name)] = ResourceId(
                   package->id.value(), type->id.value(), entry->id.value());
             }
           }
         }
 
-        if (!writeStableIdMapToPath(mContext->getDiagnostics(),
-                                    mOptions.stableIdMap,
-                                    mOptions.resourceIdMapPath.value())) {
+        if (!WriteStableIdMapToPath(context_->GetDiagnostics(),
+                                    options_.stable_id_map,
+                                    options_.resource_id_map_path.value())) {
           return 1;
         }
       }
@@ -1522,80 +1531,80 @@
       // Static libs are merged with other apps, and ID collisions are bad, so
       // verify that
       // no IDs have been set.
-      if (!verifyNoIdsSet()) {
+      if (!VerifyNoIdsSet()) {
         return 1;
       }
     }
 
     // Add the names to mangle based on our source merge earlier.
-    mContext->setNameManglerPolicy(NameManglerPolicy{
-        mContext->getCompilationPackage(), mTableMerger->getMergedPackages()});
+    context_->SetNameManglerPolicy(NameManglerPolicy{
+        context_->GetCompilationPackage(), table_merger_->merged_packages()});
 
     // Add our table to the symbol table.
-    mContext->getExternalSymbols()->prependSource(
-        util::make_unique<ResourceTableSymbolSource>(&mFinalTable));
+    context_->GetExternalSymbols()->PrependSource(
+        util::make_unique<ResourceTableSymbolSource>(&final_table_));
 
     ReferenceLinker linker;
-    if (!linker.consume(mContext, &mFinalTable)) {
-      mContext->getDiagnostics()->error(DiagMessage()
+    if (!linker.Consume(context_, &final_table_)) {
+      context_->GetDiagnostics()->Error(DiagMessage()
                                         << "failed linking references");
       return 1;
     }
 
-    if (mOptions.staticLib) {
-      if (!mOptions.products.empty()) {
-        mContext->getDiagnostics()
-            ->warn(DiagMessage()
+    if (options_.static_lib) {
+      if (!options_.products.empty()) {
+        context_->GetDiagnostics()
+            ->Warn(DiagMessage()
                    << "can't select products when building static library");
       }
     } else {
-      ProductFilter productFilter(mOptions.products);
-      if (!productFilter.consume(mContext, &mFinalTable)) {
-        mContext->getDiagnostics()->error(DiagMessage()
+      ProductFilter product_filter(options_.products);
+      if (!product_filter.Consume(context_, &final_table_)) {
+        context_->GetDiagnostics()->Error(DiagMessage()
                                           << "failed stripping products");
         return 1;
       }
     }
 
-    if (!mOptions.noAutoVersion) {
+    if (!options_.no_auto_version) {
       AutoVersioner versioner;
-      if (!versioner.consume(mContext, &mFinalTable)) {
-        mContext->getDiagnostics()->error(DiagMessage()
+      if (!versioner.Consume(context_, &final_table_)) {
+        context_->GetDiagnostics()->Error(DiagMessage()
                                           << "failed versioning styles");
         return 1;
       }
     }
 
-    if (!mOptions.staticLib && mContext->getMinSdkVersion() > 0) {
-      if (mContext->verbose()) {
-        mContext->getDiagnostics()->note(
+    if (!options_.static_lib && context_->GetMinSdkVersion() > 0) {
+      if (context_->IsVerbose()) {
+        context_->GetDiagnostics()->Note(
             DiagMessage() << "collapsing resource versions for minimum SDK "
-                          << mContext->getMinSdkVersion());
+                          << context_->GetMinSdkVersion());
       }
 
       VersionCollapser collapser;
-      if (!collapser.consume(mContext, &mFinalTable)) {
+      if (!collapser.Consume(context_, &final_table_)) {
         return 1;
       }
     }
 
-    if (!mOptions.noResourceDeduping) {
+    if (!options_.no_resource_deduping) {
       ResourceDeduper deduper;
-      if (!deduper.consume(mContext, &mFinalTable)) {
-        mContext->getDiagnostics()->error(DiagMessage()
+      if (!deduper.Consume(context_, &final_table_)) {
+        context_->GetDiagnostics()->Error(DiagMessage()
                                           << "failed deduping resources");
         return 1;
       }
     }
 
-    proguard::KeepSet proguardKeepSet;
-    proguard::KeepSet proguardMainDexKeepSet;
+    proguard::KeepSet proguard_keep_set;
+    proguard::KeepSet proguard_main_dex_keep_set;
 
-    if (mOptions.staticLib) {
-      if (mOptions.tableSplitterOptions.configFilter != nullptr ||
-          mOptions.tableSplitterOptions.preferredDensity) {
-        mContext->getDiagnostics()
-            ->warn(DiagMessage()
+    if (options_.static_lib) {
+      if (options_.table_splitter_options.config_filter != nullptr ||
+          options_.table_splitter_options.preferred_density) {
+        context_->GetDiagnostics()
+            ->Warn(DiagMessage()
                    << "can't strip resources when building static library");
       }
     } else {
@@ -1604,73 +1613,73 @@
       // than or equal to the minSdk. Otherwise the resources that have had
       // their SDK version
       // stripped due to minSdk won't ever match.
-      std::vector<SplitConstraints> adjustedConstraintsList;
-      adjustedConstraintsList.reserve(mOptions.splitConstraints.size());
-      for (const SplitConstraints& constraints : mOptions.splitConstraints) {
-        SplitConstraints adjustedConstraints;
+      std::vector<SplitConstraints> adjusted_constraints_list;
+      adjusted_constraints_list.reserve(options_.split_constraints.size());
+      for (const SplitConstraints& constraints : options_.split_constraints) {
+        SplitConstraints adjusted_constraints;
         for (const ConfigDescription& config : constraints.configs) {
-          if (config.sdkVersion <= mContext->getMinSdkVersion()) {
-            adjustedConstraints.configs.insert(config.copyWithoutSdkVersion());
+          if (config.sdkVersion <= context_->GetMinSdkVersion()) {
+            adjusted_constraints.configs.insert(config.CopyWithoutSdkVersion());
           } else {
-            adjustedConstraints.configs.insert(config);
+            adjusted_constraints.configs.insert(config);
           }
         }
-        adjustedConstraintsList.push_back(std::move(adjustedConstraints));
+        adjusted_constraints_list.push_back(std::move(adjusted_constraints));
       }
 
-      TableSplitter tableSplitter(adjustedConstraintsList,
-                                  mOptions.tableSplitterOptions);
-      if (!tableSplitter.verifySplitConstraints(mContext)) {
+      TableSplitter table_splitter(adjusted_constraints_list,
+                                   options_.table_splitter_options);
+      if (!table_splitter.VerifySplitConstraints(context_)) {
         return 1;
       }
-      tableSplitter.splitTable(&mFinalTable);
+      table_splitter.SplitTable(&final_table_);
 
       // Now we need to write out the Split APKs.
-      auto pathIter = mOptions.splitPaths.begin();
-      auto splitConstraintsIter = adjustedConstraintsList.begin();
-      for (std::unique_ptr<ResourceTable>& splitTable :
-           tableSplitter.getSplits()) {
-        if (mContext->verbose()) {
-          mContext->getDiagnostics()->note(
-              DiagMessage(*pathIter)
+      auto path_iter = options_.split_paths.begin();
+      auto split_constraints_iter = adjusted_constraints_list.begin();
+      for (std::unique_ptr<ResourceTable>& split_table :
+           table_splitter.splits()) {
+        if (context_->IsVerbose()) {
+          context_->GetDiagnostics()->Note(
+              DiagMessage(*path_iter)
               << "generating split with configurations '"
-              << util::joiner(splitConstraintsIter->configs, ", ") << "'");
+              << util::Joiner(split_constraints_iter->configs, ", ") << "'");
         }
 
-        std::unique_ptr<IArchiveWriter> archiveWriter =
-            makeArchiveWriter(*pathIter);
-        if (!archiveWriter) {
-          mContext->getDiagnostics()->error(DiagMessage()
+        std::unique_ptr<IArchiveWriter> archive_writer =
+            MakeArchiveWriter(*path_iter);
+        if (!archive_writer) {
+          context_->GetDiagnostics()->Error(DiagMessage()
                                             << "failed to create archive");
           return 1;
         }
 
         // Generate an AndroidManifest.xml for each split.
-        std::unique_ptr<xml::XmlResource> splitManifest =
-            generateSplitManifest(appInfo, *splitConstraintsIter);
+        std::unique_ptr<xml::XmlResource> split_manifest =
+            GenerateSplitManifest(app_info, *split_constraints_iter);
 
         XmlReferenceLinker linker;
-        if (!linker.consume(mContext, splitManifest.get())) {
-          mContext->getDiagnostics()->error(
+        if (!linker.Consume(context_, split_manifest.get())) {
+          context_->GetDiagnostics()->Error(
               DiagMessage() << "failed to create Split AndroidManifest.xml");
           return 1;
         }
 
-        if (!writeApk(archiveWriter.get(), &proguardKeepSet,
-                      splitManifest.get(), splitTable.get())) {
+        if (!WriteApk(archive_writer.get(), &proguard_keep_set,
+                      split_manifest.get(), split_table.get())) {
           return 1;
         }
 
-        ++pathIter;
-        ++splitConstraintsIter;
+        ++path_iter;
+        ++split_constraints_iter;
       }
     }
 
     // Start writing the base APK.
-    std::unique_ptr<IArchiveWriter> archiveWriter =
-        makeArchiveWriter(mOptions.outputPath);
-    if (!archiveWriter) {
-      mContext->getDiagnostics()->error(DiagMessage()
+    std::unique_ptr<IArchiveWriter> archive_writer =
+        MakeArchiveWriter(options_.output_path);
+    if (!archive_writer) {
+      context_->GetDiagnostics()->Error(DiagMessage()
                                         << "failed to create archive");
       return 1;
     }
@@ -1681,35 +1690,35 @@
       // from the name
       // (aka, which package the AndroidManifest.xml is coming from).
       // So we give it a package name so it can see local resources.
-      manifestXml->file.name.package = mContext->getCompilationPackage();
+      manifest_xml->file.name.package = context_->GetCompilationPackage();
 
-      XmlReferenceLinker manifestLinker;
-      if (manifestLinker.consume(mContext, manifestXml.get())) {
-        if (mOptions.generateProguardRulesPath &&
-            !proguard::collectProguardRulesForManifest(
-                Source(mOptions.manifestPath), manifestXml.get(),
-                &proguardKeepSet)) {
+      XmlReferenceLinker manifest_linker;
+      if (manifest_linker.Consume(context_, manifest_xml.get())) {
+        if (options_.generate_proguard_rules_path &&
+            !proguard::CollectProguardRulesForManifest(
+                Source(options_.manifest_path), manifest_xml.get(),
+                &proguard_keep_set)) {
           error = true;
         }
 
-        if (mOptions.generateMainDexProguardRulesPath &&
-            !proguard::collectProguardRulesForManifest(
-                Source(mOptions.manifestPath), manifestXml.get(),
-                &proguardMainDexKeepSet, true)) {
+        if (options_.generate_main_dex_proguard_rules_path &&
+            !proguard::CollectProguardRulesForManifest(
+                Source(options_.manifest_path), manifest_xml.get(),
+                &proguard_main_dex_keep_set, true)) {
           error = true;
         }
 
-        if (mOptions.generateJavaClassPath) {
-          if (!writeManifestJavaFile(manifestXml.get())) {
+        if (options_.generate_java_class_path) {
+          if (!WriteManifestJavaFile(manifest_xml.get())) {
             error = true;
           }
         }
 
-        if (mOptions.noXmlNamespaces) {
+        if (options_.no_xml_namespaces) {
           // PackageParser will fail if URIs are removed from
           // AndroidManifest.xml.
-          XmlNamespaceRemover namespaceRemover(true /* keepUris */);
-          if (!namespaceRemover.consume(mContext, manifestXml.get())) {
+          XmlNamespaceRemover namespace_remover(true /* keepUris */);
+          if (!namespace_remover.Consume(context_, manifest_xml.get())) {
             error = true;
           }
         }
@@ -1719,382 +1728,385 @@
     }
 
     if (error) {
-      mContext->getDiagnostics()->error(DiagMessage()
+      context_->GetDiagnostics()->Error(DiagMessage()
                                         << "failed processing manifest");
       return 1;
     }
 
-    if (!writeApk(archiveWriter.get(), &proguardKeepSet, manifestXml.get(),
-                  &mFinalTable)) {
+    if (!WriteApk(archive_writer.get(), &proguard_keep_set, manifest_xml.get(),
+                  &final_table_)) {
       return 1;
     }
 
-    if (mOptions.generateJavaClassPath) {
+    if (options_.generate_java_class_path) {
       JavaClassGeneratorOptions options;
       options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
-      options.javadocAnnotations = mOptions.javadocAnnotations;
+      options.javadoc_annotations = options_.javadoc_annotations;
 
-      if (mOptions.staticLib || mOptions.generateNonFinalIds) {
-        options.useFinal = false;
+      if (options_.static_lib || options_.generate_non_final_ids) {
+        options.use_final = false;
       }
 
-      const StringPiece actualPackage = mContext->getCompilationPackage();
-      StringPiece outputPackage = mContext->getCompilationPackage();
-      if (mOptions.customJavaPackage) {
+      const StringPiece actual_package = context_->GetCompilationPackage();
+      StringPiece output_package = context_->GetCompilationPackage();
+      if (options_.custom_java_package) {
         // Override the output java package to the custom one.
-        outputPackage = mOptions.customJavaPackage.value();
+        output_package = options_.custom_java_package.value();
       }
 
-      if (mOptions.privateSymbols) {
+      if (options_.private_symbols) {
         // If we defined a private symbols package, we only emit Public symbols
         // to the original package, and private and public symbols to the
         // private package.
 
         options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic;
-        if (!writeJavaFile(&mFinalTable, mContext->getCompilationPackage(),
-                           outputPackage, options)) {
+        if (!WriteJavaFile(&final_table_, context_->GetCompilationPackage(),
+                           output_package, options)) {
           return 1;
         }
 
         options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate;
-        outputPackage = mOptions.privateSymbols.value();
+        output_package = options_.private_symbols.value();
       }
 
-      if (!writeJavaFile(&mFinalTable, actualPackage, outputPackage, options)) {
+      if (!WriteJavaFile(&final_table_, actual_package, output_package,
+                         options)) {
         return 1;
       }
 
-      for (const std::string& extraPackage : mOptions.extraJavaPackages) {
-        if (!writeJavaFile(&mFinalTable, actualPackage, extraPackage,
+      for (const std::string& extra_package : options_.extra_java_packages) {
+        if (!WriteJavaFile(&final_table_, actual_package, extra_package,
                            options)) {
           return 1;
         }
       }
     }
 
-    if (!writeProguardFile(mOptions.generateProguardRulesPath,
-                           proguardKeepSet)) {
+    if (!WriteProguardFile(options_.generate_proguard_rules_path,
+                           proguard_keep_set)) {
       return 1;
     }
 
-    if (!writeProguardFile(mOptions.generateMainDexProguardRulesPath,
-                           proguardMainDexKeepSet)) {
+    if (!WriteProguardFile(options_.generate_main_dex_proguard_rules_path,
+                           proguard_main_dex_keep_set)) {
       return 1;
     }
 
-    if (mContext->verbose()) {
-      DebugPrintTableOptions debugPrintTableOptions;
-      debugPrintTableOptions.showSources = true;
-      Debug::printTable(&mFinalTable, debugPrintTableOptions);
+    if (context_->IsVerbose()) {
+      DebugPrintTableOptions debug_print_table_options;
+      debug_print_table_options.show_sources = true;
+      Debug::PrintTable(&final_table_, debug_print_table_options);
     }
     return 0;
   }
 
  private:
-  LinkOptions mOptions;
-  LinkContext* mContext;
-  ResourceTable mFinalTable;
+  LinkOptions options_;
+  LinkContext* context_;
+  ResourceTable final_table_;
 
-  std::unique_ptr<TableMerger> mTableMerger;
+  std::unique_ptr<TableMerger> table_merger_;
 
   // A pointer to the FileCollection representing the filesystem (not archives).
-  std::unique_ptr<io::FileCollection> mFileCollection;
+  std::unique_ptr<io::FileCollection> file_collection_;
 
   // A vector of IFileCollections. This is mainly here to keep ownership of the
   // collections.
-  std::vector<std::unique_ptr<io::IFileCollection>> mCollections;
+  std::vector<std::unique_ptr<io::IFileCollection>> collections_;
 
   // A vector of ResourceTables. This is here to retain ownership, so that the
   // SymbolTable
   // can use these.
-  std::vector<std::unique_ptr<ResourceTable>> mStaticTableIncludes;
+  std::vector<std::unique_ptr<ResourceTable>> static_table_includes_;
 };
 
-int link(const std::vector<StringPiece>& args) {
+int Link(const std::vector<StringPiece>& args) {
   LinkContext context;
   LinkOptions options;
-  std::vector<std::string> overlayArgList;
-  std::vector<std::string> extraJavaPackages;
+  std::vector<std::string> overlay_arg_list;
+  std::vector<std::string> extra_java_packages;
   Maybe<std::string> configs;
-  Maybe<std::string> preferredDensity;
-  Maybe<std::string> productList;
-  bool legacyXFlag = false;
-  bool requireLocalization = false;
+  Maybe<std::string> preferred_density;
+  Maybe<std::string> product_list;
+  bool legacy_x_flag = false;
+  bool require_localization = false;
   bool verbose = false;
-  Maybe<std::string> stableIdFilePath;
-  std::vector<std::string> splitArgs;
+  Maybe<std::string> stable_id_file_path;
+  std::vector<std::string> split_args;
   Flags flags =
       Flags()
-          .requiredFlag("-o", "Output path", &options.outputPath)
-          .requiredFlag("--manifest", "Path to the Android manifest to build",
-                        &options.manifestPath)
-          .optionalFlagList("-I", "Adds an Android APK to link against",
-                            &options.includePaths)
-          .optionalFlagList(
+          .RequiredFlag("-o", "Output path", &options.output_path)
+          .RequiredFlag("--manifest", "Path to the Android manifest to build",
+                        &options.manifest_path)
+          .OptionalFlagList("-I", "Adds an Android APK to link against",
+                            &options.include_paths)
+          .OptionalFlagList(
               "-R",
               "Compilation unit to link, using `overlay` semantics.\n"
               "The last conflicting resource given takes precedence.",
-              &overlayArgList)
-          .optionalFlag("--java", "Directory in which to generate R.java",
-                        &options.generateJavaClassPath)
-          .optionalFlag("--proguard",
+              &overlay_arg_list)
+          .OptionalFlag("--java", "Directory in which to generate R.java",
+                        &options.generate_java_class_path)
+          .OptionalFlag("--proguard",
                         "Output file for generated Proguard rules",
-                        &options.generateProguardRulesPath)
-          .optionalFlag(
+                        &options.generate_proguard_rules_path)
+          .OptionalFlag(
               "--proguard-main-dex",
               "Output file for generated Proguard rules for the main dex",
-              &options.generateMainDexProguardRulesPath)
-          .optionalSwitch("--no-auto-version",
+              &options.generate_main_dex_proguard_rules_path)
+          .OptionalSwitch("--no-auto-version",
                           "Disables automatic style and layout SDK versioning",
-                          &options.noAutoVersion)
-          .optionalSwitch("--no-version-vectors",
+                          &options.no_auto_version)
+          .OptionalSwitch("--no-version-vectors",
                           "Disables automatic versioning of vector drawables. "
                           "Use this only\n"
                           "when building with vector drawable support library",
-                          &options.noVersionVectors)
-          .optionalSwitch("--no-resource-deduping",
+                          &options.no_version_vectors)
+          .OptionalSwitch("--no-resource-deduping",
                           "Disables automatic deduping of resources with\n"
                           "identical values across compatible configurations.",
-                          &options.noResourceDeduping)
-          .optionalSwitch(
+                          &options.no_resource_deduping)
+          .OptionalSwitch(
               "-x",
               "Legacy flag that specifies to use the package identifier 0x01",
-              &legacyXFlag)
-          .optionalSwitch("-z",
+              &legacy_x_flag)
+          .OptionalSwitch("-z",
                           "Require localization of strings marked 'suggested'",
-                          &requireLocalization)
-          .optionalFlag(
+                          &require_localization)
+          .OptionalFlag(
               "-c",
               "Comma separated list of configurations to include. The default\n"
               "is all configurations",
               &configs)
-          .optionalFlag(
+          .OptionalFlag(
               "--preferred-density",
               "Selects the closest matching density and strips out all others.",
-              &preferredDensity)
-          .optionalFlag("--product",
+              &preferred_density)
+          .OptionalFlag("--product",
                         "Comma separated list of product names to keep",
-                        &productList)
-          .optionalSwitch("--output-to-dir",
+                        &product_list)
+          .OptionalSwitch("--output-to-dir",
                           "Outputs the APK contents to a directory specified "
                           "by -o",
-                          &options.outputToDirectory)
-          .optionalSwitch("--no-xml-namespaces",
+                          &options.output_to_directory)
+          .OptionalSwitch("--no-xml-namespaces",
                           "Removes XML namespace prefix and URI "
                           "information from AndroidManifest.xml\nand XML "
                           "binaries in res/*.",
-                          &options.noXmlNamespaces)
-          .optionalFlag("--min-sdk-version",
+                          &options.no_xml_namespaces)
+          .OptionalFlag("--min-sdk-version",
                         "Default minimum SDK version to use for "
                         "AndroidManifest.xml",
-                        &options.manifestFixerOptions.minSdkVersionDefault)
-          .optionalFlag("--target-sdk-version",
-                        "Default target SDK version to use for "
-                        "AndroidManifest.xml",
-                        &options.manifestFixerOptions.targetSdkVersionDefault)
-          .optionalFlag("--version-code",
+                        &options.manifest_fixer_options.min_sdk_version_default)
+          .OptionalFlag(
+              "--target-sdk-version",
+              "Default target SDK version to use for "
+              "AndroidManifest.xml",
+              &options.manifest_fixer_options.target_sdk_version_default)
+          .OptionalFlag("--version-code",
                         "Version code (integer) to inject into the "
                         "AndroidManifest.xml if none is present",
-                        &options.manifestFixerOptions.versionCodeDefault)
-          .optionalFlag("--version-name",
+                        &options.manifest_fixer_options.version_code_default)
+          .OptionalFlag("--version-name",
                         "Version name to inject into the AndroidManifest.xml "
                         "if none is present",
-                        &options.manifestFixerOptions.versionNameDefault)
-          .optionalSwitch("--static-lib", "Generate a static Android library",
-                          &options.staticLib)
-          .optionalSwitch("--no-static-lib-packages",
+                        &options.manifest_fixer_options.version_name_default)
+          .OptionalSwitch("--static-lib", "Generate a static Android library",
+                          &options.static_lib)
+          .OptionalSwitch("--no-static-lib-packages",
                           "Merge all library resources under the app's package",
-                          &options.noStaticLibPackages)
-          .optionalSwitch("--non-final-ids",
+                          &options.no_static_lib_packages)
+          .OptionalSwitch("--non-final-ids",
                           "Generates R.java without the final modifier.\n"
                           "This is implied when --static-lib is specified.",
-                          &options.generateNonFinalIds)
-          .optionalFlag("--stable-ids",
+                          &options.generate_non_final_ids)
+          .OptionalFlag("--stable-ids",
                         "File containing a list of name to ID mapping.",
-                        &stableIdFilePath)
-          .optionalFlag(
+                        &stable_id_file_path)
+          .OptionalFlag(
               "--emit-ids",
               "Emit a file at the given path with a list of name to ID\n"
               "mappings, suitable for use with --stable-ids.",
-              &options.resourceIdMapPath)
-          .optionalFlag("--private-symbols",
+              &options.resource_id_map_path)
+          .OptionalFlag("--private-symbols",
                         "Package name to use when generating R.java for "
                         "private symbols.\n"
                         "If not specified, public and private symbols will use "
                         "the application's "
                         "package name",
-                        &options.privateSymbols)
-          .optionalFlag("--custom-package",
+                        &options.private_symbols)
+          .OptionalFlag("--custom-package",
                         "Custom Java package under which to generate R.java",
-                        &options.customJavaPackage)
-          .optionalFlagList("--extra-packages",
+                        &options.custom_java_package)
+          .OptionalFlagList("--extra-packages",
                             "Generate the same R.java but with different "
                             "package names",
-                            &extraJavaPackages)
-          .optionalFlagList("--add-javadoc-annotation",
+                            &extra_java_packages)
+          .OptionalFlagList("--add-javadoc-annotation",
                             "Adds a JavaDoc annotation to all "
                             "generated Java classes",
-                            &options.javadocAnnotations)
-          .optionalSwitch("--auto-add-overlay",
+                            &options.javadoc_annotations)
+          .OptionalSwitch("--auto-add-overlay",
                           "Allows the addition of new resources in "
                           "overlays without <add-resource> tags",
-                          &options.autoAddOverlay)
-          .optionalFlag("--rename-manifest-package",
+                          &options.auto_add_overlay)
+          .OptionalFlag("--rename-manifest-package",
                         "Renames the package in AndroidManifest.xml",
-                        &options.manifestFixerOptions.renameManifestPackage)
-          .optionalFlag(
+                        &options.manifest_fixer_options.rename_manifest_package)
+          .OptionalFlag(
               "--rename-instrumentation-target-package",
               "Changes the name of the target package for instrumentation. "
               "Most useful "
               "when used\nin conjunction with --rename-manifest-package",
-              &options.manifestFixerOptions.renameInstrumentationTargetPackage)
-          .optionalFlagList("-0", "File extensions not to compress",
-                            &options.extensionsToNotCompress)
-          .optionalFlagList(
+              &options.manifest_fixer_options
+                   .rename_instrumentation_target_package)
+          .OptionalFlagList("-0", "File extensions not to compress",
+                            &options.extensions_to_not_compress)
+          .OptionalFlagList(
               "--split",
               "Split resources matching a set of configs out to a "
               "Split APK.\nSyntax: path/to/output.apk:<config>[,<config>[...]]",
-              &splitArgs)
-          .optionalSwitch("-v", "Enables verbose logging", &verbose);
+              &split_args)
+          .OptionalSwitch("-v", "Enables verbose logging", &verbose);
 
-  if (!flags.parse("aapt2 link", args, &std::cerr)) {
+  if (!flags.Parse("aapt2 link", args, &std::cerr)) {
     return 1;
   }
 
   // Expand all argument-files passed into the command line. These start with
   // '@'.
-  std::vector<std::string> argList;
-  for (const std::string& arg : flags.getArgs()) {
-    if (util::stringStartsWith(arg, "@")) {
+  std::vector<std::string> arg_list;
+  for (const std::string& arg : flags.GetArgs()) {
+    if (util::StartsWith(arg, "@")) {
       const std::string path = arg.substr(1, arg.size() - 1);
       std::string error;
-      if (!file::appendArgsFromFile(path, &argList, &error)) {
-        context.getDiagnostics()->error(DiagMessage(path) << error);
+      if (!file::AppendArgsFromFile(path, &arg_list, &error)) {
+        context.GetDiagnostics()->Error(DiagMessage(path) << error);
         return 1;
       }
     } else {
-      argList.push_back(arg);
+      arg_list.push_back(arg);
     }
   }
 
   // Expand all argument-files passed to -R.
-  for (const std::string& arg : overlayArgList) {
-    if (util::stringStartsWith(arg, "@")) {
+  for (const std::string& arg : overlay_arg_list) {
+    if (util::StartsWith(arg, "@")) {
       const std::string path = arg.substr(1, arg.size() - 1);
       std::string error;
-      if (!file::appendArgsFromFile(path, &options.overlayFiles, &error)) {
-        context.getDiagnostics()->error(DiagMessage(path) << error);
+      if (!file::AppendArgsFromFile(path, &options.overlay_files, &error)) {
+        context.GetDiagnostics()->Error(DiagMessage(path) << error);
         return 1;
       }
     } else {
-      options.overlayFiles.push_back(arg);
+      options.overlay_files.push_back(arg);
     }
   }
 
   if (verbose) {
-    context.setVerbose(verbose);
+    context.SetVerbose(verbose);
   }
 
   // Populate the set of extra packages for which to generate R.java.
-  for (std::string& extraPackage : extraJavaPackages) {
+  for (std::string& extra_package : extra_java_packages) {
     // A given package can actually be a colon separated list of packages.
-    for (StringPiece package : util::split(extraPackage, ':')) {
-      options.extraJavaPackages.insert(package.toString());
+    for (StringPiece package : util::Split(extra_package, ':')) {
+      options.extra_java_packages.insert(package.ToString());
     }
   }
 
-  if (productList) {
-    for (StringPiece product : util::tokenize(productList.value(), ',')) {
+  if (product_list) {
+    for (StringPiece product : util::Tokenize(product_list.value(), ',')) {
       if (product != "" && product != "default") {
-        options.products.insert(product.toString());
+        options.products.insert(product.ToString());
       }
     }
   }
 
   AxisConfigFilter filter;
   if (configs) {
-    for (const StringPiece& configStr : util::tokenize(configs.value(), ',')) {
+    for (const StringPiece& config_str : util::Tokenize(configs.value(), ',')) {
       ConfigDescription config;
       LocaleValue lv;
-      if (lv.initFromFilterString(configStr)) {
-        lv.writeTo(&config);
-      } else if (!ConfigDescription::parse(configStr, &config)) {
-        context.getDiagnostics()->error(DiagMessage() << "invalid config '"
-                                                      << configStr
+      if (lv.InitFromFilterString(config_str)) {
+        lv.WriteTo(&config);
+      } else if (!ConfigDescription::Parse(config_str, &config)) {
+        context.GetDiagnostics()->Error(DiagMessage() << "invalid config '"
+                                                      << config_str
                                                       << "' for -c option");
         return 1;
       }
 
       if (config.density != 0) {
-        context.getDiagnostics()->warn(DiagMessage() << "ignoring density '"
+        context.GetDiagnostics()->Warn(DiagMessage() << "ignoring density '"
                                                      << config
                                                      << "' for -c option");
       } else {
-        filter.addConfig(config);
+        filter.AddConfig(config);
       }
     }
 
-    options.tableSplitterOptions.configFilter = &filter;
+    options.table_splitter_options.config_filter = &filter;
   }
 
-  if (preferredDensity) {
-    ConfigDescription preferredDensityConfig;
-    if (!ConfigDescription::parse(preferredDensity.value(),
-                                  &preferredDensityConfig)) {
-      context.getDiagnostics()->error(
-          DiagMessage() << "invalid density '" << preferredDensity.value()
+  if (preferred_density) {
+    ConfigDescription preferred_density_config;
+    if (!ConfigDescription::Parse(preferred_density.value(),
+                                  &preferred_density_config)) {
+      context.GetDiagnostics()->Error(
+          DiagMessage() << "invalid density '" << preferred_density.value()
                         << "' for --preferred-density option");
       return 1;
     }
 
     // Clear the version that can be automatically added.
-    preferredDensityConfig.sdkVersion = 0;
+    preferred_density_config.sdkVersion = 0;
 
-    if (preferredDensityConfig.diff(ConfigDescription::defaultConfig()) !=
+    if (preferred_density_config.diff(ConfigDescription::DefaultConfig()) !=
         ConfigDescription::CONFIG_DENSITY) {
-      context.getDiagnostics()->error(
+      context.GetDiagnostics()->Error(
           DiagMessage() << "invalid preferred density '"
-                        << preferredDensity.value() << "'. "
+                        << preferred_density.value() << "'. "
                         << "Preferred density must only be a density value");
       return 1;
     }
-    options.tableSplitterOptions.preferredDensity =
-        preferredDensityConfig.density;
+    options.table_splitter_options.preferred_density =
+        preferred_density_config.density;
   }
 
-  if (!options.staticLib && stableIdFilePath) {
-    if (!loadStableIdMap(context.getDiagnostics(), stableIdFilePath.value(),
-                         &options.stableIdMap)) {
+  if (!options.static_lib && stable_id_file_path) {
+    if (!LoadStableIdMap(context.GetDiagnostics(), stable_id_file_path.value(),
+                         &options.stable_id_map)) {
       return 1;
     }
   }
 
   // Populate some default no-compress extensions that are already compressed.
-  options.extensionsToNotCompress.insert(
+  options.extensions_to_not_compress.insert(
       {".jpg",   ".jpeg", ".png",  ".gif", ".wav",  ".mp2",  ".mp3",  ".ogg",
        ".aac",   ".mpg",  ".mpeg", ".mid", ".midi", ".smf",  ".jet",  ".rtttl",
        ".imy",   ".xmf",  ".mp4",  ".m4a", ".m4v",  ".3gp",  ".3gpp", ".3g2",
        ".3gpp2", ".amr",  ".awb",  ".wma", ".wmv",  ".webm", ".mkv"});
 
   // Parse the split parameters.
-  for (const std::string& splitArg : splitArgs) {
-    options.splitPaths.push_back({});
-    options.splitConstraints.push_back({});
-    if (!parseSplitParameter(splitArg, context.getDiagnostics(),
-                             &options.splitPaths.back(),
-                             &options.splitConstraints.back())) {
+  for (const std::string& split_arg : split_args) {
+    options.split_paths.push_back({});
+    options.split_constraints.push_back({});
+    if (!ParseSplitParameter(split_arg, context.GetDiagnostics(),
+                             &options.split_paths.back(),
+                             &options.split_constraints.back())) {
       return 1;
     }
   }
 
   // Turn off auto versioning for static-libs.
-  if (options.staticLib) {
-    options.noAutoVersion = true;
-    options.noVersionVectors = true;
+  if (options.static_lib) {
+    options.no_auto_version = true;
+    options.no_version_vectors = true;
   }
 
   LinkCommand cmd(&context, options);
-  return cmd.run(argList);
+  return cmd.Run(arg_list);
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/Linkers.h b/tools/aapt2/link/Linkers.h
index f40c0e8..4687d2c 100644
--- a/tools/aapt2/link/Linkers.h
+++ b/tools/aapt2/link/Linkers.h
@@ -17,12 +17,15 @@
 #ifndef AAPT_LINKER_LINKERS_H
 #define AAPT_LINKER_LINKERS_H
 
+#include <set>
+#include <unordered_set>
+
+#include "android-base/macros.h"
+
 #include "Resource.h"
 #include "process/IResourceTableConsumer.h"
 #include "xml/XmlDom.h"
 
-#include <set>
-
 namespace aapt {
 
 class ResourceTable;
@@ -31,8 +34,7 @@
 
 /**
  * Defines the location in which a value exists. This determines visibility of
- * other
- * package's private symbols.
+ * other package's private symbols.
  */
 struct CallSite {
   ResourceNameRef resource;
@@ -40,26 +42,30 @@
 
 /**
  * Determines whether a versioned resource should be created. If a versioned
- * resource already
- * exists, it takes precedence.
+ * resource already exists, it takes precedence.
  */
-bool shouldGenerateVersionedResource(const ResourceEntry* entry,
+bool ShouldGenerateVersionedResource(const ResourceEntry* entry,
                                      const ConfigDescription& config,
-                                     const int sdkVersionToGenerate);
+                                     const int sdk_version_to_generate);
 
 class AutoVersioner : public IResourceTableConsumer {
  public:
-  bool consume(IAaptContext* context, ResourceTable* table) override;
-};
+  AutoVersioner() = default;
 
-class XmlAutoVersioner : public IXmlResourceConsumer {
- public:
-  bool consume(IAaptContext* context, xml::XmlResource* resource) override;
+  bool Consume(IAaptContext* context, ResourceTable* table) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AutoVersioner);
 };
 
 class VersionCollapser : public IResourceTableConsumer {
  public:
-  bool consume(IAaptContext* context, ResourceTable* table) override;
+  VersionCollapser() = default;
+
+  bool Consume(IAaptContext* context, ResourceTable* table) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(VersionCollapser);
 };
 
 /**
@@ -67,7 +73,12 @@
  */
 class ResourceDeduper : public IResourceTableConsumer {
  public:
-  bool consume(IAaptContext* context, ResourceTable* table) override;
+  ResourceDeduper() = default;
+
+  bool Consume(IAaptContext* context, ResourceTable* table) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ResourceDeduper);
 };
 
 /**
@@ -103,8 +114,46 @@
  * conflict will never
  * occur.
  */
-struct PrivateAttributeMover : public IResourceTableConsumer {
-  bool consume(IAaptContext* context, ResourceTable* table) override;
+class PrivateAttributeMover : public IResourceTableConsumer {
+ public:
+  PrivateAttributeMover() = default;
+
+  bool Consume(IAaptContext* context, ResourceTable* table) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PrivateAttributeMover);
+};
+
+class ResourceConfigValue;
+
+class ProductFilter : public IResourceTableConsumer {
+ public:
+  using ResourceConfigValueIter =
+      std::vector<std::unique_ptr<ResourceConfigValue>>::iterator;
+
+  explicit ProductFilter(std::unordered_set<std::string> products)
+      : products_(products) {}
+
+  ResourceConfigValueIter SelectProductToKeep(
+      const ResourceNameRef& name, const ResourceConfigValueIter begin,
+      const ResourceConfigValueIter end, IDiagnostics* diag);
+
+  bool Consume(IAaptContext* context, ResourceTable* table) override;
+
+ private:
+  std::unordered_set<std::string> products_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProductFilter);
+};
+
+class XmlAutoVersioner : public IXmlResourceConsumer {
+ public:
+  XmlAutoVersioner() = default;
+
+  bool Consume(IAaptContext* context, xml::XmlResource* resource) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(XmlAutoVersioner);
 };
 
 /**
@@ -116,13 +165,16 @@
  * XmlReferenceLinker.
  */
 class XmlNamespaceRemover : public IXmlResourceConsumer {
- private:
-  bool mKeepUris;
-
  public:
-  XmlNamespaceRemover(bool keepUris = false) : mKeepUris(keepUris){};
+  explicit XmlNamespaceRemover(bool keep_uris = false)
+      : keep_uris_(keep_uris){};
 
-  bool consume(IAaptContext* context, xml::XmlResource* resource) override;
+  bool Consume(IAaptContext* context, xml::XmlResource* resource) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(XmlNamespaceRemover);
+
+  bool keep_uris_;
 };
 
 /**
@@ -131,18 +183,22 @@
  * Once an XmlResource is processed by this linker, it is ready to be flattened.
  */
 class XmlReferenceLinker : public IXmlResourceConsumer {
- private:
-  std::set<int> mSdkLevelsFound;
-
  public:
-  bool consume(IAaptContext* context, xml::XmlResource* resource) override;
+  XmlReferenceLinker() = default;
+
+  bool Consume(IAaptContext* context, xml::XmlResource* resource) override;
 
   /**
    * Once the XmlResource has been consumed, this returns the various SDK levels
    * in which
    * framework attributes used within the XML document were defined.
    */
-  inline const std::set<int>& getSdkLevels() const { return mSdkLevelsFound; }
+  inline const std::set<int>& sdk_levels() const { return sdk_levels_found_; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(XmlReferenceLinker);
+
+  std::set<int> sdk_levels_found_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 3c9298b..36a3494 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -15,32 +15,36 @@
  */
 
 #include "link/ManifestFixer.h"
+
+#include <unordered_set>
+
+#include "android-base/logging.h"
+
 #include "ResourceUtils.h"
 #include "util/Util.h"
 #include "xml/XmlActionExecutor.h"
 #include "xml/XmlDom.h"
 
-#include <unordered_set>
-
 namespace aapt {
 
 /**
  * This is how PackageManager builds class names from AndroidManifest.xml
  * entries.
  */
-static bool nameIsJavaClassName(xml::Element* el, xml::Attribute* attr,
+static bool NameIsJavaClassName(xml::Element* el, xml::Attribute* attr,
                                 SourcePathDiagnostics* diag) {
   // We allow unqualified class names (ie: .HelloActivity)
   // Since we don't know the package name, we can just make a fake one here and
   // the test will be identical as long as the real package name is valid too.
-  Maybe<std::string> fullyQualifiedClassName =
-      util::getFullyQualifiedClassName("a", attr->value);
+  Maybe<std::string> fully_qualified_class_name =
+      util::GetFullyQualifiedClassName("a", attr->value);
 
-  StringPiece qualifiedClassName =
-      fullyQualifiedClassName ? fullyQualifiedClassName.value() : attr->value;
+  StringPiece qualified_class_name = fully_qualified_class_name
+                                         ? fully_qualified_class_name.value()
+                                         : attr->value;
 
-  if (!util::isJavaClassName(qualifiedClassName)) {
-    diag->error(DiagMessage(el->lineNumber)
+  if (!util::IsJavaClassName(qualified_class_name)) {
+    diag->Error(DiagMessage(el->line_number)
                 << "attribute 'android:name' in <" << el->name
                 << "> tag must be a valid Java class name");
     return false;
@@ -48,37 +52,37 @@
   return true;
 }
 
-static bool optionalNameIsJavaClassName(xml::Element* el,
+static bool OptionalNameIsJavaClassName(xml::Element* el,
                                         SourcePathDiagnostics* diag) {
-  if (xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, "name")) {
-    return nameIsJavaClassName(el, attr, diag);
+  if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
+    return NameIsJavaClassName(el, attr, diag);
   }
   return true;
 }
 
-static bool requiredNameIsJavaClassName(xml::Element* el,
+static bool RequiredNameIsJavaClassName(xml::Element* el,
                                         SourcePathDiagnostics* diag) {
-  if (xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, "name")) {
-    return nameIsJavaClassName(el, attr, diag);
+  if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
+    return NameIsJavaClassName(el, attr, diag);
   }
-  diag->error(DiagMessage(el->lineNumber)
+  diag->Error(DiagMessage(el->line_number)
               << "<" << el->name << "> is missing attribute 'android:name'");
   return false;
 }
 
-static bool verifyManifest(xml::Element* el, SourcePathDiagnostics* diag) {
-  xml::Attribute* attr = el->findAttribute({}, "package");
+static bool VerifyManifest(xml::Element* el, SourcePathDiagnostics* diag) {
+  xml::Attribute* attr = el->FindAttribute({}, "package");
   if (!attr) {
-    diag->error(DiagMessage(el->lineNumber)
+    diag->Error(DiagMessage(el->line_number)
                 << "<manifest> tag is missing 'package' attribute");
     return false;
-  } else if (ResourceUtils::isReference(attr->value)) {
-    diag->error(
-        DiagMessage(el->lineNumber)
+  } else if (ResourceUtils::IsReference(attr->value)) {
+    diag->Error(
+        DiagMessage(el->line_number)
         << "attribute 'package' in <manifest> tag must not be a reference");
     return false;
-  } else if (!util::isJavaPackageName(attr->value)) {
-    diag->error(DiagMessage(el->lineNumber)
+  } else if (!util::IsJavaPackageName(attr->value)) {
+    diag->Error(DiagMessage(el->line_number)
                 << "attribute 'package' in <manifest> tag is not a valid Java "
                    "package name: '"
                 << attr->value << "'");
@@ -89,242 +93,246 @@
 
 /**
  * The coreApp attribute in <manifest> is not a regular AAPT attribute, so type
- * checking on it
- * is manual.
+ * checking on it is manual.
  */
-static bool fixCoreAppAttribute(xml::Element* el, SourcePathDiagnostics* diag) {
-  if (xml::Attribute* attr = el->findAttribute("", "coreApp")) {
+static bool FixCoreAppAttribute(xml::Element* el, SourcePathDiagnostics* diag) {
+  if (xml::Attribute* attr = el->FindAttribute("", "coreApp")) {
     std::unique_ptr<BinaryPrimitive> result =
-        ResourceUtils::tryParseBool(attr->value);
+        ResourceUtils::TryParseBool(attr->value);
     if (!result) {
-      diag->error(DiagMessage(el->lineNumber)
+      diag->Error(DiagMessage(el->line_number)
                   << "attribute coreApp must be a boolean");
       return false;
     }
-    attr->compiledValue = std::move(result);
+    attr->compiled_value = std::move(result);
   }
   return true;
 }
 
-bool ManifestFixer::buildRules(xml::XmlActionExecutor* executor,
+bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
                                IDiagnostics* diag) {
   // First verify some options.
-  if (mOptions.renameManifestPackage) {
-    if (!util::isJavaPackageName(mOptions.renameManifestPackage.value())) {
-      diag->error(DiagMessage() << "invalid manifest package override '"
-                                << mOptions.renameManifestPackage.value()
+  if (options_.rename_manifest_package) {
+    if (!util::IsJavaPackageName(options_.rename_manifest_package.value())) {
+      diag->Error(DiagMessage() << "invalid manifest package override '"
+                                << options_.rename_manifest_package.value()
                                 << "'");
       return false;
     }
   }
 
-  if (mOptions.renameInstrumentationTargetPackage) {
-    if (!util::isJavaPackageName(
-            mOptions.renameInstrumentationTargetPackage.value())) {
-      diag->error(DiagMessage()
+  if (options_.rename_instrumentation_target_package) {
+    if (!util::IsJavaPackageName(
+            options_.rename_instrumentation_target_package.value())) {
+      diag->Error(DiagMessage()
                   << "invalid instrumentation target package override '"
-                  << mOptions.renameInstrumentationTargetPackage.value()
+                  << options_.rename_instrumentation_target_package.value()
                   << "'");
       return false;
     }
   }
 
   // Common intent-filter actions.
-  xml::XmlNodeAction intentFilterAction;
-  intentFilterAction["action"];
-  intentFilterAction["category"];
-  intentFilterAction["data"];
+  xml::XmlNodeAction intent_filter_action;
+  intent_filter_action["action"];
+  intent_filter_action["category"];
+  intent_filter_action["data"];
 
   // Common meta-data actions.
-  xml::XmlNodeAction metaDataAction;
+  xml::XmlNodeAction meta_data_action;
 
   // Manifest actions.
-  xml::XmlNodeAction& manifestAction = (*executor)["manifest"];
-  manifestAction.action(verifyManifest);
-  manifestAction.action(fixCoreAppAttribute);
-  manifestAction.action([&](xml::Element* el) -> bool {
-    if (mOptions.versionNameDefault) {
-      if (el->findAttribute(xml::kSchemaAndroid, "versionName") == nullptr) {
+  xml::XmlNodeAction& manifest_action = (*executor)["manifest"];
+  manifest_action.Action(VerifyManifest);
+  manifest_action.Action(FixCoreAppAttribute);
+  manifest_action.Action([&](xml::Element* el) -> bool {
+    if (options_.version_name_default) {
+      if (el->FindAttribute(xml::kSchemaAndroid, "versionName") == nullptr) {
         el->attributes.push_back(
             xml::Attribute{xml::kSchemaAndroid, "versionName",
-                           mOptions.versionNameDefault.value()});
+                           options_.version_name_default.value()});
       }
     }
 
-    if (mOptions.versionCodeDefault) {
-      if (el->findAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) {
+    if (options_.version_code_default) {
+      if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) {
         el->attributes.push_back(
             xml::Attribute{xml::kSchemaAndroid, "versionCode",
-                           mOptions.versionCodeDefault.value()});
+                           options_.version_code_default.value()});
       }
     }
     return true;
   });
 
   // Meta tags.
-  manifestAction["eat-comment"];
+  manifest_action["eat-comment"];
 
   // Uses-sdk actions.
-  manifestAction["uses-sdk"].action([&](xml::Element* el) -> bool {
-    if (mOptions.minSdkVersionDefault &&
-        el->findAttribute(xml::kSchemaAndroid, "minSdkVersion") == nullptr) {
+  manifest_action["uses-sdk"].Action([&](xml::Element* el) -> bool {
+    if (options_.min_sdk_version_default &&
+        el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion") == nullptr) {
       // There was no minSdkVersion defined and we have a default to assign.
       el->attributes.push_back(
           xml::Attribute{xml::kSchemaAndroid, "minSdkVersion",
-                         mOptions.minSdkVersionDefault.value()});
+                         options_.min_sdk_version_default.value()});
     }
 
-    if (mOptions.targetSdkVersionDefault &&
-        el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion") == nullptr) {
+    if (options_.target_sdk_version_default &&
+        el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion") == nullptr) {
       // There was no targetSdkVersion defined and we have a default to assign.
       el->attributes.push_back(
           xml::Attribute{xml::kSchemaAndroid, "targetSdkVersion",
-                         mOptions.targetSdkVersionDefault.value()});
+                         options_.target_sdk_version_default.value()});
     }
     return true;
   });
 
   // Instrumentation actions.
-  manifestAction["instrumentation"].action([&](xml::Element* el) -> bool {
-    if (!mOptions.renameInstrumentationTargetPackage) {
+  manifest_action["instrumentation"].Action([&](xml::Element* el) -> bool {
+    if (!options_.rename_instrumentation_target_package) {
       return true;
     }
 
     if (xml::Attribute* attr =
-            el->findAttribute(xml::kSchemaAndroid, "targetPackage")) {
-      attr->value = mOptions.renameInstrumentationTargetPackage.value();
+            el->FindAttribute(xml::kSchemaAndroid, "targetPackage")) {
+      attr->value = options_.rename_instrumentation_target_package.value();
     }
     return true;
   });
 
-  manifestAction["original-package"];
-  manifestAction["protected-broadcast"];
-  manifestAction["uses-permission"];
-  manifestAction["permission"];
-  manifestAction["permission-tree"];
-  manifestAction["permission-group"];
+  manifest_action["original-package"];
+  manifest_action["protected-broadcast"];
+  manifest_action["uses-permission"];
+  manifest_action["permission"];
+  manifest_action["permission-tree"];
+  manifest_action["permission-group"];
 
-  manifestAction["uses-configuration"];
-  manifestAction["uses-feature"];
-  manifestAction["supports-screens"];
+  manifest_action["uses-configuration"];
+  manifest_action["uses-feature"];
+  manifest_action["supports-screens"];
 
-  manifestAction["compatible-screens"];
-  manifestAction["compatible-screens"]["screen"];
+  manifest_action["compatible-screens"];
+  manifest_action["compatible-screens"]["screen"];
 
-  manifestAction["supports-gl-texture"];
+  manifest_action["supports-gl-texture"];
 
   // Application actions.
-  xml::XmlNodeAction& applicationAction = manifestAction["application"];
-  applicationAction.action(optionalNameIsJavaClassName);
+  xml::XmlNodeAction& application_action = manifest_action["application"];
+  application_action.Action(OptionalNameIsJavaClassName);
 
   // Uses library actions.
-  applicationAction["uses-library"];
+  application_action["uses-library"];
 
   // Meta-data.
-  applicationAction["meta-data"] = metaDataAction;
+  application_action["meta-data"] = meta_data_action;
 
   // Activity actions.
-  applicationAction["activity"].action(requiredNameIsJavaClassName);
-  applicationAction["activity"]["intent-filter"] = intentFilterAction;
-  applicationAction["activity"]["meta-data"] = metaDataAction;
+  application_action["activity"].Action(RequiredNameIsJavaClassName);
+  application_action["activity"]["intent-filter"] = intent_filter_action;
+  application_action["activity"]["meta-data"] = meta_data_action;
 
   // Activity alias actions.
-  applicationAction["activity-alias"]["intent-filter"] = intentFilterAction;
-  applicationAction["activity-alias"]["meta-data"] = metaDataAction;
+  application_action["activity-alias"]["intent-filter"] = intent_filter_action;
+  application_action["activity-alias"]["meta-data"] = meta_data_action;
 
   // Service actions.
-  applicationAction["service"].action(requiredNameIsJavaClassName);
-  applicationAction["service"]["intent-filter"] = intentFilterAction;
-  applicationAction["service"]["meta-data"] = metaDataAction;
+  application_action["service"].Action(RequiredNameIsJavaClassName);
+  application_action["service"]["intent-filter"] = intent_filter_action;
+  application_action["service"]["meta-data"] = meta_data_action;
 
   // Receiver actions.
-  applicationAction["receiver"].action(requiredNameIsJavaClassName);
-  applicationAction["receiver"]["intent-filter"] = intentFilterAction;
-  applicationAction["receiver"]["meta-data"] = metaDataAction;
+  application_action["receiver"].Action(RequiredNameIsJavaClassName);
+  application_action["receiver"]["intent-filter"] = intent_filter_action;
+  application_action["receiver"]["meta-data"] = meta_data_action;
 
   // Provider actions.
-  applicationAction["provider"].action(requiredNameIsJavaClassName);
-  applicationAction["provider"]["intent-filter"] = intentFilterAction;
-  applicationAction["provider"]["meta-data"] = metaDataAction;
-  applicationAction["provider"]["grant-uri-permissions"];
-  applicationAction["provider"]["path-permissions"];
+  application_action["provider"].Action(RequiredNameIsJavaClassName);
+  application_action["provider"]["intent-filter"] = intent_filter_action;
+  application_action["provider"]["meta-data"] = meta_data_action;
+  application_action["provider"]["grant-uri-permissions"];
+  application_action["provider"]["path-permissions"];
 
   return true;
 }
 
 class FullyQualifiedClassNameVisitor : public xml::Visitor {
  public:
-  using xml::Visitor::visit;
+  using xml::Visitor::Visit;
 
   explicit FullyQualifiedClassNameVisitor(const StringPiece& package)
-      : mPackage(package) {}
+      : package_(package) {}
 
-  void visit(xml::Element* el) override {
+  void Visit(xml::Element* el) override {
     for (xml::Attribute& attr : el->attributes) {
-      if (attr.namespaceUri == xml::kSchemaAndroid &&
-          mClassAttributes.find(attr.name) != mClassAttributes.end()) {
-        if (Maybe<std::string> newValue =
-                util::getFullyQualifiedClassName(mPackage, attr.value)) {
-          attr.value = std::move(newValue.value());
+      if (attr.namespace_uri == xml::kSchemaAndroid &&
+          class_attributes_.find(attr.name) != class_attributes_.end()) {
+        if (Maybe<std::string> new_value =
+                util::GetFullyQualifiedClassName(package_, attr.value)) {
+          attr.value = std::move(new_value.value());
         }
       }
     }
 
     // Super implementation to iterate over the children.
-    xml::Visitor::visit(el);
+    xml::Visitor::Visit(el);
   }
 
  private:
-  StringPiece mPackage;
-  std::unordered_set<StringPiece> mClassAttributes = {"name"};
+  StringPiece package_;
+  std::unordered_set<StringPiece> class_attributes_ = {"name"};
 };
 
-static bool renameManifestPackage(const StringPiece& packageOverride,
-                                  xml::Element* manifestEl) {
-  xml::Attribute* attr = manifestEl->findAttribute({}, "package");
+static bool RenameManifestPackage(const StringPiece& package_override,
+                                  xml::Element* manifest_el) {
+  xml::Attribute* attr = manifest_el->FindAttribute({}, "package");
 
   // We've already verified that the manifest element is present, with a package
   // name specified.
-  assert(attr);
+  CHECK(attr != nullptr);
 
-  std::string originalPackage = std::move(attr->value);
-  attr->value = packageOverride.toString();
+  std::string original_package = std::move(attr->value);
+  attr->value = package_override.ToString();
 
-  FullyQualifiedClassNameVisitor visitor(originalPackage);
-  manifestEl->accept(&visitor);
+  FullyQualifiedClassNameVisitor visitor(original_package);
+  manifest_el->Accept(&visitor);
   return true;
 }
 
-bool ManifestFixer::consume(IAaptContext* context, xml::XmlResource* doc) {
-  xml::Element* root = xml::findRootElement(doc->root.get());
-  if (!root || !root->namespaceUri.empty() || root->name != "manifest") {
-    context->getDiagnostics()->error(DiagMessage(doc->file.source)
+bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) {
+  xml::Element* root = xml::FindRootElement(doc->root.get());
+  if (!root || !root->namespace_uri.empty() || root->name != "manifest") {
+    context->GetDiagnostics()->Error(DiagMessage(doc->file.source)
                                      << "root tag must be <manifest>");
     return false;
   }
 
-  if ((mOptions.minSdkVersionDefault || mOptions.targetSdkVersionDefault) &&
-      root->findChild({}, "uses-sdk") == nullptr) {
-    // Auto insert a <uses-sdk> element.
-    std::unique_ptr<xml::Element> usesSdk = util::make_unique<xml::Element>();
-    usesSdk->name = "uses-sdk";
-    root->addChild(std::move(usesSdk));
+  if ((options_.min_sdk_version_default ||
+       options_.target_sdk_version_default) &&
+      root->FindChild({}, "uses-sdk") == nullptr) {
+    // Auto insert a <uses-sdk> element. This must be inserted before the
+    // <application> tag. The device runtime PackageParser will make SDK version
+    // decisions while parsing <application>.
+    std::unique_ptr<xml::Element> uses_sdk = util::make_unique<xml::Element>();
+    uses_sdk->name = "uses-sdk";
+    root->InsertChild(0, std::move(uses_sdk));
   }
 
   xml::XmlActionExecutor executor;
-  if (!buildRules(&executor, context->getDiagnostics())) {
+  if (!BuildRules(&executor, context->GetDiagnostics())) {
     return false;
   }
 
-  if (!executor.execute(xml::XmlActionExecutorPolicy::Whitelist,
-                        context->getDiagnostics(), doc)) {
+  if (!executor.Execute(xml::XmlActionExecutorPolicy::kWhitelist,
+                        context->GetDiagnostics(), doc)) {
     return false;
   }
 
-  if (mOptions.renameManifestPackage) {
+  if (options_.rename_manifest_package) {
     // Rename manifest package outside of the XmlActionExecutor.
-    // We need to extract the old package name and FullyQualify all class names.
-    if (!renameManifestPackage(mOptions.renameManifestPackage.value(), root)) {
+    // We need to extract the old package name and FullyQualify all class
+    // names.
+    if (!RenameManifestPackage(options_.rename_manifest_package.value(),
+                               root)) {
       return false;
     }
   }
diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h
index c3a114b..470f65e 100644
--- a/tools/aapt2/link/ManifestFixer.h
+++ b/tools/aapt2/link/ManifestFixer.h
@@ -17,22 +17,24 @@
 #ifndef AAPT_LINK_MANIFESTFIXER_H
 #define AAPT_LINK_MANIFESTFIXER_H
 
+#include <string>
+
+#include "android-base/macros.h"
+
 #include "process/IResourceTableConsumer.h"
 #include "util/Maybe.h"
 #include "xml/XmlActionExecutor.h"
 #include "xml/XmlDom.h"
 
-#include <string>
-
 namespace aapt {
 
 struct ManifestFixerOptions {
-  Maybe<std::string> minSdkVersionDefault;
-  Maybe<std::string> targetSdkVersionDefault;
-  Maybe<std::string> renameManifestPackage;
-  Maybe<std::string> renameInstrumentationTargetPackage;
-  Maybe<std::string> versionNameDefault;
-  Maybe<std::string> versionCodeDefault;
+  Maybe<std::string> min_sdk_version_default;
+  Maybe<std::string> target_sdk_version_default;
+  Maybe<std::string> rename_manifest_package;
+  Maybe<std::string> rename_instrumentation_target_package;
+  Maybe<std::string> version_name_default;
+  Maybe<std::string> version_code_default;
 };
 
 /**
@@ -42,14 +44,16 @@
 class ManifestFixer : public IXmlResourceConsumer {
  public:
   explicit ManifestFixer(const ManifestFixerOptions& options)
-      : mOptions(options) {}
+      : options_(options) {}
 
-  bool consume(IAaptContext* context, xml::XmlResource* doc) override;
+  bool Consume(IAaptContext* context, xml::XmlResource* doc) override;
 
  private:
-  bool buildRules(xml::XmlActionExecutor* executor, IDiagnostics* diag);
+  DISALLOW_COPY_AND_ASSIGN(ManifestFixer);
 
-  ManifestFixerOptions mOptions;
+  bool BuildRules(xml::XmlActionExecutor* executor, IDiagnostics* diag);
+
+  ManifestFixerOptions options_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index dc78d98..e9bc64a 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -15,10 +15,8 @@
  */
 
 #include "link/ManifestFixer.h"
-#include "test/Builders.h"
-#include "test/Context.h"
 
-#include <gtest/gtest.h>
+#include "test/Test.h"
 
 namespace aapt {
 
@@ -28,42 +26,42 @@
   void SetUp() override {
     mContext =
         test::ContextBuilder()
-            .setCompilationPackage("android")
-            .setPackageId(0x01)
-            .setNameManglerPolicy(NameManglerPolicy{"android"})
-            .addSymbolSource(
+            .SetCompilationPackage("android")
+            .SetPackageId(0x01)
+            .SetNameManglerPolicy(NameManglerPolicy{"android"})
+            .AddSymbolSource(
                 test::StaticSymbolSourceBuilder()
-                    .addSymbol(
+                    .AddSymbol(
                         "android:attr/package", ResourceId(0x01010000),
                         test::AttributeBuilder()
-                            .setTypeMask(android::ResTable_map::TYPE_STRING)
-                            .build())
-                    .addSymbol(
+                            .SetTypeMask(android::ResTable_map::TYPE_STRING)
+                            .Build())
+                    .AddSymbol(
                         "android:attr/minSdkVersion", ResourceId(0x01010001),
                         test::AttributeBuilder()
-                            .setTypeMask(android::ResTable_map::TYPE_STRING |
+                            .SetTypeMask(android::ResTable_map::TYPE_STRING |
                                          android::ResTable_map::TYPE_INTEGER)
-                            .build())
-                    .addSymbol(
+                            .Build())
+                    .AddSymbol(
                         "android:attr/targetSdkVersion", ResourceId(0x01010002),
                         test::AttributeBuilder()
-                            .setTypeMask(android::ResTable_map::TYPE_STRING |
+                            .SetTypeMask(android::ResTable_map::TYPE_STRING |
                                          android::ResTable_map::TYPE_INTEGER)
-                            .build())
-                    .addSymbol("android:string/str", ResourceId(0x01060000))
-                    .build())
-            .build();
+                            .Build())
+                    .AddSymbol("android:string/str", ResourceId(0x01060000))
+                    .Build())
+            .Build();
   }
 
-  std::unique_ptr<xml::XmlResource> verify(const StringPiece& str) {
-    return verifyWithOptions(str, {});
+  std::unique_ptr<xml::XmlResource> Verify(const StringPiece& str) {
+    return VerifyWithOptions(str, {});
   }
 
-  std::unique_ptr<xml::XmlResource> verifyWithOptions(
+  std::unique_ptr<xml::XmlResource> VerifyWithOptions(
       const StringPiece& str, const ManifestFixerOptions& options) {
-    std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(str);
+    std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(str);
     ManifestFixer fixer(options);
-    if (fixer.consume(mContext.get(), doc.get())) {
+    if (fixer.Consume(mContext.get(), doc.get())) {
       return doc;
     }
     return {};
@@ -71,28 +69,28 @@
 };
 
 TEST_F(ManifestFixerTest, EnsureManifestIsRootTag) {
-  EXPECT_EQ(nullptr, verify("<other-tag />"));
-  EXPECT_EQ(nullptr, verify("<ns:manifest xmlns:ns=\"com\" />"));
-  EXPECT_NE(nullptr, verify("<manifest package=\"android\"></manifest>"));
+  EXPECT_EQ(nullptr, Verify("<other-tag />"));
+  EXPECT_EQ(nullptr, Verify("<ns:manifest xmlns:ns=\"com\" />"));
+  EXPECT_NE(nullptr, Verify("<manifest package=\"android\"></manifest>"));
 }
 
 TEST_F(ManifestFixerTest, EnsureManifestHasPackage) {
-  EXPECT_NE(nullptr, verify("<manifest package=\"android\" />"));
-  EXPECT_NE(nullptr, verify("<manifest package=\"com.android\" />"));
-  EXPECT_NE(nullptr, verify("<manifest package=\"com.android.google\" />"));
+  EXPECT_NE(nullptr, Verify("<manifest package=\"android\" />"));
+  EXPECT_NE(nullptr, Verify("<manifest package=\"com.android\" />"));
+  EXPECT_NE(nullptr, Verify("<manifest package=\"com.android.google\" />"));
   EXPECT_EQ(nullptr,
-            verify("<manifest package=\"com.android.google.Class$1\" />"));
-  EXPECT_EQ(nullptr, verify("<manifest "
+            Verify("<manifest package=\"com.android.google.Class$1\" />"));
+  EXPECT_EQ(nullptr, Verify("<manifest "
                             "xmlns:android=\"http://schemas.android.com/apk/"
                             "res/android\" "
                             "android:package=\"com.android\" />"));
-  EXPECT_EQ(nullptr, verify("<manifest package=\"@string/str\" />"));
+  EXPECT_EQ(nullptr, Verify("<manifest package=\"@string/str\" />"));
 }
 
 TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) {
   ManifestFixerOptions options = {std::string("8"), std::string("22")};
 
-  std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                 package="android">
         <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="21" />
@@ -103,18 +101,18 @@
   xml::Element* el;
   xml::Attribute* attr;
 
-  el = xml::findRootElement(doc.get());
+  el = xml::FindRootElement(doc.get());
   ASSERT_NE(nullptr, el);
-  el = el->findChild({}, "uses-sdk");
+  el = el->FindChild({}, "uses-sdk");
   ASSERT_NE(nullptr, el);
-  attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion");
+  attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ("7", attr->value);
-  attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion");
+  attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ("21", attr->value);
 
-  doc = verifyWithOptions(R"EOF(
+  doc = VerifyWithOptions(R"EOF(
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                 package="android">
         <uses-sdk android:targetSdkVersion="21" />
@@ -122,18 +120,18 @@
                           options);
   ASSERT_NE(nullptr, doc);
 
-  el = xml::findRootElement(doc.get());
+  el = xml::FindRootElement(doc.get());
   ASSERT_NE(nullptr, el);
-  el = el->findChild({}, "uses-sdk");
+  el = el->FindChild({}, "uses-sdk");
   ASSERT_NE(nullptr, el);
-  attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion");
+  attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ("8", attr->value);
-  attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion");
+  attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ("21", attr->value);
 
-  doc = verifyWithOptions(R"EOF(
+  doc = VerifyWithOptions(R"EOF(
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                 package="android">
         <uses-sdk />
@@ -141,40 +139,84 @@
                           options);
   ASSERT_NE(nullptr, doc);
 
-  el = xml::findRootElement(doc.get());
+  el = xml::FindRootElement(doc.get());
   ASSERT_NE(nullptr, el);
-  el = el->findChild({}, "uses-sdk");
+  el = el->FindChild({}, "uses-sdk");
   ASSERT_NE(nullptr, el);
-  attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion");
+  attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ("8", attr->value);
-  attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion");
+  attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ("22", attr->value);
 
-  doc = verifyWithOptions(R"EOF(
+  doc = VerifyWithOptions(R"EOF(
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                 package="android" />)EOF",
                           options);
   ASSERT_NE(nullptr, doc);
 
-  el = xml::findRootElement(doc.get());
+  el = xml::FindRootElement(doc.get());
   ASSERT_NE(nullptr, el);
-  el = el->findChild({}, "uses-sdk");
+  el = el->FindChild({}, "uses-sdk");
   ASSERT_NE(nullptr, el);
-  attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion");
+  attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ("8", attr->value);
-  attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion");
+  attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ("22", attr->value);
 }
 
+TEST_F(ManifestFixerTest, UsesSdkMustComeBeforeApplication) {
+  ManifestFixerOptions options = {std::string("8"), std::string("22")};
+  std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+          <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+                    package="android">
+            <application android:name=".MainApplication" />
+          </manifest>)EOF",
+                                                            options);
+  ASSERT_NE(nullptr, doc);
+
+  xml::Element* manifest_el = xml::FindRootElement(doc.get());
+  ASSERT_NE(nullptr, manifest_el);
+  ASSERT_EQ("manifest", manifest_el->name);
+
+  xml::Element* application_el = manifest_el->FindChild("", "application");
+  ASSERT_NE(nullptr, application_el);
+
+  xml::Element* uses_sdk_el = manifest_el->FindChild("", "uses-sdk");
+  ASSERT_NE(nullptr, uses_sdk_el);
+
+  // Check that the uses_sdk_el comes before application_el in the children
+  // vector.
+  // Since there are no namespaces here, these children are direct descendants
+  // of manifest.
+  auto uses_sdk_iter =
+      std::find_if(manifest_el->children.begin(), manifest_el->children.end(),
+                   [&](const std::unique_ptr<xml::Node>& child) {
+                     return child.get() == uses_sdk_el;
+                   });
+
+  auto application_iter =
+      std::find_if(manifest_el->children.begin(), manifest_el->children.end(),
+                   [&](const std::unique_ptr<xml::Node>& child) {
+                     return child.get() == application_el;
+                   });
+
+  ASSERT_NE(manifest_el->children.end(), uses_sdk_iter);
+  ASSERT_NE(manifest_el->children.end(), application_iter);
+
+  // The distance should be positive, meaning uses_sdk_iter comes before
+  // application_iter.
+  EXPECT_GT(std::distance(uses_sdk_iter, application_iter), 0);
+}
+
 TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) {
   ManifestFixerOptions options;
-  options.renameManifestPackage = std::string("com.android");
+  options.rename_manifest_package = std::string("com.android");
 
-  std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                 package="android">
         <application android:name=".MainApplication" text="hello">
@@ -185,38 +227,38 @@
                                                             options);
   ASSERT_NE(nullptr, doc);
 
-  xml::Element* manifestEl = xml::findRootElement(doc.get());
+  xml::Element* manifestEl = xml::FindRootElement(doc.get());
   ASSERT_NE(nullptr, manifestEl);
 
   xml::Attribute* attr = nullptr;
 
-  attr = manifestEl->findAttribute({}, "package");
+  attr = manifestEl->FindAttribute({}, "package");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ(std::string("com.android"), attr->value);
 
-  xml::Element* applicationEl = manifestEl->findChild({}, "application");
+  xml::Element* applicationEl = manifestEl->FindChild({}, "application");
   ASSERT_NE(nullptr, applicationEl);
 
-  attr = applicationEl->findAttribute(xml::kSchemaAndroid, "name");
+  attr = applicationEl->FindAttribute(xml::kSchemaAndroid, "name");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ(std::string("android.MainApplication"), attr->value);
 
-  attr = applicationEl->findAttribute({}, "text");
+  attr = applicationEl->FindAttribute({}, "text");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ(std::string("hello"), attr->value);
 
   xml::Element* el;
-  el = applicationEl->findChild({}, "activity");
+  el = applicationEl->FindChild({}, "activity");
   ASSERT_NE(nullptr, el);
 
-  attr = el->findAttribute(xml::kSchemaAndroid, "name");
+  attr = el->FindAttribute(xml::kSchemaAndroid, "name");
   ASSERT_NE(nullptr, el);
   EXPECT_EQ(std::string("android.activity.Start"), attr->value);
 
-  el = applicationEl->findChild({}, "receiver");
+  el = applicationEl->FindChild({}, "receiver");
   ASSERT_NE(nullptr, el);
 
-  attr = el->findAttribute(xml::kSchemaAndroid, "name");
+  attr = el->FindAttribute(xml::kSchemaAndroid, "name");
   ASSERT_NE(nullptr, el);
   EXPECT_EQ(std::string("com.google.android.Receiver"), attr->value);
 }
@@ -224,9 +266,9 @@
 TEST_F(ManifestFixerTest,
        RenameManifestInstrumentationPackageAndFullyQualifyTarget) {
   ManifestFixerOptions options;
-  options.renameInstrumentationTargetPackage = std::string("com.android");
+  options.rename_instrumentation_target_package = std::string("com.android");
 
-  std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                 package="android">
         <instrumentation android:targetPackage="android" />
@@ -234,63 +276,63 @@
                                                             options);
   ASSERT_NE(nullptr, doc);
 
-  xml::Element* manifestEl = xml::findRootElement(doc.get());
-  ASSERT_NE(nullptr, manifestEl);
+  xml::Element* manifest_el = xml::FindRootElement(doc.get());
+  ASSERT_NE(nullptr, manifest_el);
 
-  xml::Element* instrumentationEl =
-      manifestEl->findChild({}, "instrumentation");
-  ASSERT_NE(nullptr, instrumentationEl);
+  xml::Element* instrumentation_el =
+      manifest_el->FindChild({}, "instrumentation");
+  ASSERT_NE(nullptr, instrumentation_el);
 
   xml::Attribute* attr =
-      instrumentationEl->findAttribute(xml::kSchemaAndroid, "targetPackage");
+      instrumentation_el->FindAttribute(xml::kSchemaAndroid, "targetPackage");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ(std::string("com.android"), attr->value);
 }
 
 TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) {
   ManifestFixerOptions options;
-  options.versionNameDefault = std::string("Beta");
-  options.versionCodeDefault = std::string("0x10000000");
+  options.version_name_default = std::string("Beta");
+  options.version_code_default = std::string("0x10000000");
 
-  std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                 package="android" />)EOF",
                                                             options);
   ASSERT_NE(nullptr, doc);
 
-  xml::Element* manifestEl = xml::findRootElement(doc.get());
-  ASSERT_NE(nullptr, manifestEl);
+  xml::Element* manifest_el = xml::FindRootElement(doc.get());
+  ASSERT_NE(nullptr, manifest_el);
 
   xml::Attribute* attr =
-      manifestEl->findAttribute(xml::kSchemaAndroid, "versionName");
+      manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ(std::string("Beta"), attr->value);
 
-  attr = manifestEl->findAttribute(xml::kSchemaAndroid, "versionCode");
+  attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
   ASSERT_NE(nullptr, attr);
   EXPECT_EQ(std::string("0x10000000"), attr->value);
 }
 
 TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) {
   EXPECT_EQ(nullptr,
-            verify("<manifest package=\"android\" coreApp=\"hello\" />"));
+            Verify("<manifest package=\"android\" coreApp=\"hello\" />"));
   EXPECT_EQ(nullptr,
-            verify("<manifest package=\"android\" coreApp=\"1dp\" />"));
+            Verify("<manifest package=\"android\" coreApp=\"1dp\" />"));
 
   std::unique_ptr<xml::XmlResource> doc =
-      verify("<manifest package=\"android\" coreApp=\"true\" />");
+      Verify("<manifest package=\"android\" coreApp=\"true\" />");
   ASSERT_NE(nullptr, doc);
 
-  xml::Element* el = xml::findRootElement(doc.get());
+  xml::Element* el = xml::FindRootElement(doc.get());
   ASSERT_NE(nullptr, el);
 
   EXPECT_EQ("manifest", el->name);
 
-  xml::Attribute* attr = el->findAttribute("", "coreApp");
+  xml::Attribute* attr = el->FindAttribute("", "coreApp");
   ASSERT_NE(nullptr, attr);
 
-  EXPECT_NE(nullptr, attr->compiledValue);
-  EXPECT_NE(nullptr, valueCast<BinaryPrimitive>(attr->compiledValue.get()));
+  EXPECT_NE(nullptr, attr->compiled_value);
+  EXPECT_NE(nullptr, ValueCast<BinaryPrimitive>(attr->compiled_value.get()));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/PrivateAttributeMover.cpp b/tools/aapt2/link/PrivateAttributeMover.cpp
index 174b41f..cc07a6e 100644
--- a/tools/aapt2/link/PrivateAttributeMover.cpp
+++ b/tools/aapt2/link/PrivateAttributeMover.cpp
@@ -14,27 +14,30 @@
  * limitations under the License.
  */
 
-#include "ResourceTable.h"
 #include "link/Linkers.h"
 
 #include <algorithm>
 #include <iterator>
 
+#include "android-base/logging.h"
+
+#include "ResourceTable.h"
+
 namespace aapt {
 
 template <typename InputContainer, typename OutputIterator, typename Predicate>
-OutputIterator moveIf(InputContainer& inputContainer, OutputIterator result,
-                      Predicate pred) {
-  const auto last = inputContainer.end();
-  auto newEnd =
-      std::find_if(inputContainer.begin(), inputContainer.end(), pred);
-  if (newEnd == last) {
+OutputIterator move_if(InputContainer& input_container, OutputIterator result,
+                       Predicate pred) {
+  const auto last = input_container.end();
+  auto new_end =
+      std::find_if(input_container.begin(), input_container.end(), pred);
+  if (new_end == last) {
     return result;
   }
 
-  *result = std::move(*newEnd);
+  *result = std::move(*new_end);
 
-  auto first = newEnd;
+  auto first = new_end;
   ++first;
 
   for (; first != last; ++first) {
@@ -44,39 +47,38 @@
       ++result;
     } else {
       // We want to keep this guy, but we will need to move it up the list to
-      // replace
-      // missing items.
-      *newEnd = std::move(*first);
-      ++newEnd;
+      // replace missing items.
+      *new_end = std::move(*first);
+      ++new_end;
     }
   }
 
-  inputContainer.erase(newEnd, last);
+  input_container.erase(new_end, last);
   return result;
 }
 
-bool PrivateAttributeMover::consume(IAaptContext* context,
+bool PrivateAttributeMover::Consume(IAaptContext* context,
                                     ResourceTable* table) {
   for (auto& package : table->packages) {
-    ResourceTableType* type = package->findType(ResourceType::kAttr);
+    ResourceTableType* type = package->FindType(ResourceType::kAttr);
     if (!type) {
       continue;
     }
 
-    if (type->symbolStatus.state != SymbolState::kPublic) {
+    if (type->symbol_status.state != SymbolState::kPublic) {
       // No public attributes, so we can safely leave these private attributes
       // where they are.
       return true;
     }
 
-    ResourceTableType* privAttrType =
-        package->findOrCreateType(ResourceType::kAttrPrivate);
-    assert(privAttrType->entries.empty());
+    ResourceTableType* priv_attr_type =
+        package->FindOrCreateType(ResourceType::kAttrPrivate);
+    CHECK(priv_attr_type->entries.empty());
 
-    moveIf(type->entries, std::back_inserter(privAttrType->entries),
-           [](const std::unique_ptr<ResourceEntry>& entry) -> bool {
-             return entry->symbolStatus.state != SymbolState::kPublic;
-           });
+    move_if(type->entries, std::back_inserter(priv_attr_type->entries),
+            [](const std::unique_ptr<ResourceEntry>& entry) -> bool {
+              return entry->symbol_status.state != SymbolState::kPublic;
+            });
     break;
   }
   return true;
diff --git a/tools/aapt2/link/PrivateAttributeMover_test.cpp b/tools/aapt2/link/PrivateAttributeMover_test.cpp
index a7a1013..90c4922 100644
--- a/tools/aapt2/link/PrivateAttributeMover_test.cpp
+++ b/tools/aapt2/link/PrivateAttributeMover_test.cpp
@@ -15,64 +15,65 @@
  */
 
 #include "link/Linkers.h"
+
 #include "test/Test.h"
 
 namespace aapt {
 
 TEST(PrivateAttributeMoverTest, MovePrivateAttributes) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .addSimple("android:attr/publicA")
-          .addSimple("android:attr/privateA")
-          .addSimple("android:attr/publicB")
-          .addSimple("android:attr/privateB")
-          .setSymbolState("android:attr/publicA", ResourceId(0x01010000),
+          .AddSimple("android:attr/publicA")
+          .AddSimple("android:attr/privateA")
+          .AddSimple("android:attr/publicB")
+          .AddSimple("android:attr/privateB")
+          .SetSymbolState("android:attr/publicA", ResourceId(0x01010000),
                           SymbolState::kPublic)
-          .setSymbolState("android:attr/publicB", ResourceId(0x01010000),
+          .SetSymbolState("android:attr/publicB", ResourceId(0x01010000),
                           SymbolState::kPublic)
-          .build();
+          .Build();
 
   PrivateAttributeMover mover;
-  ASSERT_TRUE(mover.consume(context.get(), table.get()));
+  ASSERT_TRUE(mover.Consume(context.get(), table.get()));
 
-  ResourceTablePackage* package = table->findPackage("android");
+  ResourceTablePackage* package = table->FindPackage("android");
   ASSERT_NE(package, nullptr);
 
-  ResourceTableType* type = package->findType(ResourceType::kAttr);
+  ResourceTableType* type = package->FindType(ResourceType::kAttr);
   ASSERT_NE(type, nullptr);
   ASSERT_EQ(type->entries.size(), 2u);
-  EXPECT_NE(type->findEntry("publicA"), nullptr);
-  EXPECT_NE(type->findEntry("publicB"), nullptr);
+  EXPECT_NE(type->FindEntry("publicA"), nullptr);
+  EXPECT_NE(type->FindEntry("publicB"), nullptr);
 
-  type = package->findType(ResourceType::kAttrPrivate);
+  type = package->FindType(ResourceType::kAttrPrivate);
   ASSERT_NE(type, nullptr);
   ASSERT_EQ(type->entries.size(), 2u);
-  EXPECT_NE(type->findEntry("privateA"), nullptr);
-  EXPECT_NE(type->findEntry("privateB"), nullptr);
+  EXPECT_NE(type->FindEntry("privateA"), nullptr);
+  EXPECT_NE(type->FindEntry("privateB"), nullptr);
 }
 
 TEST(PrivateAttributeMoverTest,
      LeavePrivateAttributesWhenNoPublicAttributesDefined) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
 
   std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-                                             .addSimple("android:attr/privateA")
-                                             .addSimple("android:attr/privateB")
-                                             .build();
+                                             .AddSimple("android:attr/privateA")
+                                             .AddSimple("android:attr/privateB")
+                                             .Build();
 
   PrivateAttributeMover mover;
-  ASSERT_TRUE(mover.consume(context.get(), table.get()));
+  ASSERT_TRUE(mover.Consume(context.get(), table.get()));
 
-  ResourceTablePackage* package = table->findPackage("android");
+  ResourceTablePackage* package = table->FindPackage("android");
   ASSERT_NE(package, nullptr);
 
-  ResourceTableType* type = package->findType(ResourceType::kAttr);
+  ResourceTableType* type = package->FindType(ResourceType::kAttr);
   ASSERT_NE(type, nullptr);
   ASSERT_EQ(type->entries.size(), 2u);
 
-  type = package->findType(ResourceType::kAttrPrivate);
+  type = package->FindType(ResourceType::kAttrPrivate);
   ASSERT_EQ(type, nullptr);
 }
 
diff --git a/tools/aapt2/link/ProductFilter.cpp b/tools/aapt2/link/ProductFilter.cpp
index d59b682..c1a95ee 100644
--- a/tools/aapt2/link/ProductFilter.cpp
+++ b/tools/aapt2/link/ProductFilter.cpp
@@ -14,103 +14,106 @@
  * limitations under the License.
  */
 
-#include "link/ProductFilter.h"
+#include "link/Linkers.h"
+
+#include "ResourceTable.h"
 
 namespace aapt {
 
-ProductFilter::ResourceConfigValueIter ProductFilter::selectProductToKeep(
+ProductFilter::ResourceConfigValueIter ProductFilter::SelectProductToKeep(
     const ResourceNameRef& name, const ResourceConfigValueIter begin,
     const ResourceConfigValueIter end, IDiagnostics* diag) {
-  ResourceConfigValueIter defaultProductIter = end;
-  ResourceConfigValueIter selectedProductIter = end;
+  ResourceConfigValueIter default_product_iter = end;
+  ResourceConfigValueIter selected_product_iter = end;
 
   for (ResourceConfigValueIter iter = begin; iter != end; ++iter) {
-    ResourceConfigValue* configValue = iter->get();
-    if (mProducts.find(configValue->product) != mProducts.end()) {
-      if (selectedProductIter != end) {
+    ResourceConfigValue* config_value = iter->get();
+    if (products_.find(config_value->product) != products_.end()) {
+      if (selected_product_iter != end) {
         // We have two possible values for this product!
-        diag->error(DiagMessage(configValue->value->getSource())
-                    << "selection of product '" << configValue->product
+        diag->Error(DiagMessage(config_value->value->GetSource())
+                    << "selection of product '" << config_value->product
                     << "' for resource " << name << " is ambiguous");
 
-        ResourceConfigValue* previouslySelectedConfigValue =
-            selectedProductIter->get();
-        diag->note(
-            DiagMessage(previouslySelectedConfigValue->value->getSource())
-            << "product '" << previouslySelectedConfigValue->product
+        ResourceConfigValue* previously_selected_config_value =
+            selected_product_iter->get();
+        diag->Note(
+            DiagMessage(previously_selected_config_value->value->GetSource())
+            << "product '" << previously_selected_config_value->product
             << "' is also a candidate");
         return end;
       }
 
       // Select this product.
-      selectedProductIter = iter;
+      selected_product_iter = iter;
     }
 
-    if (configValue->product.empty() || configValue->product == "default") {
-      if (defaultProductIter != end) {
+    if (config_value->product.empty() || config_value->product == "default") {
+      if (default_product_iter != end) {
         // We have two possible default values.
-        diag->error(DiagMessage(configValue->value->getSource())
+        diag->Error(DiagMessage(config_value->value->GetSource())
                     << "multiple default products defined for resource "
                     << name);
 
-        ResourceConfigValue* previouslyDefaultConfigValue =
-            defaultProductIter->get();
-        diag->note(DiagMessage(previouslyDefaultConfigValue->value->getSource())
-                   << "default product also defined here");
+        ResourceConfigValue* previously_default_config_value =
+            default_product_iter->get();
+        diag->Note(
+            DiagMessage(previously_default_config_value->value->GetSource())
+            << "default product also defined here");
         return end;
       }
 
       // Mark the default.
-      defaultProductIter = iter;
+      default_product_iter = iter;
     }
   }
 
-  if (defaultProductIter == end) {
-    diag->error(DiagMessage() << "no default product defined for resource "
+  if (default_product_iter == end) {
+    diag->Error(DiagMessage() << "no default product defined for resource "
                               << name);
     return end;
   }
 
-  if (selectedProductIter == end) {
-    selectedProductIter = defaultProductIter;
+  if (selected_product_iter == end) {
+    selected_product_iter = default_product_iter;
   }
-  return selectedProductIter;
+  return selected_product_iter;
 }
 
-bool ProductFilter::consume(IAaptContext* context, ResourceTable* table) {
+bool ProductFilter::Consume(IAaptContext* context, ResourceTable* table) {
   bool error = false;
   for (auto& pkg : table->packages) {
     for (auto& type : pkg->types) {
       for (auto& entry : type->entries) {
-        std::vector<std::unique_ptr<ResourceConfigValue>> newValues;
+        std::vector<std::unique_ptr<ResourceConfigValue>> new_values;
 
         ResourceConfigValueIter iter = entry->values.begin();
-        ResourceConfigValueIter startRangeIter = iter;
+        ResourceConfigValueIter start_range_iter = iter;
         while (iter != entry->values.end()) {
           ++iter;
           if (iter == entry->values.end() ||
-              (*iter)->config != (*startRangeIter)->config) {
+              (*iter)->config != (*start_range_iter)->config) {
             // End of the array, or we saw a different config,
             // so this must be the end of a range of products.
             // Select the product to keep from the set of products defined.
             ResourceNameRef name(pkg->name, type->type, entry->name);
-            auto valueToKeep = selectProductToKeep(name, startRangeIter, iter,
-                                                   context->getDiagnostics());
-            if (valueToKeep == iter) {
+            auto value_to_keep = SelectProductToKeep(
+                name, start_range_iter, iter, context->GetDiagnostics());
+            if (value_to_keep == iter) {
               // An error occurred, we could not pick a product.
               error = true;
             } else {
               // We selected a product to keep. Move it to the new array.
-              newValues.push_back(std::move(*valueToKeep));
+              new_values.push_back(std::move(*value_to_keep));
             }
 
             // Start the next range of products.
-            startRangeIter = iter;
+            start_range_iter = iter;
           }
         }
 
         // Now move the new values in to place.
-        entry->values = std::move(newValues);
+        entry->values = std::move(new_values);
       }
     }
   }
diff --git a/tools/aapt2/link/ProductFilter.h b/tools/aapt2/link/ProductFilter.h
deleted file mode 100644
index cc8b8c2..0000000
--- a/tools/aapt2/link/ProductFilter.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 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 AAPT_LINK_PRODUCTFILTER_H
-#define AAPT_LINK_PRODUCTFILTER_H
-
-#include "ResourceTable.h"
-#include "process/IResourceTableConsumer.h"
-
-#include <android-base/macros.h>
-#include <unordered_set>
-
-namespace aapt {
-
-class ProductFilter {
- public:
-  using ResourceConfigValueIter =
-      std::vector<std::unique_ptr<ResourceConfigValue>>::iterator;
-
-  explicit ProductFilter(std::unordered_set<std::string> products)
-      : mProducts(products) {}
-
-  ResourceConfigValueIter selectProductToKeep(
-      const ResourceNameRef& name, const ResourceConfigValueIter begin,
-      const ResourceConfigValueIter end, IDiagnostics* diag);
-
-  bool consume(IAaptContext* context, ResourceTable* table);
-
- private:
-  std::unordered_set<std::string> mProducts;
-
-  DISALLOW_COPY_AND_ASSIGN(ProductFilter);
-};
-
-}  // namespace aapt
-
-#endif /* AAPT_LINK_PRODUCTFILTER_H */
diff --git a/tools/aapt2/link/ProductFilter_test.cpp b/tools/aapt2/link/ProductFilter_test.cpp
index 7f78f8b..379ad26 100644
--- a/tools/aapt2/link/ProductFilter_test.cpp
+++ b/tools/aapt2/link/ProductFilter_test.cpp
@@ -14,116 +14,117 @@
  * limitations under the License.
  */
 
-#include "link/ProductFilter.h"
+#include "link/Linkers.h"
+
 #include "test/Test.h"
 
 namespace aapt {
 
 TEST(ProductFilterTest, SelectTwoProducts) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
 
-  const ConfigDescription land = test::parseConfigOrDie("land");
-  const ConfigDescription port = test::parseConfigOrDie("port");
+  const ConfigDescription land = test::ParseConfigOrDie("land");
+  const ConfigDescription port = test::ParseConfigOrDie("port");
 
   ResourceTable table;
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/one"), land, "",
-      test::ValueBuilder<Id>().setSource(Source("land/default.xml")).build(),
-      context->getDiagnostics()));
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/one"), land, "tablet",
-      test::ValueBuilder<Id>().setSource(Source("land/tablet.xml")).build(),
-      context->getDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/one"), land, "",
+      test::ValueBuilder<Id>().SetSource(Source("land/default.xml")).Build(),
+      context->GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/one"), land, "tablet",
+      test::ValueBuilder<Id>().SetSource(Source("land/tablet.xml")).Build(),
+      context->GetDiagnostics()));
 
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/one"), port, "",
-      test::ValueBuilder<Id>().setSource(Source("port/default.xml")).build(),
-      context->getDiagnostics()));
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/one"), port, "tablet",
-      test::ValueBuilder<Id>().setSource(Source("port/tablet.xml")).build(),
-      context->getDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/one"), port, "",
+      test::ValueBuilder<Id>().SetSource(Source("port/default.xml")).Build(),
+      context->GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/one"), port, "tablet",
+      test::ValueBuilder<Id>().SetSource(Source("port/tablet.xml")).Build(),
+      context->GetDiagnostics()));
 
   ProductFilter filter({"tablet"});
-  ASSERT_TRUE(filter.consume(context.get(), &table));
+  ASSERT_TRUE(filter.Consume(context.get(), &table));
 
-  EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>(
+  EXPECT_EQ(nullptr, test::GetValueForConfigAndProduct<Id>(
                          &table, "android:string/one", land, ""));
-  EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(
+  EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<Id>(
                          &table, "android:string/one", land, "tablet"));
-  EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>(
+  EXPECT_EQ(nullptr, test::GetValueForConfigAndProduct<Id>(
                          &table, "android:string/one", port, ""));
-  EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(
+  EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<Id>(
                          &table, "android:string/one", port, "tablet"));
 }
 
 TEST(ProductFilterTest, SelectDefaultProduct) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
 
   ResourceTable table;
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/one"),
-      ConfigDescription::defaultConfig(), "",
-      test::ValueBuilder<Id>().setSource(Source("default.xml")).build(),
-      context->getDiagnostics()));
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/one"),
-      ConfigDescription::defaultConfig(), "tablet",
-      test::ValueBuilder<Id>().setSource(Source("tablet.xml")).build(),
-      context->getDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/one"),
+      ConfigDescription::DefaultConfig(), "",
+      test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build(),
+      context->GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/one"),
+      ConfigDescription::DefaultConfig(), "tablet",
+      test::ValueBuilder<Id>().SetSource(Source("tablet.xml")).Build(),
+      context->GetDiagnostics()));
 
   ProductFilter filter({});
-  ASSERT_TRUE(filter.consume(context.get(), &table));
+  ASSERT_TRUE(filter.Consume(context.get(), &table));
 
-  EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(
+  EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<Id>(
                          &table, "android:string/one",
-                         ConfigDescription::defaultConfig(), ""));
-  EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>(
+                         ConfigDescription::DefaultConfig(), ""));
+  EXPECT_EQ(nullptr, test::GetValueForConfigAndProduct<Id>(
                          &table, "android:string/one",
-                         ConfigDescription::defaultConfig(), "tablet"));
+                         ConfigDescription::DefaultConfig(), "tablet"));
 }
 
 TEST(ProductFilterTest, FailOnAmbiguousProduct) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
 
   ResourceTable table;
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/one"),
-      ConfigDescription::defaultConfig(), "",
-      test::ValueBuilder<Id>().setSource(Source("default.xml")).build(),
-      context->getDiagnostics()));
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/one"),
-      ConfigDescription::defaultConfig(), "tablet",
-      test::ValueBuilder<Id>().setSource(Source("tablet.xml")).build(),
-      context->getDiagnostics()));
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/one"),
-      ConfigDescription::defaultConfig(), "no-sdcard",
-      test::ValueBuilder<Id>().setSource(Source("no-sdcard.xml")).build(),
-      context->getDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/one"),
+      ConfigDescription::DefaultConfig(), "",
+      test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build(),
+      context->GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/one"),
+      ConfigDescription::DefaultConfig(), "tablet",
+      test::ValueBuilder<Id>().SetSource(Source("tablet.xml")).Build(),
+      context->GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/one"),
+      ConfigDescription::DefaultConfig(), "no-sdcard",
+      test::ValueBuilder<Id>().SetSource(Source("no-sdcard.xml")).Build(),
+      context->GetDiagnostics()));
 
   ProductFilter filter({"tablet", "no-sdcard"});
-  ASSERT_FALSE(filter.consume(context.get(), &table));
+  ASSERT_FALSE(filter.Consume(context.get(), &table));
 }
 
 TEST(ProductFilterTest, FailOnMultipleDefaults) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
 
   ResourceTable table;
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/one"),
-      ConfigDescription::defaultConfig(), "",
-      test::ValueBuilder<Id>().setSource(Source(".xml")).build(),
-      context->getDiagnostics()));
-  ASSERT_TRUE(table.addResource(
-      test::parseNameOrDie("android:string/one"),
-      ConfigDescription::defaultConfig(), "default",
-      test::ValueBuilder<Id>().setSource(Source("default.xml")).build(),
-      context->getDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/one"),
+      ConfigDescription::DefaultConfig(), "",
+      test::ValueBuilder<Id>().SetSource(Source(".xml")).Build(),
+      context->GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(
+      test::ParseNameOrDie("android:string/one"),
+      ConfigDescription::DefaultConfig(), "default",
+      test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build(),
+      context->GetDiagnostics()));
 
   ProductFilter filter({});
-  ASSERT_FALSE(filter.consume(context.get(), &table));
+  ASSERT_FALSE(filter.Consume(context.get(), &table));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index 7fe0956..be787b2 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -14,7 +14,11 @@
  * limitations under the License.
  */
 
-#include "ReferenceLinker.h"
+#include "link/ReferenceLinker.h"
+
+#include "android-base/logging.h"
+#include "androidfw/ResourceTypes.h"
+
 #include "Diagnostics.h"
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
@@ -26,9 +30,6 @@
 #include "util/Util.h"
 #include "xml/XmlUtil.h"
 
-#include <androidfw/ResourceTypes.h>
-#include <cassert>
-
 namespace aapt {
 
 namespace {
@@ -46,21 +47,21 @@
  */
 class ReferenceLinkerVisitor : public ValueVisitor {
  public:
-  using ValueVisitor::visit;
+  using ValueVisitor::Visit;
 
   ReferenceLinkerVisitor(IAaptContext* context, SymbolTable* symbols,
-                         StringPool* stringPool, xml::IPackageDeclStack* decl,
-                         CallSite* callSite)
-      : mContext(context),
-        mSymbols(symbols),
-        mPackageDecls(decl),
-        mStringPool(stringPool),
-        mCallSite(callSite) {}
+                         StringPool* string_pool, xml::IPackageDeclStack* decl,
+                         CallSite* callsite)
+      : context_(context),
+        symbols_(symbols),
+        package_decls_(decl),
+        string_pool_(string_pool),
+        callsite_(callsite) {}
 
-  void visit(Reference* ref) override {
-    if (!ReferenceLinker::linkReference(ref, mContext, mSymbols, mPackageDecls,
-                                        mCallSite)) {
-      mError = true;
+  void Visit(Reference* ref) override {
+    if (!ReferenceLinker::LinkReference(ref, context_, symbols_, package_decls_,
+                                        callsite_)) {
+      error_ = true;
     }
   }
 
@@ -72,13 +73,13 @@
    * lookup the attributes to find out which types are allowed for the
    * attributes' values.
    */
-  void visit(Style* style) override {
+  void Visit(Style* style) override {
     if (style->parent) {
-      visit(&style->parent.value());
+      Visit(&style->parent.value());
     }
 
     for (Style::Entry& entry : style->entries) {
-      std::string errStr;
+      std::string err_str;
 
       // Transform the attribute reference so that it is using the fully
       // qualified package
@@ -86,17 +87,17 @@
       // resources if
       // there was a '*' in the reference or if the package came from the
       // private namespace.
-      Reference transformedReference = entry.key;
-      transformReferenceFromNamespace(mPackageDecls,
-                                      mContext->getCompilationPackage(),
-                                      &transformedReference);
+      Reference transformed_reference = entry.key;
+      TransformReferenceFromNamespace(package_decls_,
+                                      context_->GetCompilationPackage(),
+                                      &transformed_reference);
 
       // Find the attribute in the symbol table and check if it is visible from
       // this callsite.
       const SymbolTable::Symbol* symbol =
-          ReferenceLinker::resolveAttributeCheckVisibility(
-              transformedReference, mContext->getNameMangler(), mSymbols,
-              mCallSite, &errStr);
+          ReferenceLinker::ResolveAttributeCheckVisibility(
+              transformed_reference, context_->GetNameMangler(), symbols_,
+              callsite_, &err_str);
       if (symbol) {
         // Assign our style key the correct ID.
         // The ID may not exist.
@@ -104,11 +105,11 @@
 
         // Try to convert the value to a more specific, typed value based on the
         // attribute it is set to.
-        entry.value = parseValueWithAttribute(std::move(entry.value),
+        entry.value = ParseValueWithAttribute(std::move(entry.value),
                                               symbol->attribute.get());
 
         // Link/resolve the final value (mostly if it's a reference).
-        entry.value->accept(this);
+        entry.value->Accept(this);
 
         // Now verify that the type of this item is compatible with the
         // attribute it
@@ -116,39 +117,34 @@
         // check is
         // fast and we avoid creating a DiagMessage when the match is
         // successful.
-        if (!symbol->attribute->matches(entry.value.get(), nullptr)) {
+        if (!symbol->attribute->Matches(entry.value.get(), nullptr)) {
           // The actual type of this item is incompatible with the attribute.
-          DiagMessage msg(entry.key.getSource());
+          DiagMessage msg(entry.key.GetSource());
 
           // Call the matches method again, this time with a DiagMessage so we
           // fill
           // in the actual error message.
-          symbol->attribute->matches(entry.value.get(), &msg);
-          mContext->getDiagnostics()->error(msg);
-          mError = true;
+          symbol->attribute->Matches(entry.value.get(), &msg);
+          context_->GetDiagnostics()->Error(msg);
+          error_ = true;
         }
 
       } else {
-        DiagMessage msg(entry.key.getSource());
+        DiagMessage msg(entry.key.GetSource());
         msg << "style attribute '";
-        ReferenceLinker::writeResourceName(&msg, entry.key,
-                                           transformedReference);
-        msg << "' " << errStr;
-        mContext->getDiagnostics()->error(msg);
-        mError = true;
+        ReferenceLinker::WriteResourceName(&msg, entry.key,
+                                           transformed_reference);
+        msg << "' " << err_str;
+        context_->GetDiagnostics()->Error(msg);
+        error_ = true;
       }
     }
   }
 
-  bool hasError() { return mError; }
+  bool HasError() { return error_; }
 
  private:
-  IAaptContext* mContext;
-  SymbolTable* mSymbols;
-  xml::IPackageDeclStack* mPackageDecls;
-  StringPool* mStringPool;
-  CallSite* mCallSite;
-  bool mError = false;
+  DISALLOW_COPY_AND_ASSIGN(ReferenceLinkerVisitor);
 
   /**
    * Transform a RawString value into a more specific, appropriate value, based
@@ -156,20 +152,20 @@
    * Attribute. If a non RawString value is passed in, this is an identity
    * transform.
    */
-  std::unique_ptr<Item> parseValueWithAttribute(std::unique_ptr<Item> value,
+  std::unique_ptr<Item> ParseValueWithAttribute(std::unique_ptr<Item> value,
                                                 const Attribute* attr) {
-    if (RawString* rawString = valueCast<RawString>(value.get())) {
+    if (RawString* raw_string = ValueCast<RawString>(value.get())) {
       std::unique_ptr<Item> transformed =
-          ResourceUtils::tryParseItemForAttribute(*rawString->value, attr);
+          ResourceUtils::TryParseItemForAttribute(*raw_string->value, attr);
 
       // If we could not parse as any specific type, try a basic STRING.
       if (!transformed &&
-          (attr->typeMask & android::ResTable_map::TYPE_STRING)) {
-        util::StringBuilder stringBuilder;
-        stringBuilder.append(*rawString->value);
-        if (stringBuilder) {
+          (attr->type_mask & android::ResTable_map::TYPE_STRING)) {
+        util::StringBuilder string_builder;
+        string_builder.Append(*raw_string->value);
+        if (string_builder) {
           transformed = util::make_unique<String>(
-              mStringPool->makeRef(stringBuilder.str()));
+              string_pool_->MakeRef(string_builder.ToString()));
         }
       }
 
@@ -179,6 +175,31 @@
     };
     return value;
   }
+
+  IAaptContext* context_;
+  SymbolTable* symbols_;
+  xml::IPackageDeclStack* package_decls_;
+  StringPool* string_pool_;
+  CallSite* callsite_;
+  bool error_ = false;
+};
+
+class EmptyDeclStack : public xml::IPackageDeclStack {
+ public:
+  EmptyDeclStack() = default;
+
+  Maybe<xml::ExtractedPackage> TransformPackageAlias(
+      const StringPiece& alias,
+      const StringPiece& local_package) const override {
+    if (alias.empty()) {
+      return xml::ExtractedPackage{local_package.ToString(),
+                                   true /* private */};
+    }
+    return {};
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(EmptyDeclStack);
 };
 
 }  // namespace
@@ -188,14 +209,14 @@
  * requesting private access
  * or if the callsite comes from the same package.
  */
-bool ReferenceLinker::isSymbolVisible(const SymbolTable::Symbol& symbol,
+bool ReferenceLinker::IsSymbolVisible(const SymbolTable::Symbol& symbol,
                                       const Reference& ref,
-                                      const CallSite& callSite) {
-  if (!symbol.isPublic && !ref.privateReference) {
+                                      const CallSite& callsite) {
+  if (!symbol.is_public && !ref.private_reference) {
     if (ref.name) {
-      return callSite.resource.package == ref.name.value().package;
+      return callsite.resource.package == ref.name.value().package;
     } else if (ref.id && symbol.id) {
-      return ref.id.value().packageId() == symbol.id.value().packageId();
+      return ref.id.value().package_id() == symbol.id.value().package_id();
     } else {
       return false;
     }
@@ -203,160 +224,144 @@
   return true;
 }
 
-const SymbolTable::Symbol* ReferenceLinker::resolveSymbol(
+const SymbolTable::Symbol* ReferenceLinker::ResolveSymbol(
     const Reference& reference, NameMangler* mangler, SymbolTable* symbols) {
   if (reference.name) {
-    Maybe<ResourceName> mangled = mangler->mangleName(reference.name.value());
-    return symbols->findByName(mangled ? mangled.value()
+    Maybe<ResourceName> mangled = mangler->MangleName(reference.name.value());
+    return symbols->FindByName(mangled ? mangled.value()
                                        : reference.name.value());
   } else if (reference.id) {
-    return symbols->findById(reference.id.value());
+    return symbols->FindById(reference.id.value());
   } else {
     return nullptr;
   }
 }
 
-const SymbolTable::Symbol* ReferenceLinker::resolveSymbolCheckVisibility(
-    const Reference& reference, NameMangler* nameMangler, SymbolTable* symbols,
-    CallSite* callSite, std::string* outError) {
+const SymbolTable::Symbol* ReferenceLinker::ResolveSymbolCheckVisibility(
+    const Reference& reference, NameMangler* name_mangler, SymbolTable* symbols,
+    CallSite* callsite, std::string* out_error) {
   const SymbolTable::Symbol* symbol =
-      resolveSymbol(reference, nameMangler, symbols);
+      ResolveSymbol(reference, name_mangler, symbols);
   if (!symbol) {
-    if (outError) *outError = "not found";
+    if (out_error) *out_error = "not found";
     return nullptr;
   }
 
-  if (!isSymbolVisible(*symbol, reference, *callSite)) {
-    if (outError) *outError = "is private";
+  if (!IsSymbolVisible(*symbol, reference, *callsite)) {
+    if (out_error) *out_error = "is private";
     return nullptr;
   }
   return symbol;
 }
 
-const SymbolTable::Symbol* ReferenceLinker::resolveAttributeCheckVisibility(
-    const Reference& reference, NameMangler* nameMangler, SymbolTable* symbols,
-    CallSite* callSite, std::string* outError) {
-  const SymbolTable::Symbol* symbol = resolveSymbolCheckVisibility(
-      reference, nameMangler, symbols, callSite, outError);
+const SymbolTable::Symbol* ReferenceLinker::ResolveAttributeCheckVisibility(
+    const Reference& reference, NameMangler* name_mangler, SymbolTable* symbols,
+    CallSite* callsite, std::string* out_error) {
+  const SymbolTable::Symbol* symbol = ResolveSymbolCheckVisibility(
+      reference, name_mangler, symbols, callsite, out_error);
   if (!symbol) {
     return nullptr;
   }
 
   if (!symbol->attribute) {
-    if (outError) *outError = "is not an attribute";
+    if (out_error) *out_error = "is not an attribute";
     return nullptr;
   }
   return symbol;
 }
 
-Maybe<xml::AaptAttribute> ReferenceLinker::compileXmlAttribute(
-    const Reference& reference, NameMangler* nameMangler, SymbolTable* symbols,
-    CallSite* callSite, std::string* outError) {
+Maybe<xml::AaptAttribute> ReferenceLinker::CompileXmlAttribute(
+    const Reference& reference, NameMangler* name_mangler, SymbolTable* symbols,
+    CallSite* callsite, std::string* out_error) {
   const SymbolTable::Symbol* symbol =
-      resolveSymbol(reference, nameMangler, symbols);
+      ResolveSymbol(reference, name_mangler, symbols);
   if (!symbol) {
-    if (outError) *outError = "not found";
+    if (out_error) *out_error = "not found";
     return {};
   }
 
   if (!symbol->attribute) {
-    if (outError) *outError = "is not an attribute";
+    if (out_error) *out_error = "is not an attribute";
     return {};
   }
   return xml::AaptAttribute{symbol->id, *symbol->attribute};
 }
 
-void ReferenceLinker::writeResourceName(DiagMessage* outMsg,
+void ReferenceLinker::WriteResourceName(DiagMessage* out_msg,
                                         const Reference& orig,
                                         const Reference& transformed) {
-  assert(outMsg);
+  CHECK(out_msg != nullptr);
 
   if (orig.name) {
-    *outMsg << orig.name.value();
+    *out_msg << orig.name.value();
     if (transformed.name.value() != orig.name.value()) {
-      *outMsg << " (aka " << transformed.name.value() << ")";
+      *out_msg << " (aka " << transformed.name.value() << ")";
     }
   } else {
-    *outMsg << orig.id.value();
+    *out_msg << orig.id.value();
   }
 }
 
-bool ReferenceLinker::linkReference(Reference* reference, IAaptContext* context,
+bool ReferenceLinker::LinkReference(Reference* reference, IAaptContext* context,
                                     SymbolTable* symbols,
                                     xml::IPackageDeclStack* decls,
-                                    CallSite* callSite) {
-  assert(reference);
-  assert(reference->name || reference->id);
+                                    CallSite* callsite) {
+  CHECK(reference != nullptr);
+  CHECK(reference->name || reference->id);
 
-  Reference transformedReference = *reference;
-  transformReferenceFromNamespace(decls, context->getCompilationPackage(),
-                                  &transformedReference);
+  Reference transformed_reference = *reference;
+  TransformReferenceFromNamespace(decls, context->GetCompilationPackage(),
+                                  &transformed_reference);
 
-  std::string errStr;
-  const SymbolTable::Symbol* s = resolveSymbolCheckVisibility(
-      transformedReference, context->getNameMangler(), symbols, callSite,
-      &errStr);
+  std::string err_str;
+  const SymbolTable::Symbol* s = ResolveSymbolCheckVisibility(
+      transformed_reference, context->GetNameMangler(), symbols, callsite,
+      &err_str);
   if (s) {
     // The ID may not exist. This is fine because of the possibility of building
-    // against
-    // libraries without assigned IDs.
+    // against libraries without assigned IDs.
     // Ex: Linking against own resources when building a static library.
     reference->id = s->id;
     return true;
   }
 
-  DiagMessage errorMsg(reference->getSource());
-  errorMsg << "resource ";
-  writeResourceName(&errorMsg, *reference, transformedReference);
-  errorMsg << " " << errStr;
-  context->getDiagnostics()->error(errorMsg);
+  DiagMessage error_msg(reference->GetSource());
+  error_msg << "resource ";
+  WriteResourceName(&error_msg, *reference, transformed_reference);
+  error_msg << " " << err_str;
+  context->GetDiagnostics()->Error(error_msg);
   return false;
 }
 
-namespace {
-
-struct EmptyDeclStack : public xml::IPackageDeclStack {
-  Maybe<xml::ExtractedPackage> transformPackageAlias(
-      const StringPiece& alias,
-      const StringPiece& localPackage) const override {
-    if (alias.empty()) {
-      return xml::ExtractedPackage{localPackage.toString(), true /* private */};
-    }
-    return {};
-  }
-};
-
-}  // namespace
-
-bool ReferenceLinker::consume(IAaptContext* context, ResourceTable* table) {
-  EmptyDeclStack declStack;
+bool ReferenceLinker::Consume(IAaptContext* context, ResourceTable* table) {
+  EmptyDeclStack decl_stack;
   bool error = false;
   for (auto& package : table->packages) {
     for (auto& type : package->types) {
       for (auto& entry : type->entries) {
         // Symbol state information may be lost if there is no value for the
         // resource.
-        if (entry->symbolStatus.state != SymbolState::kUndefined &&
+        if (entry->symbol_status.state != SymbolState::kUndefined &&
             entry->values.empty()) {
-          context->getDiagnostics()->error(
-              DiagMessage(entry->symbolStatus.source)
+          context->GetDiagnostics()->Error(
+              DiagMessage(entry->symbol_status.source)
               << "no definition for declared symbol '"
               << ResourceNameRef(package->name, type->type, entry->name)
               << "'");
           error = true;
         }
 
-        CallSite callSite = {
+        CallSite callsite = {
             ResourceNameRef(package->name, type->type, entry->name)};
-        ReferenceLinkerVisitor visitor(context, context->getExternalSymbols(),
-                                       &table->stringPool, &declStack,
-                                       &callSite);
+        ReferenceLinkerVisitor visitor(context, context->GetExternalSymbols(),
+                                       &table->string_pool, &decl_stack,
+                                       &callsite);
 
-        for (auto& configValue : entry->values) {
-          configValue->value->accept(&visitor);
+        for (auto& config_value : entry->values) {
+          config_value->value->Accept(&visitor);
         }
 
-        if (visitor.hasError()) {
+        if (visitor.HasError()) {
           error = true;
         }
       }
diff --git a/tools/aapt2/link/ReferenceLinker.h b/tools/aapt2/link/ReferenceLinker.h
index 8f6604f..bdabf24 100644
--- a/tools/aapt2/link/ReferenceLinker.h
+++ b/tools/aapt2/link/ReferenceLinker.h
@@ -17,6 +17,8 @@
 #ifndef AAPT_LINKER_REFERENCELINKER_H
 #define AAPT_LINKER_REFERENCELINKER_H
 
+#include "android-base/macros.h"
+
 #include "Resource.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
@@ -25,8 +27,6 @@
 #include "process/SymbolTable.h"
 #include "xml/XmlDom.h"
 
-#include <cassert>
-
 namespace aapt {
 
 /**
@@ -36,33 +36,33 @@
  * Once the ResourceTable is processed by this linker, it is ready to be
  * flattened.
  */
-struct ReferenceLinker : public IResourceTableConsumer {
+class ReferenceLinker : public IResourceTableConsumer {
+ public:
+  ReferenceLinker() = default;
+
   /**
    * Returns true if the symbol is visible by the reference and from the
    * callsite.
    */
-  static bool isSymbolVisible(const SymbolTable::Symbol& symbol,
-                              const Reference& ref, const CallSite& callSite);
+  static bool IsSymbolVisible(const SymbolTable::Symbol& symbol,
+                              const Reference& ref, const CallSite& callsite);
 
   /**
    * Performs name mangling and looks up the resource in the symbol table.
-   * Returns nullptr
-   * if the symbol was not found.
+   * Returns nullptr if the symbol was not found.
    */
-  static const SymbolTable::Symbol* resolveSymbol(const Reference& reference,
+  static const SymbolTable::Symbol* ResolveSymbol(const Reference& reference,
                                                   NameMangler* mangler,
                                                   SymbolTable* symbols);
 
   /**
    * Performs name mangling and looks up the resource in the symbol table. If
-   * the symbol is
-   * not visible by the reference at the callsite, nullptr is returned. outError
-   * holds
-   * the error message.
+   * the symbol is not visible by the reference at the callsite, nullptr is
+   * returned. out_error holds the error message.
    */
-  static const SymbolTable::Symbol* resolveSymbolCheckVisibility(
-      const Reference& reference, NameMangler* nameMangler,
-      SymbolTable* symbols, CallSite* callSite, std::string* outError);
+  static const SymbolTable::Symbol* ResolveSymbolCheckVisibility(
+      const Reference& reference, NameMangler* name_mangler,
+      SymbolTable* symbols, CallSite* callsite, std::string* out_error);
 
   /**
    * Same as resolveSymbolCheckVisibility(), but also makes sure the symbol is
@@ -70,25 +70,24 @@
    * That is, the return value will have a non-null value for
    * ISymbolTable::Symbol::attribute.
    */
-  static const SymbolTable::Symbol* resolveAttributeCheckVisibility(
-      const Reference& reference, NameMangler* nameMangler,
-      SymbolTable* symbols, CallSite* callSite, std::string* outError);
+  static const SymbolTable::Symbol* ResolveAttributeCheckVisibility(
+      const Reference& reference, NameMangler* name_mangler,
+      SymbolTable* symbols, CallSite* callsite, std::string* out_error);
 
   /**
    * Resolves the attribute reference and returns an xml::AaptAttribute if
    * successful.
    * If resolution fails, outError holds the error message.
    */
-  static Maybe<xml::AaptAttribute> compileXmlAttribute(
-      const Reference& reference, NameMangler* nameMangler,
-      SymbolTable* symbols, CallSite* callSite, std::string* outError);
+  static Maybe<xml::AaptAttribute> CompileXmlAttribute(
+      const Reference& reference, NameMangler* name_mangler,
+      SymbolTable* symbols, CallSite* callsite, std::string* out_error);
 
   /**
-   * Writes the resource name to the DiagMessage, using the "orig_name (aka
-   * <transformed_name>)"
-   * syntax.
+   * Writes the resource name to the DiagMessage, using the
+   * "orig_name (aka <transformed_name>)" syntax.
    */
-  static void writeResourceName(DiagMessage* outMsg, const Reference& orig,
+  static void WriteResourceName(DiagMessage* out_msg, const Reference& orig,
                                 const Reference& transformed);
 
   /**
@@ -100,14 +99,17 @@
    * Returns false on failure, and an error message is logged to the
    * IDiagnostics in the context.
    */
-  static bool linkReference(Reference* reference, IAaptContext* context,
+  static bool LinkReference(Reference* reference, IAaptContext* context,
                             SymbolTable* symbols, xml::IPackageDeclStack* decls,
-                            CallSite* callSite);
+                            CallSite* callsite);
 
   /**
    * Links all references in the ResourceTable.
    */
-  bool consume(IAaptContext* context, ResourceTable* table) override;
+  bool Consume(IAaptContext* context, ResourceTable* table) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ReferenceLinker);
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/ReferenceLinker_test.cpp b/tools/aapt2/link/ReferenceLinker_test.cpp
index 8aa3616..4ca36a9 100644
--- a/tools/aapt2/link/ReferenceLinker_test.cpp
+++ b/tools/aapt2/link/ReferenceLinker_test.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "link/ReferenceLinker.h"
+
 #include "test/Test.h"
 
 using android::ResTable_map;
@@ -24,46 +25,46 @@
 TEST(ReferenceLinkerTest, LinkSimpleReferences) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.test", 0x7f)
-          .addReference("com.app.test:string/foo", ResourceId(0x7f020000),
+          .SetPackageId("com.app.test", 0x7f)
+          .AddReference("com.app.test:string/foo", ResourceId(0x7f020000),
                         "com.app.test:string/bar")
 
           // Test use of local reference (w/o package name).
-          .addReference("com.app.test:string/bar", ResourceId(0x7f020001),
+          .AddReference("com.app.test:string/bar", ResourceId(0x7f020001),
                         "string/baz")
 
-          .addReference("com.app.test:string/baz", ResourceId(0x7f020002),
+          .AddReference("com.app.test:string/baz", ResourceId(0x7f020002),
                         "android:string/ok")
-          .build();
+          .Build();
 
   std::unique_ptr<IAaptContext> context =
       test::ContextBuilder()
-          .setCompilationPackage("com.app.test")
-          .setPackageId(0x7f)
-          .setNameManglerPolicy(NameManglerPolicy{"com.app.test"})
-          .addSymbolSource(
+          .SetCompilationPackage("com.app.test")
+          .SetPackageId(0x7f)
+          .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"})
+          .AddSymbolSource(
               util::make_unique<ResourceTableSymbolSource>(table.get()))
-          .addSymbolSource(
+          .AddSymbolSource(
               test::StaticSymbolSourceBuilder()
-                  .addPublicSymbol("android:string/ok", ResourceId(0x01040034))
-                  .build())
-          .build();
+                  .AddPublicSymbol("android:string/ok", ResourceId(0x01040034))
+                  .Build())
+          .Build();
 
   ReferenceLinker linker;
-  ASSERT_TRUE(linker.consume(context.get(), table.get()));
+  ASSERT_TRUE(linker.Consume(context.get(), table.get()));
 
   Reference* ref =
-      test::getValue<Reference>(table.get(), "com.app.test:string/foo");
+      test::GetValue<Reference>(table.get(), "com.app.test:string/foo");
   ASSERT_NE(ref, nullptr);
   AAPT_ASSERT_TRUE(ref->id);
   EXPECT_EQ(ref->id.value(), ResourceId(0x7f020001));
 
-  ref = test::getValue<Reference>(table.get(), "com.app.test:string/bar");
+  ref = test::GetValue<Reference>(table.get(), "com.app.test:string/bar");
   ASSERT_NE(ref, nullptr);
   AAPT_ASSERT_TRUE(ref->id);
   EXPECT_EQ(ref->id.value(), ResourceId(0x7f020002));
 
-  ref = test::getValue<Reference>(table.get(), "com.app.test:string/baz");
+  ref = test::GetValue<Reference>(table.get(), "com.app.test:string/baz");
   ASSERT_NE(ref, nullptr);
   AAPT_ASSERT_TRUE(ref->id);
   EXPECT_EQ(ref->id.value(), ResourceId(0x01040034));
@@ -72,53 +73,53 @@
 TEST(ReferenceLinkerTest, LinkStyleAttributes) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.test", 0x7f)
-          .addValue("com.app.test:style/Theme",
+          .SetPackageId("com.app.test", 0x7f)
+          .AddValue("com.app.test:style/Theme",
                     test::StyleBuilder()
-                        .setParent("android:style/Theme.Material")
-                        .addItem("android:attr/foo",
-                                 ResourceUtils::tryParseColor("#ff00ff"))
-                        .addItem("android:attr/bar", {} /* placeholder */)
-                        .build())
-          .build();
+                        .SetParent("android:style/Theme.Material")
+                        .AddItem("android:attr/foo",
+                                 ResourceUtils::TryParseColor("#ff00ff"))
+                        .AddItem("android:attr/bar", {} /* placeholder */)
+                        .Build())
+          .Build();
 
   {
     // We need to fill in the value for the attribute android:attr/bar after we
     // build the
     // table, because we need access to the string pool.
     Style* style =
-        test::getValue<Style>(table.get(), "com.app.test:style/Theme");
+        test::GetValue<Style>(table.get(), "com.app.test:style/Theme");
     ASSERT_NE(style, nullptr);
     style->entries.back().value =
-        util::make_unique<RawString>(table->stringPool.makeRef("one|two"));
+        util::make_unique<RawString>(table->string_pool.MakeRef("one|two"));
   }
 
   std::unique_ptr<IAaptContext> context =
       test::ContextBuilder()
-          .setCompilationPackage("com.app.test")
-          .setPackageId(0x7f)
-          .setNameManglerPolicy(NameManglerPolicy{"com.app.test"})
-          .addSymbolSource(
+          .SetCompilationPackage("com.app.test")
+          .SetPackageId(0x7f)
+          .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"})
+          .AddSymbolSource(
               test::StaticSymbolSourceBuilder()
-                  .addPublicSymbol("android:style/Theme.Material",
+                  .AddPublicSymbol("android:style/Theme.Material",
                                    ResourceId(0x01060000))
-                  .addPublicSymbol("android:attr/foo", ResourceId(0x01010001),
+                  .AddPublicSymbol("android:attr/foo", ResourceId(0x01010001),
                                    test::AttributeBuilder()
-                                       .setTypeMask(ResTable_map::TYPE_COLOR)
-                                       .build())
-                  .addPublicSymbol("android:attr/bar", ResourceId(0x01010002),
+                                       .SetTypeMask(ResTable_map::TYPE_COLOR)
+                                       .Build())
+                  .AddPublicSymbol("android:attr/bar", ResourceId(0x01010002),
                                    test::AttributeBuilder()
-                                       .setTypeMask(ResTable_map::TYPE_FLAGS)
-                                       .addItem("one", 0x01)
-                                       .addItem("two", 0x02)
-                                       .build())
-                  .build())
-          .build();
+                                       .SetTypeMask(ResTable_map::TYPE_FLAGS)
+                                       .AddItem("one", 0x01)
+                                       .AddItem("two", 0x02)
+                                       .Build())
+                  .Build())
+          .Build();
 
   ReferenceLinker linker;
-  ASSERT_TRUE(linker.consume(context.get(), table.get()));
+  ASSERT_TRUE(linker.Consume(context.get(), table.get()));
 
-  Style* style = test::getValue<Style>(table.get(), "com.app.test:style/Theme");
+  Style* style = test::GetValue<Style>(table.get(), "com.app.test:style/Theme");
   ASSERT_NE(style, nullptr);
   AAPT_ASSERT_TRUE(style->parent);
   AAPT_ASSERT_TRUE(style->parent.value().id);
@@ -128,44 +129,44 @@
 
   AAPT_ASSERT_TRUE(style->entries[0].key.id);
   EXPECT_EQ(style->entries[0].key.id.value(), ResourceId(0x01010001));
-  ASSERT_NE(valueCast<BinaryPrimitive>(style->entries[0].value.get()), nullptr);
+  ASSERT_NE(ValueCast<BinaryPrimitive>(style->entries[0].value.get()), nullptr);
 
   AAPT_ASSERT_TRUE(style->entries[1].key.id);
   EXPECT_EQ(style->entries[1].key.id.value(), ResourceId(0x01010002));
-  ASSERT_NE(valueCast<BinaryPrimitive>(style->entries[1].value.get()), nullptr);
+  ASSERT_NE(ValueCast<BinaryPrimitive>(style->entries[1].value.get()), nullptr);
 }
 
 TEST(ReferenceLinkerTest, LinkMangledReferencesAndAttributes) {
   std::unique_ptr<IAaptContext> context =
       test::ContextBuilder()
-          .setCompilationPackage("com.app.test")
-          .setPackageId(0x7f)
-          .setNameManglerPolicy(
+          .SetCompilationPackage("com.app.test")
+          .SetPackageId(0x7f)
+          .SetNameManglerPolicy(
               NameManglerPolicy{"com.app.test", {"com.android.support"}})
-          .addSymbolSource(
+          .AddSymbolSource(
               test::StaticSymbolSourceBuilder()
-                  .addPublicSymbol("com.app.test:attr/com.android.support$foo",
+                  .AddPublicSymbol("com.app.test:attr/com.android.support$foo",
                                    ResourceId(0x7f010000),
                                    test::AttributeBuilder()
-                                       .setTypeMask(ResTable_map::TYPE_COLOR)
-                                       .build())
-                  .build())
-          .build();
+                                       .SetTypeMask(ResTable_map::TYPE_COLOR)
+                                       .Build())
+                  .Build())
+          .Build();
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.test", 0x7f)
-          .addValue("com.app.test:style/Theme", ResourceId(0x7f020000),
+          .SetPackageId("com.app.test", 0x7f)
+          .AddValue("com.app.test:style/Theme", ResourceId(0x7f020000),
                     test::StyleBuilder()
-                        .addItem("com.android.support:attr/foo",
-                                 ResourceUtils::tryParseColor("#ff0000"))
-                        .build())
-          .build();
+                        .AddItem("com.android.support:attr/foo",
+                                 ResourceUtils::TryParseColor("#ff0000"))
+                        .Build())
+          .Build();
 
   ReferenceLinker linker;
-  ASSERT_TRUE(linker.consume(context.get(), table.get()));
+  ASSERT_TRUE(linker.Consume(context.get(), table.get()));
 
-  Style* style = test::getValue<Style>(table.get(), "com.app.test:style/Theme");
+  Style* style = test::GetValue<Style>(table.get(), "com.app.test:style/Theme");
   ASSERT_NE(style, nullptr);
   ASSERT_EQ(1u, style->entries.size());
   AAPT_ASSERT_TRUE(style->entries.front().key.id);
@@ -175,85 +176,85 @@
 TEST(ReferenceLinkerTest, FailToLinkPrivateSymbols) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.test", 0x7f)
-          .addReference("com.app.test:string/foo", ResourceId(0x7f020000),
+          .SetPackageId("com.app.test", 0x7f)
+          .AddReference("com.app.test:string/foo", ResourceId(0x7f020000),
                         "android:string/hidden")
-          .build();
+          .Build();
 
   std::unique_ptr<IAaptContext> context =
       test::ContextBuilder()
-          .setCompilationPackage("com.app.test")
-          .setPackageId(0x7f)
-          .setNameManglerPolicy(NameManglerPolicy{"com.app.test"})
-          .addSymbolSource(
+          .SetCompilationPackage("com.app.test")
+          .SetPackageId(0x7f)
+          .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"})
+          .AddSymbolSource(
               util::make_unique<ResourceTableSymbolSource>(table.get()))
-          .addSymbolSource(
+          .AddSymbolSource(
               test::StaticSymbolSourceBuilder()
-                  .addSymbol("android:string/hidden", ResourceId(0x01040034))
-                  .build())
-          .build();
+                  .AddSymbol("android:string/hidden", ResourceId(0x01040034))
+                  .Build())
+          .Build();
 
   ReferenceLinker linker;
-  ASSERT_FALSE(linker.consume(context.get(), table.get()));
+  ASSERT_FALSE(linker.Consume(context.get(), table.get()));
 }
 
 TEST(ReferenceLinkerTest, FailToLinkPrivateMangledSymbols) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.test", 0x7f)
-          .addReference("com.app.test:string/foo", ResourceId(0x7f020000),
+          .SetPackageId("com.app.test", 0x7f)
+          .AddReference("com.app.test:string/foo", ResourceId(0x7f020000),
                         "com.app.lib:string/hidden")
-          .build();
+          .Build();
 
   std::unique_ptr<IAaptContext> context =
       test::ContextBuilder()
-          .setCompilationPackage("com.app.test")
-          .setPackageId(0x7f)
-          .setNameManglerPolicy(
+          .SetCompilationPackage("com.app.test")
+          .SetPackageId(0x7f)
+          .SetNameManglerPolicy(
               NameManglerPolicy{"com.app.test", {"com.app.lib"}})
-          .addSymbolSource(
+          .AddSymbolSource(
               util::make_unique<ResourceTableSymbolSource>(table.get()))
-          .addSymbolSource(
+          .AddSymbolSource(
               test::StaticSymbolSourceBuilder()
-                  .addSymbol("com.app.test:string/com.app.lib$hidden",
+                  .AddSymbol("com.app.test:string/com.app.lib$hidden",
                              ResourceId(0x7f040034))
-                  .build())
+                  .Build())
 
-          .build();
+          .Build();
 
   ReferenceLinker linker;
-  ASSERT_FALSE(linker.consume(context.get(), table.get()));
+  ASSERT_FALSE(linker.Consume(context.get(), table.get()));
 }
 
 TEST(ReferenceLinkerTest, FailToLinkPrivateStyleAttributes) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.test", 0x7f)
-          .addValue("com.app.test:style/Theme",
+          .SetPackageId("com.app.test", 0x7f)
+          .AddValue("com.app.test:style/Theme",
                     test::StyleBuilder()
-                        .addItem("android:attr/hidden",
-                                 ResourceUtils::tryParseColor("#ff00ff"))
-                        .build())
-          .build();
+                        .AddItem("android:attr/hidden",
+                                 ResourceUtils::TryParseColor("#ff00ff"))
+                        .Build())
+          .Build();
 
   std::unique_ptr<IAaptContext> context =
       test::ContextBuilder()
-          .setCompilationPackage("com.app.test")
-          .setPackageId(0x7f)
-          .setNameManglerPolicy(NameManglerPolicy{"com.app.test"})
-          .addSymbolSource(
+          .SetCompilationPackage("com.app.test")
+          .SetPackageId(0x7f)
+          .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"})
+          .AddSymbolSource(
               util::make_unique<ResourceTableSymbolSource>(table.get()))
-          .addSymbolSource(
+          .AddSymbolSource(
               test::StaticSymbolSourceBuilder()
-                  .addSymbol("android:attr/hidden", ResourceId(0x01010001),
+                  .AddSymbol("android:attr/hidden", ResourceId(0x01010001),
                              test::AttributeBuilder()
-                                 .setTypeMask(android::ResTable_map::TYPE_COLOR)
-                                 .build())
-                  .build())
-          .build();
+                                 .SetTypeMask(android::ResTable_map::TYPE_COLOR)
+                                 .Build())
+                  .Build())
+          .Build();
 
   ReferenceLinker linker;
-  ASSERT_FALSE(linker.consume(context.get(), table.get()));
+  ASSERT_FALSE(linker.Consume(context.get(), table.get()));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/ResourceDeduper.cpp b/tools/aapt2/link/ResourceDeduper.cpp
index f565359..9431dce 100644
--- a/tools/aapt2/link/ResourceDeduper.cpp
+++ b/tools/aapt2/link/ResourceDeduper.cpp
@@ -14,12 +14,13 @@
  * limitations under the License.
  */
 
-#include "DominatorTree.h"
-#include "ResourceTable.h"
 #include "link/Linkers.h"
 
 #include <algorithm>
 
+#include "DominatorTree.h"
+#include "ResourceTable.h"
+
 namespace aapt {
 
 namespace {
@@ -40,55 +41,57 @@
   using Node = DominatorTree::Node;
 
   explicit DominatedKeyValueRemover(IAaptContext* context, ResourceEntry* entry)
-      : mContext(context), mEntry(entry) {}
+      : context_(context), entry_(entry) {}
 
-  void visitConfig(Node* node) {
+  void VisitConfig(Node* node) {
     Node* parent = node->parent();
     if (!parent) {
       return;
     }
-    ResourceConfigValue* nodeValue = node->value();
-    ResourceConfigValue* parentValue = parent->value();
-    if (!nodeValue || !parentValue) {
+    ResourceConfigValue* node_value = node->value();
+    ResourceConfigValue* parent_value = parent->value();
+    if (!node_value || !parent_value) {
       return;
     }
-    if (!nodeValue->value->equals(parentValue->value.get())) {
+    if (!node_value->value->Equals(parent_value->value.get())) {
       return;
     }
 
     // Compare compatible configs for this entry and ensure the values are
     // equivalent.
-    const ConfigDescription& nodeConfiguration = nodeValue->config;
-    for (const auto& sibling : mEntry->values) {
+    const ConfigDescription& node_configuration = node_value->config;
+    for (const auto& sibling : entry_->values) {
       if (!sibling->value) {
         // Sibling was already removed.
         continue;
       }
-      if (nodeConfiguration.isCompatibleWith(sibling->config) &&
-          !nodeValue->value->equals(sibling->value.get())) {
+      if (node_configuration.IsCompatibleWith(sibling->config) &&
+          !node_value->value->Equals(sibling->value.get())) {
         // The configurations are compatible, but the value is
         // different, so we can't remove this value.
         return;
       }
     }
-    if (mContext->verbose()) {
-      mContext->getDiagnostics()->note(
-          DiagMessage(nodeValue->value->getSource())
+    if (context_->IsVerbose()) {
+      context_->GetDiagnostics()->Note(
+          DiagMessage(node_value->value->GetSource())
           << "removing dominated duplicate resource with name \""
-          << mEntry->name << "\"");
+          << entry_->name << "\"");
     }
-    nodeValue->value = {};
+    node_value->value = {};
   }
 
  private:
-  IAaptContext* mContext;
-  ResourceEntry* mEntry;
+  DISALLOW_COPY_AND_ASSIGN(DominatedKeyValueRemover);
+
+  IAaptContext* context_;
+  ResourceEntry* entry_;
 };
 
-static void dedupeEntry(IAaptContext* context, ResourceEntry* entry) {
+static void DedupeEntry(IAaptContext* context, ResourceEntry* entry) {
   DominatorTree tree(entry->values);
   DominatedKeyValueRemover remover(context, entry);
-  tree.accept(&remover);
+  tree.Accept(&remover);
 
   // Erase the values that were removed.
   entry->values.erase(
@@ -102,15 +105,15 @@
 
 }  // namespace
 
-bool ResourceDeduper::consume(IAaptContext* context, ResourceTable* table) {
+bool ResourceDeduper::Consume(IAaptContext* context, ResourceTable* table) {
   for (auto& package : table->packages) {
     for (auto& type : package->types) {
       for (auto& entry : type->entries) {
-        dedupeEntry(context, entry.get());
+        DedupeEntry(context, entry.get());
       }
     }
   }
   return true;
 }
 
-}  // aapt
+}  // namespace aapt
diff --git a/tools/aapt2/link/ResourceDeduper_test.cpp b/tools/aapt2/link/ResourceDeduper_test.cpp
index 7e2d476..d38059d 100644
--- a/tools/aapt2/link/ResourceDeduper_test.cpp
+++ b/tools/aapt2/link/ResourceDeduper_test.cpp
@@ -14,70 +14,74 @@
  * limitations under the License.
  */
 
-#include "ResourceTable.h"
 #include "link/Linkers.h"
+
+#include "ResourceTable.h"
 #include "test/Test.h"
 
 namespace aapt {
 
 TEST(ResourceDeduperTest, SameValuesAreDeduped) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
-  const ConfigDescription defaultConfig = {};
-  const ConfigDescription enConfig = test::parseConfigOrDie("en");
-  const ConfigDescription enV21Config = test::parseConfigOrDie("en-v21");
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  const ConfigDescription default_config = {};
+  const ConfigDescription en_config = test::ParseConfigOrDie("en");
+  const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
   // Chosen because this configuration is compatible with en.
-  const ConfigDescription landConfig = test::parseConfigOrDie("land");
+  const ConfigDescription land_config = test::ParseConfigOrDie("land");
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .addString("android:string/dedupe", ResourceId{}, defaultConfig,
+          .AddString("android:string/dedupe", ResourceId{}, default_config,
                      "dedupe")
-          .addString("android:string/dedupe", ResourceId{}, enConfig, "dedupe")
-          .addString("android:string/dedupe", ResourceId{}, landConfig,
+          .AddString("android:string/dedupe", ResourceId{}, en_config, "dedupe")
+          .AddString("android:string/dedupe", ResourceId{}, land_config,
                      "dedupe")
-          .addString("android:string/dedupe2", ResourceId{}, defaultConfig,
+          .AddString("android:string/dedupe2", ResourceId{}, default_config,
                      "dedupe")
-          .addString("android:string/dedupe2", ResourceId{}, enConfig, "dedupe")
-          .addString("android:string/dedupe2", ResourceId{}, enV21Config,
+          .AddString("android:string/dedupe2", ResourceId{}, en_config,
+                     "dedupe")
+          .AddString("android:string/dedupe2", ResourceId{}, en_v21_config,
                      "keep")
-          .addString("android:string/dedupe2", ResourceId{}, landConfig,
+          .AddString("android:string/dedupe2", ResourceId{}, land_config,
                      "dedupe")
-          .build();
+          .Build();
 
-  ASSERT_TRUE(ResourceDeduper().consume(context.get(), table.get()));
-  EXPECT_EQ(nullptr, test::getValueForConfig<String>(
-                         table.get(), "android:string/dedupe", enConfig));
-  EXPECT_EQ(nullptr, test::getValueForConfig<String>(
-                         table.get(), "android:string/dedupe", landConfig));
-  EXPECT_EQ(nullptr, test::getValueForConfig<String>(
-                         table.get(), "android:string/dedupe2", enConfig));
-  EXPECT_NE(nullptr, test::getValueForConfig<String>(
-                         table.get(), "android:string/dedupe2", enV21Config));
+  ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get()));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
+                         table.get(), "android:string/dedupe", en_config));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
+                         table.get(), "android:string/dedupe", land_config));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
+                         table.get(), "android:string/dedupe2", en_config));
+  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
+                         table.get(), "android:string/dedupe2", en_v21_config));
 }
 
 TEST(ResourceDeduperTest, DifferentValuesAreKept) {
-  std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
-  const ConfigDescription defaultConfig = {};
-  const ConfigDescription enConfig = test::parseConfigOrDie("en");
-  const ConfigDescription enV21Config = test::parseConfigOrDie("en-v21");
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  const ConfigDescription default_config = {};
+  const ConfigDescription en_config = test::ParseConfigOrDie("en");
+  const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
   // Chosen because this configuration is compatible with en.
-  const ConfigDescription landConfig = test::parseConfigOrDie("land");
+  const ConfigDescription land_config = test::ParseConfigOrDie("land");
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .addString("android:string/keep", ResourceId{}, defaultConfig, "keep")
-          .addString("android:string/keep", ResourceId{}, enConfig, "keep")
-          .addString("android:string/keep", ResourceId{}, enV21Config, "keep2")
-          .addString("android:string/keep", ResourceId{}, landConfig, "keep2")
-          .build();
+          .AddString("android:string/keep", ResourceId{}, default_config,
+                     "keep")
+          .AddString("android:string/keep", ResourceId{}, en_config, "keep")
+          .AddString("android:string/keep", ResourceId{}, en_v21_config,
+                     "keep2")
+          .AddString("android:string/keep", ResourceId{}, land_config, "keep2")
+          .Build();
 
-  ASSERT_TRUE(ResourceDeduper().consume(context.get(), table.get()));
-  EXPECT_NE(nullptr, test::getValueForConfig<String>(
-                         table.get(), "android:string/keep", enConfig));
-  EXPECT_NE(nullptr, test::getValueForConfig<String>(
-                         table.get(), "android:string/keep", enV21Config));
-  EXPECT_NE(nullptr, test::getValueForConfig<String>(
-                         table.get(), "android:string/keep", landConfig));
+  ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get()));
+  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
+                         table.get(), "android:string/keep", en_config));
+  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
+                         table.get(), "android:string/keep", en_v21_config));
+  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
+                         table.get(), "android:string/keep", land_config));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index adf83a4..d808da3 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -15,51 +15,52 @@
  */
 
 #include "link/TableMerger.h"
+
+#include "android-base/logging.h"
+
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
 #include "util/Util.h"
 
-#include <cassert>
-
 namespace aapt {
 
-TableMerger::TableMerger(IAaptContext* context, ResourceTable* outTable,
+TableMerger::TableMerger(IAaptContext* context, ResourceTable* out_table,
                          const TableMergerOptions& options)
-    : mContext(context), mMasterTable(outTable), mOptions(options) {
+    : context_(context), master_table_(out_table), options_(options) {
   // Create the desired package that all tables will be merged into.
-  mMasterPackage = mMasterTable->createPackage(
-      mContext->getCompilationPackage(), mContext->getPackageId());
-  assert(mMasterPackage && "package name or ID already taken");
+  master_package_ = master_table_->CreatePackage(
+      context_->GetCompilationPackage(), context_->GetPackageId());
+  CHECK(master_package_ != nullptr) << "package name or ID already taken";
 }
 
-bool TableMerger::merge(const Source& src, ResourceTable* table,
+bool TableMerger::Merge(const Source& src, ResourceTable* table,
                         io::IFileCollection* collection) {
-  return mergeImpl(src, table, collection, false /* overlay */,
+  return MergeImpl(src, table, collection, false /* overlay */,
                    true /* allow new */);
 }
 
-bool TableMerger::mergeOverlay(const Source& src, ResourceTable* table,
+bool TableMerger::MergeOverlay(const Source& src, ResourceTable* table,
                                io::IFileCollection* collection) {
-  return mergeImpl(src, table, collection, true /* overlay */,
-                   mOptions.autoAddOverlay);
+  return MergeImpl(src, table, collection, true /* overlay */,
+                   options_.auto_add_overlay);
 }
 
 /**
  * This will merge packages with the same package name (or no package name).
  */
-bool TableMerger::mergeImpl(const Source& src, ResourceTable* table,
+bool TableMerger::MergeImpl(const Source& src, ResourceTable* table,
                             io::IFileCollection* collection, bool overlay,
-                            bool allowNew) {
-  const uint8_t desiredPackageId = mContext->getPackageId();
+                            bool allow_new) {
+  const uint8_t desired_package_id = context_->GetPackageId();
 
   bool error = false;
   for (auto& package : table->packages) {
     // Warn of packages with an unrelated ID.
     const Maybe<ResourceId>& id = package->id;
-    if (id && id.value() != 0x0 && id.value() != desiredPackageId) {
-      mContext->getDiagnostics()->warn(DiagMessage(src) << "ignoring package "
+    if (id && id.value() != 0x0 && id.value() != desired_package_id) {
+      context_->GetDiagnostics()->Warn(DiagMessage(src) << "ignoring package "
                                                         << package->name);
       continue;
     }
@@ -70,22 +71,22 @@
     // simply
     // uses of the attribute or definitions.
     if (package->name.empty() ||
-        mContext->getCompilationPackage() == package->name) {
+        context_->GetCompilationPackage() == package->name) {
       FileMergeCallback callback;
       if (collection) {
         callback = [&](const ResourceNameRef& name,
-                       const ConfigDescription& config, FileReference* newFile,
-                       FileReference* oldFile) -> bool {
+                       const ConfigDescription& config, FileReference* new_file,
+                       FileReference* old_file) -> bool {
           // The old file's path points inside the APK, so we can use it as is.
-          io::IFile* f = collection->findFile(*oldFile->path);
+          io::IFile* f = collection->FindFile(*old_file->path);
           if (!f) {
-            mContext->getDiagnostics()->error(DiagMessage(src)
-                                              << "file '" << *oldFile->path
+            context_->GetDiagnostics()->Error(DiagMessage(src)
+                                              << "file '" << *old_file->path
                                               << "' not found");
             return false;
           }
 
-          newFile->file = f;
+          new_file->file = f;
           return true;
         };
       }
@@ -95,8 +96,8 @@
       // mangled, then looked up at resolution time.
       // Also, when linking, we convert references with no package name to use
       // the compilation package name.
-      error |= !doMerge(src, table, package.get(), false /* mangle */, overlay,
-                        allowNew, callback);
+      error |= !DoMerge(src, table, package.get(), false /* mangle */, overlay,
+                        allow_new, callback);
     }
   }
   return !error;
@@ -105,86 +106,87 @@
 /**
  * This will merge and mangle resources from a static library.
  */
-bool TableMerger::mergeAndMangle(const Source& src,
-                                 const StringPiece& packageName,
+bool TableMerger::MergeAndMangle(const Source& src,
+                                 const StringPiece& package_name,
                                  ResourceTable* table,
                                  io::IFileCollection* collection) {
   bool error = false;
   for (auto& package : table->packages) {
     // Warn of packages with an unrelated ID.
-    if (packageName != package->name) {
-      mContext->getDiagnostics()->warn(DiagMessage(src) << "ignoring package "
+    if (package_name != package->name) {
+      context_->GetDiagnostics()->Warn(DiagMessage(src) << "ignoring package "
                                                         << package->name);
       continue;
     }
 
-    bool mangle = packageName != mContext->getCompilationPackage();
-    mMergedPackages.insert(package->name);
+    bool mangle = package_name != context_->GetCompilationPackage();
+    merged_packages_.insert(package->name);
 
-    auto callback = [&](const ResourceNameRef& name,
-                        const ConfigDescription& config, FileReference* newFile,
-                        FileReference* oldFile) -> bool {
+    auto callback = [&](
+        const ResourceNameRef& name, const ConfigDescription& config,
+        FileReference* new_file, FileReference* old_file) -> bool {
       // The old file's path points inside the APK, so we can use it as is.
-      io::IFile* f = collection->findFile(*oldFile->path);
+      io::IFile* f = collection->FindFile(*old_file->path);
       if (!f) {
-        mContext->getDiagnostics()->error(
-            DiagMessage(src) << "file '" << *oldFile->path << "' not found");
+        context_->GetDiagnostics()->Error(
+            DiagMessage(src) << "file '" << *old_file->path << "' not found");
         return false;
       }
 
-      newFile->file = f;
+      new_file->file = f;
       return true;
     };
 
-    error |= !doMerge(src, table, package.get(), mangle, false /* overlay */,
+    error |= !DoMerge(src, table, package.get(), mangle, false /* overlay */,
                       true /* allow new */, callback);
   }
   return !error;
 }
 
-static bool mergeType(IAaptContext* context, const Source& src,
-                      ResourceTableType* dstType, ResourceTableType* srcType) {
-  if (dstType->symbolStatus.state < srcType->symbolStatus.state) {
+static bool MergeType(IAaptContext* context, const Source& src,
+                      ResourceTableType* dst_type,
+                      ResourceTableType* src_type) {
+  if (dst_type->symbol_status.state < src_type->symbol_status.state) {
     // The incoming type's visibility is stronger, so we should override
     // the visibility.
-    if (srcType->symbolStatus.state == SymbolState::kPublic) {
+    if (src_type->symbol_status.state == SymbolState::kPublic) {
       // Only copy the ID if the source is public, or else the ID is
       // meaningless.
-      dstType->id = srcType->id;
+      dst_type->id = src_type->id;
     }
-    dstType->symbolStatus = std::move(srcType->symbolStatus);
-  } else if (dstType->symbolStatus.state == SymbolState::kPublic &&
-             srcType->symbolStatus.state == SymbolState::kPublic &&
-             dstType->id && srcType->id &&
-             dstType->id.value() != srcType->id.value()) {
+    dst_type->symbol_status = std::move(src_type->symbol_status);
+  } else if (dst_type->symbol_status.state == SymbolState::kPublic &&
+             src_type->symbol_status.state == SymbolState::kPublic &&
+             dst_type->id && src_type->id &&
+             dst_type->id.value() != src_type->id.value()) {
     // Both types are public and have different IDs.
-    context->getDiagnostics()->error(DiagMessage(src)
-                                     << "cannot merge type '" << srcType->type
+    context->GetDiagnostics()->Error(DiagMessage(src)
+                                     << "cannot merge type '" << src_type->type
                                      << "': conflicting public IDs");
     return false;
   }
   return true;
 }
 
-static bool mergeEntry(IAaptContext* context, const Source& src,
-                       ResourceEntry* dstEntry, ResourceEntry* srcEntry) {
-  if (dstEntry->symbolStatus.state < srcEntry->symbolStatus.state) {
+static bool MergeEntry(IAaptContext* context, const Source& src,
+                       ResourceEntry* dst_entry, ResourceEntry* src_entry) {
+  if (dst_entry->symbol_status.state < src_entry->symbol_status.state) {
     // The incoming type's visibility is stronger, so we should override
     // the visibility.
-    if (srcEntry->symbolStatus.state == SymbolState::kPublic) {
+    if (src_entry->symbol_status.state == SymbolState::kPublic) {
       // Only copy the ID if the source is public, or else the ID is
       // meaningless.
-      dstEntry->id = srcEntry->id;
+      dst_entry->id = src_entry->id;
     }
-    dstEntry->symbolStatus = std::move(srcEntry->symbolStatus);
-  } else if (srcEntry->symbolStatus.state == SymbolState::kPublic &&
-             dstEntry->symbolStatus.state == SymbolState::kPublic &&
-             dstEntry->id && srcEntry->id &&
-             dstEntry->id.value() != srcEntry->id.value()) {
+    dst_entry->symbol_status = std::move(src_entry->symbol_status);
+  } else if (src_entry->symbol_status.state == SymbolState::kPublic &&
+             dst_entry->symbol_status.state == SymbolState::kPublic &&
+             dst_entry->id && src_entry->id &&
+             dst_entry->id.value() != src_entry->id.value()) {
     // Both entries are public and have different IDs.
-    context->getDiagnostics()->error(DiagMessage(src)
-                                     << "cannot merge entry '" << srcEntry->name
-                                     << "': conflicting public IDs");
+    context->GetDiagnostics()->Error(
+        DiagMessage(src) << "cannot merge entry '" << src_entry->name
+                         << "': conflicting public IDs");
     return false;
   }
   return true;
@@ -199,141 +201,145 @@
  * and accumulate. If both values are Styleables, we just merge them into the
  * existing value.
  */
-static ResourceTable::CollisionResult resolveMergeCollision(Value* existing,
+static ResourceTable::CollisionResult ResolveMergeCollision(Value* existing,
                                                             Value* incoming) {
-  if (Styleable* existingStyleable = valueCast<Styleable>(existing)) {
-    if (Styleable* incomingStyleable = valueCast<Styleable>(incoming)) {
+  if (Styleable* existing_styleable = ValueCast<Styleable>(existing)) {
+    if (Styleable* incoming_styleable = ValueCast<Styleable>(incoming)) {
       // Styleables get merged.
-      existingStyleable->mergeWith(incomingStyleable);
+      existing_styleable->MergeWith(incoming_styleable);
       return ResourceTable::CollisionResult::kKeepOriginal;
     }
   }
   // Delegate to the default handler.
-  return ResourceTable::resolveValueCollision(existing, incoming);
+  return ResourceTable::ResolveValueCollision(existing, incoming);
 }
 
-static ResourceTable::CollisionResult mergeConfigValue(
-    IAaptContext* context, const ResourceNameRef& resName, const bool overlay,
-    ResourceConfigValue* dstConfigValue, ResourceConfigValue* srcConfigValue) {
+static ResourceTable::CollisionResult MergeConfigValue(
+    IAaptContext* context, const ResourceNameRef& res_name, const bool overlay,
+    ResourceConfigValue* dst_config_value,
+    ResourceConfigValue* src_config_value) {
   using CollisionResult = ResourceTable::CollisionResult;
 
-  Value* dstValue = dstConfigValue->value.get();
-  Value* srcValue = srcConfigValue->value.get();
+  Value* dst_value = dst_config_value->value.get();
+  Value* src_value = src_config_value->value.get();
 
-  CollisionResult collisionResult;
+  CollisionResult collision_result;
   if (overlay) {
-    collisionResult = resolveMergeCollision(dstValue, srcValue);
+    collision_result = ResolveMergeCollision(dst_value, src_value);
   } else {
-    collisionResult = ResourceTable::resolveValueCollision(dstValue, srcValue);
+    collision_result =
+        ResourceTable::ResolveValueCollision(dst_value, src_value);
   }
 
-  if (collisionResult == CollisionResult::kConflict) {
+  if (collision_result == CollisionResult::kConflict) {
     if (overlay) {
       return CollisionResult::kTakeNew;
     }
 
     // Error!
-    context->getDiagnostics()->error(
-        DiagMessage(srcValue->getSource())
-        << "resource '" << resName << "' has a conflicting value for "
-        << "configuration (" << srcConfigValue->config << ")");
-    context->getDiagnostics()->note(DiagMessage(dstValue->getSource())
+    context->GetDiagnostics()->Error(
+        DiagMessage(src_value->GetSource())
+        << "resource '" << res_name << "' has a conflicting value for "
+        << "configuration (" << src_config_value->config << ")");
+    context->GetDiagnostics()->Note(DiagMessage(dst_value->GetSource())
                                     << "originally defined here");
     return CollisionResult::kConflict;
   }
-  return collisionResult;
+  return collision_result;
 }
 
-bool TableMerger::doMerge(const Source& src, ResourceTable* srcTable,
-                          ResourceTablePackage* srcPackage,
-                          const bool manglePackage, const bool overlay,
-                          const bool allowNewResources,
+bool TableMerger::DoMerge(const Source& src, ResourceTable* src_table,
+                          ResourceTablePackage* src_package,
+                          const bool mangle_package, const bool overlay,
+                          const bool allow_new_resources,
                           const FileMergeCallback& callback) {
   bool error = false;
 
-  for (auto& srcType : srcPackage->types) {
-    ResourceTableType* dstType =
-        mMasterPackage->findOrCreateType(srcType->type);
-    if (!mergeType(mContext, src, dstType, srcType.get())) {
+  for (auto& src_type : src_package->types) {
+    ResourceTableType* dst_type =
+        master_package_->FindOrCreateType(src_type->type);
+    if (!MergeType(context_, src, dst_type, src_type.get())) {
       error = true;
       continue;
     }
 
-    for (auto& srcEntry : srcType->entries) {
-      std::string entryName = srcEntry->name;
-      if (manglePackage) {
-        entryName = NameMangler::mangleEntry(srcPackage->name, srcEntry->name);
+    for (auto& src_entry : src_type->entries) {
+      std::string entry_name = src_entry->name;
+      if (mangle_package) {
+        entry_name =
+            NameMangler::MangleEntry(src_package->name, src_entry->name);
       }
 
-      ResourceEntry* dstEntry;
-      if (allowNewResources) {
-        dstEntry = dstType->findOrCreateEntry(entryName);
+      ResourceEntry* dst_entry;
+      if (allow_new_resources) {
+        dst_entry = dst_type->FindOrCreateEntry(entry_name);
       } else {
-        dstEntry = dstType->findEntry(entryName);
+        dst_entry = dst_type->FindEntry(entry_name);
       }
 
-      const ResourceNameRef resName(srcPackage->name, srcType->type,
-                                    srcEntry->name);
+      const ResourceNameRef res_name(src_package->name, src_type->type,
+                                     src_entry->name);
 
-      if (!dstEntry) {
-        mContext->getDiagnostics()->error(
-            DiagMessage(src) << "resource " << resName
+      if (!dst_entry) {
+        context_->GetDiagnostics()->Error(
+            DiagMessage(src) << "resource " << res_name
                              << " does not override an existing resource");
-        mContext->getDiagnostics()->note(
+        context_->GetDiagnostics()->Note(
             DiagMessage(src) << "define an <add-resource> tag or use "
                              << "--auto-add-overlay");
         error = true;
         continue;
       }
 
-      if (!mergeEntry(mContext, src, dstEntry, srcEntry.get())) {
+      if (!MergeEntry(context_, src, dst_entry, src_entry.get())) {
         error = true;
         continue;
       }
 
-      for (auto& srcConfigValue : srcEntry->values) {
+      for (auto& src_config_value : src_entry->values) {
         using CollisionResult = ResourceTable::CollisionResult;
 
-        ResourceConfigValue* dstConfigValue = dstEntry->findValue(
-            srcConfigValue->config, srcConfigValue->product);
-        if (dstConfigValue) {
-          CollisionResult collisionResult = mergeConfigValue(
-              mContext, resName, overlay, dstConfigValue, srcConfigValue.get());
-          if (collisionResult == CollisionResult::kConflict) {
+        ResourceConfigValue* dst_config_value = dst_entry->FindValue(
+            src_config_value->config, src_config_value->product);
+        if (dst_config_value) {
+          CollisionResult collision_result =
+              MergeConfigValue(context_, res_name, overlay, dst_config_value,
+                               src_config_value.get());
+          if (collision_result == CollisionResult::kConflict) {
             error = true;
             continue;
-          } else if (collisionResult == CollisionResult::kKeepOriginal) {
+          } else if (collision_result == CollisionResult::kKeepOriginal) {
             continue;
           }
         } else {
-          dstConfigValue = dstEntry->findOrCreateValue(srcConfigValue->config,
-                                                       srcConfigValue->product);
+          dst_config_value = dst_entry->FindOrCreateValue(
+              src_config_value->config, src_config_value->product);
         }
 
         // Continue if we're taking the new resource.
 
         if (FileReference* f =
-                valueCast<FileReference>(srcConfigValue->value.get())) {
-          std::unique_ptr<FileReference> newFileRef;
-          if (manglePackage) {
-            newFileRef = cloneAndMangleFile(srcPackage->name, *f);
+                ValueCast<FileReference>(src_config_value->value.get())) {
+          std::unique_ptr<FileReference> new_file_ref;
+          if (mangle_package) {
+            new_file_ref = CloneAndMangleFile(src_package->name, *f);
           } else {
-            newFileRef = std::unique_ptr<FileReference>(
-                f->clone(&mMasterTable->stringPool));
+            new_file_ref = std::unique_ptr<FileReference>(
+                f->Clone(&master_table_->string_pool));
           }
 
           if (callback) {
-            if (!callback(resName, srcConfigValue->config, newFileRef.get(),
-                          f)) {
+            if (!callback(res_name, src_config_value->config,
+                          new_file_ref.get(), f)) {
               error = true;
               continue;
             }
           }
-          dstConfigValue->value = std::move(newFileRef);
+          dst_config_value->value = std::move(new_file_ref);
 
         } else {
-          dstConfigValue->value = std::unique_ptr<Value>(
-              srcConfigValue->value->clone(&mMasterTable->stringPool));
+          dst_config_value->value = std::unique_ptr<Value>(
+              src_config_value->value->Clone(&master_table_->string_pool));
         }
       }
     }
@@ -341,50 +347,50 @@
   return !error;
 }
 
-std::unique_ptr<FileReference> TableMerger::cloneAndMangleFile(
-    const std::string& package, const FileReference& fileRef) {
+std::unique_ptr<FileReference> TableMerger::CloneAndMangleFile(
+    const std::string& package, const FileReference& file_ref) {
   StringPiece prefix, entry, suffix;
-  if (util::extractResFilePathParts(*fileRef.path, &prefix, &entry, &suffix)) {
-    std::string mangledEntry =
-        NameMangler::mangleEntry(package, entry.toString());
-    std::string newPath = prefix.toString() + mangledEntry + suffix.toString();
-    std::unique_ptr<FileReference> newFileRef =
+  if (util::ExtractResFilePathParts(*file_ref.path, &prefix, &entry, &suffix)) {
+    std::string mangled_entry =
+        NameMangler::MangleEntry(package, entry.ToString());
+    std::string newPath = prefix.ToString() + mangled_entry + suffix.ToString();
+    std::unique_ptr<FileReference> new_file_ref =
         util::make_unique<FileReference>(
-            mMasterTable->stringPool.makeRef(newPath));
-    newFileRef->setComment(fileRef.getComment());
-    newFileRef->setSource(fileRef.getSource());
-    return newFileRef;
+            master_table_->string_pool.MakeRef(newPath));
+    new_file_ref->SetComment(file_ref.GetComment());
+    new_file_ref->SetSource(file_ref.GetSource());
+    return new_file_ref;
   }
   return std::unique_ptr<FileReference>(
-      fileRef.clone(&mMasterTable->stringPool));
+      file_ref.Clone(&master_table_->string_pool));
 }
 
-bool TableMerger::mergeFileImpl(const ResourceFile& fileDesc, io::IFile* file,
+bool TableMerger::MergeFileImpl(const ResourceFile& file_desc, io::IFile* file,
                                 bool overlay) {
   ResourceTable table;
-  std::string path = ResourceUtils::buildResourceFileName(fileDesc, nullptr);
-  std::unique_ptr<FileReference> fileRef =
-      util::make_unique<FileReference>(table.stringPool.makeRef(path));
-  fileRef->setSource(fileDesc.source);
-  fileRef->file = file;
+  std::string path = ResourceUtils::BuildResourceFileName(file_desc);
+  std::unique_ptr<FileReference> file_ref =
+      util::make_unique<FileReference>(table.string_pool.MakeRef(path));
+  file_ref->SetSource(file_desc.source);
+  file_ref->file = file;
 
-  ResourceTablePackage* pkg = table.createPackage(fileDesc.name.package, 0x0);
-  pkg->findOrCreateType(fileDesc.name.type)
-      ->findOrCreateEntry(fileDesc.name.entry)
-      ->findOrCreateValue(fileDesc.config, {})
-      ->value = std::move(fileRef);
+  ResourceTablePackage* pkg = table.CreatePackage(file_desc.name.package, 0x0);
+  pkg->FindOrCreateType(file_desc.name.type)
+      ->FindOrCreateEntry(file_desc.name.entry)
+      ->FindOrCreateValue(file_desc.config, {})
+      ->value = std::move(file_ref);
 
-  return doMerge(file->getSource(), &table, pkg, false /* mangle */,
-                 overlay /* overlay */, true /* allow new */, {});
+  return DoMerge(file->GetSource(), &table, pkg, false /* mangle */,
+                 overlay /* overlay */, true /* allow_new */, {});
 }
 
-bool TableMerger::mergeFile(const ResourceFile& fileDesc, io::IFile* file) {
-  return mergeFileImpl(fileDesc, file, false /* overlay */);
+bool TableMerger::MergeFile(const ResourceFile& file_desc, io::IFile* file) {
+  return MergeFileImpl(file_desc, file, false /* overlay */);
 }
 
-bool TableMerger::mergeFileOverlay(const ResourceFile& fileDesc,
+bool TableMerger::MergeFileOverlay(const ResourceFile& file_desc,
                                    io::IFile* file) {
-  return mergeFileImpl(fileDesc, file, true /* overlay */);
+  return MergeFileImpl(file_desc, file, true /* overlay */);
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/TableMerger.h b/tools/aapt2/link/TableMerger.h
index c2e7181..4ab83c3 100644
--- a/tools/aapt2/link/TableMerger.h
+++ b/tools/aapt2/link/TableMerger.h
@@ -17,6 +17,11 @@
 #ifndef AAPT_TABLEMERGER_H
 #define AAPT_TABLEMERGER_H
 
+#include <functional>
+#include <map>
+
+#include "android-base/macros.h"
+
 #include "Resource.h"
 #include "ResourceTable.h"
 #include "ResourceValues.h"
@@ -25,9 +30,6 @@
 #include "process/IResourceTableConsumer.h"
 #include "util/Util.h"
 
-#include <functional>
-#include <map>
-
 namespace aapt {
 
 struct TableMergerOptions {
@@ -35,7 +37,7 @@
    * If true, resources in overlays can be added without previously having
    * existed.
    */
-  bool autoAddOverlay = false;
+  bool auto_add_overlay = false;
 };
 
 /**
@@ -62,15 +64,14 @@
 class TableMerger {
  public:
   /**
-   * Note: The outTable ResourceTable must live longer than this TableMerger.
-   * References
-   * are made to this ResourceTable for efficiency reasons.
+   * Note: The out_table ResourceTable must live longer than this TableMerger.
+   * References are made to this ResourceTable for efficiency reasons.
    */
-  TableMerger(IAaptContext* context, ResourceTable* outTable,
+  TableMerger(IAaptContext* context, ResourceTable* out_table,
               const TableMergerOptions& options);
 
-  const std::set<std::string>& getMergedPackages() const {
-    return mMergedPackages;
+  const std::set<std::string>& merged_packages() const {
+    return merged_packages_;
   }
 
   /**
@@ -78,7 +79,7 @@
    * An io::IFileCollection is optional and used to find the referenced Files
    * and process them.
    */
-  bool merge(const Source& src, ResourceTable* table,
+  bool Merge(const Source& src, ResourceTable* table,
              io::IFileCollection* collection = nullptr);
 
   /**
@@ -86,7 +87,7 @@
    * An io::IFileCollection is optional and used to find the referenced Files
    * and process them.
    */
-  bool mergeOverlay(const Source& src, ResourceTable* table,
+  bool MergeOverlay(const Source& src, ResourceTable* table,
                     io::IFileCollection* collection = nullptr);
 
   /**
@@ -95,44 +96,45 @@
    * An io::IFileCollection is needed in order to find the referenced Files and
    * process them.
    */
-  bool mergeAndMangle(const Source& src, const StringPiece& package,
+  bool MergeAndMangle(const Source& src, const StringPiece& package,
                       ResourceTable* table, io::IFileCollection* collection);
 
   /**
    * Merges a compiled file that belongs to this same or empty package. This is
    * for local sources.
    */
-  bool mergeFile(const ResourceFile& fileDesc, io::IFile* file);
+  bool MergeFile(const ResourceFile& fileDesc, io::IFile* file);
 
   /**
    * Merges a compiled file from an overlay, overriding an existing definition.
    */
-  bool mergeFileOverlay(const ResourceFile& fileDesc, io::IFile* file);
+  bool MergeFileOverlay(const ResourceFile& fileDesc, io::IFile* file);
 
  private:
+  DISALLOW_COPY_AND_ASSIGN(TableMerger);
+
   using FileMergeCallback = std::function<bool(const ResourceNameRef&,
                                                const ConfigDescription& config,
                                                FileReference*, FileReference*)>;
 
-  IAaptContext* mContext;
-  ResourceTable* mMasterTable;
-  TableMergerOptions mOptions;
-  ResourceTablePackage* mMasterPackage;
+  IAaptContext* context_;
+  ResourceTable* master_table_;
+  TableMergerOptions options_;
+  ResourceTablePackage* master_package_;
+  std::set<std::string> merged_packages_;
 
-  std::set<std::string> mMergedPackages;
-
-  bool mergeFileImpl(const ResourceFile& fileDesc, io::IFile* file,
+  bool MergeFileImpl(const ResourceFile& file_desc, io::IFile* file,
                      bool overlay);
 
-  bool mergeImpl(const Source& src, ResourceTable* srcTable,
-                 io::IFileCollection* collection, bool overlay, bool allowNew);
+  bool MergeImpl(const Source& src, ResourceTable* src_table,
+                 io::IFileCollection* collection, bool overlay, bool allow_new);
 
-  bool doMerge(const Source& src, ResourceTable* srcTable,
-               ResourceTablePackage* srcPackage, const bool manglePackage,
-               const bool overlay, const bool allowNewResources,
+  bool DoMerge(const Source& src, ResourceTable* src_table,
+               ResourceTablePackage* src_package, const bool mangle_package,
+               const bool overlay, const bool allow_new_resources,
                const FileMergeCallback& callback);
 
-  std::unique_ptr<FileReference> cloneAndMangleFile(const std::string& package,
+  std::unique_ptr<FileReference> CloneAndMangleFile(const std::string& package,
                                                     const FileReference& value);
 };
 
diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp
index e0b2b66..742f5a7 100644
--- a/tools/aapt2/link/TableMerger_test.cpp
+++ b/tools/aapt2/link/TableMerger_test.cpp
@@ -15,139 +15,137 @@
  */
 
 #include "link/TableMerger.h"
+
 #include "filter/ConfigFilter.h"
 #include "io/FileSystem.h"
-#include "test/Builders.h"
-#include "test/Context.h"
-
-#include <gtest/gtest.h>
+#include "test/Test.h"
 
 namespace aapt {
 
 struct TableMergerTest : public ::testing::Test {
-  std::unique_ptr<IAaptContext> mContext;
+  std::unique_ptr<IAaptContext> context_;
 
   void SetUp() override {
-    mContext =
+    context_ =
         test::ContextBuilder()
             // We are compiling this package.
-            .setCompilationPackage("com.app.a")
+            .SetCompilationPackage("com.app.a")
 
             // Merge all packages that have this package ID.
-            .setPackageId(0x7f)
+            .SetPackageId(0x7f)
 
             // Mangle all packages that do not have this package name.
-            .setNameManglerPolicy(NameManglerPolicy{"com.app.a", {"com.app.b"}})
+            .SetNameManglerPolicy(NameManglerPolicy{"com.app.a", {"com.app.b"}})
 
-            .build();
+            .Build();
   }
 };
 
 TEST_F(TableMergerTest, SimpleMerge) {
-  std::unique_ptr<ResourceTable> tableA =
+  std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.a", 0x7f)
-          .addReference("com.app.a:id/foo", "com.app.a:id/bar")
-          .addReference("com.app.a:id/bar", "com.app.b:id/foo")
-          .addValue(
+          .SetPackageId("com.app.a", 0x7f)
+          .AddReference("com.app.a:id/foo", "com.app.a:id/bar")
+          .AddReference("com.app.a:id/bar", "com.app.b:id/foo")
+          .AddValue(
               "com.app.a:styleable/view",
-              test::StyleableBuilder().addItem("com.app.b:id/foo").build())
-          .build();
+              test::StyleableBuilder().AddItem("com.app.b:id/foo").Build())
+          .Build();
 
-  std::unique_ptr<ResourceTable> tableB = test::ResourceTableBuilder()
-                                              .setPackageId("com.app.b", 0x7f)
-                                              .addSimple("com.app.b:id/foo")
-                                              .build();
+  std::unique_ptr<ResourceTable> table_b = test::ResourceTableBuilder()
+                                               .SetPackageId("com.app.b", 0x7f)
+                                               .AddSimple("com.app.b:id/foo")
+                                               .Build();
 
-  ResourceTable finalTable;
-  TableMerger merger(mContext.get(), &finalTable, TableMergerOptions{});
+  ResourceTable final_table;
+  TableMerger merger(context_.get(), &final_table, TableMergerOptions{});
   io::FileCollection collection;
 
-  ASSERT_TRUE(merger.merge({}, tableA.get()));
+  ASSERT_TRUE(merger.Merge({}, table_a.get()));
   ASSERT_TRUE(
-      merger.mergeAndMangle({}, "com.app.b", tableB.get(), &collection));
+      merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection));
 
-  EXPECT_TRUE(merger.getMergedPackages().count("com.app.b") != 0);
+  EXPECT_TRUE(merger.merged_packages().count("com.app.b") != 0);
 
   // Entries from com.app.a should not be mangled.
   AAPT_EXPECT_TRUE(
-      finalTable.findResource(test::parseNameOrDie("com.app.a:id/foo")));
+      final_table.FindResource(test::ParseNameOrDie("com.app.a:id/foo")));
   AAPT_EXPECT_TRUE(
-      finalTable.findResource(test::parseNameOrDie("com.app.a:id/bar")));
-  AAPT_EXPECT_TRUE(finalTable.findResource(
-      test::parseNameOrDie("com.app.a:styleable/view")));
+      final_table.FindResource(test::ParseNameOrDie("com.app.a:id/bar")));
+  AAPT_EXPECT_TRUE(final_table.FindResource(
+      test::ParseNameOrDie("com.app.a:styleable/view")));
 
   // The unmangled name should not be present.
   AAPT_EXPECT_FALSE(
-      finalTable.findResource(test::parseNameOrDie("com.app.b:id/foo")));
+      final_table.FindResource(test::ParseNameOrDie("com.app.b:id/foo")));
 
   // Look for the mangled name.
-  AAPT_EXPECT_TRUE(finalTable.findResource(
-      test::parseNameOrDie("com.app.a:id/com.app.b$foo")));
+  AAPT_EXPECT_TRUE(final_table.FindResource(
+      test::ParseNameOrDie("com.app.a:id/com.app.b$foo")));
 }
 
 TEST_F(TableMergerTest, MergeFile) {
-  ResourceTable finalTable;
+  ResourceTable final_table;
   TableMergerOptions options;
-  options.autoAddOverlay = false;
-  TableMerger merger(mContext.get(), &finalTable, options);
+  options.auto_add_overlay = false;
+  TableMerger merger(context_.get(), &final_table, options);
 
-  ResourceFile fileDesc;
-  fileDesc.config = test::parseConfigOrDie("hdpi-v4");
-  fileDesc.name = test::parseNameOrDie("layout/main");
-  fileDesc.source = Source("res/layout-hdpi/main.xml");
-  test::TestFile testFile("path/to/res/layout-hdpi/main.xml.flat");
+  ResourceFile file_desc;
+  file_desc.config = test::ParseConfigOrDie("hdpi-v4");
+  file_desc.name = test::ParseNameOrDie("layout/main");
+  file_desc.source = Source("res/layout-hdpi/main.xml");
+  test::TestFile test_file("path/to/res/layout-hdpi/main.xml.flat");
 
-  ASSERT_TRUE(merger.mergeFile(fileDesc, &testFile));
+  ASSERT_TRUE(merger.MergeFile(file_desc, &test_file));
 
-  FileReference* file = test::getValueForConfig<FileReference>(
-      &finalTable, "com.app.a:layout/main", test::parseConfigOrDie("hdpi-v4"));
+  FileReference* file = test::GetValueForConfig<FileReference>(
+      &final_table, "com.app.a:layout/main", test::ParseConfigOrDie("hdpi-v4"));
   ASSERT_NE(nullptr, file);
   EXPECT_EQ(std::string("res/layout-hdpi-v4/main.xml"), *file->path);
 }
 
 TEST_F(TableMergerTest, MergeFileOverlay) {
-  ResourceTable finalTable;
-  TableMergerOptions tableMergerOptions;
-  tableMergerOptions.autoAddOverlay = false;
-  TableMerger merger(mContext.get(), &finalTable, tableMergerOptions);
+  ResourceTable final_table;
+  TableMergerOptions options;
+  options.auto_add_overlay = false;
+  TableMerger merger(context_.get(), &final_table, options);
 
-  ResourceFile fileDesc;
-  fileDesc.name = test::parseNameOrDie("xml/foo");
-  test::TestFile fileA("path/to/fileA.xml.flat");
-  test::TestFile fileB("path/to/fileB.xml.flat");
+  ResourceFile file_desc;
+  file_desc.name = test::ParseNameOrDie("xml/foo");
+  test::TestFile file_a("path/to/fileA.xml.flat");
+  test::TestFile file_b("path/to/fileB.xml.flat");
 
-  ASSERT_TRUE(merger.mergeFile(fileDesc, &fileA));
-  ASSERT_TRUE(merger.mergeFileOverlay(fileDesc, &fileB));
+  ASSERT_TRUE(merger.MergeFile(file_desc, &file_a));
+  ASSERT_TRUE(merger.MergeFileOverlay(file_desc, &file_b));
 }
 
 TEST_F(TableMergerTest, MergeFileReferences) {
-  std::unique_ptr<ResourceTable> tableA =
+  std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.a", 0x7f)
-          .addFileReference("com.app.a:xml/file", "res/xml/file.xml")
-          .build();
-  std::unique_ptr<ResourceTable> tableB =
+          .SetPackageId("com.app.a", 0x7f)
+          .AddFileReference("com.app.a:xml/file", "res/xml/file.xml")
+          .Build();
+  std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.b", 0x7f)
-          .addFileReference("com.app.b:xml/file", "res/xml/file.xml")
-          .build();
+          .SetPackageId("com.app.b", 0x7f)
+          .AddFileReference("com.app.b:xml/file", "res/xml/file.xml")
+          .Build();
 
-  ResourceTable finalTable;
-  TableMerger merger(mContext.get(), &finalTable, TableMergerOptions{});
+  ResourceTable final_table;
+  TableMerger merger(context_.get(), &final_table, TableMergerOptions{});
   io::FileCollection collection;
-  collection.insertFile("res/xml/file.xml");
+  collection.InsertFile("res/xml/file.xml");
 
-  ASSERT_TRUE(merger.merge({}, tableA.get()));
+  ASSERT_TRUE(merger.Merge({}, table_a.get()));
   ASSERT_TRUE(
-      merger.mergeAndMangle({}, "com.app.b", tableB.get(), &collection));
+      merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection));
 
   FileReference* f =
-      test::getValue<FileReference>(&finalTable, "com.app.a:xml/file");
+      test::GetValue<FileReference>(&final_table, "com.app.a:xml/file");
   ASSERT_NE(f, nullptr);
   EXPECT_EQ(std::string("res/xml/file.xml"), *f->path);
 
-  f = test::getValue<FileReference>(&finalTable,
+  f = test::GetValue<FileReference>(&final_table,
                                     "com.app.a:xml/com.app.b$file");
   ASSERT_NE(f, nullptr);
   EXPECT_EQ(std::string("res/xml/com.app.b$file.xml"), *f->path);
@@ -156,25 +154,25 @@
 TEST_F(TableMergerTest, OverrideResourceWithOverlay) {
   std::unique_ptr<ResourceTable> base =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x00)
-          .addValue("bool/foo", ResourceUtils::tryParseBool("true"))
-          .build();
+          .SetPackageId("", 0x00)
+          .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
+          .Build();
   std::unique_ptr<ResourceTable> overlay =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x00)
-          .addValue("bool/foo", ResourceUtils::tryParseBool("false"))
-          .build();
+          .SetPackageId("", 0x00)
+          .AddValue("bool/foo", ResourceUtils::TryParseBool("false"))
+          .Build();
 
-  ResourceTable finalTable;
-  TableMergerOptions tableMergerOptions;
-  tableMergerOptions.autoAddOverlay = false;
-  TableMerger merger(mContext.get(), &finalTable, tableMergerOptions);
+  ResourceTable final_table;
+  TableMergerOptions options;
+  options.auto_add_overlay = false;
+  TableMerger merger(context_.get(), &final_table, options);
 
-  ASSERT_TRUE(merger.merge({}, base.get()));
-  ASSERT_TRUE(merger.mergeOverlay({}, overlay.get()));
+  ASSERT_TRUE(merger.Merge({}, base.get()));
+  ASSERT_TRUE(merger.MergeOverlay({}, overlay.get()));
 
   BinaryPrimitive* foo =
-      test::getValue<BinaryPrimitive>(&finalTable, "com.app.a:bool/foo");
+      test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/foo");
   ASSERT_NE(nullptr, foo);
   EXPECT_EQ(0x0u, foo->value.data);
 }
@@ -182,170 +180,168 @@
 TEST_F(TableMergerTest, OverrideSameResourceIdsWithOverlay) {
   std::unique_ptr<ResourceTable> base =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x7f)
-          .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001),
+          .SetPackageId("", 0x7f)
+          .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001),
                           SymbolState::kPublic)
-          .build();
+          .Build();
   std::unique_ptr<ResourceTable> overlay =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x7f)
-          .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001),
+          .SetPackageId("", 0x7f)
+          .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001),
                           SymbolState::kPublic)
-          .build();
+          .Build();
 
-  ResourceTable finalTable;
-  TableMergerOptions tableMergerOptions;
-  tableMergerOptions.autoAddOverlay = false;
-  TableMerger merger(mContext.get(), &finalTable, tableMergerOptions);
+  ResourceTable final_table;
+  TableMergerOptions options;
+  options.auto_add_overlay = false;
+  TableMerger merger(context_.get(), &final_table, options);
 
-  ASSERT_TRUE(merger.merge({}, base.get()));
-  ASSERT_TRUE(merger.mergeOverlay({}, overlay.get()));
+  ASSERT_TRUE(merger.Merge({}, base.get()));
+  ASSERT_TRUE(merger.MergeOverlay({}, overlay.get()));
 }
 
 TEST_F(TableMergerTest, FailToOverrideConflictingTypeIdsWithOverlay) {
   std::unique_ptr<ResourceTable> base =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x7f)
-          .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001),
+          .SetPackageId("", 0x7f)
+          .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001),
                           SymbolState::kPublic)
-          .build();
+          .Build();
   std::unique_ptr<ResourceTable> overlay =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x7f)
-          .setSymbolState("bool/foo", ResourceId(0x7f, 0x02, 0x0001),
+          .SetPackageId("", 0x7f)
+          .SetSymbolState("bool/foo", ResourceId(0x7f, 0x02, 0x0001),
                           SymbolState::kPublic)
-          .build();
+          .Build();
 
-  ResourceTable finalTable;
-  TableMergerOptions tableMergerOptions;
-  tableMergerOptions.autoAddOverlay = false;
-  TableMerger merger(mContext.get(), &finalTable, tableMergerOptions);
+  ResourceTable final_table;
+  TableMergerOptions options;
+  options.auto_add_overlay = false;
+  TableMerger merger(context_.get(), &final_table, options);
 
-  ASSERT_TRUE(merger.merge({}, base.get()));
-  ASSERT_FALSE(merger.mergeOverlay({}, overlay.get()));
+  ASSERT_TRUE(merger.Merge({}, base.get()));
+  ASSERT_FALSE(merger.MergeOverlay({}, overlay.get()));
 }
 
 TEST_F(TableMergerTest, FailToOverrideConflictingEntryIdsWithOverlay) {
   std::unique_ptr<ResourceTable> base =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x7f)
-          .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001),
+          .SetPackageId("", 0x7f)
+          .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001),
                           SymbolState::kPublic)
-          .build();
+          .Build();
   std::unique_ptr<ResourceTable> overlay =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x7f)
-          .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0002),
+          .SetPackageId("", 0x7f)
+          .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0002),
                           SymbolState::kPublic)
-          .build();
+          .Build();
 
-  ResourceTable finalTable;
-  TableMergerOptions tableMergerOptions;
-  tableMergerOptions.autoAddOverlay = false;
-  TableMerger merger(mContext.get(), &finalTable, tableMergerOptions);
+  ResourceTable final_table;
+  TableMergerOptions options;
+  options.auto_add_overlay = false;
+  TableMerger merger(context_.get(), &final_table, options);
 
-  ASSERT_TRUE(merger.merge({}, base.get()));
-  ASSERT_FALSE(merger.mergeOverlay({}, overlay.get()));
+  ASSERT_TRUE(merger.Merge({}, base.get()));
+  ASSERT_FALSE(merger.MergeOverlay({}, overlay.get()));
 }
 
 TEST_F(TableMergerTest, MergeAddResourceFromOverlay) {
-  std::unique_ptr<ResourceTable> tableA =
+  std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x7f)
-          .setSymbolState("bool/foo", {}, SymbolState::kUndefined)
-          .build();
-  std::unique_ptr<ResourceTable> tableB =
+          .SetPackageId("", 0x7f)
+          .SetSymbolState("bool/foo", {}, SymbolState::kUndefined)
+          .Build();
+  std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x7f)
-          .addValue("bool/foo", ResourceUtils::tryParseBool("true"))
-          .build();
+          .SetPackageId("", 0x7f)
+          .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
+          .Build();
 
-  ResourceTable finalTable;
-  TableMerger merger(mContext.get(), &finalTable, TableMergerOptions{});
+  ResourceTable final_table;
+  TableMerger merger(context_.get(), &final_table, TableMergerOptions{});
 
-  ASSERT_TRUE(merger.merge({}, tableA.get()));
-  ASSERT_TRUE(merger.mergeOverlay({}, tableB.get()));
+  ASSERT_TRUE(merger.Merge({}, table_a.get()));
+  ASSERT_TRUE(merger.MergeOverlay({}, table_b.get()));
 }
 
 TEST_F(TableMergerTest, MergeAddResourceFromOverlayWithAutoAddOverlay) {
-  std::unique_ptr<ResourceTable> tableA =
-      test::ResourceTableBuilder().setPackageId("", 0x7f).build();
-  std::unique_ptr<ResourceTable> tableB =
+  std::unique_ptr<ResourceTable> table_a =
+      test::ResourceTableBuilder().SetPackageId("", 0x7f).Build();
+  std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x7f)
-          .addValue("bool/foo", ResourceUtils::tryParseBool("true"))
-          .build();
+          .SetPackageId("", 0x7f)
+          .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
+          .Build();
 
-  ResourceTable finalTable;
+  ResourceTable final_table;
   TableMergerOptions options;
-  options.autoAddOverlay = true;
-  TableMerger merger(mContext.get(), &finalTable, options);
+  options.auto_add_overlay = true;
+  TableMerger merger(context_.get(), &final_table, options);
 
-  ASSERT_TRUE(merger.merge({}, tableA.get()));
-  ASSERT_TRUE(merger.mergeOverlay({}, tableB.get()));
+  ASSERT_TRUE(merger.Merge({}, table_a.get()));
+  ASSERT_TRUE(merger.MergeOverlay({}, table_b.get()));
 }
 
 TEST_F(TableMergerTest, FailToMergeNewResourceWithoutAutoAddOverlay) {
-  std::unique_ptr<ResourceTable> tableA =
-      test::ResourceTableBuilder().setPackageId("", 0x7f).build();
-  std::unique_ptr<ResourceTable> tableB =
+  std::unique_ptr<ResourceTable> table_a =
+      test::ResourceTableBuilder().SetPackageId("", 0x7f).Build();
+  std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .setPackageId("", 0x7f)
-          .addValue("bool/foo", ResourceUtils::tryParseBool("true"))
-          .build();
+          .SetPackageId("", 0x7f)
+          .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
+          .Build();
 
-  ResourceTable finalTable;
+  ResourceTable final_table;
   TableMergerOptions options;
-  options.autoAddOverlay = false;
-  TableMerger merger(mContext.get(), &finalTable, options);
+  options.auto_add_overlay = false;
+  TableMerger merger(context_.get(), &final_table, options);
 
-  ASSERT_TRUE(merger.merge({}, tableA.get()));
-  ASSERT_FALSE(merger.mergeOverlay({}, tableB.get()));
+  ASSERT_TRUE(merger.Merge({}, table_a.get()));
+  ASSERT_FALSE(merger.MergeOverlay({}, table_b.get()));
 }
 
 TEST_F(TableMergerTest, OverlaidStyleablesShouldBeMerged) {
-  std::unique_ptr<ResourceTable> tableA =
+  std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.a", 0x7f)
-          .addValue("com.app.a:styleable/Foo",
+          .SetPackageId("com.app.a", 0x7f)
+          .AddValue("com.app.a:styleable/Foo",
                     test::StyleableBuilder()
-                        .addItem("com.app.a:attr/bar")
-                        .addItem("com.app.a:attr/foo", ResourceId(0x01010000))
-                        .build())
-          .build();
+                        .AddItem("com.app.a:attr/bar")
+                        .AddItem("com.app.a:attr/foo", ResourceId(0x01010000))
+                        .Build())
+          .Build();
 
-  std::unique_ptr<ResourceTable> tableB =
+  std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
-          .setPackageId("com.app.a", 0x7f)
-          .addValue("com.app.a:styleable/Foo",
+          .SetPackageId("com.app.a", 0x7f)
+          .AddValue("com.app.a:styleable/Foo",
                     test::StyleableBuilder()
-                        .addItem("com.app.a:attr/bat")
-                        .addItem("com.app.a:attr/foo")
-                        .build())
-          .build();
+                        .AddItem("com.app.a:attr/bat")
+                        .AddItem("com.app.a:attr/foo")
+                        .Build())
+          .Build();
 
-  ResourceTable finalTable;
+  ResourceTable final_table;
   TableMergerOptions options;
-  options.autoAddOverlay = true;
-  TableMerger merger(mContext.get(), &finalTable, options);
+  options.auto_add_overlay = true;
+  TableMerger merger(context_.get(), &final_table, options);
 
-  ASSERT_TRUE(merger.merge({}, tableA.get()));
-  ASSERT_TRUE(merger.mergeOverlay({}, tableB.get()));
-
-  Debug::printTable(&finalTable, {});
+  ASSERT_TRUE(merger.Merge({}, table_a.get()));
+  ASSERT_TRUE(merger.MergeOverlay({}, table_b.get()));
 
   Styleable* styleable =
-      test::getValue<Styleable>(&finalTable, "com.app.a:styleable/Foo");
+      test::GetValue<Styleable>(&final_table, "com.app.a:styleable/Foo");
   ASSERT_NE(nullptr, styleable);
 
-  std::vector<Reference> expectedRefs = {
-      Reference(test::parseNameOrDie("com.app.a:attr/bar")),
-      Reference(test::parseNameOrDie("com.app.a:attr/bat")),
-      Reference(test::parseNameOrDie("com.app.a:attr/foo"),
+  std::vector<Reference> expected_refs = {
+      Reference(test::ParseNameOrDie("com.app.a:attr/bar")),
+      Reference(test::ParseNameOrDie("com.app.a:attr/bat")),
+      Reference(test::ParseNameOrDie("com.app.a:attr/foo"),
                 ResourceId(0x01010000)),
   };
 
-  EXPECT_EQ(expectedRefs, styleable->entries);
+  EXPECT_EQ(expected_refs, styleable->entries);
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/VersionCollapser.cpp b/tools/aapt2/link/VersionCollapser.cpp
index 61a1f86..3df5899 100644
--- a/tools/aapt2/link/VersionCollapser.cpp
+++ b/tools/aapt2/link/VersionCollapser.cpp
@@ -14,50 +14,51 @@
  * limitations under the License.
  */
 
-#include "ResourceTable.h"
 #include "link/Linkers.h"
 
 #include <algorithm>
 #include <vector>
 
+#include "ResourceTable.h"
+
 namespace aapt {
 
 template <typename Iterator, typename Pred>
 class FilterIterator {
  public:
   FilterIterator(Iterator begin, Iterator end, Pred pred = Pred())
-      : mCurrent(begin), mEnd(end), mPred(pred) {
-    advance();
+      : current_(begin), end_(end), pred_(pred) {
+    Advance();
   }
 
-  bool hasNext() { return mCurrent != mEnd; }
+  bool HasNext() { return current_ != end_; }
 
-  Iterator nextIter() {
-    Iterator iter = mCurrent;
-    ++mCurrent;
-    advance();
+  Iterator NextIter() {
+    Iterator iter = current_;
+    ++current_;
+    Advance();
     return iter;
   }
 
-  typename Iterator::reference next() { return *nextIter(); }
+  typename Iterator::reference Next() { return *NextIter(); }
 
  private:
-  void advance() {
-    for (; mCurrent != mEnd; ++mCurrent) {
-      if (mPred(*mCurrent)) {
+  void Advance() {
+    for (; current_ != end_; ++current_) {
+      if (pred_(*current_)) {
         return;
       }
     }
   }
 
-  Iterator mCurrent, mEnd;
-  Pred mPred;
+  Iterator current_, end_;
+  Pred pred_;
 };
 
 template <typename Iterator, typename Pred>
-FilterIterator<Iterator, Pred> makeFilterIterator(Iterator begin,
-                                                  Iterator end = Iterator(),
-                                                  Pred pred = Pred()) {
+FilterIterator<Iterator, Pred> make_filter_iterator(Iterator begin,
+                                                    Iterator end = Iterator(),
+                                                    Pred pred = Pred()) {
   return FilterIterator<Iterator, Pred>(begin, end, pred);
 }
 
@@ -68,7 +69,7 @@
  * next smallest
  * one will be kept.
  */
-static void collapseVersions(int minSdk, ResourceEntry* entry) {
+static void CollapseVersions(int min_sdk, ResourceEntry* entry) {
   // First look for all sdks less than minSdk.
   for (auto iter = entry->values.rbegin(); iter != entry->values.rend();
        ++iter) {
@@ -78,15 +79,14 @@
     }
 
     const ConfigDescription& config = (*iter)->config;
-    if (config.sdkVersion <= minSdk) {
+    if (config.sdkVersion <= min_sdk) {
       // This is the first configuration we've found with a smaller or equal SDK
       // level
       // to the minimum. We MUST keep this one, but remove all others we find,
       // which get
       // overridden by this one.
 
-      ConfigDescription configWithoutSdk = config;
-      configWithoutSdk.sdkVersion = 0;
+      ConfigDescription config_without_sdk = config.CopyWithoutSdkVersion();
       auto pred = [&](const std::unique_ptr<ResourceConfigValue>& val) -> bool {
         // Check that the value hasn't already been marked for removal.
         if (!val) {
@@ -94,16 +94,16 @@
         }
 
         // Only return Configs that differ in SDK version.
-        configWithoutSdk.sdkVersion = val->config.sdkVersion;
-        return configWithoutSdk == val->config &&
-               val->config.sdkVersion <= minSdk;
+        config_without_sdk.sdkVersion = val->config.sdkVersion;
+        return config_without_sdk == val->config &&
+               val->config.sdkVersion <= min_sdk;
       };
 
       // Remove the rest that match.
-      auto filterIter =
-          makeFilterIterator(iter + 1, entry->values.rend(), pred);
-      while (filterIter.hasNext()) {
-        filterIter.next() = {};
+      auto filter_iter =
+          make_filter_iterator(iter + 1, entry->values.rend(), pred);
+      while (filter_iter.HasNext()) {
+        filter_iter.Next() = {};
       }
     }
   }
@@ -121,16 +121,16 @@
   // struct
   // and take up less space in the resources.arsc table.
   bool modified = false;
-  for (std::unique_ptr<ResourceConfigValue>& configValue : entry->values) {
-    if (configValue->config.sdkVersion != 0 &&
-        configValue->config.sdkVersion <= minSdk) {
+  for (std::unique_ptr<ResourceConfigValue>& config_value : entry->values) {
+    if (config_value->config.sdkVersion != 0 &&
+        config_value->config.sdkVersion <= min_sdk) {
       // Override the resource with a Configuration without an SDK.
-      std::unique_ptr<ResourceConfigValue> newValue =
+      std::unique_ptr<ResourceConfigValue> new_value =
           util::make_unique<ResourceConfigValue>(
-              configValue->config.copyWithoutSdkVersion(),
-              configValue->product);
-      newValue->value = std::move(configValue->value);
-      configValue = std::move(newValue);
+              config_value->config.CopyWithoutSdkVersion(),
+              config_value->product);
+      new_value->value = std::move(config_value->value);
+      config_value = std::move(new_value);
 
       modified = true;
     }
@@ -138,8 +138,7 @@
 
   if (modified) {
     // We've modified the keys (ConfigDescription) by changing the sdkVersion to
-    // 0.
-    // We MUST re-sort to ensure ordering guarantees hold.
+    // 0. We MUST re-sort to ensure ordering guarantees hold.
     std::sort(entry->values.begin(), entry->values.end(),
               [](const std::unique_ptr<ResourceConfigValue>& a,
                  const std::unique_ptr<ResourceConfigValue>& b) -> bool {
@@ -148,12 +147,12 @@
   }
 }
 
-bool VersionCollapser::consume(IAaptContext* context, ResourceTable* table) {
-  const int minSdk = context->getMinSdkVersion();
+bool VersionCollapser::Consume(IAaptContext* context, ResourceTable* table) {
+  const int min_sdk = context->GetMinSdkVersion();
   for (auto& package : table->packages) {
     for (auto& type : package->types) {
       for (auto& entry : type->entries) {
-        collapseVersions(minSdk, entry.get());
+        CollapseVersions(min_sdk, entry.get());
       }
     }
   }
diff --git a/tools/aapt2/link/VersionCollapser_test.cpp b/tools/aapt2/link/VersionCollapser_test.cpp
index c0e0ddb..1b5592f 100644
--- a/tools/aapt2/link/VersionCollapser_test.cpp
+++ b/tools/aapt2/link/VersionCollapser_test.cpp
@@ -15,103 +15,103 @@
  */
 
 #include "link/Linkers.h"
+
 #include "test/Test.h"
 
 namespace aapt {
 
-template <typename T>
-using uptr = std::unique_ptr<T>;
-
-static uptr<ResourceTable> buildTableWithConfigs(
+static std::unique_ptr<ResourceTable> BuildTableWithConfigs(
     const StringPiece& name, std::initializer_list<std::string> list) {
   test::ResourceTableBuilder builder;
   for (const std::string& item : list) {
-    builder.addSimple(name, test::parseConfigOrDie(item));
+    builder.AddSimple(name, test::ParseConfigOrDie(item));
   }
-  return builder.build();
+  return builder.Build();
 }
 
 TEST(VersionCollapserTest, CollapseVersions) {
-  uptr<IAaptContext> context =
-      test::ContextBuilder().setMinSdkVersion(7).build();
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder().SetMinSdkVersion(7).Build();
 
-  const StringPiece resName = "@android:string/foo";
+  const StringPiece res_name = "@android:string/foo";
 
-  uptr<ResourceTable> table = buildTableWithConfigs(
-      resName,
+  std::unique_ptr<ResourceTable> table = BuildTableWithConfigs(
+      res_name,
       {"land-v4", "land-v5", "sw600dp", "land-v6", "land-v14", "land-v21"});
 
   VersionCollapser collapser;
-  ASSERT_TRUE(collapser.consume(context.get(), table.get()));
+  ASSERT_TRUE(collapser.Consume(context.get(), table.get()));
 
   // These should be removed.
   EXPECT_EQ(nullptr,
-            test::getValueForConfig<Id>(table.get(), resName,
-                                        test::parseConfigOrDie("land-v4")));
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land-v4")));
   EXPECT_EQ(nullptr,
-            test::getValueForConfig<Id>(table.get(), resName,
-                                        test::parseConfigOrDie("land-v5")));
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land-v5")));
   // This one should be removed because it was renamed to 'land', with the
   // version dropped.
   EXPECT_EQ(nullptr,
-            test::getValueForConfig<Id>(table.get(), resName,
-                                        test::parseConfigOrDie("land-v6")));
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land-v6")));
 
   // These should remain.
   EXPECT_NE(nullptr,
-            test::getValueForConfig<Id>(table.get(), resName,
-                                        test::parseConfigOrDie("sw600dp")));
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("sw600dp")));
 
   // 'land' should be present because it was renamed from 'land-v6'.
-  EXPECT_NE(nullptr, test::getValueForConfig<Id>(
-                         table.get(), resName, test::parseConfigOrDie("land")));
   EXPECT_NE(nullptr,
-            test::getValueForConfig<Id>(table.get(), resName,
-                                        test::parseConfigOrDie("land-v14")));
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land")));
   EXPECT_NE(nullptr,
-            test::getValueForConfig<Id>(table.get(), resName,
-                                        test::parseConfigOrDie("land-v21")));
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land-v14")));
+  EXPECT_NE(nullptr,
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land-v21")));
 }
 
 TEST(VersionCollapserTest, CollapseVersionsWhenMinSdkIsHighest) {
-  uptr<IAaptContext> context =
-      test::ContextBuilder().setMinSdkVersion(21).build();
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder().SetMinSdkVersion(21).Build();
 
-  const StringPiece resName = "@android:string/foo";
+  const StringPiece res_name = "@android:string/foo";
 
-  uptr<ResourceTable> table = buildTableWithConfigs(
-      resName, {"land-v4", "land-v5", "sw600dp", "land-v6", "land-v14",
-                "land-v21", "land-v22"});
+  std::unique_ptr<ResourceTable> table = BuildTableWithConfigs(
+      res_name, {"land-v4", "land-v5", "sw600dp", "land-v6", "land-v14",
+                 "land-v21", "land-v22"});
   VersionCollapser collapser;
-  ASSERT_TRUE(collapser.consume(context.get(), table.get()));
+  ASSERT_TRUE(collapser.Consume(context.get(), table.get()));
 
   // These should all be removed.
   EXPECT_EQ(nullptr,
-            test::getValueForConfig<Id>(table.get(), resName,
-                                        test::parseConfigOrDie("land-v4")));
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land-v4")));
   EXPECT_EQ(nullptr,
-            test::getValueForConfig<Id>(table.get(), resName,
-                                        test::parseConfigOrDie("land-v5")));
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land-v5")));
   EXPECT_EQ(nullptr,
-            test::getValueForConfig<Id>(table.get(), resName,
-                                        test::parseConfigOrDie("land-v6")));
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land-v6")));
   EXPECT_EQ(nullptr,
-            test::getValueForConfig<Id>(table.get(), resName,
-                                        test::parseConfigOrDie("land-v14")));
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land-v14")));
 
   // These should remain.
   EXPECT_NE(nullptr,
-            test::getValueForConfig<Id>(
-                table.get(), resName,
-                test::parseConfigOrDie("sw600dp").copyWithoutSdkVersion()));
+            test::GetValueForConfig<Id>(
+                table.get(), res_name,
+                test::ParseConfigOrDie("sw600dp").CopyWithoutSdkVersion()));
 
   // land-v21 should have been converted to land.
-  EXPECT_NE(nullptr, test::getValueForConfig<Id>(
-                         table.get(), resName, test::parseConfigOrDie("land")));
+  EXPECT_NE(nullptr,
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land")));
   // land-v22 should remain as-is.
   EXPECT_NE(nullptr,
-            test::getValueForConfig<Id>(table.get(), resName,
-                                        test::parseConfigOrDie("land-v22")));
+            test::GetValueForConfig<Id>(table.get(), res_name,
+                                        test::ParseConfigOrDie("land-v22")));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/XmlNamespaceRemover.cpp b/tools/aapt2/link/XmlNamespaceRemover.cpp
index 6e8d80d..24aa566 100644
--- a/tools/aapt2/link/XmlNamespaceRemover.cpp
+++ b/tools/aapt2/link/XmlNamespaceRemover.cpp
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-#include "ResourceTable.h"
 #include "link/Linkers.h"
 
 #include <algorithm>
 
+#include "ResourceTable.h"
+
 namespace aapt {
 
 namespace {
@@ -28,12 +29,12 @@
  */
 class XmlVisitor : public xml::Visitor {
  public:
-  XmlVisitor(bool keepUris) : mKeepUris(keepUris) {}
+  explicit XmlVisitor(bool keep_uris) : keep_uris_(keep_uris) {}
 
-  void visit(xml::Element* el) override {
+  void Visit(xml::Element* el) override {
     // Strip namespaces
     for (auto& child : el->children) {
-      while (child && xml::nodeCast<xml::Namespace>(child.get())) {
+      while (child && xml::NodeCast<xml::Namespace>(child.get())) {
         if (child->children.empty()) {
           child = {};
         } else {
@@ -49,36 +50,38 @@
                        }),
         el->children.end());
 
-    if (!mKeepUris) {
+    if (!keep_uris_) {
       for (xml::Attribute& attr : el->attributes) {
-        attr.namespaceUri = std::string();
+        attr.namespace_uri = std::string();
       }
-      el->namespaceUri = std::string();
+      el->namespace_uri = std::string();
     }
-    xml::Visitor::visit(el);
+    xml::Visitor::Visit(el);
   }
 
  private:
-  bool mKeepUris;
+  DISALLOW_COPY_AND_ASSIGN(XmlVisitor);
+
+  bool keep_uris_;
 };
 
 }  // namespace
 
-bool XmlNamespaceRemover::consume(IAaptContext* context,
+bool XmlNamespaceRemover::Consume(IAaptContext* context,
                                   xml::XmlResource* resource) {
   if (!resource->root) {
     return false;
   }
   // Replace any root namespaces until the root is a non-namespace node
-  while (xml::nodeCast<xml::Namespace>(resource->root.get())) {
+  while (xml::NodeCast<xml::Namespace>(resource->root.get())) {
     if (resource->root->children.empty()) {
       break;
     }
     resource->root = std::move(resource->root->children.front());
     resource->root->parent = nullptr;
   }
-  XmlVisitor visitor(mKeepUris);
-  resource->root->accept(&visitor);
+  XmlVisitor visitor(keep_uris_);
+  resource->root->Accept(&visitor);
   return true;
 }
 
diff --git a/tools/aapt2/link/XmlNamespaceRemover_test.cpp b/tools/aapt2/link/XmlNamespaceRemover_test.cpp
index d2daaee..a176c03 100644
--- a/tools/aapt2/link/XmlNamespaceRemover_test.cpp
+++ b/tools/aapt2/link/XmlNamespaceRemover_test.cpp
@@ -15,83 +15,94 @@
  */
 
 #include "link/Linkers.h"
+
 #include "test/Test.h"
 
 namespace aapt {
 
 class XmlUriTestVisitor : public xml::Visitor {
  public:
-  void visit(xml::Element* el) override {
+  XmlUriTestVisitor() = default;
+
+  void Visit(xml::Element* el) override {
     for (const auto& attr : el->attributes) {
-      EXPECT_EQ(std::string(), attr.namespaceUri);
+      EXPECT_EQ(std::string(), attr.namespace_uri);
     }
-    EXPECT_EQ(std::string(), el->namespaceUri);
-    xml::Visitor::visit(el);
+    EXPECT_EQ(std::string(), el->namespace_uri);
+    xml::Visitor::Visit(el);
   }
 
-  void visit(xml::Namespace* ns) override {
-    EXPECT_EQ(std::string(), ns->namespaceUri);
-    xml::Visitor::visit(ns);
+  void Visit(xml::Namespace* ns) override {
+    EXPECT_EQ(std::string(), ns->namespace_uri);
+    xml::Visitor::Visit(ns);
   }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(XmlUriTestVisitor);
 };
 
 class XmlNamespaceTestVisitor : public xml::Visitor {
  public:
-  void visit(xml::Namespace* ns) override {
-    ADD_FAILURE() << "Detected namespace: " << ns->namespacePrefix << "=\""
-                  << ns->namespaceUri << "\"";
-    xml::Visitor::visit(ns);
+  XmlNamespaceTestVisitor() = default;
+
+  void Visit(xml::Namespace* ns) override {
+    ADD_FAILURE() << "Detected namespace: " << ns->namespace_prefix << "=\""
+                  << ns->namespace_uri << "\"";
+    xml::Visitor::Visit(ns);
   }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(XmlNamespaceTestVisitor);
 };
 
 class XmlNamespaceRemoverTest : public ::testing::Test {
  public:
   void SetUp() override {
-    mContext =
-        test::ContextBuilder().setCompilationPackage("com.app.test").build();
+    context_ =
+        test::ContextBuilder().SetCompilationPackage("com.app.test").Build();
   }
 
  protected:
-  std::unique_ptr<IAaptContext> mContext;
+  std::unique_ptr<IAaptContext> context_;
 };
 
 TEST_F(XmlNamespaceRemoverTest, RemoveUris) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDomForPackageName(mContext.get(), R"EOF(
+      test::BuildXmlDomForPackageName(context_.get(), R"EOF(
             <View xmlns:android="http://schemas.android.com/apk/res/android"
                   android:text="hello" />)EOF");
 
   XmlNamespaceRemover remover;
-  ASSERT_TRUE(remover.consume(mContext.get(), doc.get()));
+  ASSERT_TRUE(remover.Consume(context_.get(), doc.get()));
 
   xml::Node* root = doc.get()->root.get();
   ASSERT_NE(root, nullptr);
 
   XmlUriTestVisitor visitor;
-  root->accept(&visitor);
+  root->Accept(&visitor);
 }
 
 TEST_F(XmlNamespaceRemoverTest, RemoveNamespaces) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDomForPackageName(mContext.get(), R"EOF(
+      test::BuildXmlDomForPackageName(context_.get(), R"EOF(
             <View xmlns:android="http://schemas.android.com/apk/res/android"
                   xmlns:foo="http://schemas.android.com/apk/res/foo"
                   foo:bar="foobar"
                   android:text="hello" />)EOF");
 
   XmlNamespaceRemover remover;
-  ASSERT_TRUE(remover.consume(mContext.get(), doc.get()));
+  ASSERT_TRUE(remover.Consume(context_.get(), doc.get()));
 
   xml::Node* root = doc.get()->root.get();
   ASSERT_NE(root, nullptr);
 
   XmlNamespaceTestVisitor visitor;
-  root->accept(&visitor);
+  root->Accept(&visitor);
 }
 
 TEST_F(XmlNamespaceRemoverTest, RemoveNestedNamespaces) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDomForPackageName(mContext.get(), R"EOF(
+      test::BuildXmlDomForPackageName(context_.get(), R"EOF(
             <View xmlns:android="http://schemas.android.com/apk/res/android"
                   android:text="hello">
               <View xmlns:foo="http://schemas.example.com/foo"
@@ -99,13 +110,13 @@
             </View>)EOF");
 
   XmlNamespaceRemover remover;
-  ASSERT_TRUE(remover.consume(mContext.get(), doc.get()));
+  ASSERT_TRUE(remover.Consume(context_.get(), doc.get()));
 
   xml::Node* root = doc.get()->root.get();
   ASSERT_NE(root, nullptr);
 
   XmlNamespaceTestVisitor visitor;
-  root->accept(&visitor);
+  root->Accept(&visitor);
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/XmlReferenceLinker.cpp b/tools/aapt2/link/XmlReferenceLinker.cpp
index 945f98a..a819831 100644
--- a/tools/aapt2/link/XmlReferenceLinker.cpp
+++ b/tools/aapt2/link/XmlReferenceLinker.cpp
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
+#include "link/Linkers.h"
+
 #include "Diagnostics.h"
 #include "ResourceUtils.h"
 #include "SdkConstants.h"
-#include "link/Linkers.h"
 #include "link/ReferenceLinker.h"
 #include "process/IResourceTableConsumer.h"
 #include "process/SymbolTable.h"
@@ -37,31 +38,33 @@
  */
 class ReferenceVisitor : public ValueVisitor {
  public:
-  using ValueVisitor::visit;
+  using ValueVisitor::Visit;
 
   ReferenceVisitor(IAaptContext* context, SymbolTable* symbols,
-                   xml::IPackageDeclStack* decls, CallSite* callSite)
-      : mContext(context),
-        mSymbols(symbols),
-        mDecls(decls),
-        mCallSite(callSite),
-        mError(false) {}
+                   xml::IPackageDeclStack* decls, CallSite* callsite)
+      : context_(context),
+        symbols_(symbols),
+        decls_(decls),
+        callsite_(callsite),
+        error_(false) {}
 
-  void visit(Reference* ref) override {
-    if (!ReferenceLinker::linkReference(ref, mContext, mSymbols, mDecls,
-                                        mCallSite)) {
-      mError = true;
+  void Visit(Reference* ref) override {
+    if (!ReferenceLinker::LinkReference(ref, context_, symbols_, decls_,
+                                        callsite_)) {
+      error_ = true;
     }
   }
 
-  bool hasError() const { return mError; }
+  bool HasError() const { return error_; }
 
  private:
-  IAaptContext* mContext;
-  SymbolTable* mSymbols;
-  xml::IPackageDeclStack* mDecls;
-  CallSite* mCallSite;
-  bool mError;
+  DISALLOW_COPY_AND_ASSIGN(ReferenceVisitor);
+
+  IAaptContext* context_;
+  SymbolTable* symbols_;
+  xml::IPackageDeclStack* decls_;
+  CallSite* callsite_;
+  bool error_;
 };
 
 /**
@@ -69,114 +72,117 @@
  */
 class XmlVisitor : public xml::PackageAwareVisitor {
  public:
-  using xml::PackageAwareVisitor::visit;
+  using xml::PackageAwareVisitor::Visit;
 
   XmlVisitor(IAaptContext* context, SymbolTable* symbols, const Source& source,
-             std::set<int>* sdkLevelsFound, CallSite* callSite)
-      : mContext(context),
-        mSymbols(symbols),
-        mSource(source),
-        mSdkLevelsFound(sdkLevelsFound),
-        mCallSite(callSite),
-        mReferenceVisitor(context, symbols, this, callSite) {}
+             std::set<int>* sdk_levels_found, CallSite* callsite)
+      : context_(context),
+        symbols_(symbols),
+        source_(source),
+        sdk_levels_found_(sdk_levels_found),
+        callsite_(callsite),
+        reference_visitor_(context, symbols, this, callsite) {}
 
-  void visit(xml::Element* el) override {
-    const Source source = mSource.withLine(el->lineNumber);
+  void Visit(xml::Element* el) override {
+    const Source source = source_.WithLine(el->line_number);
     for (xml::Attribute& attr : el->attributes) {
-      Maybe<xml::ExtractedPackage> maybePackage =
-          xml::extractPackageFromNamespace(attr.namespaceUri);
-      if (maybePackage) {
+      Maybe<xml::ExtractedPackage> maybe_package =
+          xml::ExtractPackageFromNamespace(attr.namespace_uri);
+      if (maybe_package) {
         // There is a valid package name for this attribute. We will look this
         // up.
-        StringPiece package = maybePackage.value().package;
+        StringPiece package = maybe_package.value().package;
         if (package.empty()) {
           // Empty package means the 'current' or 'local' package.
-          package = mContext->getCompilationPackage();
+          package = context_->GetCompilationPackage();
         }
 
-        Reference attrRef(
+        Reference attr_ref(
             ResourceNameRef(package, ResourceType::kAttr, attr.name));
-        attrRef.privateReference = maybePackage.value().privateNamespace;
+        attr_ref.private_reference = maybe_package.value().private_namespace;
 
-        std::string errStr;
-        attr.compiledAttribute = ReferenceLinker::compileXmlAttribute(
-            attrRef, mContext->getNameMangler(), mSymbols, mCallSite, &errStr);
+        std::string err_str;
+        attr.compiled_attribute = ReferenceLinker::CompileXmlAttribute(
+            attr_ref, context_->GetNameMangler(), symbols_, callsite_,
+            &err_str);
 
         // Convert the string value into a compiled Value if this is a valid
         // attribute.
-        if (attr.compiledAttribute) {
-          if (attr.compiledAttribute.value().id) {
+        if (attr.compiled_attribute) {
+          if (attr.compiled_attribute.value().id) {
             // Record all SDK levels from which the attributes were defined.
-            const size_t sdkLevel = findAttributeSdkLevel(
-                attr.compiledAttribute.value().id.value());
-            if (sdkLevel > 1) {
-              mSdkLevelsFound->insert(sdkLevel);
+            const size_t sdk_level = FindAttributeSdkLevel(
+                attr.compiled_attribute.value().id.value());
+            if (sdk_level > 1) {
+              sdk_levels_found_->insert(sdk_level);
             }
           }
 
           const Attribute* attribute =
-              &attr.compiledAttribute.value().attribute;
-          attr.compiledValue =
-              ResourceUtils::tryParseItemForAttribute(attr.value, attribute);
-          if (!attr.compiledValue &&
-              !(attribute->typeMask & android::ResTable_map::TYPE_STRING)) {
+              &attr.compiled_attribute.value().attribute;
+          attr.compiled_value =
+              ResourceUtils::TryParseItemForAttribute(attr.value, attribute);
+          if (!attr.compiled_value &&
+              !(attribute->type_mask & android::ResTable_map::TYPE_STRING)) {
             // We won't be able to encode this as a string.
-            mContext->getDiagnostics()->error(
+            context_->GetDiagnostics()->Error(
                 DiagMessage(source) << "'" << attr.value << "' "
                                     << "is incompatible with attribute "
                                     << package << ":" << attr.name << " "
                                     << *attribute);
-            mError = true;
+            error_ = true;
           }
 
         } else {
-          mContext->getDiagnostics()->error(DiagMessage(source)
+          context_->GetDiagnostics()->Error(DiagMessage(source)
                                             << "attribute '" << package << ":"
-                                            << attr.name << "' " << errStr);
-          mError = true;
+                                            << attr.name << "' " << err_str);
+          error_ = true;
         }
-      } else if (!attr.compiledValue) {
+      } else if (!attr.compiled_value) {
         // We still encode references, but only if we haven't manually set this
         // to
         // another compiled value.
-        attr.compiledValue = ResourceUtils::tryParseReference(attr.value);
+        attr.compiled_value = ResourceUtils::TryParseReference(attr.value);
       }
 
-      if (attr.compiledValue) {
+      if (attr.compiled_value) {
         // With a compiledValue, we must resolve the reference and assign it an
         // ID.
-        attr.compiledValue->setSource(source);
-        attr.compiledValue->accept(&mReferenceVisitor);
+        attr.compiled_value->SetSource(source);
+        attr.compiled_value->Accept(&reference_visitor_);
       }
     }
 
     // Call the super implementation.
-    xml::PackageAwareVisitor::visit(el);
+    xml::PackageAwareVisitor::Visit(el);
   }
 
-  bool hasError() { return mError || mReferenceVisitor.hasError(); }
+  bool HasError() { return error_ || reference_visitor_.HasError(); }
 
  private:
-  IAaptContext* mContext;
-  SymbolTable* mSymbols;
-  Source mSource;
-  std::set<int>* mSdkLevelsFound;
-  CallSite* mCallSite;
-  ReferenceVisitor mReferenceVisitor;
-  bool mError = false;
+  DISALLOW_COPY_AND_ASSIGN(XmlVisitor);
+
+  IAaptContext* context_;
+  SymbolTable* symbols_;
+  Source source_;
+  std::set<int>* sdk_levels_found_;
+  CallSite* callsite_;
+  ReferenceVisitor reference_visitor_;
+  bool error_ = false;
 };
 
 }  // namespace
 
-bool XmlReferenceLinker::consume(IAaptContext* context,
+bool XmlReferenceLinker::Consume(IAaptContext* context,
                                  xml::XmlResource* resource) {
-  mSdkLevelsFound.clear();
-  CallSite callSite = {resource->file.name};
-  XmlVisitor visitor(context, context->getExternalSymbols(),
-                     resource->file.source, &mSdkLevelsFound, &callSite);
+  sdk_levels_found_.clear();
+  CallSite callsite = {resource->file.name};
+  XmlVisitor visitor(context, context->GetExternalSymbols(),
+                     resource->file.source, &sdk_levels_found_, &callsite);
   if (resource->root) {
-    resource->root->accept(&visitor);
-    return !visitor.hasError();
+    resource->root->Accept(&visitor);
+    return !visitor.HasError();
   }
   return false;
 }
diff --git a/tools/aapt2/link/XmlReferenceLinker_test.cpp b/tools/aapt2/link/XmlReferenceLinker_test.cpp
index 35d479f..810f63c 100644
--- a/tools/aapt2/link/XmlReferenceLinker_test.cpp
+++ b/tools/aapt2/link/XmlReferenceLinker_test.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "link/Linkers.h"
+
 #include "test/Test.h"
 
 namespace aapt {
@@ -22,72 +23,72 @@
 class XmlReferenceLinkerTest : public ::testing::Test {
  public:
   void SetUp() override {
-    mContext =
+    context_ =
         test::ContextBuilder()
-            .setCompilationPackage("com.app.test")
-            .setNameManglerPolicy(
+            .SetCompilationPackage("com.app.test")
+            .SetNameManglerPolicy(
                 NameManglerPolicy{"com.app.test", {"com.android.support"}})
-            .addSymbolSource(
+            .AddSymbolSource(
                 test::StaticSymbolSourceBuilder()
-                    .addPublicSymbol(
+                    .AddPublicSymbol(
                         "android:attr/layout_width", ResourceId(0x01010000),
                         test::AttributeBuilder()
-                            .setTypeMask(android::ResTable_map::TYPE_ENUM |
+                            .SetTypeMask(android::ResTable_map::TYPE_ENUM |
                                          android::ResTable_map::TYPE_DIMENSION)
-                            .addItem("match_parent", 0xffffffff)
-                            .build())
-                    .addPublicSymbol(
+                            .AddItem("match_parent", 0xffffffff)
+                            .Build())
+                    .AddPublicSymbol(
                         "android:attr/background", ResourceId(0x01010001),
                         test::AttributeBuilder()
-                            .setTypeMask(android::ResTable_map::TYPE_COLOR)
-                            .build())
-                    .addPublicSymbol("android:attr/attr",
+                            .SetTypeMask(android::ResTable_map::TYPE_COLOR)
+                            .Build())
+                    .AddPublicSymbol("android:attr/attr",
                                      ResourceId(0x01010002),
-                                     test::AttributeBuilder().build())
-                    .addPublicSymbol(
+                                     test::AttributeBuilder().Build())
+                    .AddPublicSymbol(
                         "android:attr/text", ResourceId(0x01010003),
                         test::AttributeBuilder()
-                            .setTypeMask(android::ResTable_map::TYPE_STRING)
-                            .build())
+                            .SetTypeMask(android::ResTable_map::TYPE_STRING)
+                            .Build())
 
                     // Add one real symbol that was introduces in v21
-                    .addPublicSymbol("android:attr/colorAccent",
+                    .AddPublicSymbol("android:attr/colorAccent",
                                      ResourceId(0x01010435),
-                                     test::AttributeBuilder().build())
+                                     test::AttributeBuilder().Build())
 
                     // Private symbol.
-                    .addSymbol("android:color/hidden", ResourceId(0x01020001))
+                    .AddSymbol("android:color/hidden", ResourceId(0x01020001))
 
-                    .addPublicSymbol("android:id/id", ResourceId(0x01030000))
-                    .addSymbol("com.app.test:id/id", ResourceId(0x7f030000))
-                    .addSymbol("com.app.test:color/green",
+                    .AddPublicSymbol("android:id/id", ResourceId(0x01030000))
+                    .AddSymbol("com.app.test:id/id", ResourceId(0x7f030000))
+                    .AddSymbol("com.app.test:color/green",
                                ResourceId(0x7f020000))
-                    .addSymbol("com.app.test:color/red", ResourceId(0x7f020001))
-                    .addSymbol(
+                    .AddSymbol("com.app.test:color/red", ResourceId(0x7f020001))
+                    .AddSymbol(
                         "com.app.test:attr/colorAccent", ResourceId(0x7f010000),
                         test::AttributeBuilder()
-                            .setTypeMask(android::ResTable_map::TYPE_COLOR)
-                            .build())
-                    .addPublicSymbol(
+                            .SetTypeMask(android::ResTable_map::TYPE_COLOR)
+                            .Build())
+                    .AddPublicSymbol(
                         "com.app.test:attr/com.android.support$colorAccent",
                         ResourceId(0x7f010001),
                         test::AttributeBuilder()
-                            .setTypeMask(android::ResTable_map::TYPE_COLOR)
-                            .build())
-                    .addPublicSymbol("com.app.test:attr/attr",
+                            .SetTypeMask(android::ResTable_map::TYPE_COLOR)
+                            .Build())
+                    .AddPublicSymbol("com.app.test:attr/attr",
                                      ResourceId(0x7f010002),
-                                     test::AttributeBuilder().build())
-                    .build())
-            .build();
+                                     test::AttributeBuilder().Build())
+                    .Build())
+            .Build();
   }
 
  protected:
-  std::unique_ptr<IAaptContext> mContext;
+  std::unique_ptr<IAaptContext> context_;
 };
 
 TEST_F(XmlReferenceLinkerTest, LinkBasicAttributes) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDomForPackageName(mContext.get(), R"EOF(
+      test::BuildXmlDomForPackageName(context_.get(), R"EOF(
         <View xmlns:android="http://schemas.android.com/apk/res/android"
               android:layout_width="match_parent"
               android:background="@color/green"
@@ -95,123 +96,125 @@
               class="hello" />)EOF");
 
   XmlReferenceLinker linker;
-  ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
+  ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
 
-  xml::Element* viewEl = xml::findRootElement(doc.get());
-  ASSERT_NE(viewEl, nullptr);
+  xml::Element* view_el = xml::FindRootElement(doc.get());
+  ASSERT_NE(view_el, nullptr);
 
-  xml::Attribute* xmlAttr =
-      viewEl->findAttribute(xml::kSchemaAndroid, "layout_width");
-  ASSERT_NE(xmlAttr, nullptr);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
-  EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(),
+  xml::Attribute* xml_attr =
+      view_el->FindAttribute(xml::kSchemaAndroid, "layout_width");
+  ASSERT_NE(xml_attr, nullptr);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id);
+  EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(),
             ResourceId(0x01010000));
-  ASSERT_NE(xmlAttr->compiledValue, nullptr);
-  ASSERT_NE(valueCast<BinaryPrimitive>(xmlAttr->compiledValue.get()), nullptr);
+  ASSERT_NE(xml_attr->compiled_value, nullptr);
+  ASSERT_NE(ValueCast<BinaryPrimitive>(xml_attr->compiled_value.get()),
+            nullptr);
 
-  xmlAttr = viewEl->findAttribute(xml::kSchemaAndroid, "background");
-  ASSERT_NE(xmlAttr, nullptr);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
-  EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(),
+  xml_attr = view_el->FindAttribute(xml::kSchemaAndroid, "background");
+  ASSERT_NE(xml_attr, nullptr);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id);
+  EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(),
             ResourceId(0x01010001));
-  ASSERT_NE(xmlAttr->compiledValue, nullptr);
-  Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get());
+  ASSERT_NE(xml_attr->compiled_value, nullptr);
+  Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get());
   ASSERT_NE(ref, nullptr);
   AAPT_ASSERT_TRUE(ref->name);
   EXPECT_EQ(ref->name.value(),
-            test::parseNameOrDie("color/green"));  // Make sure the name
+            test::ParseNameOrDie("color/green"));  // Make sure the name
                                                    // didn't change.
   AAPT_ASSERT_TRUE(ref->id);
   EXPECT_EQ(ref->id.value(), ResourceId(0x7f020000));
 
-  xmlAttr = viewEl->findAttribute(xml::kSchemaAndroid, "text");
-  ASSERT_NE(xmlAttr, nullptr);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
+  xml_attr = view_el->FindAttribute(xml::kSchemaAndroid, "text");
+  ASSERT_NE(xml_attr, nullptr);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute);
   ASSERT_FALSE(
-      xmlAttr->compiledValue);  // Strings don't get compiled for memory sake.
+      xml_attr->compiled_value);  // Strings don't get compiled for memory sake.
 
-  xmlAttr = viewEl->findAttribute("", "class");
-  ASSERT_NE(xmlAttr, nullptr);
-  AAPT_ASSERT_FALSE(xmlAttr->compiledAttribute);
-  ASSERT_EQ(xmlAttr->compiledValue, nullptr);
+  xml_attr = view_el->FindAttribute("", "class");
+  ASSERT_NE(xml_attr, nullptr);
+  AAPT_ASSERT_FALSE(xml_attr->compiled_attribute);
+  ASSERT_EQ(xml_attr->compiled_value, nullptr);
 }
 
 TEST_F(XmlReferenceLinkerTest, PrivateSymbolsAreNotLinked) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDomForPackageName(mContext.get(), R"EOF(
+      test::BuildXmlDomForPackageName(context_.get(), R"EOF(
         <View xmlns:android="http://schemas.android.com/apk/res/android"
               android:colorAccent="@android:color/hidden" />)EOF");
 
   XmlReferenceLinker linker;
-  ASSERT_FALSE(linker.consume(mContext.get(), doc.get()));
+  ASSERT_FALSE(linker.Consume(context_.get(), doc.get()));
 }
 
 TEST_F(XmlReferenceLinkerTest,
        PrivateSymbolsAreLinkedWhenReferenceHasStarPrefix) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDomForPackageName(mContext.get(), R"EOF(
+      test::BuildXmlDomForPackageName(context_.get(), R"EOF(
     <View xmlns:android="http://schemas.android.com/apk/res/android"
           android:colorAccent="@*android:color/hidden" />)EOF");
 
   XmlReferenceLinker linker;
-  ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
+  ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
 }
 
 TEST_F(XmlReferenceLinkerTest, SdkLevelsAreRecorded) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDomForPackageName(mContext.get(), R"EOF(
+      test::BuildXmlDomForPackageName(context_.get(), R"EOF(
         <View xmlns:android="http://schemas.android.com/apk/res/android"
               android:colorAccent="#ffffff" />)EOF");
 
   XmlReferenceLinker linker;
-  ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
-  EXPECT_TRUE(linker.getSdkLevels().count(21) == 1);
+  ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
+  EXPECT_TRUE(linker.sdk_levels().count(21) == 1);
 }
 
 TEST_F(XmlReferenceLinkerTest, LinkMangledAttributes) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDomForPackageName(mContext.get(), R"EOF(
+      test::BuildXmlDomForPackageName(context_.get(), R"EOF(
             <View xmlns:support="http://schemas.android.com/apk/res/com.android.support"
                   support:colorAccent="#ff0000" />)EOF");
 
   XmlReferenceLinker linker;
-  ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
+  ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
 
-  xml::Element* viewEl = xml::findRootElement(doc.get());
-  ASSERT_NE(viewEl, nullptr);
+  xml::Element* view_el = xml::FindRootElement(doc.get());
+  ASSERT_NE(view_el, nullptr);
 
-  xml::Attribute* xmlAttr = viewEl->findAttribute(
-      xml::buildPackageNamespace("com.android.support"), "colorAccent");
-  ASSERT_NE(xmlAttr, nullptr);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
-  EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(),
+  xml::Attribute* xml_attr = view_el->FindAttribute(
+      xml::BuildPackageNamespace("com.android.support"), "colorAccent");
+  ASSERT_NE(xml_attr, nullptr);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id);
+  EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(),
             ResourceId(0x7f010001));
-  ASSERT_NE(valueCast<BinaryPrimitive>(xmlAttr->compiledValue.get()), nullptr);
+  ASSERT_NE(ValueCast<BinaryPrimitive>(xml_attr->compiled_value.get()),
+            nullptr);
 }
 
 TEST_F(XmlReferenceLinkerTest, LinkAutoResReference) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDomForPackageName(mContext.get(), R"EOF(
+      test::BuildXmlDomForPackageName(context_.get(), R"EOF(
             <View xmlns:app="http://schemas.android.com/apk/res-auto"
                   app:colorAccent="@app:color/red" />)EOF");
 
   XmlReferenceLinker linker;
-  ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
+  ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
 
-  xml::Element* viewEl = xml::findRootElement(doc.get());
-  ASSERT_NE(viewEl, nullptr);
+  xml::Element* view_el = xml::FindRootElement(doc.get());
+  ASSERT_NE(view_el, nullptr);
 
-  xml::Attribute* xmlAttr =
-      viewEl->findAttribute(xml::kSchemaAuto, "colorAccent");
-  ASSERT_NE(xmlAttr, nullptr);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
-  EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(),
+  xml::Attribute* xml_attr =
+      view_el->FindAttribute(xml::kSchemaAuto, "colorAccent");
+  ASSERT_NE(xml_attr, nullptr);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id);
+  EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(),
             ResourceId(0x7f010000));
-  Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get());
+  Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get());
   ASSERT_NE(ref, nullptr);
   AAPT_ASSERT_TRUE(ref->name);
   AAPT_ASSERT_TRUE(ref->id);
@@ -220,7 +223,7 @@
 
 TEST_F(XmlReferenceLinkerTest, LinkViewWithShadowedPackageAlias) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDomForPackageName(mContext.get(), R"EOF(
+      test::BuildXmlDomForPackageName(context_.get(), R"EOF(
             <View xmlns:app="http://schemas.android.com/apk/res/android"
                   app:attr="@app:id/id">
               <View xmlns:app="http://schemas.android.com/apk/res/com.app.test"
@@ -228,38 +231,39 @@
             </View>)EOF");
 
   XmlReferenceLinker linker;
-  ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
+  ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
 
-  xml::Element* viewEl = xml::findRootElement(doc.get());
-  ASSERT_NE(viewEl, nullptr);
+  xml::Element* view_el = xml::FindRootElement(doc.get());
+  ASSERT_NE(view_el, nullptr);
 
   // All attributes and references in this element should be referring to
   // "android" (0x01).
-  xml::Attribute* xmlAttr = viewEl->findAttribute(xml::kSchemaAndroid, "attr");
-  ASSERT_NE(xmlAttr, nullptr);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
-  EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(),
+  xml::Attribute* xml_attr =
+      view_el->FindAttribute(xml::kSchemaAndroid, "attr");
+  ASSERT_NE(xml_attr, nullptr);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id);
+  EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(),
             ResourceId(0x01010002));
-  Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get());
+  Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get());
   ASSERT_NE(ref, nullptr);
   AAPT_ASSERT_TRUE(ref->id);
   EXPECT_EQ(ref->id.value(), ResourceId(0x01030000));
 
-  ASSERT_FALSE(viewEl->getChildElements().empty());
-  viewEl = viewEl->getChildElements().front();
-  ASSERT_NE(viewEl, nullptr);
+  ASSERT_FALSE(view_el->GetChildElements().empty());
+  view_el = view_el->GetChildElements().front();
+  ASSERT_NE(view_el, nullptr);
 
   // All attributes and references in this element should be referring to
   // "com.app.test" (0x7f).
-  xmlAttr =
-      viewEl->findAttribute(xml::buildPackageNamespace("com.app.test"), "attr");
-  ASSERT_NE(xmlAttr, nullptr);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
-  EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(),
+  xml_attr = view_el->FindAttribute(xml::BuildPackageNamespace("com.app.test"),
+                                    "attr");
+  ASSERT_NE(xml_attr, nullptr);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id);
+  EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(),
             ResourceId(0x7f010002));
-  ref = valueCast<Reference>(xmlAttr->compiledValue.get());
+  ref = ValueCast<Reference>(xml_attr->compiled_value.get());
   ASSERT_NE(ref, nullptr);
   AAPT_ASSERT_TRUE(ref->id);
   EXPECT_EQ(ref->id.value(), ResourceId(0x7f030000));
@@ -267,26 +271,26 @@
 
 TEST_F(XmlReferenceLinkerTest, LinkViewWithLocalPackageAndAliasOfTheSameName) {
   std::unique_ptr<xml::XmlResource> doc =
-      test::buildXmlDomForPackageName(mContext.get(), R"EOF(
+      test::BuildXmlDomForPackageName(context_.get(), R"EOF(
             <View xmlns:android="http://schemas.android.com/apk/res/com.app.test"
                   android:attr="@id/id"/>)EOF");
 
   XmlReferenceLinker linker;
-  ASSERT_TRUE(linker.consume(mContext.get(), doc.get()));
+  ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
 
-  xml::Element* viewEl = xml::findRootElement(doc.get());
-  ASSERT_NE(viewEl, nullptr);
+  xml::Element* view_el = xml::FindRootElement(doc.get());
+  ASSERT_NE(view_el, nullptr);
 
   // All attributes and references in this element should be referring to
   // "com.app.test" (0x7f).
-  xml::Attribute* xmlAttr =
-      viewEl->findAttribute(xml::buildPackageNamespace("com.app.test"), "attr");
-  ASSERT_NE(xmlAttr, nullptr);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute);
-  AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id);
-  EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(),
+  xml::Attribute* xml_attr = view_el->FindAttribute(
+      xml::BuildPackageNamespace("com.app.test"), "attr");
+  ASSERT_NE(xml_attr, nullptr);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute);
+  AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id);
+  EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(),
             ResourceId(0x7f010002));
-  Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get());
+  Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get());
   ASSERT_NE(ref, nullptr);
   AAPT_ASSERT_TRUE(ref->id);
   EXPECT_EQ(ref->id.value(), ResourceId(0x7f030000));
diff --git a/tools/aapt2/process/IResourceTableConsumer.h b/tools/aapt2/process/IResourceTableConsumer.h
index a9bde39..4526a79 100644
--- a/tools/aapt2/process/IResourceTableConsumer.h
+++ b/tools/aapt2/process/IResourceTableConsumer.h
@@ -17,16 +17,16 @@
 #ifndef AAPT_PROCESS_IRESOURCETABLECONSUMER_H
 #define AAPT_PROCESS_IRESOURCETABLECONSUMER_H
 
+#include <iostream>
+#include <list>
+#include <sstream>
+
 #include "Diagnostics.h"
 #include "NameMangler.h"
 #include "Resource.h"
 #include "ResourceValues.h"
 #include "Source.h"
 
-#include <iostream>
-#include <list>
-#include <sstream>
-
 namespace aapt {
 
 class ResourceTable;
@@ -35,19 +35,19 @@
 struct IAaptContext {
   virtual ~IAaptContext() = default;
 
-  virtual SymbolTable* getExternalSymbols() = 0;
-  virtual IDiagnostics* getDiagnostics() = 0;
-  virtual const std::string& getCompilationPackage() = 0;
-  virtual uint8_t getPackageId() = 0;
-  virtual NameMangler* getNameMangler() = 0;
-  virtual bool verbose() = 0;
-  virtual int getMinSdkVersion() = 0;
+  virtual SymbolTable* GetExternalSymbols() = 0;
+  virtual IDiagnostics* GetDiagnostics() = 0;
+  virtual const std::string& GetCompilationPackage() = 0;
+  virtual uint8_t GetPackageId() = 0;
+  virtual NameMangler* GetNameMangler() = 0;
+  virtual bool IsVerbose() = 0;
+  virtual int GetMinSdkVersion() = 0;
 };
 
 struct IResourceTableConsumer {
   virtual ~IResourceTableConsumer() = default;
 
-  virtual bool consume(IAaptContext* context, ResourceTable* table) = 0;
+  virtual bool Consume(IAaptContext* context, ResourceTable* table) = 0;
 };
 
 namespace xml {
@@ -57,7 +57,7 @@
 struct IXmlResourceConsumer {
   virtual ~IXmlResourceConsumer() = default;
 
-  virtual bool consume(IAaptContext* context, xml::XmlResource* resource) = 0;
+  virtual bool Consume(IAaptContext* context, xml::XmlResource* resource) = 0;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp
index 00ffeb2..767384d 100644
--- a/tools/aapt2/process/SymbolTable.cpp
+++ b/tools/aapt2/process/SymbolTable.cpp
@@ -15,80 +15,81 @@
  */
 
 #include "process/SymbolTable.h"
+
+#include "androidfw/AssetManager.h"
+#include "androidfw/ResourceTypes.h"
+
 #include "ConfigDescription.h"
 #include "Resource.h"
 #include "ResourceUtils.h"
 #include "ValueVisitor.h"
 #include "util/Util.h"
 
-#include <androidfw/AssetManager.h>
-#include <androidfw/ResourceTypes.h>
-
 namespace aapt {
 
-void SymbolTable::appendSource(std::unique_ptr<ISymbolSource> source) {
-  mSources.push_back(std::move(source));
+void SymbolTable::AppendSource(std::unique_ptr<ISymbolSource> source) {
+  sources_.push_back(std::move(source));
 
   // We do not clear the cache, because sources earlier in the list take
   // precedent.
 }
 
-void SymbolTable::prependSource(std::unique_ptr<ISymbolSource> source) {
-  mSources.insert(mSources.begin(), std::move(source));
+void SymbolTable::PrependSource(std::unique_ptr<ISymbolSource> source) {
+  sources_.insert(sources_.begin(), std::move(source));
 
   // We must clear the cache in case we did a lookup before adding this
   // resource.
-  mCache.clear();
+  cache_.clear();
 }
 
-const SymbolTable::Symbol* SymbolTable::findByName(const ResourceName& name) {
-  if (const std::shared_ptr<Symbol>& s = mCache.get(name)) {
+const SymbolTable::Symbol* SymbolTable::FindByName(const ResourceName& name) {
+  if (const std::shared_ptr<Symbol>& s = cache_.get(name)) {
     return s.get();
   }
 
   // We did not find it in the cache, so look through the sources.
-  for (auto& symbolSource : mSources) {
-    std::unique_ptr<Symbol> symbol = symbolSource->findByName(name);
+  for (auto& symbolSource : sources_) {
+    std::unique_ptr<Symbol> symbol = symbolSource->FindByName(name);
     if (symbol) {
       // Take ownership of the symbol into a shared_ptr. We do this because
       // LruCache
       // doesn't support unique_ptr.
-      std::shared_ptr<Symbol> sharedSymbol =
+      std::shared_ptr<Symbol> shared_symbol =
           std::shared_ptr<Symbol>(symbol.release());
-      mCache.put(name, sharedSymbol);
+      cache_.put(name, shared_symbol);
 
-      if (sharedSymbol->id) {
+      if (shared_symbol->id) {
         // The symbol has an ID, so we can also cache this!
-        mIdCache.put(sharedSymbol->id.value(), sharedSymbol);
+        id_cache_.put(shared_symbol->id.value(), shared_symbol);
       }
-      return sharedSymbol.get();
+      return shared_symbol.get();
     }
   }
   return nullptr;
 }
 
-const SymbolTable::Symbol* SymbolTable::findById(const ResourceId& id) {
-  if (const std::shared_ptr<Symbol>& s = mIdCache.get(id)) {
+const SymbolTable::Symbol* SymbolTable::FindById(const ResourceId& id) {
+  if (const std::shared_ptr<Symbol>& s = id_cache_.get(id)) {
     return s.get();
   }
 
   // We did not find it in the cache, so look through the sources.
-  for (auto& symbolSource : mSources) {
-    std::unique_ptr<Symbol> symbol = symbolSource->findById(id);
+  for (auto& symbolSource : sources_) {
+    std::unique_ptr<Symbol> symbol = symbolSource->FindById(id);
     if (symbol) {
       // Take ownership of the symbol into a shared_ptr. We do this because
       // LruCache
       // doesn't support unique_ptr.
-      std::shared_ptr<Symbol> sharedSymbol =
+      std::shared_ptr<Symbol> shared_symbol =
           std::shared_ptr<Symbol>(symbol.release());
-      mIdCache.put(id, sharedSymbol);
-      return sharedSymbol.get();
+      id_cache_.put(id, shared_symbol);
+      return shared_symbol.get();
     }
   }
   return nullptr;
 }
 
-const SymbolTable::Symbol* SymbolTable::findByReference(const Reference& ref) {
+const SymbolTable::Symbol* SymbolTable::FindByReference(const Reference& ref) {
   // First try the ID. This is because when we lookup by ID, we only fill in the
   // ID cache.
   // Looking up by name fills in the name and ID cache. So a cache miss will
@@ -102,22 +103,22 @@
   // succeeded to lookup by ID. Subsequent lookups will miss then hit.
   const SymbolTable::Symbol* symbol = nullptr;
   if (ref.id) {
-    symbol = findById(ref.id.value());
+    symbol = FindById(ref.id.value());
   }
 
   if (ref.name && !symbol) {
-    symbol = findByName(ref.name.value());
+    symbol = FindByName(ref.name.value());
   }
   return symbol;
 }
 
-std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::findByName(
+std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::FindByName(
     const ResourceName& name) {
-  Maybe<ResourceTable::SearchResult> result = mTable->findResource(name);
+  Maybe<ResourceTable::SearchResult> result = table_->FindResource(name);
   if (!result) {
     if (name.type == ResourceType::kAttr) {
       // Recurse and try looking up a private attribute.
-      return findByName(
+      return FindByName(
           ResourceName(name.package, ResourceType::kAttrPrivate, name.entry));
     }
     return {};
@@ -127,7 +128,7 @@
 
   std::unique_ptr<SymbolTable::Symbol> symbol =
       util::make_unique<SymbolTable::Symbol>();
-  symbol->isPublic = (sr.entry->symbolStatus.state == SymbolState::kPublic);
+  symbol->is_public = (sr.entry->symbol_status.state == SymbolState::kPublic);
 
   if (sr.package->id && sr.type->id && sr.entry->id) {
     symbol->id = ResourceId(sr.package->id.value(), sr.type->id.value(),
@@ -137,10 +138,10 @@
   if (name.type == ResourceType::kAttr ||
       name.type == ResourceType::kAttrPrivate) {
     const ConfigDescription kDefaultConfig;
-    ResourceConfigValue* configValue = sr.entry->findValue(kDefaultConfig);
-    if (configValue) {
+    ResourceConfigValue* config_value = sr.entry->FindValue(kDefaultConfig);
+    if (config_value) {
       // This resource has an Attribute.
-      if (Attribute* attr = valueCast<Attribute>(configValue->value.get())) {
+      if (Attribute* attr = ValueCast<Attribute>(config_value->value.get())) {
         symbol->attribute = std::make_shared<Attribute>(*attr);
       } else {
         return {};
@@ -150,13 +151,13 @@
   return symbol;
 }
 
-bool AssetManagerSymbolSource::addAssetPath(const StringPiece& path) {
+bool AssetManagerSymbolSource::AddAssetPath(const StringPiece& path) {
   int32_t cookie = 0;
-  return mAssets.addAssetPath(android::String8(path.data(), path.size()),
+  return assets_.addAssetPath(android::String8(path.data(), path.size()),
                               &cookie);
 }
 
-static std::unique_ptr<SymbolTable::Symbol> lookupAttributeInTable(
+static std::unique_ptr<SymbolTable::Symbol> LookupAttributeInTable(
     const android::ResTable& table, ResourceId id) {
   // Try as a bag.
   const android::ResTable::bag_entry* entry;
@@ -175,41 +176,42 @@
   for (size_t i = 0; i < (size_t)count; i++) {
     if (entry[i].map.name.ident == android::ResTable_map::ATTR_TYPE) {
       s->attribute = std::make_shared<Attribute>(false);
-      s->attribute->typeMask = entry[i].map.value.data;
+      s->attribute->type_mask = entry[i].map.value.data;
       break;
     }
   }
 
   if (s->attribute) {
     for (size_t i = 0; i < (size_t)count; i++) {
-      const android::ResTable_map& mapEntry = entry[i].map;
-      if (Res_INTERNALID(mapEntry.name.ident)) {
-        switch (mapEntry.name.ident) {
+      const android::ResTable_map& map_entry = entry[i].map;
+      if (Res_INTERNALID(map_entry.name.ident)) {
+        switch (map_entry.name.ident) {
           case android::ResTable_map::ATTR_MIN:
-            s->attribute->minInt = static_cast<int32_t>(mapEntry.value.data);
+            s->attribute->min_int = static_cast<int32_t>(map_entry.value.data);
             break;
           case android::ResTable_map::ATTR_MAX:
-            s->attribute->maxInt = static_cast<int32_t>(mapEntry.value.data);
+            s->attribute->max_int = static_cast<int32_t>(map_entry.value.data);
             break;
         }
         continue;
       }
 
-      android::ResTable::resource_name entryName;
-      if (!table.getResourceName(mapEntry.name.ident, false, &entryName)) {
+      android::ResTable::resource_name entry_name;
+      if (!table.getResourceName(map_entry.name.ident, false, &entry_name)) {
         table.unlockBag(entry);
         return nullptr;
       }
 
-      Maybe<ResourceName> parsedName = ResourceUtils::toResourceName(entryName);
-      if (!parsedName) {
+      Maybe<ResourceName> parsed_name =
+          ResourceUtils::ToResourceName(entry_name);
+      if (!parsed_name) {
         return nullptr;
       }
 
       Attribute::Symbol symbol;
-      symbol.symbol.name = parsedName.value();
-      symbol.symbol.id = ResourceId(mapEntry.name.ident);
-      symbol.value = mapEntry.value.data;
+      symbol.symbol.name = parsed_name.value();
+      symbol.symbol.id = ResourceId(map_entry.name.ident);
+      symbol.value = map_entry.value.data;
       s->attribute->symbols.push_back(std::move(symbol));
     }
   }
@@ -217,81 +219,81 @@
   return s;
 }
 
-std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::findByName(
+std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindByName(
     const ResourceName& name) {
-  const android::ResTable& table = mAssets.getResources(false);
+  const android::ResTable& table = assets_.getResources(false);
 
-  const std::u16string package16 = util::utf8ToUtf16(name.package);
-  const std::u16string type16 = util::utf8ToUtf16(toString(name.type));
-  const std::u16string entry16 = util::utf8ToUtf16(name.entry);
+  const std::u16string package16 = util::Utf8ToUtf16(name.package);
+  const std::u16string type16 = util::Utf8ToUtf16(ToString(name.type));
+  const std::u16string entry16 = util::Utf8ToUtf16(name.entry);
 
-  uint32_t typeSpecFlags = 0;
-  ResourceId resId = table.identifierForName(
+  uint32_t type_spec_flags = 0;
+  ResourceId res_id = table.identifierForName(
       entry16.data(), entry16.size(), type16.data(), type16.size(),
-      package16.data(), package16.size(), &typeSpecFlags);
-  if (!resId.isValid()) {
+      package16.data(), package16.size(), &type_spec_flags);
+  if (!res_id.is_valid()) {
     return {};
   }
 
   std::unique_ptr<SymbolTable::Symbol> s;
   if (name.type == ResourceType::kAttr) {
-    s = lookupAttributeInTable(table, resId);
+    s = LookupAttributeInTable(table, res_id);
   } else {
     s = util::make_unique<SymbolTable::Symbol>();
-    s->id = resId;
+    s->id = res_id;
   }
 
   if (s) {
-    s->isPublic =
-        (typeSpecFlags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0;
+    s->is_public =
+        (type_spec_flags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0;
     return s;
   }
   return {};
 }
 
-static Maybe<ResourceName> getResourceName(const android::ResTable& table,
+static Maybe<ResourceName> GetResourceName(const android::ResTable& table,
                                            ResourceId id) {
-  android::ResTable::resource_name resName = {};
-  if (!table.getResourceName(id.id, true, &resName)) {
+  android::ResTable::resource_name res_name = {};
+  if (!table.getResourceName(id.id, true, &res_name)) {
     return {};
   }
-  return ResourceUtils::toResourceName(resName);
+  return ResourceUtils::ToResourceName(res_name);
 }
 
-std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::findById(
+std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindById(
     ResourceId id) {
-  const android::ResTable& table = mAssets.getResources(false);
-  Maybe<ResourceName> maybeName = getResourceName(table, id);
-  if (!maybeName) {
+  const android::ResTable& table = assets_.getResources(false);
+  Maybe<ResourceName> maybe_name = GetResourceName(table, id);
+  if (!maybe_name) {
     return {};
   }
 
-  uint32_t typeSpecFlags = 0;
-  table.getResourceFlags(id.id, &typeSpecFlags);
+  uint32_t type_spec_flags = 0;
+  table.getResourceFlags(id.id, &type_spec_flags);
 
   std::unique_ptr<SymbolTable::Symbol> s;
-  if (maybeName.value().type == ResourceType::kAttr) {
-    s = lookupAttributeInTable(table, id);
+  if (maybe_name.value().type == ResourceType::kAttr) {
+    s = LookupAttributeInTable(table, id);
   } else {
     s = util::make_unique<SymbolTable::Symbol>();
     s->id = id;
   }
 
   if (s) {
-    s->isPublic =
-        (typeSpecFlags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0;
+    s->is_public =
+        (type_spec_flags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0;
     return s;
   }
   return {};
 }
 
-std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::findByReference(
+std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindByReference(
     const Reference& ref) {
   // AssetManager always prefers IDs.
   if (ref.id) {
-    return findById(ref.id.value());
+    return FindById(ref.id.value());
   } else if (ref.name) {
-    return findByName(ref.name.value());
+    return FindByName(ref.name.value());
   }
   return {};
 }
diff --git a/tools/aapt2/process/SymbolTable.h b/tools/aapt2/process/SymbolTable.h
index 89d87de..25f7565 100644
--- a/tools/aapt2/process/SymbolTable.h
+++ b/tools/aapt2/process/SymbolTable.h
@@ -17,28 +17,28 @@
 #ifndef AAPT_PROCESS_SYMBOLTABLE_H
 #define AAPT_PROCESS_SYMBOLTABLE_H
 
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+#include "android-base/macros.h"
+#include "androidfw/AssetManager.h"
+#include "utils/JenkinsHash.h"
+#include "utils/LruCache.h"
+
 #include "Resource.h"
 #include "ResourceTable.h"
 #include "ResourceValues.h"
 #include "util/Util.h"
 
-#include <utils/JenkinsHash.h>
-#include <utils/LruCache.h>
-
-#include <android-base/macros.h>
-#include <androidfw/AssetManager.h>
-#include <algorithm>
-#include <memory>
-#include <vector>
-
 namespace aapt {
 
 inline android::hash_t hash_type(const ResourceName& name) {
-  std::hash<std::string> strHash;
+  std::hash<std::string> str_hash;
   android::hash_t hash = 0;
-  hash = android::JenkinsHashMix(hash, (uint32_t)strHash(name.package));
+  hash = android::JenkinsHashMix(hash, (uint32_t)str_hash(name.package));
   hash = android::JenkinsHashMix(hash, (uint32_t)name.type);
-  hash = android::JenkinsHashMix(hash, (uint32_t)strHash(name.entry));
+  hash = android::JenkinsHashMix(hash, (uint32_t)str_hash(name.entry));
   return hash;
 }
 
@@ -60,7 +60,7 @@
 
     Symbol(const Maybe<ResourceId>& i, const std::shared_ptr<Attribute>& attr,
            bool pub)
-        : id(i), attribute(attr), isPublic(pub) {}
+        : id(i), attribute(attr), is_public(pub) {}
 
     Symbol(const Symbol&) = default;
     Symbol(Symbol&&) = default;
@@ -69,36 +69,34 @@
 
     Maybe<ResourceId> id;
     std::shared_ptr<Attribute> attribute;
-    bool isPublic = false;
+    bool is_public = false;
   };
 
-  SymbolTable() : mCache(200), mIdCache(200) {}
+  SymbolTable() : cache_(200), id_cache_(200) {}
 
-  void appendSource(std::unique_ptr<ISymbolSource> source);
-  void prependSource(std::unique_ptr<ISymbolSource> source);
+  void AppendSource(std::unique_ptr<ISymbolSource> source);
+  void PrependSource(std::unique_ptr<ISymbolSource> source);
 
   /**
-   * Never hold on to the result between calls to findByName or findById. The
-   * results
-   * are typically stored in a cache which may evict entries.
+   * Never hold on to the result between calls to FindByName or FindById. The
+   * results stored in a cache which may evict entries.
    */
-  const Symbol* findByName(const ResourceName& name);
-  const Symbol* findById(const ResourceId& id);
+  const Symbol* FindByName(const ResourceName& name);
+  const Symbol* FindById(const ResourceId& id);
 
   /**
    * Let's the ISymbolSource decide whether looking up by name or ID is faster,
-   * if both
-   * are available.
+   * if both are available.
    */
-  const Symbol* findByReference(const Reference& ref);
+  const Symbol* FindByReference(const Reference& ref);
 
  private:
-  std::vector<std::unique_ptr<ISymbolSource>> mSources;
+  std::vector<std::unique_ptr<ISymbolSource>> sources_;
 
   // We use shared_ptr because unique_ptr is not supported and
   // we need automatic deletion.
-  android::LruCache<ResourceName, std::shared_ptr<Symbol>> mCache;
-  android::LruCache<ResourceId, std::shared_ptr<Symbol>> mIdCache;
+  android::LruCache<ResourceName, std::shared_ptr<Symbol>> cache_;
+  android::LruCache<ResourceId, std::shared_ptr<Symbol>> id_cache_;
 
   DISALLOW_COPY_AND_ASSIGN(SymbolTable);
 };
@@ -112,19 +110,19 @@
  public:
   virtual ~ISymbolSource() = default;
 
-  virtual std::unique_ptr<SymbolTable::Symbol> findByName(
+  virtual std::unique_ptr<SymbolTable::Symbol> FindByName(
       const ResourceName& name) = 0;
-  virtual std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) = 0;
+  virtual std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) = 0;
 
   /**
    * Default implementation tries the name if it exists, else the ID.
    */
-  virtual std::unique_ptr<SymbolTable::Symbol> findByReference(
+  virtual std::unique_ptr<SymbolTable::Symbol> FindByReference(
       const Reference& ref) {
     if (ref.name) {
-      return findByName(ref.name.value());
+      return FindByName(ref.name.value());
     } else if (ref.id) {
-      return findById(ref.id.value());
+      return FindById(ref.id.value());
     }
     return {};
   }
@@ -137,17 +135,17 @@
  */
 class ResourceTableSymbolSource : public ISymbolSource {
  public:
-  explicit ResourceTableSymbolSource(ResourceTable* table) : mTable(table) {}
+  explicit ResourceTableSymbolSource(ResourceTable* table) : table_(table) {}
 
-  std::unique_ptr<SymbolTable::Symbol> findByName(
+  std::unique_ptr<SymbolTable::Symbol> FindByName(
       const ResourceName& name) override;
 
-  std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) override {
+  std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) override {
     return {};
   }
 
  private:
-  ResourceTable* mTable;
+  ResourceTable* table_;
 
   DISALLOW_COPY_AND_ASSIGN(ResourceTableSymbolSource);
 };
@@ -156,16 +154,16 @@
  public:
   AssetManagerSymbolSource() = default;
 
-  bool addAssetPath(const StringPiece& path);
+  bool AddAssetPath(const StringPiece& path);
 
-  std::unique_ptr<SymbolTable::Symbol> findByName(
+  std::unique_ptr<SymbolTable::Symbol> FindByName(
       const ResourceName& name) override;
-  std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) override;
-  std::unique_ptr<SymbolTable::Symbol> findByReference(
+  std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) override;
+  std::unique_ptr<SymbolTable::Symbol> FindByReference(
       const Reference& ref) override;
 
  private:
-  android::AssetManager mAssets;
+  android::AssetManager assets_;
 
   DISALLOW_COPY_AND_ASSIGN(AssetManagerSymbolSource);
 };
diff --git a/tools/aapt2/process/SymbolTable_test.cpp b/tools/aapt2/process/SymbolTable_test.cpp
index 00474f7..9ea0786 100644
--- a/tools/aapt2/process/SymbolTable_test.cpp
+++ b/tools/aapt2/process/SymbolTable_test.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "process/SymbolTable.h"
+
 #include "test/Test.h"
 
 namespace aapt {
@@ -22,20 +23,20 @@
 TEST(ResourceTableSymbolSourceTest, FindSymbols) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .addSimple("android:id/foo", ResourceId(0x01020000))
-          .addSimple("android:id/bar")
-          .addValue("android:attr/foo", ResourceId(0x01010000),
-                    test::AttributeBuilder().build())
-          .build();
+          .AddSimple("android:id/foo", ResourceId(0x01020000))
+          .AddSimple("android:id/bar")
+          .AddValue("android:attr/foo", ResourceId(0x01010000),
+                    test::AttributeBuilder().Build())
+          .Build();
 
-  ResourceTableSymbolSource symbolSource(table.get());
+  ResourceTableSymbolSource symbol_source(table.get());
   EXPECT_NE(nullptr,
-            symbolSource.findByName(test::parseNameOrDie("android:id/foo")));
+            symbol_source.FindByName(test::ParseNameOrDie("android:id/foo")));
   EXPECT_NE(nullptr,
-            symbolSource.findByName(test::parseNameOrDie("android:id/bar")));
+            symbol_source.FindByName(test::ParseNameOrDie("android:id/bar")));
 
   std::unique_ptr<SymbolTable::Symbol> s =
-      symbolSource.findByName(test::parseNameOrDie("android:attr/foo"));
+      symbol_source.FindByName(test::ParseNameOrDie("android:attr/foo"));
   ASSERT_NE(nullptr, s);
   EXPECT_NE(nullptr, s->attribute);
 }
@@ -43,13 +44,13 @@
 TEST(ResourceTableSymbolSourceTest, FindPrivateAttrSymbol) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .addValue("android:^attr-private/foo", ResourceId(0x01010000),
-                    test::AttributeBuilder().build())
-          .build();
+          .AddValue("android:^attr-private/foo", ResourceId(0x01010000),
+                    test::AttributeBuilder().Build())
+          .Build();
 
-  ResourceTableSymbolSource symbolSource(table.get());
+  ResourceTableSymbolSource symbol_source(table.get());
   std::unique_ptr<SymbolTable::Symbol> s =
-      symbolSource.findByName(test::parseNameOrDie("android:attr/foo"));
+      symbol_source.FindByName(test::ParseNameOrDie("android:attr/foo"));
   ASSERT_NE(nullptr, s);
   EXPECT_NE(nullptr, s->attribute);
 }
diff --git a/tools/aapt2/proto/ProtoHelpers.cpp b/tools/aapt2/proto/ProtoHelpers.cpp
index 2aa8aa5..38bf4e3 100644
--- a/tools/aapt2/proto/ProtoHelpers.cpp
+++ b/tools/aapt2/proto/ProtoHelpers.cpp
@@ -18,120 +18,151 @@
 
 namespace aapt {
 
-void serializeStringPoolToPb(const StringPool& pool, pb::StringPool* outPbPool) {
-    BigBuffer buffer(1024);
-    StringPool::flattenUtf8(&buffer, pool);
+void SerializeStringPoolToPb(const StringPool& pool,
+                             pb::StringPool* out_pb_pool) {
+  BigBuffer buffer(1024);
+  StringPool::FlattenUtf8(&buffer, pool);
 
-    std::string* data = outPbPool->mutable_data();
-    data->reserve(buffer.size());
+  std::string* data = out_pb_pool->mutable_data();
+  data->reserve(buffer.size());
 
-    size_t offset = 0;
-    for (const BigBuffer::Block& block : buffer) {
-        data->insert(data->begin() + offset, block.buffer.get(), block.buffer.get() + block.size);
-        offset += block.size;
-    }
+  size_t offset = 0;
+  for (const BigBuffer::Block& block : buffer) {
+    data->insert(data->begin() + offset, block.buffer.get(),
+                 block.buffer.get() + block.size);
+    offset += block.size;
+  }
 }
 
-void serializeSourceToPb(const Source& source, StringPool* srcPool, pb::Source* outPbSource) {
-    StringPool::Ref ref = srcPool->makeRef(source.path);
-    outPbSource->set_path_idx(static_cast<uint32_t>(ref.getIndex()));
-    if (source.line) {
-        outPbSource->set_line_no(static_cast<uint32_t>(source.line.value()));
-    }
+void SerializeSourceToPb(const Source& source, StringPool* src_pool,
+                         pb::Source* out_pb_source) {
+  StringPool::Ref ref = src_pool->MakeRef(source.path);
+  out_pb_source->set_path_idx(static_cast<uint32_t>(ref.index()));
+  if (source.line) {
+    out_pb_source->set_line_no(static_cast<uint32_t>(source.line.value()));
+  }
 }
 
-void deserializeSourceFromPb(const pb::Source& pbSource, const android::ResStringPool& srcPool,
-                             Source* outSource) {
-    if (pbSource.has_path_idx()) {
-        outSource->path = util::getString(srcPool, pbSource.path_idx());
-    }
+void DeserializeSourceFromPb(const pb::Source& pb_source,
+                             const android::ResStringPool& src_pool,
+                             Source* out_source) {
+  if (pb_source.has_path_idx()) {
+    out_source->path = util::GetString(src_pool, pb_source.path_idx());
+  }
 
-    if (pbSource.has_line_no()) {
-        outSource->line = static_cast<size_t>(pbSource.line_no());
-    }
+  if (pb_source.has_line_no()) {
+    out_source->line = static_cast<size_t>(pb_source.line_no());
+  }
 }
 
-pb::SymbolStatus_Visibility serializeVisibilityToPb(SymbolState state) {
-    switch (state) {
-    case SymbolState::kPrivate: return pb::SymbolStatus_Visibility_Private;
-    case SymbolState::kPublic: return pb::SymbolStatus_Visibility_Public;
-    default: break;
-    }
-    return pb::SymbolStatus_Visibility_Unknown;
+pb::SymbolStatus_Visibility SerializeVisibilityToPb(SymbolState state) {
+  switch (state) {
+    case SymbolState::kPrivate:
+      return pb::SymbolStatus_Visibility_Private;
+    case SymbolState::kPublic:
+      return pb::SymbolStatus_Visibility_Public;
+    default:
+      break;
+  }
+  return pb::SymbolStatus_Visibility_Unknown;
 }
 
-SymbolState deserializeVisibilityFromPb(pb::SymbolStatus_Visibility pbVisibility) {
-    switch (pbVisibility) {
-    case pb::SymbolStatus_Visibility_Private: return SymbolState::kPrivate;
-    case pb::SymbolStatus_Visibility_Public: return SymbolState::kPublic;
-    default: break;
-    }
-    return SymbolState::kUndefined;
+SymbolState DeserializeVisibilityFromPb(
+    pb::SymbolStatus_Visibility pb_visibility) {
+  switch (pb_visibility) {
+    case pb::SymbolStatus_Visibility_Private:
+      return SymbolState::kPrivate;
+    case pb::SymbolStatus_Visibility_Public:
+      return SymbolState::kPublic;
+    default:
+      break;
+  }
+  return SymbolState::kUndefined;
 }
 
-void serializeConfig(const ConfigDescription& config, pb::ConfigDescription* outPbConfig) {
-    android::ResTable_config flatConfig = config;
-    flatConfig.size = sizeof(flatConfig);
-    flatConfig.swapHtoD();
-    outPbConfig->set_data(&flatConfig, sizeof(flatConfig));
+void SerializeConfig(const ConfigDescription& config,
+                     pb::ConfigDescription* out_pb_config) {
+  android::ResTable_config flat_config = config;
+  flat_config.size = sizeof(flat_config);
+  flat_config.swapHtoD();
+  out_pb_config->set_data(&flat_config, sizeof(flat_config));
 }
 
-bool deserializeConfigDescriptionFromPb(const pb::ConfigDescription& pbConfig,
-                                        ConfigDescription* outConfig) {
-    if (!pbConfig.has_data()) {
-        return false;
-    }
+bool DeserializeConfigDescriptionFromPb(const pb::ConfigDescription& pb_config,
+                                        ConfigDescription* out_config) {
+  if (!pb_config.has_data()) {
+    return false;
+  }
 
-    const android::ResTable_config* config;
-    if (pbConfig.data().size() > sizeof(*config)) {
-        return false;
-    }
+  const android::ResTable_config* config;
+  if (pb_config.data().size() > sizeof(*config)) {
+    return false;
+  }
 
-    config = reinterpret_cast<const android::ResTable_config*>(pbConfig.data().data());
-    outConfig->copyFromDtoH(*config);
-    return true;
+  config = reinterpret_cast<const android::ResTable_config*>(
+      pb_config.data().data());
+  out_config->copyFromDtoH(*config);
+  return true;
 }
 
-pb::Reference_Type serializeReferenceTypeToPb(Reference::Type type) {
-    switch (type) {
-    case Reference::Type::kResource:  return pb::Reference_Type_Ref;
-    case Reference::Type::kAttribute: return pb::Reference_Type_Attr;
-    default: break;
-    }
-    return pb::Reference_Type_Ref;
+pb::Reference_Type SerializeReferenceTypeToPb(Reference::Type type) {
+  switch (type) {
+    case Reference::Type::kResource:
+      return pb::Reference_Type_Ref;
+    case Reference::Type::kAttribute:
+      return pb::Reference_Type_Attr;
+    default:
+      break;
+  }
+  return pb::Reference_Type_Ref;
 }
 
-Reference::Type deserializeReferenceTypeFromPb(pb::Reference_Type pbType) {
-    switch (pbType) {
-    case pb::Reference_Type_Ref:  return Reference::Type::kResource;
-    case pb::Reference_Type_Attr: return Reference::Type::kAttribute;
-    default: break;
-    }
-    return Reference::Type::kResource;
+Reference::Type DeserializeReferenceTypeFromPb(pb::Reference_Type pb_type) {
+  switch (pb_type) {
+    case pb::Reference_Type_Ref:
+      return Reference::Type::kResource;
+    case pb::Reference_Type_Attr:
+      return Reference::Type::kAttribute;
+    default:
+      break;
+  }
+  return Reference::Type::kResource;
 }
 
-pb::Plural_Arity serializePluralEnumToPb(size_t pluralIdx) {
-    switch (pluralIdx) {
-    case Plural::Zero:  return pb::Plural_Arity_Zero;
-    case Plural::One:   return pb::Plural_Arity_One;
-    case Plural::Two:   return pb::Plural_Arity_Two;
-    case Plural::Few:   return pb::Plural_Arity_Few;
-    case Plural::Many:  return pb::Plural_Arity_Many;
-    default: break;
-    }
-    return pb::Plural_Arity_Other;
+pb::Plural_Arity SerializePluralEnumToPb(size_t plural_idx) {
+  switch (plural_idx) {
+    case Plural::Zero:
+      return pb::Plural_Arity_Zero;
+    case Plural::One:
+      return pb::Plural_Arity_One;
+    case Plural::Two:
+      return pb::Plural_Arity_Two;
+    case Plural::Few:
+      return pb::Plural_Arity_Few;
+    case Plural::Many:
+      return pb::Plural_Arity_Many;
+    default:
+      break;
+  }
+  return pb::Plural_Arity_Other;
 }
 
-size_t deserializePluralEnumFromPb(pb::Plural_Arity arity) {
-    switch (arity) {
-    case pb::Plural_Arity_Zero: return Plural::Zero;
-    case pb::Plural_Arity_One:  return Plural::One;
-    case pb::Plural_Arity_Two:  return Plural::Two;
-    case pb::Plural_Arity_Few:  return Plural::Few;
-    case pb::Plural_Arity_Many: return Plural::Many;
-    default: break;
-    }
-    return Plural::Other;
+size_t DeserializePluralEnumFromPb(pb::Plural_Arity arity) {
+  switch (arity) {
+    case pb::Plural_Arity_Zero:
+      return Plural::Zero;
+    case pb::Plural_Arity_One:
+      return Plural::One;
+    case pb::Plural_Arity_Two:
+      return Plural::Two;
+    case pb::Plural_Arity_Few:
+      return Plural::Few;
+    case pb::Plural_Arity_Many:
+      return Plural::Many;
+    default:
+      break;
+  }
+  return Plural::Other;
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/proto/ProtoHelpers.h b/tools/aapt2/proto/ProtoHelpers.h
index 7271e8b..735cda0 100644
--- a/tools/aapt2/proto/ProtoHelpers.h
+++ b/tools/aapt2/proto/ProtoHelpers.h
@@ -17,39 +17,44 @@
 #ifndef AAPT_PROTO_PROTOHELPERS_H
 #define AAPT_PROTO_PROTOHELPERS_H
 
+#include "androidfw/ResourceTypes.h"
+
 #include "ConfigDescription.h"
 #include "ResourceTable.h"
 #include "Source.h"
 #include "StringPool.h"
-
 #include "proto/frameworks/base/tools/aapt2/Format.pb.h"
 
-#include <androidfw/ResourceTypes.h>
-
 namespace aapt {
 
-void serializeStringPoolToPb(const StringPool& pool, pb::StringPool* outPbPool);
+void SerializeStringPoolToPb(const StringPool& pool,
+                             pb::StringPool* out_pb_pool);
 
-void serializeSourceToPb(const Source& source, StringPool* srcPool,
-                         pb::Source* outPbSource);
-void deserializeSourceFromPb(const pb::Source& pbSource,
-                             const android::ResStringPool& srcPool,
-                             Source* outSource);
+void SerializeSourceToPb(const Source& source, StringPool* src_pool,
+                         pb::Source* out_pb_source);
 
-pb::SymbolStatus_Visibility serializeVisibilityToPb(SymbolState state);
-SymbolState deserializeVisibilityFromPb(
-    pb::SymbolStatus_Visibility pbVisibility);
+void DeserializeSourceFromPb(const pb::Source& pb_source,
+                             const android::ResStringPool& src_pool,
+                             Source* out_source);
 
-void serializeConfig(const ConfigDescription& config,
-                     pb::ConfigDescription* outPbConfig);
-bool deserializeConfigDescriptionFromPb(const pb::ConfigDescription& pbConfig,
-                                        ConfigDescription* outConfig);
+pb::SymbolStatus_Visibility SerializeVisibilityToPb(SymbolState state);
 
-pb::Reference_Type serializeReferenceTypeToPb(Reference::Type type);
-Reference::Type deserializeReferenceTypeFromPb(pb::Reference_Type pbType);
+SymbolState DeserializeVisibilityFromPb(
+    pb::SymbolStatus_Visibility pb_visibility);
 
-pb::Plural_Arity serializePluralEnumToPb(size_t pluralIdx);
-size_t deserializePluralEnumFromPb(pb::Plural_Arity arity);
+void SerializeConfig(const ConfigDescription& config,
+                     pb::ConfigDescription* out_pb_config);
+
+bool DeserializeConfigDescriptionFromPb(const pb::ConfigDescription& pb_config,
+                                        ConfigDescription* out_config);
+
+pb::Reference_Type SerializeReferenceTypeToPb(Reference::Type type);
+
+Reference::Type DeserializeReferenceTypeFromPb(pb::Reference_Type pb_type);
+
+pb::Plural_Arity SerializePluralEnumToPb(size_t plural_idx);
+
+size_t DeserializePluralEnumFromPb(pb::Plural_Arity arity);
 
 }  // namespace aapt
 
diff --git a/tools/aapt2/proto/ProtoSerialize.h b/tools/aapt2/proto/ProtoSerialize.h
index 378dafd..39c5003 100644
--- a/tools/aapt2/proto/ProtoSerialize.h
+++ b/tools/aapt2/proto/ProtoSerialize.h
@@ -17,15 +17,15 @@
 #ifndef AAPT_FLATTEN_TABLEPROTOSERIALIZER_H
 #define AAPT_FLATTEN_TABLEPROTOSERIALIZER_H
 
+#include "android-base/macros.h"
+#include "google/protobuf/io/coded_stream.h"
+#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
+
 #include "Diagnostics.h"
 #include "ResourceTable.h"
 #include "Source.h"
 #include "proto/ProtoHelpers.h"
 
-#include <android-base/macros.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
-
 namespace aapt {
 
 class CompiledFileOutputStream {
@@ -42,9 +42,9 @@
  private:
   DISALLOW_COPY_AND_ASSIGN(CompiledFileOutputStream);
 
-  void ensureAlignedWrite();
+  void EnsureAlignedWrite();
 
-  google::protobuf::io::CodedOutputStream mOut;
+  google::protobuf::io::CodedOutputStream out_;
 };
 
 class CompiledFileInputStream {
@@ -58,18 +58,18 @@
  private:
   DISALLOW_COPY_AND_ASSIGN(CompiledFileInputStream);
 
-  void ensureAlignedRead();
+  void EnsureAlignedRead();
 
-  google::protobuf::io::CodedInputStream mIn;
+  google::protobuf::io::CodedInputStream in_;
 };
 
-std::unique_ptr<pb::ResourceTable> serializeTableToPb(ResourceTable* table);
-std::unique_ptr<ResourceTable> deserializeTableFromPb(
+std::unique_ptr<pb::ResourceTable> SerializeTableToPb(ResourceTable* table);
+std::unique_ptr<ResourceTable> DeserializeTableFromPb(
     const pb::ResourceTable& pbTable, const Source& source, IDiagnostics* diag);
 
-std::unique_ptr<pb::CompiledFile> serializeCompiledFileToPb(
+std::unique_ptr<pb::CompiledFile> SerializeCompiledFileToPb(
     const ResourceFile& file);
-std::unique_ptr<ResourceFile> deserializeCompiledFileFromPb(
+std::unique_ptr<ResourceFile> DeserializeCompiledFileFromPb(
     const pb::CompiledFile& pbFile, const Source& source, IDiagnostics* diag);
 
 }  // namespace aapt
diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp
index 595fa6f..d93d495 100644
--- a/tools/aapt2/proto/TableProtoDeserializer.cpp
+++ b/tools/aapt2/proto/TableProtoDeserializer.cpp
@@ -14,458 +14,476 @@
  * limitations under the License.
  */
 
+#include "proto/ProtoSerialize.h"
+
+#include "android-base/logging.h"
+#include "androidfw/ResourceTypes.h"
+
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
 #include "ValueVisitor.h"
 #include "proto/ProtoHelpers.h"
-#include "proto/ProtoSerialize.h"
-
-#include <androidfw/ResourceTypes.h>
 
 namespace aapt {
 
 namespace {
 
 class ReferenceIdToNameVisitor : public ValueVisitor {
-public:
-    using ValueVisitor::visit;
+ public:
+  using ValueVisitor::Visit;
 
-    explicit ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceNameRef>* mapping) :
-            mMapping(mapping) {
-        assert(mMapping);
+  explicit ReferenceIdToNameVisitor(
+      const std::map<ResourceId, ResourceNameRef>* mapping)
+      : mapping_(mapping) {
+    CHECK(mapping_ != nullptr);
+  }
+
+  void Visit(Reference* reference) override {
+    if (!reference->id || !reference->id.value().is_valid()) {
+      return;
     }
 
-    void visit(Reference* reference) override {
-        if (!reference->id || !reference->id.value().isValid()) {
-            return;
-        }
-
-        ResourceId id = reference->id.value();
-        auto cacheIter = mMapping->find(id);
-        if (cacheIter != mMapping->end()) {
-            reference->name = cacheIter->second.toResourceName();
-        }
+    ResourceId id = reference->id.value();
+    auto cache_iter = mapping_->find(id);
+    if (cache_iter != mapping_->end()) {
+      reference->name = cache_iter->second.ToResourceName();
     }
+  }
 
-private:
-    const std::map<ResourceId, ResourceNameRef>* mMapping;
+ private:
+  const std::map<ResourceId, ResourceNameRef>* mapping_;
 };
 
 class PackagePbDeserializer {
-public:
-    PackagePbDeserializer(const android::ResStringPool* valuePool,
-                          const android::ResStringPool* sourcePool,
-                          const android::ResStringPool* symbolPool,
-                          const Source& source, IDiagnostics* diag) :
-            mValuePool(valuePool), mSourcePool(sourcePool), mSymbolPool(symbolPool),
-            mSource(source), mDiag(diag) {
+ public:
+  PackagePbDeserializer(const android::ResStringPool* valuePool,
+                        const android::ResStringPool* sourcePool,
+                        const android::ResStringPool* symbolPool,
+                        const Source& source, IDiagnostics* diag)
+      : value_pool_(valuePool),
+        source_pool_(sourcePool),
+        symbol_pool_(symbolPool),
+        source_(source),
+        diag_(diag) {}
+
+ public:
+  bool DeserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) {
+    Maybe<uint8_t> id;
+    if (pbPackage.has_package_id()) {
+      id = static_cast<uint8_t>(pbPackage.package_id());
     }
 
-public:
-    bool deserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) {
-        Maybe<uint8_t> id;
-        if (pbPackage.has_package_id()) {
-            id = static_cast<uint8_t>(pbPackage.package_id());
-        }
+    std::map<ResourceId, ResourceNameRef> idIndex;
 
-        std::map<ResourceId, ResourceNameRef> idIndex;
+    ResourceTablePackage* pkg =
+        table->CreatePackage(pbPackage.package_name(), id);
+    for (const pb::Type& pbType : pbPackage.types()) {
+      const ResourceType* resType = ParseResourceType(pbType.name());
+      if (!resType) {
+        diag_->Error(DiagMessage(source_) << "unknown type '" << pbType.name()
+                                          << "'");
+        return {};
+      }
 
-        ResourceTablePackage* pkg = table->createPackage(pbPackage.package_name(), id);
-        for (const pb::Type& pbType : pbPackage.types()) {
-            const ResourceType* resType = parseResourceType(pbType.name());
-            if (!resType) {
-                mDiag->error(DiagMessage(mSource) << "unknown type '" << pbType.name() << "'");
-                return {};
+      ResourceTableType* type = pkg->FindOrCreateType(*resType);
+
+      for (const pb::Entry& pbEntry : pbType.entries()) {
+        ResourceEntry* entry = type->FindOrCreateEntry(pbEntry.name());
+
+        // Deserialize the symbol status (public/private with source and
+        // comments).
+        if (pbEntry.has_symbol_status()) {
+          const pb::SymbolStatus& pbStatus = pbEntry.symbol_status();
+          if (pbStatus.has_source()) {
+            DeserializeSourceFromPb(pbStatus.source(), *source_pool_,
+                                    &entry->symbol_status.source);
+          }
+
+          if (pbStatus.has_comment()) {
+            entry->symbol_status.comment = pbStatus.comment();
+          }
+
+          SymbolState visibility =
+              DeserializeVisibilityFromPb(pbStatus.visibility());
+          entry->symbol_status.state = visibility;
+
+          if (visibility == SymbolState::kPublic) {
+            // This is a public symbol, we must encode the ID now if there is
+            // one.
+            if (pbEntry.has_id()) {
+              entry->id = static_cast<uint16_t>(pbEntry.id());
             }
 
-            ResourceTableType* type = pkg->findOrCreateType(*resType);
-
-            for (const pb::Entry& pbEntry : pbType.entries()) {
-                ResourceEntry* entry = type->findOrCreateEntry(pbEntry.name());
-
-                // Deserialize the symbol status (public/private with source and comments).
-                if (pbEntry.has_symbol_status()) {
-                    const pb::SymbolStatus& pbStatus = pbEntry.symbol_status();
-                    if (pbStatus.has_source()) {
-                        deserializeSourceFromPb(pbStatus.source(), *mSourcePool,
-                                                &entry->symbolStatus.source);
-                    }
-
-                    if (pbStatus.has_comment()) {
-                        entry->symbolStatus.comment = pbStatus.comment();
-                    }
-
-                    SymbolState visibility = deserializeVisibilityFromPb(pbStatus.visibility());
-                    entry->symbolStatus.state = visibility;
-
-                    if (visibility == SymbolState::kPublic) {
-                        // This is a public symbol, we must encode the ID now if there is one.
-                        if (pbEntry.has_id()) {
-                            entry->id = static_cast<uint16_t>(pbEntry.id());
-                        }
-
-                        if (type->symbolStatus.state != SymbolState::kPublic) {
-                            // If the type has not been made public, do so now.
-                            type->symbolStatus.state = SymbolState::kPublic;
-                            if (pbType.has_id()) {
-                                type->id = static_cast<uint8_t>(pbType.id());
-                            }
-                        }
-                    } else if (visibility == SymbolState::kPrivate) {
-                        if (type->symbolStatus.state == SymbolState::kUndefined) {
-                            type->symbolStatus.state = SymbolState::kPrivate;
-                        }
-                    }
-                }
-
-                ResourceId resId(pbPackage.package_id(), pbType.id(), pbEntry.id());
-                if (resId.isValid()) {
-                    idIndex[resId] = ResourceNameRef(pkg->name, type->type, entry->name);
-                }
-
-                for (const pb::ConfigValue& pbConfigValue : pbEntry.config_values()) {
-                    const pb::ConfigDescription& pbConfig = pbConfigValue.config();
-
-                    ConfigDescription config;
-                    if (!deserializeConfigDescriptionFromPb(pbConfig, &config)) {
-                        mDiag->error(DiagMessage(mSource) << "invalid configuration");
-                        return {};
-                    }
-
-                    ResourceConfigValue* configValue = entry->findOrCreateValue(config,
-                                                                                pbConfig.product());
-                    if (configValue->value) {
-                        // Duplicate config.
-                        mDiag->error(DiagMessage(mSource) << "duplicate configuration");
-                        return {};
-                    }
-
-                    configValue->value = deserializeValueFromPb(pbConfigValue.value(),
-                                                                config, &table->stringPool);
-                    if (!configValue->value) {
-                        return {};
-                    }
-                }
+            if (type->symbol_status.state != SymbolState::kPublic) {
+              // If the type has not been made public, do so now.
+              type->symbol_status.state = SymbolState::kPublic;
+              if (pbType.has_id()) {
+                type->id = static_cast<uint8_t>(pbType.id());
+              }
             }
+          } else if (visibility == SymbolState::kPrivate) {
+            if (type->symbol_status.state == SymbolState::kUndefined) {
+              type->symbol_status.state = SymbolState::kPrivate;
+            }
+          }
         }
 
-        ReferenceIdToNameVisitor visitor(&idIndex);
-        visitAllValuesInPackage(pkg, &visitor);
-        return true;
+        ResourceId resId(pbPackage.package_id(), pbType.id(), pbEntry.id());
+        if (resId.is_valid()) {
+          idIndex[resId] = ResourceNameRef(pkg->name, type->type, entry->name);
+        }
+
+        for (const pb::ConfigValue& pbConfigValue : pbEntry.config_values()) {
+          const pb::ConfigDescription& pbConfig = pbConfigValue.config();
+
+          ConfigDescription config;
+          if (!DeserializeConfigDescriptionFromPb(pbConfig, &config)) {
+            diag_->Error(DiagMessage(source_) << "invalid configuration");
+            return {};
+          }
+
+          ResourceConfigValue* configValue =
+              entry->FindOrCreateValue(config, pbConfig.product());
+          if (configValue->value) {
+            // Duplicate config.
+            diag_->Error(DiagMessage(source_) << "duplicate configuration");
+            return {};
+          }
+
+          configValue->value = DeserializeValueFromPb(
+              pbConfigValue.value(), config, &table->string_pool);
+          if (!configValue->value) {
+            return {};
+          }
+        }
+      }
     }
 
-private:
-    std::unique_ptr<Item> deserializeItemFromPb(const pb::Item& pbItem,
+    ReferenceIdToNameVisitor visitor(&idIndex);
+    VisitAllValuesInPackage(pkg, &visitor);
+    return true;
+  }
+
+ private:
+  std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
+                                              const ConfigDescription& config,
+                                              StringPool* pool) {
+    if (pb_item.has_ref()) {
+      const pb::Reference& pb_ref = pb_item.ref();
+      std::unique_ptr<Reference> ref = util::make_unique<Reference>();
+      if (!DeserializeReferenceFromPb(pb_ref, ref.get())) {
+        return {};
+      }
+      return std::move(ref);
+
+    } else if (pb_item.has_prim()) {
+      const pb::Primitive& pb_prim = pb_item.prim();
+      android::Res_value prim = {};
+      prim.dataType = static_cast<uint8_t>(pb_prim.type());
+      prim.data = pb_prim.data();
+      return util::make_unique<BinaryPrimitive>(prim);
+
+    } else if (pb_item.has_id()) {
+      return util::make_unique<Id>();
+
+    } else if (pb_item.has_str()) {
+      const uint32_t idx = pb_item.str().idx();
+      const std::string str = util::GetString(*value_pool_, idx);
+
+      const android::ResStringPool_span* spans = value_pool_->styleAt(idx);
+      if (spans && spans->name.index != android::ResStringPool_span::END) {
+        StyleString style_str = {str};
+        while (spans->name.index != android::ResStringPool_span::END) {
+          style_str.spans.push_back(
+              Span{util::GetString(*value_pool_, spans->name.index),
+                   spans->firstChar, spans->lastChar});
+          spans++;
+        }
+        return util::make_unique<StyledString>(pool->MakeRef(
+            style_str,
+            StringPool::Context(StringPool::Context::kStylePriority, config)));
+      }
+      return util::make_unique<String>(
+          pool->MakeRef(str, StringPool::Context(config)));
+
+    } else if (pb_item.has_raw_str()) {
+      const uint32_t idx = pb_item.raw_str().idx();
+      const std::string str = util::GetString(*value_pool_, idx);
+      return util::make_unique<RawString>(
+          pool->MakeRef(str, StringPool::Context(config)));
+
+    } else if (pb_item.has_file()) {
+      const uint32_t idx = pb_item.file().path_idx();
+      const std::string str = util::GetString(*value_pool_, idx);
+      return util::make_unique<FileReference>(pool->MakeRef(
+          str,
+          StringPool::Context(StringPool::Context::kHighPriority, config)));
+
+    } else {
+      diag_->Error(DiagMessage(source_) << "unknown item");
+    }
+    return {};
+  }
+
+  std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
                                                 const ConfigDescription& config,
                                                 StringPool* pool) {
-        if (pbItem.has_ref()) {
-            const pb::Reference& pbRef = pbItem.ref();
-            std::unique_ptr<Reference> ref = util::make_unique<Reference>();
-            if (!deserializeReferenceFromPb(pbRef, ref.get())) {
-                return {};
-            }
-            return std::move(ref);
+    const bool is_weak = pb_value.has_weak() ? pb_value.weak() : false;
 
-        } else if (pbItem.has_prim()) {
-            const pb::Primitive& pbPrim = pbItem.prim();
-            android::Res_value prim = {};
-            prim.dataType = static_cast<uint8_t>(pbPrim.type());
-            prim.data = pbPrim.data();
-            return util::make_unique<BinaryPrimitive>(prim);
-
-        } else if (pbItem.has_id()) {
-            return util::make_unique<Id>();
-
-        } else if (pbItem.has_str()) {
-            const uint32_t idx = pbItem.str().idx();
-            const std::string str = util::getString(*mValuePool, idx);
-
-            const android::ResStringPool_span* spans = mValuePool->styleAt(idx);
-            if (spans && spans->name.index != android::ResStringPool_span::END) {
-                StyleString styleStr = { str };
-                while (spans->name.index != android::ResStringPool_span::END) {
-                    styleStr.spans.push_back(Span{
-                            util::getString(*mValuePool, spans->name.index),
-                            spans->firstChar,
-                            spans->lastChar
-                    });
-                    spans++;
-                }
-                return util::make_unique<StyledString>(
-                        pool->makeRef(styleStr, StringPool::Context{ 1, config }));
-            }
-            return util::make_unique<String>(
-                    pool->makeRef(str, StringPool::Context{ 1, config }));
-
-        } else if (pbItem.has_raw_str()) {
-            const uint32_t idx = pbItem.raw_str().idx();
-            const std::string str = util::getString(*mValuePool, idx);
-            return util::make_unique<RawString>(
-                    pool->makeRef(str, StringPool::Context{ 1, config }));
-
-        } else if (pbItem.has_file()) {
-            const uint32_t idx = pbItem.file().path_idx();
-            const std::string str = util::getString(*mValuePool, idx);
-            return util::make_unique<FileReference>(
-                    pool->makeRef(str, StringPool::Context{ 0, config }));
-
-        } else {
-            mDiag->error(DiagMessage(mSource) << "unknown item");
-        }
+    std::unique_ptr<Value> value;
+    if (pb_value.has_item()) {
+      value = DeserializeItemFromPb(pb_value.item(), config, pool);
+      if (!value) {
         return {};
-    }
+      }
 
-    std::unique_ptr<Value> deserializeValueFromPb(const pb::Value& pbValue,
-                                                  const ConfigDescription& config,
-                                                  StringPool* pool) {
-        const bool isWeak = pbValue.has_weak() ? pbValue.weak() : false;
-
-        std::unique_ptr<Value> value;
-        if (pbValue.has_item()) {
-            value = deserializeItemFromPb(pbValue.item(), config, pool);
-            if (!value) {
-                return {};
-            }
-
-        } else if (pbValue.has_compound_value()) {
-            const pb::CompoundValue& pbCompoundValue = pbValue.compound_value();
-            if (pbCompoundValue.has_attr()) {
-                const pb::Attribute& pbAttr = pbCompoundValue.attr();
-                std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(isWeak);
-                attr->typeMask = pbAttr.format_flags();
-                attr->minInt = pbAttr.min_int();
-                attr->maxInt = pbAttr.max_int();
-                for (const pb::Attribute_Symbol& pbSymbol : pbAttr.symbols()) {
-                    Attribute::Symbol symbol;
-                    deserializeItemCommon(pbSymbol, &symbol.symbol);
-                    if (!deserializeReferenceFromPb(pbSymbol.name(), &symbol.symbol)) {
-                        return {};
-                    }
-                    symbol.value = pbSymbol.value();
-                    attr->symbols.push_back(std::move(symbol));
-                }
-                value = std::move(attr);
-
-            } else if (pbCompoundValue.has_style()) {
-                const pb::Style& pbStyle = pbCompoundValue.style();
-                std::unique_ptr<Style> style = util::make_unique<Style>();
-                if (pbStyle.has_parent()) {
-                    style->parent = Reference();
-                    if (!deserializeReferenceFromPb(pbStyle.parent(), &style->parent.value())) {
-                        return {};
-                    }
-
-                    if (pbStyle.has_parent_source()) {
-                        Source parentSource;
-                        deserializeSourceFromPb(pbStyle.parent_source(), *mSourcePool,
-                                                &parentSource);
-                        style->parent.value().setSource(std::move(parentSource));
-                    }
-                }
-
-                for (const pb::Style_Entry& pbEntry : pbStyle.entries()) {
-                    Style::Entry entry;
-                    deserializeItemCommon(pbEntry, &entry.key);
-                    if (!deserializeReferenceFromPb(pbEntry.key(), &entry.key)) {
-                        return {};
-                    }
-
-                    entry.value = deserializeItemFromPb(pbEntry.item(), config, pool);
-                    if (!entry.value) {
-                        return {};
-                    }
-
-                    deserializeItemCommon(pbEntry, entry.value.get());
-                    style->entries.push_back(std::move(entry));
-                }
-                value = std::move(style);
-
-            } else if (pbCompoundValue.has_styleable()) {
-                const pb::Styleable& pbStyleable = pbCompoundValue.styleable();
-                std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
-                for (const pb::Styleable_Entry& pbEntry : pbStyleable.entries()) {
-                    Reference attrRef;
-                    deserializeItemCommon(pbEntry, &attrRef);
-                    deserializeReferenceFromPb(pbEntry.attr(), &attrRef);
-                    styleable->entries.push_back(std::move(attrRef));
-                }
-                value = std::move(styleable);
-
-            } else if (pbCompoundValue.has_array()) {
-                const pb::Array& pbArray = pbCompoundValue.array();
-                std::unique_ptr<Array> array = util::make_unique<Array>();
-                for (const pb::Array_Entry& pbEntry : pbArray.entries()) {
-                    std::unique_ptr<Item> item = deserializeItemFromPb(pbEntry.item(), config,
-                                                                       pool);
-                    if (!item) {
-                        return {};
-                    }
-
-                    deserializeItemCommon(pbEntry, item.get());
-                    array->items.push_back(std::move(item));
-                }
-                value = std::move(array);
-
-            } else if (pbCompoundValue.has_plural()) {
-                const pb::Plural& pbPlural = pbCompoundValue.plural();
-                std::unique_ptr<Plural> plural = util::make_unique<Plural>();
-                for (const pb::Plural_Entry& pbEntry : pbPlural.entries()) {
-                    size_t pluralIdx = deserializePluralEnumFromPb(pbEntry.arity());
-                    plural->values[pluralIdx] = deserializeItemFromPb(pbEntry.item(), config,
-                                                                      pool);
-                    if (!plural->values[pluralIdx]) {
-                        return {};
-                    }
-
-                    deserializeItemCommon(pbEntry, plural->values[pluralIdx].get());
-                }
-                value = std::move(plural);
-
-            } else {
-                mDiag->error(DiagMessage(mSource) << "unknown compound value");
-                return {};
-            }
-        } else {
-            mDiag->error(DiagMessage(mSource) << "unknown value");
+    } else if (pb_value.has_compound_value()) {
+      const pb::CompoundValue& pb_compound_value = pb_value.compound_value();
+      if (pb_compound_value.has_attr()) {
+        const pb::Attribute& pb_attr = pb_compound_value.attr();
+        std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(is_weak);
+        attr->type_mask = pb_attr.format_flags();
+        attr->min_int = pb_attr.min_int();
+        attr->max_int = pb_attr.max_int();
+        for (const pb::Attribute_Symbol& pb_symbol : pb_attr.symbols()) {
+          Attribute::Symbol symbol;
+          DeserializeItemCommon(pb_symbol, &symbol.symbol);
+          if (!DeserializeReferenceFromPb(pb_symbol.name(), &symbol.symbol)) {
             return {};
+          }
+          symbol.value = pb_symbol.value();
+          attr->symbols.push_back(std::move(symbol));
+        }
+        value = std::move(attr);
+
+      } else if (pb_compound_value.has_style()) {
+        const pb::Style& pb_style = pb_compound_value.style();
+        std::unique_ptr<Style> style = util::make_unique<Style>();
+        if (pb_style.has_parent()) {
+          style->parent = Reference();
+          if (!DeserializeReferenceFromPb(pb_style.parent(),
+                                          &style->parent.value())) {
+            return {};
+          }
+
+          if (pb_style.has_parent_source()) {
+            Source parent_source;
+            DeserializeSourceFromPb(pb_style.parent_source(), *source_pool_,
+                                    &parent_source);
+            style->parent.value().SetSource(std::move(parent_source));
+          }
         }
 
-        assert(value && "forgot to set value");
+        for (const pb::Style_Entry& pb_entry : pb_style.entries()) {
+          Style::Entry entry;
+          DeserializeItemCommon(pb_entry, &entry.key);
+          if (!DeserializeReferenceFromPb(pb_entry.key(), &entry.key)) {
+            return {};
+          }
 
-        value->setWeak(isWeak);
-        deserializeItemCommon(pbValue, value.get());
-        return value;
+          entry.value = DeserializeItemFromPb(pb_entry.item(), config, pool);
+          if (!entry.value) {
+            return {};
+          }
+
+          DeserializeItemCommon(pb_entry, entry.value.get());
+          style->entries.push_back(std::move(entry));
+        }
+        value = std::move(style);
+
+      } else if (pb_compound_value.has_styleable()) {
+        const pb::Styleable& pb_styleable = pb_compound_value.styleable();
+        std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
+        for (const pb::Styleable_Entry& pb_entry : pb_styleable.entries()) {
+          Reference attr_ref;
+          DeserializeItemCommon(pb_entry, &attr_ref);
+          DeserializeReferenceFromPb(pb_entry.attr(), &attr_ref);
+          styleable->entries.push_back(std::move(attr_ref));
+        }
+        value = std::move(styleable);
+
+      } else if (pb_compound_value.has_array()) {
+        const pb::Array& pb_array = pb_compound_value.array();
+        std::unique_ptr<Array> array = util::make_unique<Array>();
+        for (const pb::Array_Entry& pb_entry : pb_array.entries()) {
+          std::unique_ptr<Item> item =
+              DeserializeItemFromPb(pb_entry.item(), config, pool);
+          if (!item) {
+            return {};
+          }
+
+          DeserializeItemCommon(pb_entry, item.get());
+          array->items.push_back(std::move(item));
+        }
+        value = std::move(array);
+
+      } else if (pb_compound_value.has_plural()) {
+        const pb::Plural& pb_plural = pb_compound_value.plural();
+        std::unique_ptr<Plural> plural = util::make_unique<Plural>();
+        for (const pb::Plural_Entry& pb_entry : pb_plural.entries()) {
+          size_t pluralIdx = DeserializePluralEnumFromPb(pb_entry.arity());
+          plural->values[pluralIdx] =
+              DeserializeItemFromPb(pb_entry.item(), config, pool);
+          if (!plural->values[pluralIdx]) {
+            return {};
+          }
+
+          DeserializeItemCommon(pb_entry, plural->values[pluralIdx].get());
+        }
+        value = std::move(plural);
+
+      } else {
+        diag_->Error(DiagMessage(source_) << "unknown compound value");
+        return {};
+      }
+    } else {
+      diag_->Error(DiagMessage(source_) << "unknown value");
+      return {};
     }
 
-    bool deserializeReferenceFromPb(const pb::Reference& pbRef, Reference* outRef) {
-        outRef->referenceType = deserializeReferenceTypeFromPb(pbRef.type());
-        outRef->privateReference = pbRef.private_();
+    CHECK(value) << "forgot to set value";
 
-        if (!pbRef.has_id() && !pbRef.has_symbol_idx()) {
-            return false;
-        }
+    value->SetWeak(is_weak);
+    DeserializeItemCommon(pb_value, value.get());
+    return value;
+  }
 
-        if (pbRef.has_id()) {
-            outRef->id = ResourceId(pbRef.id());
-        }
+  bool DeserializeReferenceFromPb(const pb::Reference& pb_ref,
+                                  Reference* out_ref) {
+    out_ref->reference_type = DeserializeReferenceTypeFromPb(pb_ref.type());
+    out_ref->private_reference = pb_ref.private_();
 
-        if (pbRef.has_symbol_idx()) {
-            const std::string strSymbol = util::getString(*mSymbolPool, pbRef.symbol_idx());
-            ResourceNameRef nameRef;
-            if (!ResourceUtils::parseResourceName(strSymbol, &nameRef, nullptr)) {
-                mDiag->error(DiagMessage(mSource) << "invalid reference name '"
-                             << strSymbol << "'");
-                return false;
-            }
-
-            outRef->name = nameRef.toResourceName();
-        }
-        return true;
+    if (!pb_ref.has_id() && !pb_ref.has_symbol_idx()) {
+      return false;
     }
 
-    template <typename T>
-    void deserializeItemCommon(const T& pbItem, Value* outValue) {
-        if (pbItem.has_source()) {
-            Source source;
-            deserializeSourceFromPb(pbItem.source(), *mSourcePool, &source);
-            outValue->setSource(std::move(source));
-        }
-
-        if (pbItem.has_comment()) {
-            outValue->setComment(pbItem.comment());
-        }
+    if (pb_ref.has_id()) {
+      out_ref->id = ResourceId(pb_ref.id());
     }
 
-private:
-    const android::ResStringPool* mValuePool;
-    const android::ResStringPool* mSourcePool;
-    const android::ResStringPool* mSymbolPool;
-    const Source mSource;
-    IDiagnostics* mDiag;
+    if (pb_ref.has_symbol_idx()) {
+      const std::string str_symbol =
+          util::GetString(*symbol_pool_, pb_ref.symbol_idx());
+      ResourceNameRef name_ref;
+      if (!ResourceUtils::ParseResourceName(str_symbol, &name_ref, nullptr)) {
+        diag_->Error(DiagMessage(source_) << "invalid reference name '"
+                                          << str_symbol << "'");
+        return false;
+      }
+
+      out_ref->name = name_ref.ToResourceName();
+    }
+    return true;
+  }
+
+  template <typename T>
+  void DeserializeItemCommon(const T& pb_item, Value* out_value) {
+    if (pb_item.has_source()) {
+      Source source;
+      DeserializeSourceFromPb(pb_item.source(), *source_pool_, &source);
+      out_value->SetSource(std::move(source));
+    }
+
+    if (pb_item.has_comment()) {
+      out_value->SetComment(pb_item.comment());
+    }
+  }
+
+ private:
+  const android::ResStringPool* value_pool_;
+  const android::ResStringPool* source_pool_;
+  const android::ResStringPool* symbol_pool_;
+  const Source source_;
+  IDiagnostics* diag_;
 };
 
-} // namespace
+}  // namespace
 
-std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& pbTable,
-                                                      const Source& source,
-                                                      IDiagnostics* diag) {
-    // We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which
-    // causes errors when qualifying it with android::
-    using namespace android;
+std::unique_ptr<ResourceTable> DeserializeTableFromPb(
+    const pb::ResourceTable& pb_table, const Source& source,
+    IDiagnostics* diag) {
+  // We import the android namespace because on Windows NO_ERROR is a macro, not
+  // an enum, which
+  // causes errors when qualifying it with android::
+  using namespace android;
 
-    std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
+  std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
 
-    if (!pbTable.has_string_pool()) {
-        diag->error(DiagMessage(source) << "no string pool found");
-        return {};
-    }
+  if (!pb_table.has_string_pool()) {
+    diag->Error(DiagMessage(source) << "no string pool found");
+    return {};
+  }
 
-    ResStringPool valuePool;
-    status_t result = valuePool.setTo(pbTable.string_pool().data().data(),
-                                      pbTable.string_pool().data().size());
+  ResStringPool value_pool;
+  status_t result = value_pool.setTo(pb_table.string_pool().data().data(),
+                                     pb_table.string_pool().data().size());
+  if (result != NO_ERROR) {
+    diag->Error(DiagMessage(source) << "invalid string pool");
+    return {};
+  }
+
+  ResStringPool source_pool;
+  if (pb_table.has_source_pool()) {
+    result = source_pool.setTo(pb_table.source_pool().data().data(),
+                               pb_table.source_pool().data().size());
     if (result != NO_ERROR) {
-        diag->error(DiagMessage(source) << "invalid string pool");
-        return {};
+      diag->Error(DiagMessage(source) << "invalid source pool");
+      return {};
     }
+  }
 
-    ResStringPool sourcePool;
-    if (pbTable.has_source_pool()) {
-        result = sourcePool.setTo(pbTable.source_pool().data().data(),
-                                  pbTable.source_pool().data().size());
-        if (result != NO_ERROR) {
-            diag->error(DiagMessage(source) << "invalid source pool");
-            return {};
-        }
+  ResStringPool symbol_pool;
+  if (pb_table.has_symbol_pool()) {
+    result = symbol_pool.setTo(pb_table.symbol_pool().data().data(),
+                               pb_table.symbol_pool().data().size());
+    if (result != NO_ERROR) {
+      diag->Error(DiagMessage(source) << "invalid symbol pool");
+      return {};
     }
+  }
 
-    ResStringPool symbolPool;
-    if (pbTable.has_symbol_pool()) {
-        result = symbolPool.setTo(pbTable.symbol_pool().data().data(),
-                                  pbTable.symbol_pool().data().size());
-        if (result != NO_ERROR) {
-            diag->error(DiagMessage(source) << "invalid symbol pool");
-            return {};
-        }
+  PackagePbDeserializer package_pb_deserializer(&value_pool, &source_pool,
+                                                &symbol_pool, source, diag);
+  for (const pb::Package& pb_package : pb_table.packages()) {
+    if (!package_pb_deserializer.DeserializeFromPb(pb_package, table.get())) {
+      return {};
     }
-
-    PackagePbDeserializer packagePbDeserializer(&valuePool, &sourcePool, &symbolPool, source, diag);
-    for (const pb::Package& pbPackage : pbTable.packages()) {
-        if (!packagePbDeserializer.deserializeFromPb(pbPackage, table.get())) {
-            return {};
-        }
-    }
-    return table;
+  }
+  return table;
 }
 
-std::unique_ptr<ResourceFile> deserializeCompiledFileFromPb(const pb::CompiledFile& pbFile,
-                                                            const Source& source,
-                                                            IDiagnostics* diag) {
-    std::unique_ptr<ResourceFile> file = util::make_unique<ResourceFile>();
+std::unique_ptr<ResourceFile> DeserializeCompiledFileFromPb(
+    const pb::CompiledFile& pb_file, const Source& source, IDiagnostics* diag) {
+  std::unique_ptr<ResourceFile> file = util::make_unique<ResourceFile>();
 
-    ResourceNameRef nameRef;
+  ResourceNameRef name_ref;
 
-    // Need to create an lvalue here so that nameRef can point to something real.
-    if (!ResourceUtils::parseResourceName(pbFile.resource_name(), &nameRef)) {
-        diag->error(DiagMessage(source) << "invalid resource name in compiled file header: "
-                    << pbFile.resource_name());
-        return {};
+  // Need to create an lvalue here so that nameRef can point to something real.
+  if (!ResourceUtils::ParseResourceName(pb_file.resource_name(), &name_ref)) {
+    diag->Error(DiagMessage(source)
+                << "invalid resource name in compiled file header: "
+                << pb_file.resource_name());
+    return {};
+  }
+  file->name = name_ref.ToResourceName();
+  file->source.path = pb_file.source_path();
+  DeserializeConfigDescriptionFromPb(pb_file.config(), &file->config);
+
+  for (const pb::CompiledFile_Symbol& pb_symbol : pb_file.exported_symbols()) {
+    // Need to create an lvalue here so that nameRef can point to something
+    // real.
+    if (!ResourceUtils::ParseResourceName(pb_symbol.resource_name(),
+                                          &name_ref)) {
+      diag->Error(DiagMessage(source)
+                  << "invalid resource name for exported symbol in "
+                     "compiled file header: "
+                  << pb_file.resource_name());
+      return {};
     }
-    file->name = nameRef.toResourceName();
-    file->source.path = pbFile.source_path();
-    deserializeConfigDescriptionFromPb(pbFile.config(), &file->config);
-
-    for (const pb::CompiledFile_Symbol& pbSymbol : pbFile.exported_symbols()) {
-        // Need to create an lvalue here so that nameRef can point to something real.
-        if (!ResourceUtils::parseResourceName(pbSymbol.resource_name(), &nameRef)) {
-            diag->error(DiagMessage(source) << "invalid resource name for exported symbol in "
-                                               "compiled file header: "
-                                            << pbFile.resource_name());
-            return {};
-        }
-        file->exportedSymbols.push_back(
-                SourcedResourceName{ nameRef.toResourceName(), pbSymbol.line_no() });
-    }
-    return file;
+    file->exported_symbols.push_back(
+        SourcedResourceName{name_ref.ToResourceName(), pb_symbol.line_no()});
+  }
+  return file;
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/proto/TableProtoSerializer.cpp b/tools/aapt2/proto/TableProtoSerializer.cpp
index a5c2cbc..68db6b3 100644
--- a/tools/aapt2/proto/TableProtoSerializer.cpp
+++ b/tools/aapt2/proto/TableProtoSerializer.cpp
@@ -22,6 +22,8 @@
 #include "proto/ProtoSerialize.h"
 #include "util/BigBuffer.h"
 
+#include <android-base/logging.h>
+
 using google::protobuf::io::CodedOutputStream;
 using google::protobuf::io::CodedInputStream;
 using google::protobuf::io::ZeroCopyOutputStream;
@@ -31,179 +33,185 @@
 namespace {
 
 class PbSerializerVisitor : public RawValueVisitor {
-public:
-    using RawValueVisitor::visit;
+ public:
+  using RawValueVisitor::Visit;
 
-    /**
-     * Constructor to use when expecting to serialize any value.
-     */
-    PbSerializerVisitor(StringPool* sourcePool, StringPool* symbolPool, pb::Value* outPbValue) :
-            mSourcePool(sourcePool), mSymbolPool(symbolPool), mOutPbValue(outPbValue),
-            mOutPbItem(nullptr) {
+  /**
+   * Constructor to use when expecting to serialize any value.
+   */
+  PbSerializerVisitor(StringPool* source_pool, StringPool* symbol_pool,
+                      pb::Value* out_pb_value)
+      : source_pool_(source_pool),
+        symbol_pool_(symbol_pool),
+        out_pb_value_(out_pb_value),
+        out_pb_item_(nullptr) {}
+
+  /**
+   * Constructor to use when expecting to serialize an Item.
+   */
+  PbSerializerVisitor(StringPool* sourcePool, StringPool* symbolPool,
+                      pb::Item* outPbItem)
+      : source_pool_(sourcePool),
+        symbol_pool_(symbolPool),
+        out_pb_value_(nullptr),
+        out_pb_item_(outPbItem) {}
+
+  void Visit(Reference* ref) override {
+    SerializeReferenceToPb(*ref, pb_item()->mutable_ref());
+  }
+
+  void Visit(String* str) override {
+    pb_item()->mutable_str()->set_idx(str->value.index());
+  }
+
+  void Visit(StyledString* str) override {
+    pb_item()->mutable_str()->set_idx(str->value.index());
+  }
+
+  void Visit(FileReference* file) override {
+    pb_item()->mutable_file()->set_path_idx(file->path.index());
+  }
+
+  void Visit(Id* id) override { pb_item()->mutable_id(); }
+
+  void Visit(RawString* raw_str) override {
+    pb_item()->mutable_raw_str()->set_idx(raw_str->value.index());
+  }
+
+  void Visit(BinaryPrimitive* prim) override {
+    android::Res_value val = {};
+    prim->Flatten(&val);
+
+    pb::Primitive* pb_prim = pb_item()->mutable_prim();
+    pb_prim->set_type(val.dataType);
+    pb_prim->set_data(val.data);
+  }
+
+  void VisitItem(Item* item) override { LOG(FATAL) << "unimplemented item"; }
+
+  void Visit(Attribute* attr) override {
+    pb::Attribute* pb_attr = pb_compound_value()->mutable_attr();
+    pb_attr->set_format_flags(attr->type_mask);
+    pb_attr->set_min_int(attr->min_int);
+    pb_attr->set_max_int(attr->max_int);
+
+    for (auto& symbol : attr->symbols) {
+      pb::Attribute_Symbol* pb_symbol = pb_attr->add_symbols();
+      SerializeItemCommonToPb(symbol.symbol, pb_symbol);
+      SerializeReferenceToPb(symbol.symbol, pb_symbol->mutable_name());
+      pb_symbol->set_value(symbol.value);
+    }
+  }
+
+  void Visit(Style* style) override {
+    pb::Style* pb_style = pb_compound_value()->mutable_style();
+    if (style->parent) {
+      SerializeReferenceToPb(style->parent.value(), pb_style->mutable_parent());
+      SerializeSourceToPb(style->parent.value().GetSource(), source_pool_,
+                          pb_style->mutable_parent_source());
     }
 
-    /**
-     * Constructor to use when expecting to serialize an Item.
-     */
-    PbSerializerVisitor(StringPool* sourcePool, StringPool* symbolPool, pb::Item* outPbItem) :
-            mSourcePool(sourcePool), mSymbolPool(symbolPool), mOutPbValue(nullptr),
-            mOutPbItem(outPbItem) {
+    for (Style::Entry& entry : style->entries) {
+      pb::Style_Entry* pb_entry = pb_style->add_entries();
+      SerializeReferenceToPb(entry.key, pb_entry->mutable_key());
+
+      pb::Item* pb_item = pb_entry->mutable_item();
+      SerializeItemCommonToPb(entry.key, pb_entry);
+      PbSerializerVisitor sub_visitor(source_pool_, symbol_pool_, pb_item);
+      entry.value->Accept(&sub_visitor);
+    }
+  }
+
+  void Visit(Styleable* styleable) override {
+    pb::Styleable* pb_styleable = pb_compound_value()->mutable_styleable();
+    for (Reference& entry : styleable->entries) {
+      pb::Styleable_Entry* pb_entry = pb_styleable->add_entries();
+      SerializeItemCommonToPb(entry, pb_entry);
+      SerializeReferenceToPb(entry, pb_entry->mutable_attr());
+    }
+  }
+
+  void Visit(Array* array) override {
+    pb::Array* pb_array = pb_compound_value()->mutable_array();
+    for (auto& value : array->items) {
+      pb::Array_Entry* pb_entry = pb_array->add_entries();
+      SerializeItemCommonToPb(*value, pb_entry);
+      PbSerializerVisitor sub_visitor(source_pool_, symbol_pool_,
+                                      pb_entry->mutable_item());
+      value->Accept(&sub_visitor);
+    }
+  }
+
+  void Visit(Plural* plural) override {
+    pb::Plural* pb_plural = pb_compound_value()->mutable_plural();
+    const size_t count = plural->values.size();
+    for (size_t i = 0; i < count; i++) {
+      if (!plural->values[i]) {
+        // No plural value set here.
+        continue;
+      }
+
+      pb::Plural_Entry* pb_entry = pb_plural->add_entries();
+      pb_entry->set_arity(SerializePluralEnumToPb(i));
+      pb::Item* pb_element = pb_entry->mutable_item();
+      SerializeItemCommonToPb(*plural->values[i], pb_entry);
+      PbSerializerVisitor sub_visitor(source_pool_, symbol_pool_, pb_element);
+      plural->values[i]->Accept(&sub_visitor);
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PbSerializerVisitor);
+
+  pb::Item* pb_item() {
+    if (out_pb_value_) {
+      return out_pb_value_->mutable_item();
+    }
+    return out_pb_item_;
+  }
+
+  pb::CompoundValue* pb_compound_value() {
+    CHECK(out_pb_value_ != nullptr);
+    return out_pb_value_->mutable_compound_value();
+  }
+
+  template <typename T>
+  void SerializeItemCommonToPb(const Item& item, T* pb_item) {
+    SerializeSourceToPb(item.GetSource(), source_pool_,
+                        pb_item->mutable_source());
+    if (!item.GetComment().empty()) {
+      pb_item->set_comment(item.GetComment());
+    }
+  }
+
+  void SerializeReferenceToPb(const Reference& ref, pb::Reference* pb_ref) {
+    if (ref.id) {
+      pb_ref->set_id(ref.id.value().id);
     }
 
-    void visit(Reference* ref) override {
-        serializeReferenceToPb(*ref, getPbItem()->mutable_ref());
+    if (ref.name) {
+      StringPool::Ref symbol_ref =
+          symbol_pool_->MakeRef(ref.name.value().ToString());
+      pb_ref->set_symbol_idx(static_cast<uint32_t>(symbol_ref.index()));
     }
 
-    void visit(String* str) override {
-        getPbItem()->mutable_str()->set_idx(str->value.getIndex());
-    }
+    pb_ref->set_private_(ref.private_reference);
+    pb_ref->set_type(SerializeReferenceTypeToPb(ref.reference_type));
+  }
 
-    void visit(StyledString* str) override {
-        getPbItem()->mutable_str()->set_idx(str->value.getIndex());
-    }
-
-    void visit(FileReference* file) override {
-        getPbItem()->mutable_file()->set_path_idx(file->path.getIndex());
-    }
-
-    void visit(Id* id) override {
-        getPbItem()->mutable_id();
-    }
-
-    void visit(RawString* rawStr) override {
-        getPbItem()->mutable_raw_str()->set_idx(rawStr->value.getIndex());
-    }
-
-    void visit(BinaryPrimitive* prim) override {
-        android::Res_value val = {};
-        prim->flatten(&val);
-
-        pb::Primitive* pbPrim = getPbItem()->mutable_prim();
-        pbPrim->set_type(val.dataType);
-        pbPrim->set_data(val.data);
-    }
-
-    void visitItem(Item* item) override {
-        assert(false && "unimplemented item");
-    }
-
-    void visit(Attribute* attr) override {
-        pb::Attribute* pbAttr = getPbCompoundValue()->mutable_attr();
-        pbAttr->set_format_flags(attr->typeMask);
-        pbAttr->set_min_int(attr->minInt);
-        pbAttr->set_max_int(attr->maxInt);
-
-        for (auto& symbol : attr->symbols) {
-            pb::Attribute_Symbol* pbSymbol = pbAttr->add_symbols();
-            serializeItemCommonToPb(symbol.symbol, pbSymbol);
-            serializeReferenceToPb(symbol.symbol, pbSymbol->mutable_name());
-            pbSymbol->set_value(symbol.value);
-        }
-    }
-
-    void visit(Style* style) override {
-        pb::Style* pbStyle = getPbCompoundValue()->mutable_style();
-        if (style->parent) {
-            serializeReferenceToPb(style->parent.value(), pbStyle->mutable_parent());
-            serializeSourceToPb(style->parent.value().getSource(),
-                                mSourcePool,
-                                pbStyle->mutable_parent_source());
-        }
-
-        for (Style::Entry& entry : style->entries) {
-            pb::Style_Entry* pbEntry = pbStyle->add_entries();
-            serializeReferenceToPb(entry.key, pbEntry->mutable_key());
-
-            pb::Item* pbItem = pbEntry->mutable_item();
-            serializeItemCommonToPb(entry.key, pbEntry);
-            PbSerializerVisitor subVisitor(mSourcePool, mSymbolPool, pbItem);
-            entry.value->accept(&subVisitor);
-        }
-    }
-
-    void visit(Styleable* styleable) override {
-        pb::Styleable* pbStyleable = getPbCompoundValue()->mutable_styleable();
-        for (Reference& entry : styleable->entries) {
-            pb::Styleable_Entry* pbEntry = pbStyleable->add_entries();
-            serializeItemCommonToPb(entry, pbEntry);
-            serializeReferenceToPb(entry, pbEntry->mutable_attr());
-        }
-    }
-
-    void visit(Array* array) override {
-        pb::Array* pbArray = getPbCompoundValue()->mutable_array();
-        for (auto& value : array->items) {
-            pb::Array_Entry* pbEntry = pbArray->add_entries();
-            serializeItemCommonToPb(*value, pbEntry);
-            PbSerializerVisitor subVisitor(mSourcePool, mSymbolPool, pbEntry->mutable_item());
-            value->accept(&subVisitor);
-        }
-    }
-
-    void visit(Plural* plural) override {
-        pb::Plural* pbPlural = getPbCompoundValue()->mutable_plural();
-        const size_t count = plural->values.size();
-        for (size_t i = 0; i < count; i++) {
-            if (!plural->values[i]) {
-                // No plural value set here.
-                continue;
-            }
-
-            pb::Plural_Entry* pbEntry = pbPlural->add_entries();
-            pbEntry->set_arity(serializePluralEnumToPb(i));
-            pb::Item* pbElement = pbEntry->mutable_item();
-            serializeItemCommonToPb(*plural->values[i], pbEntry);
-            PbSerializerVisitor subVisitor(mSourcePool, mSymbolPool, pbElement);
-            plural->values[i]->accept(&subVisitor);
-        }
-    }
-
-private:
-    pb::Item* getPbItem() {
-        if (mOutPbValue) {
-            return mOutPbValue->mutable_item();
-        }
-        return mOutPbItem;
-    }
-
-    pb::CompoundValue* getPbCompoundValue() {
-        assert(mOutPbValue);
-        return mOutPbValue->mutable_compound_value();
-    }
-
-    template <typename T>
-    void serializeItemCommonToPb(const Item& item, T* pbItem) {
-        serializeSourceToPb(item.getSource(), mSourcePool, pbItem->mutable_source());
-        if (!item.getComment().empty()) {
-            pbItem->set_comment(item.getComment());
-        }
-    }
-
-    void serializeReferenceToPb(const Reference& ref, pb::Reference* pbRef) {
-        if (ref.id) {
-            pbRef->set_id(ref.id.value().id);
-        }
-
-        if (ref.name) {
-            StringPool::Ref symbolRef = mSymbolPool->makeRef(ref.name.value().toString());
-            pbRef->set_symbol_idx(static_cast<uint32_t>(symbolRef.getIndex()));
-        }
-
-        pbRef->set_private_(ref.privateReference);
-        pbRef->set_type(serializeReferenceTypeToPb(ref.referenceType));
-    }
-
-    StringPool* mSourcePool;
-    StringPool* mSymbolPool;
-    pb::Value* mOutPbValue;
-    pb::Item* mOutPbItem;
+  StringPool* source_pool_;
+  StringPool* symbol_pool_;
+  pb::Value* out_pb_value_;
+  pb::Item* out_pb_item_;
 };
 
-} // namespace
+}  // namespace
 
-std::unique_ptr<pb::ResourceTable> serializeTableToPb(ResourceTable* table) {
-    // We must do this before writing the resources, since the string pool IDs may change.
-    table->stringPool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
+std::unique_ptr<pb::ResourceTable> SerializeTableToPb(ResourceTable* table) {
+  // We must do this before writing the resources, since the string pool IDs may
+  // change.
+  table->string_pool.Sort(
+      [](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
         int diff = a.context.priority - b.context.priority;
         if (diff < 0) return true;
         if (diff > 0) return false;
@@ -211,192 +219,195 @@
         if (diff < 0) return true;
         if (diff > 0) return false;
         return a.value < b.value;
-    });
-    table->stringPool.prune();
+      });
+  table->string_pool.Prune();
 
-    auto pbTable = util::make_unique<pb::ResourceTable>();
-    serializeStringPoolToPb(table->stringPool, pbTable->mutable_string_pool());
+  auto pb_table = util::make_unique<pb::ResourceTable>();
+  SerializeStringPoolToPb(table->string_pool, pb_table->mutable_string_pool());
 
-    StringPool sourcePool, symbolPool;
+  StringPool source_pool, symbol_pool;
 
-    for (auto& package : table->packages) {
-        pb::Package* pbPackage = pbTable->add_packages();
-        if (package->id) {
-            pbPackage->set_package_id(package->id.value());
+  for (auto& package : table->packages) {
+    pb::Package* pb_package = pb_table->add_packages();
+    if (package->id) {
+      pb_package->set_package_id(package->id.value());
+    }
+    pb_package->set_package_name(package->name);
+
+    for (auto& type : package->types) {
+      pb::Type* pb_type = pb_package->add_types();
+      if (type->id) {
+        pb_type->set_id(type->id.value());
+      }
+      pb_type->set_name(ToString(type->type).ToString());
+
+      for (auto& entry : type->entries) {
+        pb::Entry* pb_entry = pb_type->add_entries();
+        if (entry->id) {
+          pb_entry->set_id(entry->id.value());
         }
-        pbPackage->set_package_name(package->name);
+        pb_entry->set_name(entry->name);
 
-        for (auto& type : package->types) {
-            pb::Type* pbType = pbPackage->add_types();
-            if (type->id) {
-                pbType->set_id(type->id.value());
-            }
-            pbType->set_name(toString(type->type).toString());
+        // Write the SymbolStatus struct.
+        pb::SymbolStatus* pb_status = pb_entry->mutable_symbol_status();
+        pb_status->set_visibility(
+            SerializeVisibilityToPb(entry->symbol_status.state));
+        SerializeSourceToPb(entry->symbol_status.source, &source_pool,
+                            pb_status->mutable_source());
+        pb_status->set_comment(entry->symbol_status.comment);
 
-            for (auto& entry : type->entries) {
-                pb::Entry* pbEntry = pbType->add_entries();
-                if (entry->id) {
-                    pbEntry->set_id(entry->id.value());
-                }
-                pbEntry->set_name(entry->name);
+        for (auto& config_value : entry->values) {
+          pb::ConfigValue* pb_config_value = pb_entry->add_config_values();
+          SerializeConfig(config_value->config,
+                          pb_config_value->mutable_config());
+          if (!config_value->product.empty()) {
+            pb_config_value->mutable_config()->set_product(
+                config_value->product);
+          }
 
-                // Write the SymbolStatus struct.
-                pb::SymbolStatus* pbStatus = pbEntry->mutable_symbol_status();
-                pbStatus->set_visibility(serializeVisibilityToPb(entry->symbolStatus.state));
-                serializeSourceToPb(entry->symbolStatus.source, &sourcePool,
-                                    pbStatus->mutable_source());
-                pbStatus->set_comment(entry->symbolStatus.comment);
+          pb::Value* pb_value = pb_config_value->mutable_value();
+          SerializeSourceToPb(config_value->value->GetSource(), &source_pool,
+                              pb_value->mutable_source());
+          if (!config_value->value->GetComment().empty()) {
+            pb_value->set_comment(config_value->value->GetComment());
+          }
 
-                for (auto& configValue : entry->values) {
-                    pb::ConfigValue* pbConfigValue = pbEntry->add_config_values();
-                    serializeConfig(configValue->config, pbConfigValue->mutable_config());
-                    if (!configValue->product.empty()) {
-                        pbConfigValue->mutable_config()->set_product(configValue->product);
-                    }
+          if (config_value->value->IsWeak()) {
+            pb_value->set_weak(true);
+          }
 
-                    pb::Value* pbValue = pbConfigValue->mutable_value();
-                    serializeSourceToPb(configValue->value->getSource(), &sourcePool,
-                                        pbValue->mutable_source());
-                    if (!configValue->value->getComment().empty()) {
-                        pbValue->set_comment(configValue->value->getComment());
-                    }
-
-                    if (configValue->value->isWeak()) {
-                        pbValue->set_weak(true);
-                    }
-
-                    PbSerializerVisitor visitor(&sourcePool, &symbolPool, pbValue);
-                    configValue->value->accept(&visitor);
-                }
-            }
+          PbSerializerVisitor visitor(&source_pool, &symbol_pool, pb_value);
+          config_value->value->Accept(&visitor);
         }
+      }
     }
+  }
 
-    serializeStringPoolToPb(sourcePool, pbTable->mutable_source_pool());
-    serializeStringPoolToPb(symbolPool, pbTable->mutable_symbol_pool());
-    return pbTable;
+  SerializeStringPoolToPb(source_pool, pb_table->mutable_source_pool());
+  SerializeStringPoolToPb(symbol_pool, pb_table->mutable_symbol_pool());
+  return pb_table;
 }
 
-std::unique_ptr<pb::CompiledFile> serializeCompiledFileToPb(const ResourceFile& file) {
-    auto pbFile = util::make_unique<pb::CompiledFile>();
-    pbFile->set_resource_name(file.name.toString());
-    pbFile->set_source_path(file.source.path);
-    serializeConfig(file.config, pbFile->mutable_config());
+std::unique_ptr<pb::CompiledFile> SerializeCompiledFileToPb(
+    const ResourceFile& file) {
+  auto pb_file = util::make_unique<pb::CompiledFile>();
+  pb_file->set_resource_name(file.name.ToString());
+  pb_file->set_source_path(file.source.path);
+  SerializeConfig(file.config, pb_file->mutable_config());
 
-    for (const SourcedResourceName& exported : file.exportedSymbols) {
-        pb::CompiledFile_Symbol* pbSymbol = pbFile->add_exported_symbols();
-        pbSymbol->set_resource_name(exported.name.toString());
-        pbSymbol->set_line_no(exported.line);
-    }
-    return pbFile;
+  for (const SourcedResourceName& exported : file.exported_symbols) {
+    pb::CompiledFile_Symbol* pb_symbol = pb_file->add_exported_symbols();
+    pb_symbol->set_resource_name(exported.name.ToString());
+    pb_symbol->set_line_no(exported.line);
+  }
+  return pb_file;
 }
 
-CompiledFileOutputStream::CompiledFileOutputStream(ZeroCopyOutputStream* out) : mOut(out) {
-}
+CompiledFileOutputStream::CompiledFileOutputStream(ZeroCopyOutputStream* out)
+    : out_(out) {}
 
-void CompiledFileOutputStream::ensureAlignedWrite() {
-    const int padding = mOut.ByteCount() % 4;
-    if (padding > 0) {
-        uint32_t zero = 0u;
-        mOut.WriteRaw(&zero, padding);
-    }
+void CompiledFileOutputStream::EnsureAlignedWrite() {
+  const int padding = out_.ByteCount() % 4;
+  if (padding > 0) {
+    uint32_t zero = 0u;
+    out_.WriteRaw(&zero, padding);
+  }
 }
 
 void CompiledFileOutputStream::WriteLittleEndian32(uint32_t val) {
-    ensureAlignedWrite();
-    mOut.WriteLittleEndian32(val);
+  EnsureAlignedWrite();
+  out_.WriteLittleEndian32(val);
 }
 
-void CompiledFileOutputStream::WriteCompiledFile(const pb::CompiledFile* compiledFile) {
-    ensureAlignedWrite();
-    mOut.WriteLittleEndian64(static_cast<uint64_t>(compiledFile->ByteSize()));
-    compiledFile->SerializeWithCachedSizes(&mOut);
+void CompiledFileOutputStream::WriteCompiledFile(
+    const pb::CompiledFile* compiled_file) {
+  EnsureAlignedWrite();
+  out_.WriteLittleEndian64(static_cast<uint64_t>(compiled_file->ByteSize()));
+  compiled_file->SerializeWithCachedSizes(&out_);
 }
 
 void CompiledFileOutputStream::WriteData(const BigBuffer* buffer) {
-    ensureAlignedWrite();
-    mOut.WriteLittleEndian64(static_cast<uint64_t>(buffer->size()));
-    for (const BigBuffer::Block& block : *buffer) {
-        mOut.WriteRaw(block.buffer.get(), block.size);
-    }
+  EnsureAlignedWrite();
+  out_.WriteLittleEndian64(static_cast<uint64_t>(buffer->size()));
+  for (const BigBuffer::Block& block : *buffer) {
+    out_.WriteRaw(block.buffer.get(), block.size);
+  }
 }
 
 void CompiledFileOutputStream::WriteData(const void* data, size_t len) {
-    ensureAlignedWrite();
-    mOut.WriteLittleEndian64(static_cast<uint64_t>(len));
-    mOut.WriteRaw(data, len);
+  EnsureAlignedWrite();
+  out_.WriteLittleEndian64(static_cast<uint64_t>(len));
+  out_.WriteRaw(data, len);
 }
 
-bool CompiledFileOutputStream::HadError() {
-    return mOut.HadError();
+bool CompiledFileOutputStream::HadError() { return out_.HadError(); }
+
+CompiledFileInputStream::CompiledFileInputStream(const void* data, size_t size)
+    : in_(static_cast<const uint8_t*>(data), size) {}
+
+void CompiledFileInputStream::EnsureAlignedRead() {
+  const int padding = in_.CurrentPosition() % 4;
+  if (padding > 0) {
+    // Reads are always 4 byte aligned.
+    in_.Skip(padding);
+  }
 }
 
-CompiledFileInputStream::CompiledFileInputStream(const void* data, size_t size) :
-        mIn(static_cast<const uint8_t*>(data), size) {
+bool CompiledFileInputStream::ReadLittleEndian32(uint32_t* out_val) {
+  EnsureAlignedRead();
+  return in_.ReadLittleEndian32(out_val);
 }
 
-void CompiledFileInputStream::ensureAlignedRead() {
-    const int padding = mIn.CurrentPosition() % 4;
-    if (padding > 0) {
-        // Reads are always 4 byte aligned.
-        mIn.Skip(padding);
-    }
+bool CompiledFileInputStream::ReadCompiledFile(pb::CompiledFile* out_val) {
+  EnsureAlignedRead();
+
+  uint64_t pb_size = 0u;
+  if (!in_.ReadLittleEndian64(&pb_size)) {
+    return false;
+  }
+
+  CodedInputStream::Limit l = in_.PushLimit(static_cast<int>(pb_size));
+
+  // Check that we haven't tried to read past the end.
+  if (static_cast<uint64_t>(in_.BytesUntilLimit()) != pb_size) {
+    in_.PopLimit(l);
+    in_.PushLimit(0);
+    return false;
+  }
+
+  if (!out_val->ParsePartialFromCodedStream(&in_)) {
+    in_.PopLimit(l);
+    in_.PushLimit(0);
+    return false;
+  }
+
+  in_.PopLimit(l);
+  return true;
 }
 
-bool CompiledFileInputStream::ReadLittleEndian32(uint32_t* outVal) {
-    ensureAlignedRead();
-    return mIn.ReadLittleEndian32(outVal);
+bool CompiledFileInputStream::ReadDataMetaData(uint64_t* out_offset,
+                                               uint64_t* out_len) {
+  EnsureAlignedRead();
+
+  uint64_t pb_size = 0u;
+  if (!in_.ReadLittleEndian64(&pb_size)) {
+    return false;
+  }
+
+  // Check that we aren't trying to read past the end.
+  if (pb_size > static_cast<uint64_t>(in_.BytesUntilLimit())) {
+    in_.PushLimit(0);
+    return false;
+  }
+
+  uint64_t offset = static_cast<uint64_t>(in_.CurrentPosition());
+  if (!in_.Skip(pb_size)) {
+    return false;
+  }
+
+  *out_offset = offset;
+  *out_len = pb_size;
+  return true;
 }
 
-bool CompiledFileInputStream::ReadCompiledFile(pb::CompiledFile* outVal) {
-    ensureAlignedRead();
-
-    uint64_t pbSize = 0u;
-    if (!mIn.ReadLittleEndian64(&pbSize)) {
-        return false;
-    }
-
-    CodedInputStream::Limit l = mIn.PushLimit(static_cast<int>(pbSize));
-
-    // Check that we haven't tried to read past the end.
-    if (static_cast<uint64_t>(mIn.BytesUntilLimit()) != pbSize) {
-        mIn.PopLimit(l);
-        mIn.PushLimit(0);
-        return false;
-    }
-
-    if (!outVal->ParsePartialFromCodedStream(&mIn)) {
-        mIn.PopLimit(l);
-        mIn.PushLimit(0);
-        return false;
-    }
-
-    mIn.PopLimit(l);
-    return true;
-}
-
-bool CompiledFileInputStream::ReadDataMetaData(uint64_t* outOffset, uint64_t* outLen) {
-    ensureAlignedRead();
-
-    uint64_t pbSize = 0u;
-    if (!mIn.ReadLittleEndian64(&pbSize)) {
-        return false;
-    }
-
-    // Check that we aren't trying to read past the end.
-    if (pbSize > static_cast<uint64_t>(mIn.BytesUntilLimit())) {
-        mIn.PushLimit(0);
-        return false;
-    }
-
-    uint64_t offset = static_cast<uint64_t>(mIn.CurrentPosition());
-    if (!mIn.Skip(pbSize)) {
-        return false;
-    }
-
-    *outOffset = offset;
-    *outLen = pbSize;
-    return true;
-}
-
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/proto/TableProtoSerializer_test.cpp b/tools/aapt2/proto/TableProtoSerializer_test.cpp
index 2bd9767..fdd5197 100644
--- a/tools/aapt2/proto/TableProtoSerializer_test.cpp
+++ b/tools/aapt2/proto/TableProtoSerializer_test.cpp
@@ -14,200 +14,211 @@
  * limitations under the License.
  */
 
-#include "ResourceTable.h"
 #include "proto/ProtoSerialize.h"
+
+#include "ResourceTable.h"
 #include "test/Test.h"
 
-using namespace google::protobuf::io;
+using ::google::protobuf::io::StringOutputStream;
 
 namespace aapt {
 
 TEST(TableProtoSerializer, SerializeSinglePackage) {
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId("com.app.a", 0x7f)
-            .addFileReference("com.app.a:layout/main", ResourceId(0x7f020000),
-                              "res/layout/main.xml")
-            .addReference("com.app.a:layout/other", ResourceId(0x7f020001),
-                          "com.app.a:layout/main")
-            .addString("com.app.a:string/text", {}, "hi")
-            .addValue("com.app.a:id/foo", {}, util::make_unique<Id>())
-            .build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("com.app.a", 0x7f)
+          .AddFileReference("com.app.a:layout/main", ResourceId(0x7f020000),
+                            "res/layout/main.xml")
+          .AddReference("com.app.a:layout/other", ResourceId(0x7f020001),
+                        "com.app.a:layout/main")
+          .AddString("com.app.a:string/text", {}, "hi")
+          .AddValue("com.app.a:id/foo", {}, util::make_unique<Id>())
+          .Build();
 
-    Symbol publicSymbol;
-    publicSymbol.state = SymbolState::kPublic;
-    ASSERT_TRUE(table->setSymbolState(test::parseNameOrDie("com.app.a:layout/main"),
-                                      ResourceId(0x7f020000),
-                                      publicSymbol, context->getDiagnostics()));
+  Symbol public_symbol;
+  public_symbol.state = SymbolState::kPublic;
+  ASSERT_TRUE(table->SetSymbolState(
+      test::ParseNameOrDie("com.app.a:layout/main"), ResourceId(0x7f020000),
+      public_symbol, context->GetDiagnostics()));
 
-    Id* id = test::getValue<Id>(table.get(), "com.app.a:id/foo");
-    ASSERT_NE(nullptr, id);
+  Id* id = test::GetValue<Id>(table.get(), "com.app.a:id/foo");
+  ASSERT_NE(nullptr, id);
 
-    // Make a plural.
-    std::unique_ptr<Plural> plural = util::make_unique<Plural>();
-    plural->values[Plural::One] = util::make_unique<String>(table->stringPool.makeRef("one"));
-    ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:plurals/hey"),
-                                   ConfigDescription{}, {}, std::move(plural),
-                                   context->getDiagnostics()));
+  // Make a plural.
+  std::unique_ptr<Plural> plural = util::make_unique<Plural>();
+  plural->values[Plural::One] =
+      util::make_unique<String>(table->string_pool.MakeRef("one"));
+  ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("com.app.a:plurals/hey"),
+                                 ConfigDescription{}, {}, std::move(plural),
+                                 context->GetDiagnostics()));
 
-    // Make a resource with different products.
-    ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:integer/one"),
-                                   test::parseConfigOrDie("land"), {},
-                                   test::buildPrimitive(android::Res_value::TYPE_INT_DEC, 123u),
-                                   context->getDiagnostics()));
-    ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:integer/one"),
-                                       test::parseConfigOrDie("land"), "tablet",
-                                       test::buildPrimitive(android::Res_value::TYPE_INT_DEC, 321u),
-                                       context->getDiagnostics()));
+  // Make a resource with different products.
+  ASSERT_TRUE(table->AddResource(
+      test::ParseNameOrDie("com.app.a:integer/one"),
+      test::ParseConfigOrDie("land"), {},
+      test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 123u),
+      context->GetDiagnostics()));
+  ASSERT_TRUE(table->AddResource(
+      test::ParseNameOrDie("com.app.a:integer/one"),
+      test::ParseConfigOrDie("land"), "tablet",
+      test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 321u),
+      context->GetDiagnostics()));
 
-    // Make a reference with both resource name and resource ID.
-    // The reference should point to a resource outside of this table to test that both
-    // name and id get serialized.
-    Reference expectedRef;
-    expectedRef.name = test::parseNameOrDie("android:layout/main");
-    expectedRef.id = ResourceId(0x01020000);
-    ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:layout/abc"),
-                                   ConfigDescription::defaultConfig(), {},
-                                   util::make_unique<Reference>(expectedRef),
-                                   context->getDiagnostics()));
+  // Make a reference with both resource name and resource ID.
+  // The reference should point to a resource outside of this table to test that
+  // both
+  // name and id get serialized.
+  Reference expected_ref;
+  expected_ref.name = test::ParseNameOrDie("android:layout/main");
+  expected_ref.id = ResourceId(0x01020000);
+  ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("com.app.a:layout/abc"),
+                                 ConfigDescription::DefaultConfig(), {},
+                                 util::make_unique<Reference>(expected_ref),
+                                 context->GetDiagnostics()));
 
-    std::unique_ptr<pb::ResourceTable> pbTable = serializeTableToPb(table.get());
-    ASSERT_NE(nullptr, pbTable);
+  std::unique_ptr<pb::ResourceTable> pb_table = SerializeTableToPb(table.get());
+  ASSERT_NE(nullptr, pb_table);
 
-    std::unique_ptr<ResourceTable> newTable = deserializeTableFromPb(*pbTable,
-                                                                     Source{ "test" },
-                                                                     context->getDiagnostics());
-    ASSERT_NE(nullptr, newTable);
+  std::unique_ptr<ResourceTable> new_table = DeserializeTableFromPb(
+      *pb_table, Source{"test"}, context->GetDiagnostics());
+  ASSERT_NE(nullptr, new_table);
 
-    Id* newId = test::getValue<Id>(newTable.get(), "com.app.a:id/foo");
-    ASSERT_NE(nullptr, newId);
-    EXPECT_EQ(id->isWeak(), newId->isWeak());
+  Id* new_id = test::GetValue<Id>(new_table.get(), "com.app.a:id/foo");
+  ASSERT_NE(nullptr, new_id);
+  EXPECT_EQ(id->IsWeak(), new_id->IsWeak());
 
-    Maybe<ResourceTable::SearchResult> result = newTable->findResource(
-            test::parseNameOrDie("com.app.a:layout/main"));
-    AAPT_ASSERT_TRUE(result);
-    EXPECT_EQ(SymbolState::kPublic, result.value().type->symbolStatus.state);
-    EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbolStatus.state);
+  Maybe<ResourceTable::SearchResult> result =
+      new_table->FindResource(test::ParseNameOrDie("com.app.a:layout/main"));
+  AAPT_ASSERT_TRUE(result);
+  EXPECT_EQ(SymbolState::kPublic, result.value().type->symbol_status.state);
+  EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbol_status.state);
 
-    // Find the product-dependent values
-    BinaryPrimitive* prim = test::getValueForConfigAndProduct<BinaryPrimitive>(
-            newTable.get(), "com.app.a:integer/one", test::parseConfigOrDie("land"), "");
-    ASSERT_NE(nullptr, prim);
-    EXPECT_EQ(123u, prim->value.data);
+  // Find the product-dependent values
+  BinaryPrimitive* prim = test::GetValueForConfigAndProduct<BinaryPrimitive>(
+      new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"),
+      "");
+  ASSERT_NE(nullptr, prim);
+  EXPECT_EQ(123u, prim->value.data);
 
-    prim = test::getValueForConfigAndProduct<BinaryPrimitive>(
-            newTable.get(), "com.app.a:integer/one", test::parseConfigOrDie("land"), "tablet");
-    ASSERT_NE(nullptr, prim);
-    EXPECT_EQ(321u, prim->value.data);
+  prim = test::GetValueForConfigAndProduct<BinaryPrimitive>(
+      new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"),
+      "tablet");
+  ASSERT_NE(nullptr, prim);
+  EXPECT_EQ(321u, prim->value.data);
 
-    Reference* actualRef = test::getValue<Reference>(newTable.get(), "com.app.a:layout/abc");
-    ASSERT_NE(nullptr, actualRef);
-    AAPT_ASSERT_TRUE(actualRef->name);
-    AAPT_ASSERT_TRUE(actualRef->id);
-    EXPECT_EQ(expectedRef.name.value(), actualRef->name.value());
-    EXPECT_EQ(expectedRef.id.value(), actualRef->id.value());
+  Reference* actual_ref =
+      test::GetValue<Reference>(new_table.get(), "com.app.a:layout/abc");
+  ASSERT_NE(nullptr, actual_ref);
+  AAPT_ASSERT_TRUE(actual_ref->name);
+  AAPT_ASSERT_TRUE(actual_ref->id);
+  EXPECT_EQ(expected_ref.name.value(), actual_ref->name.value());
+  EXPECT_EQ(expected_ref.id.value(), actual_ref->id.value());
 }
 
 TEST(TableProtoSerializer, SerializeFileHeader) {
-    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
 
-    ResourceFile f;
-    f.config = test::parseConfigOrDie("hdpi-v9");
-    f.name = test::parseNameOrDie("com.app.a:layout/main");
-    f.source.path = "res/layout-hdpi-v9/main.xml";
-    f.exportedSymbols.push_back(SourcedResourceName{ test::parseNameOrDie("id/unchecked"), 23u });
+  ResourceFile f;
+  f.config = test::ParseConfigOrDie("hdpi-v9");
+  f.name = test::ParseNameOrDie("com.app.a:layout/main");
+  f.source.path = "res/layout-hdpi-v9/main.xml";
+  f.exported_symbols.push_back(
+      SourcedResourceName{test::ParseNameOrDie("id/unchecked"), 23u});
 
-    const std::string expectedData1 = "123";
-    const std::string expectedData2 = "1234";
+  const std::string expected_data1 = "123";
+  const std::string expected_data2 = "1234";
 
-    std::string outputStr;
-    {
-        std::unique_ptr<pb::CompiledFile> pbFile1 = serializeCompiledFileToPb(f);
+  std::string output_str;
+  {
+    std::unique_ptr<pb::CompiledFile> pb_file1 = SerializeCompiledFileToPb(f);
 
-        f.name.entry = "__" + f.name.entry + "$0";
-        std::unique_ptr<pb::CompiledFile> pbFile2 = serializeCompiledFileToPb(f);
+    f.name.entry = "__" + f.name.entry + "$0";
+    std::unique_ptr<pb::CompiledFile> pb_file2 = SerializeCompiledFileToPb(f);
 
-        StringOutputStream outStream(&outputStr);
-        CompiledFileOutputStream outFileStream(&outStream);
-        outFileStream.WriteLittleEndian32(2);
-        outFileStream.WriteCompiledFile(pbFile1.get());
-        outFileStream.WriteData(expectedData1.data(), expectedData1.size());
-        outFileStream.WriteCompiledFile(pbFile2.get());
-        outFileStream.WriteData(expectedData2.data(), expectedData2.size());
-        ASSERT_FALSE(outFileStream.HadError());
-    }
+    StringOutputStream out_stream(&output_str);
+    CompiledFileOutputStream out_file_stream(&out_stream);
+    out_file_stream.WriteLittleEndian32(2);
+    out_file_stream.WriteCompiledFile(pb_file1.get());
+    out_file_stream.WriteData(expected_data1.data(), expected_data1.size());
+    out_file_stream.WriteCompiledFile(pb_file2.get());
+    out_file_stream.WriteData(expected_data2.data(), expected_data2.size());
+    ASSERT_FALSE(out_file_stream.HadError());
+  }
 
-    CompiledFileInputStream inFileStream(outputStr.data(), outputStr.size());
-    uint32_t numFiles = 0;
-    ASSERT_TRUE(inFileStream.ReadLittleEndian32(&numFiles));
-    ASSERT_EQ(2u, numFiles);
+  CompiledFileInputStream in_file_stream(output_str.data(), output_str.size());
+  uint32_t num_files = 0;
+  ASSERT_TRUE(in_file_stream.ReadLittleEndian32(&num_files));
+  ASSERT_EQ(2u, num_files);
 
-    // Read the first compiled file.
+  // Read the first compiled file.
 
-    pb::CompiledFile newPbFile;
-    ASSERT_TRUE(inFileStream.ReadCompiledFile(&newPbFile));
+  pb::CompiledFile new_pb_file;
+  ASSERT_TRUE(in_file_stream.ReadCompiledFile(&new_pb_file));
 
-    std::unique_ptr<ResourceFile> file = deserializeCompiledFileFromPb(newPbFile, Source("test"),
-                                                                       context->getDiagnostics());
-    ASSERT_NE(nullptr, file);
+  std::unique_ptr<ResourceFile> file = DeserializeCompiledFileFromPb(
+      new_pb_file, Source("test"), context->GetDiagnostics());
+  ASSERT_NE(nullptr, file);
 
-    uint64_t offset, len;
-    ASSERT_TRUE(inFileStream.ReadDataMetaData(&offset, &len));
+  uint64_t offset, len;
+  ASSERT_TRUE(in_file_stream.ReadDataMetaData(&offset, &len));
 
-    std::string actualData(outputStr.data() + offset, len);
-    EXPECT_EQ(expectedData1, actualData);
+  std::string actual_data(output_str.data() + offset, len);
+  EXPECT_EQ(expected_data1, actual_data);
 
-    // Expect the data to be aligned.
-    EXPECT_EQ(0u, offset & 0x03);
+  // Expect the data to be aligned.
+  EXPECT_EQ(0u, offset & 0x03);
 
-    ASSERT_EQ(1u, file->exportedSymbols.size());
-    EXPECT_EQ(test::parseNameOrDie("id/unchecked"), file->exportedSymbols[0].name);
+  ASSERT_EQ(1u, file->exported_symbols.size());
+  EXPECT_EQ(test::ParseNameOrDie("id/unchecked"),
+            file->exported_symbols[0].name);
 
-    // Read the second compiled file.
+  // Read the second compiled file.
 
-    ASSERT_TRUE(inFileStream.ReadCompiledFile(&newPbFile));
+  ASSERT_TRUE(in_file_stream.ReadCompiledFile(&new_pb_file));
 
-    file = deserializeCompiledFileFromPb(newPbFile, Source("test"), context->getDiagnostics());
-    ASSERT_NE(nullptr, file);
+  file = DeserializeCompiledFileFromPb(new_pb_file, Source("test"),
+                                       context->GetDiagnostics());
+  ASSERT_NE(nullptr, file);
 
-    ASSERT_TRUE(inFileStream.ReadDataMetaData(&offset, &len));
+  ASSERT_TRUE(in_file_stream.ReadDataMetaData(&offset, &len));
 
-    actualData = std::string(outputStr.data() + offset, len);
-    EXPECT_EQ(expectedData2, actualData);
+  actual_data = std::string(output_str.data() + offset, len);
+  EXPECT_EQ(expected_data2, actual_data);
 
-    // Expect the data to be aligned.
-    EXPECT_EQ(0u, offset & 0x03);
+  // Expect the data to be aligned.
+  EXPECT_EQ(0u, offset & 0x03);
 }
 
 TEST(TableProtoSerializer, DeserializeCorruptHeaderSafely) {
-    ResourceFile f;
-    std::unique_ptr<pb::CompiledFile> pbFile = serializeCompiledFileToPb(f);
+  ResourceFile f;
+  std::unique_ptr<pb::CompiledFile> pb_file = SerializeCompiledFileToPb(f);
 
-    const std::string expectedData = "1234";
+  const std::string expected_data = "1234";
 
-    std::string outputStr;
-    {
-        StringOutputStream outStream(&outputStr);
-        CompiledFileOutputStream outFileStream(&outStream);
-        outFileStream.WriteLittleEndian32(1);
-        outFileStream.WriteCompiledFile(pbFile.get());
-        outFileStream.WriteData(expectedData.data(), expectedData.size());
-        ASSERT_FALSE(outFileStream.HadError());
-    }
+  std::string output_str;
+  {
+    StringOutputStream out_stream(&output_str);
+    CompiledFileOutputStream out_file_stream(&out_stream);
+    out_file_stream.WriteLittleEndian32(1);
+    out_file_stream.WriteCompiledFile(pb_file.get());
+    out_file_stream.WriteData(expected_data.data(), expected_data.size());
+    ASSERT_FALSE(out_file_stream.HadError());
+  }
 
-    outputStr[4] = 0xff;
+  output_str[4] = 0xff;
 
-    CompiledFileInputStream inFileStream(outputStr.data(), outputStr.size());
+  CompiledFileInputStream in_file_stream(output_str.data(), output_str.size());
 
-    uint32_t numFiles = 0;
-    EXPECT_TRUE(inFileStream.ReadLittleEndian32(&numFiles));
-    EXPECT_EQ(1u, numFiles);
+  uint32_t num_files = 0;
+  EXPECT_TRUE(in_file_stream.ReadLittleEndian32(&num_files));
+  EXPECT_EQ(1u, num_files);
 
-    pb::CompiledFile newPbFile;
-    EXPECT_FALSE(inFileStream.ReadCompiledFile(&newPbFile));
+  pb::CompiledFile new_pb_file;
+  EXPECT_FALSE(in_file_stream.ReadCompiledFile(&new_pb_file));
 
-    uint64_t offset, len;
-    EXPECT_FALSE(inFileStream.ReadDataMetaData(&offset, &len));
+  uint64_t offset, len;
+  EXPECT_FALSE(in_file_stream.ReadDataMetaData(&offset, &len));
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/split/TableSplitter.cpp b/tools/aapt2/split/TableSplitter.cpp
index 08b9ee9..7aad86f 100644
--- a/tools/aapt2/split/TableSplitter.cpp
+++ b/tools/aapt2/split/TableSplitter.cpp
@@ -14,251 +14,278 @@
  * limitations under the License.
  */
 
-#include "ConfigDescription.h"
-#include "ResourceTable.h"
 #include "split/TableSplitter.h"
-#include "util/Util.h"
 
 #include <algorithm>
 #include <map>
 #include <set>
 #include <unordered_map>
 #include <vector>
+#include "android-base/logging.h"
+
+#include "ConfigDescription.h"
+#include "ResourceTable.h"
+#include "util/Util.h"
 
 namespace aapt {
 
 using ConfigClaimedMap = std::unordered_map<ResourceConfigValue*, bool>;
-using ConfigDensityGroups = std::map<ConfigDescription, std::vector<ResourceConfigValue*>>;
+using ConfigDensityGroups =
+    std::map<ConfigDescription, std::vector<ResourceConfigValue*>>;
 
-static ConfigDescription copyWithoutDensity(const ConfigDescription& config) {
-    ConfigDescription withoutDensity = config;
-    withoutDensity.density = 0;
-    return withoutDensity;
+static ConfigDescription CopyWithoutDensity(const ConfigDescription& config) {
+  ConfigDescription without_density = config;
+  without_density.density = 0;
+  return without_density;
 }
 
 /**
  * Selects values that match exactly the constraints given.
  */
 class SplitValueSelector {
-public:
-    explicit SplitValueSelector(const SplitConstraints& constraints) {
-        for (const ConfigDescription& config : constraints.configs) {
-            if (config.density == 0) {
-                mDensityIndependentConfigs.insert(config);
-            } else {
-                mDensityDependentConfigToDensityMap[copyWithoutDensity(config)] = config.density;
-            }
+ public:
+  explicit SplitValueSelector(const SplitConstraints& constraints) {
+    for (const ConfigDescription& config : constraints.configs) {
+      if (config.density == 0) {
+        density_independent_configs_.insert(config);
+      } else {
+        density_dependent_config_to_density_map_[CopyWithoutDensity(config)] =
+            config.density;
+      }
+    }
+  }
+
+  std::vector<ResourceConfigValue*> SelectValues(
+      const ConfigDensityGroups& density_groups,
+      ConfigClaimedMap* claimed_values) {
+    std::vector<ResourceConfigValue*> selected;
+
+    // Select the regular values.
+    for (auto& entry : *claimed_values) {
+      // Check if the entry has a density.
+      ResourceConfigValue* config_value = entry.first;
+      if (config_value->config.density == 0 && !entry.second) {
+        // This is still available.
+        if (density_independent_configs_.find(config_value->config) !=
+            density_independent_configs_.end()) {
+          selected.push_back(config_value);
+
+          // Mark the entry as taken.
+          entry.second = true;
         }
+      }
     }
 
-    std::vector<ResourceConfigValue*> selectValues(const ConfigDensityGroups& densityGroups,
-                                                   ConfigClaimedMap* claimedValues) {
-        std::vector<ResourceConfigValue*> selected;
+    // Now examine the densities
+    for (auto& entry : density_groups) {
+      // We do not care if the value is claimed, since density values can be
+      // in multiple splits.
+      const ConfigDescription& config = entry.first;
+      const std::vector<ResourceConfigValue*>& related_values = entry.second;
+      auto density_value_iter =
+          density_dependent_config_to_density_map_.find(config);
+      if (density_value_iter !=
+          density_dependent_config_to_density_map_.end()) {
+        // Select the best one!
+        ConfigDescription target_density = config;
+        target_density.density = density_value_iter->second;
 
-        // Select the regular values.
-        for (auto& entry : *claimedValues) {
-            // Check if the entry has a density.
-            ResourceConfigValue* configValue = entry.first;
-            if (configValue->config.density == 0 && !entry.second) {
-                // This is still available.
-                if (mDensityIndependentConfigs.find(configValue->config) !=
-                        mDensityIndependentConfigs.end()) {
-                    selected.push_back(configValue);
-
-                    // Mark the entry as taken.
-                    entry.second = true;
-                }
-            }
+        ResourceConfigValue* best_value = nullptr;
+        for (ResourceConfigValue* this_value : related_values) {
+          if (!best_value ||
+              this_value->config.isBetterThan(best_value->config,
+                                              &target_density)) {
+            best_value = this_value;
+          }
         }
+        CHECK(best_value != nullptr);
 
-        // Now examine the densities
-        for (auto& entry : densityGroups) {
-            // We do not care if the value is claimed, since density values can be
-            // in multiple splits.
-            const ConfigDescription& config = entry.first;
-            const std::vector<ResourceConfigValue*>& relatedValues = entry.second;
-            auto densityValueIter = mDensityDependentConfigToDensityMap.find(config);
-            if (densityValueIter != mDensityDependentConfigToDensityMap.end()) {
-                // Select the best one!
-                ConfigDescription targetDensity = config;
-                targetDensity.density = densityValueIter->second;
-
-                ResourceConfigValue* bestValue = nullptr;
-                for (ResourceConfigValue* thisValue : relatedValues) {
-                    if (!bestValue ||
-                            thisValue->config.isBetterThan(bestValue->config, &targetDensity)) {
-                        bestValue = thisValue;
-                    }
-                }
-                assert(bestValue);
-
-                // When we select one of these, they are all claimed such that the base
-                // doesn't include any anymore.
-                (*claimedValues)[bestValue] = true;
-                selected.push_back(bestValue);
-            }
-        }
-        return selected;
+        // When we select one of these, they are all claimed such that the base
+        // doesn't include any anymore.
+        (*claimed_values)[best_value] = true;
+        selected.push_back(best_value);
+      }
     }
+    return selected;
+  }
 
-private:
-    std::set<ConfigDescription> mDensityIndependentConfigs;
-    std::map<ConfigDescription, uint16_t> mDensityDependentConfigToDensityMap;
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SplitValueSelector);
+
+  std::set<ConfigDescription> density_independent_configs_;
+  std::map<ConfigDescription, uint16_t>
+      density_dependent_config_to_density_map_;
 };
 
 /**
- * Marking non-preferred densities as claimed will make sure the base doesn't include them,
+ * Marking non-preferred densities as claimed will make sure the base doesn't
+ * include them,
  * leaving only the preferred density behind.
  */
-static void markNonPreferredDensitiesAsClaimed(uint16_t preferredDensity,
-                                               const ConfigDensityGroups& densityGroups,
-                                               ConfigClaimedMap* configClaimedMap) {
-    for (auto& entry : densityGroups) {
-        const ConfigDescription& config = entry.first;
-        const std::vector<ResourceConfigValue*>& relatedValues = entry.second;
+static void MarkNonPreferredDensitiesAsClaimed(
+    uint16_t preferred_density, const ConfigDensityGroups& density_groups,
+    ConfigClaimedMap* config_claimed_map) {
+  for (auto& entry : density_groups) {
+    const ConfigDescription& config = entry.first;
+    const std::vector<ResourceConfigValue*>& related_values = entry.second;
 
-        ConfigDescription targetDensity = config;
-        targetDensity.density = preferredDensity;
-        ResourceConfigValue* bestValue = nullptr;
-        for (ResourceConfigValue* thisValue : relatedValues) {
-            if (!bestValue) {
-                bestValue = thisValue;
-            } else if (thisValue->config.isBetterThan(bestValue->config, &targetDensity)) {
-                // Claim the previous value so that it is not included in the base.
-                (*configClaimedMap)[bestValue] = true;
-                bestValue = thisValue;
-            } else {
-                // Claim this value so that it is not included in the base.
-                (*configClaimedMap)[thisValue] = true;
-            }
-        }
-        assert(bestValue);
+    ConfigDescription target_density = config;
+    target_density.density = preferred_density;
+    ResourceConfigValue* best_value = nullptr;
+    for (ResourceConfigValue* this_value : related_values) {
+      if (!best_value) {
+        best_value = this_value;
+      } else if (this_value->config.isBetterThan(best_value->config,
+                                                 &target_density)) {
+        // Claim the previous value so that it is not included in the base.
+        (*config_claimed_map)[best_value] = true;
+        best_value = this_value;
+      } else {
+        // Claim this value so that it is not included in the base.
+        (*config_claimed_map)[this_value] = true;
+      }
     }
+    CHECK(best_value != nullptr);
+  }
 }
-bool TableSplitter::verifySplitConstraints(IAaptContext* context) {
-    bool error = false;
-    for (size_t i = 0; i < mSplitConstraints.size(); i++) {
-        for (size_t j = i + 1; j < mSplitConstraints.size(); j++) {
-            for (const ConfigDescription& config : mSplitConstraints[i].configs) {
-                if (mSplitConstraints[j].configs.find(config) !=
-                        mSplitConstraints[j].configs.end()) {
-                    context->getDiagnostics()->error(DiagMessage() << "config '" << config
-                                                     << "' appears in multiple splits, "
-                                                     << "target split ambiguous");
-                    error = true;
-                }
-            }
+bool TableSplitter::VerifySplitConstraints(IAaptContext* context) {
+  bool error = false;
+  for (size_t i = 0; i < split_constraints_.size(); i++) {
+    for (size_t j = i + 1; j < split_constraints_.size(); j++) {
+      for (const ConfigDescription& config : split_constraints_[i].configs) {
+        if (split_constraints_[j].configs.find(config) !=
+            split_constraints_[j].configs.end()) {
+          context->GetDiagnostics()->Error(DiagMessage()
+                                           << "config '" << config
+                                           << "' appears in multiple splits, "
+                                           << "target split ambiguous");
+          error = true;
         }
+      }
     }
-    return !error;
+  }
+  return !error;
 }
 
-void TableSplitter::splitTable(ResourceTable* originalTable) {
-    const size_t splitCount = mSplitConstraints.size();
-    for (auto& pkg : originalTable->packages) {
-        // Initialize all packages for splits.
-        for (size_t idx = 0; idx < splitCount; idx++) {
-            ResourceTable* splitTable = mSplits[idx].get();
-            splitTable->createPackage(pkg->name, pkg->id);
-        }
-
-        for (auto& type : pkg->types) {
-            if (type->type == ResourceType::kMipmap) {
-                // Always keep mipmaps.
-                continue;
-            }
-
-            for (auto& entry : type->entries) {
-                if (mConfigFilter) {
-                    // First eliminate any resource that we definitely don't want.
-                    for (std::unique_ptr<ResourceConfigValue>& configValue : entry->values) {
-                        if (!mConfigFilter->match(configValue->config)) {
-                            // null out the entry. We will clean up and remove nulls at the end
-                            // for performance reasons.
-                            configValue.reset();
-                        }
-                    }
-                }
-
-                // Organize the values into two separate buckets. Those that are density-dependent
-                // and those that are density-independent.
-                // One density technically matches all density, it's just that some densities
-                // match better. So we need to be aware of the full set of densities to make this
-                // decision.
-                ConfigDensityGroups densityGroups;
-                ConfigClaimedMap configClaimedMap;
-                for (const std::unique_ptr<ResourceConfigValue>& configValue : entry->values) {
-                    if (configValue) {
-                        configClaimedMap[configValue.get()] = false;
-
-                        if (configValue->config.density != 0) {
-                            // Create a bucket for this density-dependent config.
-                            densityGroups[copyWithoutDensity(configValue->config)]
-                                          .push_back(configValue.get());
-                        }
-                    }
-                }
-
-                // First we check all the splits. If it doesn't match one of the splits, we
-                // leave it in the base.
-                for (size_t idx = 0; idx < splitCount; idx++) {
-                    const SplitConstraints& splitConstraint = mSplitConstraints[idx];
-                    ResourceTable* splitTable = mSplits[idx].get();
-
-                    // Select the values we want from this entry for this split.
-                    SplitValueSelector selector(splitConstraint);
-                    std::vector<ResourceConfigValue*> selectedValues =
-                            selector.selectValues(densityGroups, &configClaimedMap);
-
-                    // No need to do any work if we selected nothing.
-                    if (!selectedValues.empty()) {
-                        // Create the same resource structure in the split. We do this lazily
-                        // because we might not have actual values for each type/entry.
-                        ResourceTablePackage* splitPkg = splitTable->findPackage(pkg->name);
-                        ResourceTableType* splitType = splitPkg->findOrCreateType(type->type);
-                        if (!splitType->id) {
-                            splitType->id = type->id;
-                            splitType->symbolStatus = type->symbolStatus;
-                        }
-
-                        ResourceEntry* splitEntry = splitType->findOrCreateEntry(entry->name);
-                        if (!splitEntry->id) {
-                            splitEntry->id = entry->id;
-                            splitEntry->symbolStatus = entry->symbolStatus;
-                        }
-
-                        // Copy the selected values into the new Split Entry.
-                        for (ResourceConfigValue* configValue : selectedValues) {
-                            ResourceConfigValue* newConfigValue = splitEntry->findOrCreateValue(
-                                    configValue->config, configValue->product);
-                            newConfigValue->value = std::unique_ptr<Value>(
-                                    configValue->value->clone(&splitTable->stringPool));
-                        }
-                    }
-                }
-
-                if (mPreferredDensity) {
-                    markNonPreferredDensitiesAsClaimed(mPreferredDensity.value(),
-                                                       densityGroups,
-                                                       &configClaimedMap);
-                }
-
-                // All splits are handled, now check to see what wasn't claimed and remove
-                // whatever exists in other splits.
-                for (std::unique_ptr<ResourceConfigValue>& configValue : entry->values) {
-                    if (configValue && configClaimedMap[configValue.get()]) {
-                        // Claimed, remove from base.
-                        configValue.reset();
-                    }
-                }
-
-                // Now erase all nullptrs.
-                entry->values.erase(
-                        std::remove(entry->values.begin(), entry->values.end(), nullptr),
-                        entry->values.end());
-            }
-        }
+void TableSplitter::SplitTable(ResourceTable* original_table) {
+  const size_t split_count = split_constraints_.size();
+  for (auto& pkg : original_table->packages) {
+    // Initialize all packages for splits.
+    for (size_t idx = 0; idx < split_count; idx++) {
+      ResourceTable* split_table = splits_[idx].get();
+      split_table->CreatePackage(pkg->name, pkg->id);
     }
+
+    for (auto& type : pkg->types) {
+      if (type->type == ResourceType::kMipmap) {
+        // Always keep mipmaps.
+        continue;
+      }
+
+      for (auto& entry : type->entries) {
+        if (options_.config_filter) {
+          // First eliminate any resource that we definitely don't want.
+          for (std::unique_ptr<ResourceConfigValue>& config_value :
+               entry->values) {
+            if (!options_.config_filter->Match(config_value->config)) {
+              // null out the entry. We will clean up and remove nulls at the
+              // end for performance reasons.
+              config_value.reset();
+            }
+          }
+        }
+
+        // Organize the values into two separate buckets. Those that are
+        // density-dependent
+        // and those that are density-independent.
+        // One density technically matches all density, it's just that some
+        // densities
+        // match better. So we need to be aware of the full set of densities to
+        // make this
+        // decision.
+        ConfigDensityGroups density_groups;
+        ConfigClaimedMap config_claimed_map;
+        for (const std::unique_ptr<ResourceConfigValue>& config_value :
+             entry->values) {
+          if (config_value) {
+            config_claimed_map[config_value.get()] = false;
+
+            if (config_value->config.density != 0) {
+              // Create a bucket for this density-dependent config.
+              density_groups[CopyWithoutDensity(config_value->config)]
+                  .push_back(config_value.get());
+            }
+          }
+        }
+
+        // First we check all the splits. If it doesn't match one of the splits,
+        // we
+        // leave it in the base.
+        for (size_t idx = 0; idx < split_count; idx++) {
+          const SplitConstraints& split_constraint = split_constraints_[idx];
+          ResourceTable* split_table = splits_[idx].get();
+
+          // Select the values we want from this entry for this split.
+          SplitValueSelector selector(split_constraint);
+          std::vector<ResourceConfigValue*> selected_values =
+              selector.SelectValues(density_groups, &config_claimed_map);
+
+          // No need to do any work if we selected nothing.
+          if (!selected_values.empty()) {
+            // Create the same resource structure in the split. We do this
+            // lazily because we might not have actual values for each
+            // type/entry.
+            ResourceTablePackage* split_pkg =
+                split_table->FindPackage(pkg->name);
+            ResourceTableType* split_type =
+                split_pkg->FindOrCreateType(type->type);
+            if (!split_type->id) {
+              split_type->id = type->id;
+              split_type->symbol_status = type->symbol_status;
+            }
+
+            ResourceEntry* split_entry =
+                split_type->FindOrCreateEntry(entry->name);
+            if (!split_entry->id) {
+              split_entry->id = entry->id;
+              split_entry->symbol_status = entry->symbol_status;
+            }
+
+            // Copy the selected values into the new Split Entry.
+            for (ResourceConfigValue* config_value : selected_values) {
+              ResourceConfigValue* new_config_value =
+                  split_entry->FindOrCreateValue(config_value->config,
+                                                 config_value->product);
+              new_config_value->value = std::unique_ptr<Value>(
+                  config_value->value->Clone(&split_table->string_pool));
+            }
+          }
+        }
+
+        if (options_.preferred_density) {
+          MarkNonPreferredDensitiesAsClaimed(options_.preferred_density.value(),
+                                             density_groups,
+                                             &config_claimed_map);
+        }
+
+        // All splits are handled, now check to see what wasn't claimed and
+        // remove
+        // whatever exists in other splits.
+        for (std::unique_ptr<ResourceConfigValue>& config_value :
+             entry->values) {
+          if (config_value && config_claimed_map[config_value.get()]) {
+            // Claimed, remove from base.
+            config_value.reset();
+          }
+        }
+
+        // Now erase all nullptrs.
+        entry->values.erase(
+            std::remove(entry->values.begin(), entry->values.end(), nullptr),
+            entry->values.end());
+      }
+    }
+  }
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/split/TableSplitter.h b/tools/aapt2/split/TableSplitter.h
index d7ecc82..1ae3271 100644
--- a/tools/aapt2/split/TableSplitter.h
+++ b/tools/aapt2/split/TableSplitter.h
@@ -17,15 +17,15 @@
 #ifndef AAPT_SPLIT_TABLESPLITTER_H
 #define AAPT_SPLIT_TABLESPLITTER_H
 
+#include <set>
+#include <vector>
+#include "android-base/macros.h"
+
 #include "ConfigDescription.h"
 #include "ResourceTable.h"
 #include "filter/ConfigFilter.h"
 #include "process/IResourceTableConsumer.h"
 
-#include <android-base/macros.h>
-#include <set>
-#include <vector>
-
 namespace aapt {
 
 struct SplitConstraints {
@@ -36,39 +36,36 @@
   /**
    * The preferred density to keep in the table, stripping out all others.
    */
-  Maybe<uint16_t> preferredDensity;
+  Maybe<uint16_t> preferred_density;
 
   /**
    * Configuration filter that determines which resource configuration values
    * end up in
    * the final table.
    */
-  IConfigFilter* configFilter = nullptr;
+  IConfigFilter* config_filter = nullptr;
 };
 
 class TableSplitter {
  public:
   TableSplitter(const std::vector<SplitConstraints>& splits,
                 const TableSplitterOptions& options)
-      : mSplitConstraints(splits),
-        mPreferredDensity(options.preferredDensity),
-        mConfigFilter(options.configFilter) {
-    for (size_t i = 0; i < mSplitConstraints.size(); i++) {
-      mSplits.push_back(util::make_unique<ResourceTable>());
+      : split_constraints_(splits), options_(options) {
+    for (size_t i = 0; i < split_constraints_.size(); i++) {
+      splits_.push_back(util::make_unique<ResourceTable>());
     }
   }
 
-  bool verifySplitConstraints(IAaptContext* context);
+  bool VerifySplitConstraints(IAaptContext* context);
 
-  void splitTable(ResourceTable* originalTable);
+  void SplitTable(ResourceTable* original_table);
 
-  std::vector<std::unique_ptr<ResourceTable>>& getSplits() { return mSplits; }
+  std::vector<std::unique_ptr<ResourceTable>>& splits() { return splits_; }
 
  private:
-  std::vector<SplitConstraints> mSplitConstraints;
-  std::vector<std::unique_ptr<ResourceTable>> mSplits;
-  Maybe<uint16_t> mPreferredDensity;
-  IConfigFilter* mConfigFilter;
+  std::vector<SplitConstraints> split_constraints_;
+  std::vector<std::unique_ptr<ResourceTable>> splits_;
+  TableSplitterOptions options_;
 
   DISALLOW_COPY_AND_ASSIGN(TableSplitter);
 };
diff --git a/tools/aapt2/split/TableSplitter_test.cpp b/tools/aapt2/split/TableSplitter_test.cpp
index 5150e82..088dac3 100644
--- a/tools/aapt2/split/TableSplitter_test.cpp
+++ b/tools/aapt2/split/TableSplitter_test.cpp
@@ -15,155 +15,192 @@
  */
 
 #include "split/TableSplitter.h"
+
 #include "test/Test.h"
 
 namespace aapt {
 
 TEST(TableSplitterTest, NoSplitPreferredDensity) {
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .addFileReference("android:drawable/icon", "res/drawable-mdpi/icon.png",
-                              test::parseConfigOrDie("mdpi"))
-            .addFileReference("android:drawable/icon", "res/drawable-hdpi/icon.png",
-                              test::parseConfigOrDie("hdpi"))
-            .addFileReference("android:drawable/icon", "res/drawable-xhdpi/icon.png",
-                              test::parseConfigOrDie("xhdpi"))
-            .addFileReference("android:drawable/icon", "res/drawable-xxhdpi/icon.png",
-                              test::parseConfigOrDie("xxhdpi"))
-            .addSimple("android:string/one")
-            .build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .AddFileReference("android:drawable/icon",
+                            "res/drawable-mdpi/icon.png",
+                            test::ParseConfigOrDie("mdpi"))
+          .AddFileReference("android:drawable/icon",
+                            "res/drawable-hdpi/icon.png",
+                            test::ParseConfigOrDie("hdpi"))
+          .AddFileReference("android:drawable/icon",
+                            "res/drawable-xhdpi/icon.png",
+                            test::ParseConfigOrDie("xhdpi"))
+          .AddFileReference("android:drawable/icon",
+                            "res/drawable-xxhdpi/icon.png",
+                            test::ParseConfigOrDie("xxhdpi"))
+          .AddSimple("android:string/one")
+          .Build();
 
-    TableSplitterOptions options;
-    options.preferredDensity = ConfigDescription::DENSITY_XHIGH;
-    TableSplitter splitter({}, options);
-    splitter.splitTable(table.get());
+  TableSplitterOptions options;
+  options.preferred_density = ConfigDescription::DENSITY_XHIGH;
+  TableSplitter splitter({}, options);
+  splitter.SplitTable(table.get());
 
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(),
-                                                              "android:drawable/icon",
-                                                              test::parseConfigOrDie("mdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(),
-                                                              "android:drawable/icon",
-                                                              test::parseConfigOrDie("hdpi")));
-    EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(table.get(),
-                                                              "android:drawable/icon",
-                                                              test::parseConfigOrDie("xhdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(),
-                                                              "android:drawable/icon",
-                                                              test::parseConfigOrDie("xxhdpi")));
-    EXPECT_NE(nullptr, test::getValue<Id>(table.get(), "android:string/one"));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         table.get(), "android:drawable/icon",
+                         test::ParseConfigOrDie("mdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         table.get(), "android:drawable/icon",
+                         test::ParseConfigOrDie("hdpi")));
+  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
+                         table.get(), "android:drawable/icon",
+                         test::ParseConfigOrDie("xhdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         table.get(), "android:drawable/icon",
+                         test::ParseConfigOrDie("xxhdpi")));
+  EXPECT_NE(nullptr, test::GetValue<Id>(table.get(), "android:string/one"));
 }
 
 TEST(TableSplitterTest, SplitTableByDensity) {
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .addFileReference("android:drawable/foo", "res/drawable-mdpi/foo.png",
-                              test::parseConfigOrDie("mdpi"))
-            .addFileReference("android:drawable/foo", "res/drawable-hdpi/foo.png",
-                              test::parseConfigOrDie("hdpi"))
-            .addFileReference("android:drawable/foo", "res/drawable-xhdpi/foo.png",
-                              test::parseConfigOrDie("xhdpi"))
-            .addFileReference("android:drawable/foo", "res/drawable-xxhdpi/foo.png",
-                              test::parseConfigOrDie("xxhdpi"))
-            .build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .AddFileReference("android:drawable/foo", "res/drawable-mdpi/foo.png",
+                            test::ParseConfigOrDie("mdpi"))
+          .AddFileReference("android:drawable/foo", "res/drawable-hdpi/foo.png",
+                            test::ParseConfigOrDie("hdpi"))
+          .AddFileReference("android:drawable/foo",
+                            "res/drawable-xhdpi/foo.png",
+                            test::ParseConfigOrDie("xhdpi"))
+          .AddFileReference("android:drawable/foo",
+                            "res/drawable-xxhdpi/foo.png",
+                            test::ParseConfigOrDie("xxhdpi"))
+          .Build();
 
-    std::vector<SplitConstraints> constraints;
-    constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("mdpi") } });
-    constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("hdpi") } });
-    constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("xhdpi") } });
+  std::vector<SplitConstraints> constraints;
+  constraints.push_back(SplitConstraints{{test::ParseConfigOrDie("mdpi")}});
+  constraints.push_back(SplitConstraints{{test::ParseConfigOrDie("hdpi")}});
+  constraints.push_back(SplitConstraints{{test::ParseConfigOrDie("xhdpi")}});
 
-    TableSplitter splitter(constraints, TableSplitterOptions{});
-    splitter.splitTable(table.get());
+  TableSplitter splitter(constraints, TableSplitterOptions{});
+  splitter.SplitTable(table.get());
 
-    ASSERT_EQ(3u, splitter.getSplits().size());
+  ASSERT_EQ(3u, splitter.splits().size());
 
-    ResourceTable* splitOne = splitter.getSplits()[0].get();
-    ResourceTable* splitTwo = splitter.getSplits()[1].get();
-    ResourceTable* splitThree = splitter.getSplits()[2].get();
+  ResourceTable* split_one = splitter.splits()[0].get();
+  ResourceTable* split_two = splitter.splits()[1].get();
+  ResourceTable* split_three = splitter.splits()[2].get();
 
-    // Just xxhdpi should be in the base.
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo",
-                                                              test::parseConfigOrDie("mdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo",
-                                                              test::parseConfigOrDie("hdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo",
-                                                              test::parseConfigOrDie("xhdpi")));
-    EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo",
-                                                              test::parseConfigOrDie("xxhdpi")));
+  // Just xxhdpi should be in the base.
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         table.get(), "android:drawable/foo",
+                         test::ParseConfigOrDie("mdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         table.get(), "android:drawable/foo",
+                         test::ParseConfigOrDie("hdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         table.get(), "android:drawable/foo",
+                         test::ParseConfigOrDie("xhdpi")));
+  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
+                         table.get(), "android:drawable/foo",
+                         test::ParseConfigOrDie("xxhdpi")));
 
-    // Each split should have one and only one drawable.
-    EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo",
-                                                              test::parseConfigOrDie("mdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo",
-                                                              test::parseConfigOrDie("hdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo",
-                                                              test::parseConfigOrDie("xhdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo",
-                                                              test::parseConfigOrDie("xxhdpi")));
+  // Each split should have one and only one drawable.
+  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
+                         split_one, "android:drawable/foo",
+                         test::ParseConfigOrDie("mdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         split_one, "android:drawable/foo",
+                         test::ParseConfigOrDie("hdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         split_one, "android:drawable/foo",
+                         test::ParseConfigOrDie("xhdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         split_one, "android:drawable/foo",
+                         test::ParseConfigOrDie("xxhdpi")));
 
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo",
-                                                              test::parseConfigOrDie("mdpi")));
-    EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo",
-                                                              test::parseConfigOrDie("hdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo",
-                                                              test::parseConfigOrDie("xhdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo",
-                                                              test::parseConfigOrDie("xxhdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         split_two, "android:drawable/foo",
+                         test::ParseConfigOrDie("mdpi")));
+  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
+                         split_two, "android:drawable/foo",
+                         test::ParseConfigOrDie("hdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         split_two, "android:drawable/foo",
+                         test::ParseConfigOrDie("xhdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         split_two, "android:drawable/foo",
+                         test::ParseConfigOrDie("xxhdpi")));
 
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo",
-                                                              test::parseConfigOrDie("mdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo",
-                                                              test::parseConfigOrDie("hdpi")));
-    EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo",
-                                                              test::parseConfigOrDie("xhdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo",
-                                                              test::parseConfigOrDie("xxhdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         split_three, "android:drawable/foo",
+                         test::ParseConfigOrDie("mdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         split_three, "android:drawable/foo",
+                         test::ParseConfigOrDie("hdpi")));
+  EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>(
+                         split_three, "android:drawable/foo",
+                         test::ParseConfigOrDie("xhdpi")));
+  EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>(
+                         split_three, "android:drawable/foo",
+                         test::ParseConfigOrDie("xxhdpi")));
 }
 
 TEST(TableSplitterTest, SplitTableByConfigAndDensity) {
-    ResourceTable table;
+  ResourceTable table;
 
-    const ResourceName foo = test::parseNameOrDie("android:string/foo");
-    ASSERT_TRUE(table.addResource(foo, test::parseConfigOrDie("land-hdpi"), {},
-                                  util::make_unique<Id>(),
-                                  test::getDiagnostics()));
-    ASSERT_TRUE(table.addResource(foo, test::parseConfigOrDie("land-xhdpi"), {},
-                                  util::make_unique<Id>(),
-                                  test::getDiagnostics()));
-    ASSERT_TRUE(table.addResource(foo, test::parseConfigOrDie("land-xxhdpi"), {},
-                                  util::make_unique<Id>(),
-                                  test::getDiagnostics()));
+  const ResourceName foo = test::ParseNameOrDie("android:string/foo");
+  ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-hdpi"), {},
+                                util::make_unique<Id>(),
+                                test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-xhdpi"), {},
+                                util::make_unique<Id>(),
+                                test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-xxhdpi"), {},
+                                util::make_unique<Id>(),
+                                test::GetDiagnostics()));
 
-    std::vector<SplitConstraints> constraints;
-    constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("land-mdpi") } });
-    constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("land-xhdpi") } });
+  std::vector<SplitConstraints> constraints;
+  constraints.push_back(
+      SplitConstraints{{test::ParseConfigOrDie("land-mdpi")}});
+  constraints.push_back(
+      SplitConstraints{{test::ParseConfigOrDie("land-xhdpi")}});
 
-    TableSplitter splitter(constraints, TableSplitterOptions{});
-    splitter.splitTable(&table);
+  TableSplitter splitter(constraints, TableSplitterOptions{});
+  splitter.SplitTable(&table);
 
-    ASSERT_EQ(2u, splitter.getSplits().size());
+  ASSERT_EQ(2u, splitter.splits().size());
 
-    ResourceTable* splitOne = splitter.getSplits()[0].get();
-    ResourceTable* splitTwo = splitter.getSplits()[1].get();
+  ResourceTable* split_one = splitter.splits()[0].get();
+  ResourceTable* split_two = splitter.splits()[1].get();
 
-    // All but the xxhdpi resource should be gone, since there were closer matches in land-xhdpi.
-    EXPECT_EQ(nullptr, test::getValueForConfig<Id>(&table, "android:string/foo",
-                                                   test::parseConfigOrDie("land-hdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<Id>(&table, "android:string/foo",
-                                                   test::parseConfigOrDie("land-xhdpi")));
-    EXPECT_NE(nullptr, test::getValueForConfig<Id>(&table, "android:string/foo",
-                                                   test::parseConfigOrDie("land-xxhdpi")));
+  // All but the xxhdpi resource should be gone, since there were closer matches
+  // in land-xhdpi.
+  EXPECT_EQ(nullptr,
+            test::GetValueForConfig<Id>(&table, "android:string/foo",
+                                        test::ParseConfigOrDie("land-hdpi")));
+  EXPECT_EQ(nullptr,
+            test::GetValueForConfig<Id>(&table, "android:string/foo",
+                                        test::ParseConfigOrDie("land-xhdpi")));
+  EXPECT_NE(nullptr,
+            test::GetValueForConfig<Id>(&table, "android:string/foo",
+                                        test::ParseConfigOrDie("land-xxhdpi")));
 
-    EXPECT_NE(nullptr, test::getValueForConfig<Id>(splitOne, "android:string/foo",
-                                                   test::parseConfigOrDie("land-hdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<Id>(splitOne, "android:string/foo",
-                                                   test::parseConfigOrDie("land-xhdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<Id>(splitOne, "android:string/foo",
-                                                   test::parseConfigOrDie("land-xxhdpi")));
+  EXPECT_NE(nullptr,
+            test::GetValueForConfig<Id>(split_one, "android:string/foo",
+                                        test::ParseConfigOrDie("land-hdpi")));
+  EXPECT_EQ(nullptr,
+            test::GetValueForConfig<Id>(split_one, "android:string/foo",
+                                        test::ParseConfigOrDie("land-xhdpi")));
+  EXPECT_EQ(nullptr,
+            test::GetValueForConfig<Id>(split_one, "android:string/foo",
+                                        test::ParseConfigOrDie("land-xxhdpi")));
 
-    EXPECT_EQ(nullptr, test::getValueForConfig<Id>(splitTwo, "android:string/foo",
-                                                   test::parseConfigOrDie("land-hdpi")));
-    EXPECT_NE(nullptr, test::getValueForConfig<Id>(splitTwo, "android:string/foo",
-                                                   test::parseConfigOrDie("land-xhdpi")));
-    EXPECT_EQ(nullptr, test::getValueForConfig<Id>(splitTwo, "android:string/foo",
-                                                   test::parseConfigOrDie("land-xxhdpi")));
+  EXPECT_EQ(nullptr,
+            test::GetValueForConfig<Id>(split_two, "android:string/foo",
+                                        test::ParseConfigOrDie("land-hdpi")));
+  EXPECT_NE(nullptr,
+            test::GetValueForConfig<Id>(split_two, "android:string/foo",
+                                        test::ParseConfigOrDie("land-xhdpi")));
+  EXPECT_EQ(nullptr,
+            test::GetValueForConfig<Id>(split_two, "android:string/foo",
+                                        test::ParseConfigOrDie("land-xxhdpi")));
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h
index c647159..9377306 100644
--- a/tools/aapt2/test/Builders.h
+++ b/tools/aapt2/test/Builders.h
@@ -17,139 +17,142 @@
 #ifndef AAPT_TEST_BUILDERS_H
 #define AAPT_TEST_BUILDERS_H
 
+#include <memory>
+
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+
 #include "ResourceTable.h"
 #include "ResourceValues.h"
 #include "test/Common.h"
 #include "util/Util.h"
 #include "xml/XmlDom.h"
 
-#include <memory>
-
 namespace aapt {
 namespace test {
 
 class ResourceTableBuilder {
- private:
-  DummyDiagnosticsImpl mDiagnostics;
-  std::unique_ptr<ResourceTable> mTable = util::make_unique<ResourceTable>();
-
  public:
   ResourceTableBuilder() = default;
 
-  StringPool* getStringPool() { return &mTable->stringPool; }
+  StringPool* string_pool() { return &table_->string_pool; }
 
-  ResourceTableBuilder& setPackageId(const StringPiece& packageName,
+  ResourceTableBuilder& SetPackageId(const StringPiece& package_name,
                                      uint8_t id) {
-    ResourceTablePackage* package = mTable->createPackage(packageName, id);
-    assert(package);
+    ResourceTablePackage* package = table_->CreatePackage(package_name, id);
+    CHECK(package != nullptr);
     return *this;
   }
 
-  ResourceTableBuilder& addSimple(const StringPiece& name,
+  ResourceTableBuilder& AddSimple(const StringPiece& name,
                                   const ResourceId& id = {}) {
-    return addValue(name, id, util::make_unique<Id>());
+    return AddValue(name, id, util::make_unique<Id>());
   }
 
-  ResourceTableBuilder& addSimple(const StringPiece& name,
+  ResourceTableBuilder& AddSimple(const StringPiece& name,
                                   const ConfigDescription& config,
                                   const ResourceId& id = {}) {
-    return addValue(name, config, id, util::make_unique<Id>());
+    return AddValue(name, config, id, util::make_unique<Id>());
   }
 
-  ResourceTableBuilder& addReference(const StringPiece& name,
+  ResourceTableBuilder& AddReference(const StringPiece& name,
                                      const StringPiece& ref) {
-    return addReference(name, {}, ref);
+    return AddReference(name, {}, ref);
   }
 
-  ResourceTableBuilder& addReference(const StringPiece& name,
+  ResourceTableBuilder& AddReference(const StringPiece& name,
                                      const ResourceId& id,
                                      const StringPiece& ref) {
-    return addValue(name, id,
-                    util::make_unique<Reference>(parseNameOrDie(ref)));
+    return AddValue(name, id,
+                    util::make_unique<Reference>(ParseNameOrDie(ref)));
   }
 
-  ResourceTableBuilder& addString(const StringPiece& name,
+  ResourceTableBuilder& AddString(const StringPiece& name,
                                   const StringPiece& str) {
-    return addString(name, {}, str);
+    return AddString(name, {}, str);
   }
 
-  ResourceTableBuilder& addString(const StringPiece& name, const ResourceId& id,
+  ResourceTableBuilder& AddString(const StringPiece& name, const ResourceId& id,
                                   const StringPiece& str) {
-    return addValue(name, id,
-                    util::make_unique<String>(mTable->stringPool.makeRef(str)));
+    return AddValue(
+        name, id, util::make_unique<String>(table_->string_pool.MakeRef(str)));
   }
 
-  ResourceTableBuilder& addString(const StringPiece& name, const ResourceId& id,
+  ResourceTableBuilder& AddString(const StringPiece& name, const ResourceId& id,
                                   const ConfigDescription& config,
                                   const StringPiece& str) {
-    return addValue(name, config, id,
-                    util::make_unique<String>(mTable->stringPool.makeRef(str)));
+    return AddValue(name, config, id, util::make_unique<String>(
+                                          table_->string_pool.MakeRef(str)));
   }
 
-  ResourceTableBuilder& addFileReference(const StringPiece& name,
+  ResourceTableBuilder& AddFileReference(const StringPiece& name,
                                          const StringPiece& path) {
-    return addFileReference(name, {}, path);
+    return AddFileReference(name, {}, path);
   }
 
-  ResourceTableBuilder& addFileReference(const StringPiece& name,
+  ResourceTableBuilder& AddFileReference(const StringPiece& name,
                                          const ResourceId& id,
                                          const StringPiece& path) {
-    return addValue(name, id, util::make_unique<FileReference>(
-                                  mTable->stringPool.makeRef(path)));
+    return AddValue(name, id, util::make_unique<FileReference>(
+                                  table_->string_pool.MakeRef(path)));
   }
 
-  ResourceTableBuilder& addFileReference(const StringPiece& name,
+  ResourceTableBuilder& AddFileReference(const StringPiece& name,
                                          const StringPiece& path,
                                          const ConfigDescription& config) {
-    return addValue(name, config, {}, util::make_unique<FileReference>(
-                                          mTable->stringPool.makeRef(path)));
+    return AddValue(name, config, {}, util::make_unique<FileReference>(
+                                          table_->string_pool.MakeRef(path)));
   }
 
-  ResourceTableBuilder& addValue(const StringPiece& name,
+  ResourceTableBuilder& AddValue(const StringPiece& name,
                                  std::unique_ptr<Value> value) {
-    return addValue(name, {}, std::move(value));
+    return AddValue(name, {}, std::move(value));
   }
 
-  ResourceTableBuilder& addValue(const StringPiece& name, const ResourceId& id,
+  ResourceTableBuilder& AddValue(const StringPiece& name, const ResourceId& id,
                                  std::unique_ptr<Value> value) {
-    return addValue(name, {}, id, std::move(value));
+    return AddValue(name, {}, id, std::move(value));
   }
 
-  ResourceTableBuilder& addValue(const StringPiece& name,
+  ResourceTableBuilder& AddValue(const StringPiece& name,
                                  const ConfigDescription& config,
                                  const ResourceId& id,
                                  std::unique_ptr<Value> value) {
-    ResourceName resName = parseNameOrDie(name);
-    bool result = mTable->addResourceAllowMangled(
-        resName, id, config, {}, std::move(value), &mDiagnostics);
-    assert(result);
+    ResourceName res_name = ParseNameOrDie(name);
+    CHECK(table_->AddResourceAllowMangled(res_name, id, config, {},
+                                          std::move(value), &diagnostics_));
     return *this;
   }
 
-  ResourceTableBuilder& setSymbolState(const StringPiece& name,
+  ResourceTableBuilder& SetSymbolState(const StringPiece& name,
                                        const ResourceId& id,
                                        SymbolState state) {
-    ResourceName resName = parseNameOrDie(name);
+    ResourceName res_name = ParseNameOrDie(name);
     Symbol symbol;
     symbol.state = state;
-    bool result =
-        mTable->setSymbolStateAllowMangled(resName, id, symbol, &mDiagnostics);
-    assert(result);
+    CHECK(table_->SetSymbolStateAllowMangled(res_name, id, symbol,
+                                             &diagnostics_));
     return *this;
   }
 
-  std::unique_ptr<ResourceTable> build() { return std::move(mTable); }
+  std::unique_ptr<ResourceTable> Build() { return std::move(table_); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ResourceTableBuilder);
+
+  DummyDiagnosticsImpl diagnostics_;
+  std::unique_ptr<ResourceTable> table_ = util::make_unique<ResourceTable>();
 };
 
-inline std::unique_ptr<Reference> buildReference(
+inline std::unique_ptr<Reference> BuildReference(
     const StringPiece& ref, const Maybe<ResourceId>& id = {}) {
   std::unique_ptr<Reference> reference =
-      util::make_unique<Reference>(parseNameOrDie(ref));
+      util::make_unique<Reference>(ParseNameOrDie(ref));
   reference->id = id;
   return reference;
 }
 
-inline std::unique_ptr<BinaryPrimitive> buildPrimitive(uint8_t type,
+inline std::unique_ptr<BinaryPrimitive> BuildPrimitive(uint8_t type,
                                                        uint32_t data) {
   android::Res_value value = {};
   value.size = sizeof(value);
@@ -160,107 +163,119 @@
 
 template <typename T>
 class ValueBuilder {
- private:
-  std::unique_ptr<Value> mValue;
-
  public:
   template <typename... Args>
   explicit ValueBuilder(Args&&... args)
-      : mValue(new T{std::forward<Args>(args)...}) {}
+      : value_(new T{std::forward<Args>(args)...}) {}
 
   template <typename... Args>
-  ValueBuilder& setSource(Args&&... args) {
-    mValue->setSource(Source{std::forward<Args>(args)...});
+  ValueBuilder& SetSource(Args&&... args) {
+    value_->SetSource(Source{std::forward<Args>(args)...});
     return *this;
   }
 
-  ValueBuilder& setComment(const StringPiece& str) {
-    mValue->setComment(str);
+  ValueBuilder& SetComment(const StringPiece& str) {
+    value_->SetComment(str);
     return *this;
   }
 
-  std::unique_ptr<Value> build() { return std::move(mValue); }
+  std::unique_ptr<Value> Build() { return std::move(value_); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ValueBuilder);
+
+  std::unique_ptr<Value> value_;
 };
 
 class AttributeBuilder {
- private:
-  std::unique_ptr<Attribute> mAttr;
-
  public:
   explicit AttributeBuilder(bool weak = false)
-      : mAttr(util::make_unique<Attribute>(weak)) {
-    mAttr->typeMask = android::ResTable_map::TYPE_ANY;
+      : attr_(util::make_unique<Attribute>(weak)) {
+    attr_->type_mask = android::ResTable_map::TYPE_ANY;
   }
 
-  AttributeBuilder& setTypeMask(uint32_t typeMask) {
-    mAttr->typeMask = typeMask;
+  AttributeBuilder& SetTypeMask(uint32_t typeMask) {
+    attr_->type_mask = typeMask;
     return *this;
   }
 
-  AttributeBuilder& addItem(const StringPiece& name, uint32_t value) {
-    mAttr->symbols.push_back(Attribute::Symbol{
+  AttributeBuilder& AddItem(const StringPiece& name, uint32_t value) {
+    attr_->symbols.push_back(Attribute::Symbol{
         Reference(ResourceName({}, ResourceType::kId, name)), value});
     return *this;
   }
 
-  std::unique_ptr<Attribute> build() { return std::move(mAttr); }
+  std::unique_ptr<Attribute> Build() { return std::move(attr_); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AttributeBuilder);
+
+  std::unique_ptr<Attribute> attr_;
 };
 
 class StyleBuilder {
- private:
-  std::unique_ptr<Style> mStyle = util::make_unique<Style>();
-
  public:
-  StyleBuilder& setParent(const StringPiece& str) {
-    mStyle->parent = Reference(parseNameOrDie(str));
+  StyleBuilder() = default;
+
+  StyleBuilder& SetParent(const StringPiece& str) {
+    style_->parent = Reference(ParseNameOrDie(str));
     return *this;
   }
 
-  StyleBuilder& addItem(const StringPiece& str, std::unique_ptr<Item> value) {
-    mStyle->entries.push_back(
-        Style::Entry{Reference(parseNameOrDie(str)), std::move(value)});
+  StyleBuilder& AddItem(const StringPiece& str, std::unique_ptr<Item> value) {
+    style_->entries.push_back(
+        Style::Entry{Reference(ParseNameOrDie(str)), std::move(value)});
     return *this;
   }
 
-  StyleBuilder& addItem(const StringPiece& str, const ResourceId& id,
+  StyleBuilder& AddItem(const StringPiece& str, const ResourceId& id,
                         std::unique_ptr<Item> value) {
-    addItem(str, std::move(value));
-    mStyle->entries.back().key.id = id;
+    AddItem(str, std::move(value));
+    style_->entries.back().key.id = id;
     return *this;
   }
 
-  std::unique_ptr<Style> build() { return std::move(mStyle); }
+  std::unique_ptr<Style> Build() { return std::move(style_); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(StyleBuilder);
+
+  std::unique_ptr<Style> style_ = util::make_unique<Style>();
 };
 
 class StyleableBuilder {
- private:
-  std::unique_ptr<Styleable> mStyleable = util::make_unique<Styleable>();
-
  public:
-  StyleableBuilder& addItem(const StringPiece& str,
+  StyleableBuilder() = default;
+
+  StyleableBuilder& AddItem(const StringPiece& str,
                             const Maybe<ResourceId>& id = {}) {
-    mStyleable->entries.push_back(Reference(parseNameOrDie(str)));
-    mStyleable->entries.back().id = id;
+    styleable_->entries.push_back(Reference(ParseNameOrDie(str)));
+    styleable_->entries.back().id = id;
     return *this;
   }
 
-  std::unique_ptr<Styleable> build() { return std::move(mStyleable); }
+  std::unique_ptr<Styleable> Build() { return std::move(styleable_); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(StyleableBuilder);
+
+  std::unique_ptr<Styleable> styleable_ = util::make_unique<Styleable>();
 };
 
-inline std::unique_ptr<xml::XmlResource> buildXmlDom(const StringPiece& str) {
+inline std::unique_ptr<xml::XmlResource> BuildXmlDom(const StringPiece& str) {
   std::stringstream in;
   in << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" << str;
   StdErrDiagnostics diag;
   std::unique_ptr<xml::XmlResource> doc =
-      xml::inflate(&in, &diag, Source("test.xml"));
-  assert(doc);
+      xml::Inflate(&in, &diag, Source("test.xml"));
+  CHECK(doc != nullptr) << "failed to parse inline XML string";
   return doc;
 }
 
-inline std::unique_ptr<xml::XmlResource> buildXmlDomForPackageName(
+inline std::unique_ptr<xml::XmlResource> BuildXmlDomForPackageName(
     IAaptContext* context, const StringPiece& str) {
-  std::unique_ptr<xml::XmlResource> doc = buildXmlDom(str);
-  doc->file.name.package = context->getCompilationPackage();
+  std::unique_ptr<xml::XmlResource> doc = BuildXmlDom(str);
+  doc->file.name.package = context->GetCompilationPackage();
   return doc;
 }
 
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 2d571e7..3689201 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -17,6 +17,12 @@
 #ifndef AAPT_TEST_COMMON_H
 #define AAPT_TEST_COMMON_H
 
+#include <iostream>
+
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+#include "gtest/gtest.h"
+
 #include "ConfigDescription.h"
 #include "Debug.h"
 #include "ResourceTable.h"
@@ -26,9 +32,6 @@
 #include "process/IResourceTableConsumer.h"
 #include "util/StringPiece.h"
 
-#include <gtest/gtest.h>
-#include <iostream>
-
 //
 // GTEST 1.7 doesn't explicitly cast to bool, which causes explicit operators to
 // fail to compile.
@@ -42,80 +45,81 @@
 namespace test {
 
 struct DummyDiagnosticsImpl : public IDiagnostics {
-  void log(Level level, DiagMessageActual& actualMsg) override {
+  void Log(Level level, DiagMessageActual& actual_msg) override {
     switch (level) {
       case Level::Note:
         return;
 
       case Level::Warn:
-        std::cerr << actualMsg.source << ": warn: " << actualMsg.message << "."
-                  << std::endl;
+        std::cerr << actual_msg.source << ": warn: " << actual_msg.message
+                  << "." << std::endl;
         break;
 
       case Level::Error:
-        std::cerr << actualMsg.source << ": error: " << actualMsg.message << "."
-                  << std::endl;
+        std::cerr << actual_msg.source << ": error: " << actual_msg.message
+                  << "." << std::endl;
         break;
     }
   }
 };
 
-inline IDiagnostics* getDiagnostics() {
+inline IDiagnostics* GetDiagnostics() {
   static DummyDiagnosticsImpl diag;
   return &diag;
 }
 
-inline ResourceName parseNameOrDie(const StringPiece& str) {
+inline ResourceName ParseNameOrDie(const StringPiece& str) {
   ResourceNameRef ref;
-  bool result = ResourceUtils::parseResourceName(str, &ref);
-  assert(result && "invalid resource name");
-  return ref.toResourceName();
+  CHECK(ResourceUtils::ParseResourceName(str, &ref)) << "invalid resource name";
+  return ref.ToResourceName();
 }
 
-inline ConfigDescription parseConfigOrDie(const StringPiece& str) {
+inline ConfigDescription ParseConfigOrDie(const StringPiece& str) {
   ConfigDescription config;
-  bool result = ConfigDescription::parse(str, &config);
-  assert(result && "invalid configuration");
+  CHECK(ConfigDescription::Parse(str, &config)) << "invalid configuration";
   return config;
 }
 
 template <typename T>
-T* getValueForConfigAndProduct(ResourceTable* table, const StringPiece& resName,
+T* GetValueForConfigAndProduct(ResourceTable* table,
+                               const StringPiece& res_name,
                                const ConfigDescription& config,
                                const StringPiece& product) {
   Maybe<ResourceTable::SearchResult> result =
-      table->findResource(parseNameOrDie(resName));
+      table->FindResource(ParseNameOrDie(res_name));
   if (result) {
-    ResourceConfigValue* configValue =
-        result.value().entry->findValue(config, product);
-    if (configValue) {
-      return valueCast<T>(configValue->value.get());
+    ResourceConfigValue* config_value =
+        result.value().entry->FindValue(config, product);
+    if (config_value) {
+      return ValueCast<T>(config_value->value.get());
     }
   }
   return nullptr;
 }
 
 template <typename T>
-T* getValueForConfig(ResourceTable* table, const StringPiece& resName,
+T* GetValueForConfig(ResourceTable* table, const StringPiece& res_name,
                      const ConfigDescription& config) {
-  return getValueForConfigAndProduct<T>(table, resName, config, {});
+  return GetValueForConfigAndProduct<T>(table, res_name, config, {});
 }
 
 template <typename T>
-T* getValue(ResourceTable* table, const StringPiece& resName) {
-  return getValueForConfig<T>(table, resName, {});
+T* GetValue(ResourceTable* table, const StringPiece& res_name) {
+  return GetValueForConfig<T>(table, res_name, {});
 }
 
 class TestFile : public io::IFile {
- private:
-  Source mSource;
-
  public:
-  explicit TestFile(const StringPiece& path) : mSource(path) {}
+  explicit TestFile(const StringPiece& path) : source_(path) {}
 
-  std::unique_ptr<io::IData> openAsData() override { return {}; }
+  std::unique_ptr<io::IData> OpenAsData() override { return {}; }
 
-  const Source& getSource() const override { return mSource; }
+  const Source& GetSource() const override { return source_; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestFile);
+
+  Source source_;
 };
 
 }  // namespace test
diff --git a/tools/aapt2/test/Context.h b/tools/aapt2/test/Context.h
index 6c7f6f7..7986329 100644
--- a/tools/aapt2/test/Context.h
+++ b/tools/aapt2/test/Context.h
@@ -17,152 +17,158 @@
 #ifndef AAPT_TEST_CONTEXT_H
 #define AAPT_TEST_CONTEXT_H
 
+#include <list>
+
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+
 #include "NameMangler.h"
 #include "process/IResourceTableConsumer.h"
 #include "process/SymbolTable.h"
 #include "test/Common.h"
 #include "util/Util.h"
 
-#include <cassert>
-#include <list>
-
 namespace aapt {
 namespace test {
 
 class Context : public IAaptContext {
  public:
-  SymbolTable* getExternalSymbols() override { return &mSymbols; }
+  Context() = default;
 
-  IDiagnostics* getDiagnostics() override { return &mDiagnostics; }
+  SymbolTable* GetExternalSymbols() override { return &symbols_; }
 
-  const std::string& getCompilationPackage() override {
-    assert(mCompilationPackage && "package name not set");
-    return mCompilationPackage.value();
+  IDiagnostics* GetDiagnostics() override { return &diagnostics_; }
+
+  const std::string& GetCompilationPackage() override {
+    CHECK(bool(compilation_package_)) << "package name not set";
+    return compilation_package_.value();
   }
 
-  uint8_t getPackageId() override {
-    assert(mPackageId && "package ID not set");
-    return mPackageId.value();
+  uint8_t GetPackageId() override {
+    CHECK(bool(package_id_)) << "package ID not set";
+    return package_id_.value();
   }
 
-  NameMangler* getNameMangler() override { return &mNameMangler; }
+  NameMangler* GetNameMangler() override { return &name_mangler_; }
 
-  bool verbose() override { return false; }
+  bool IsVerbose() override { return false; }
 
-  int getMinSdkVersion() override { return mMinSdkVersion; }
+  int GetMinSdkVersion() override { return min_sdk_version_; }
 
  private:
+  DISALLOW_COPY_AND_ASSIGN(Context);
+
   friend class ContextBuilder;
 
-  Maybe<std::string> mCompilationPackage;
-  Maybe<uint8_t> mPackageId;
-  StdErrDiagnostics mDiagnostics;
-  SymbolTable mSymbols;
-  NameMangler mNameMangler = NameMangler({});
-  int mMinSdkVersion = 0;
+  Maybe<std::string> compilation_package_;
+  Maybe<uint8_t> package_id_;
+  StdErrDiagnostics diagnostics_;
+  SymbolTable symbols_;
+  NameMangler name_mangler_ = NameMangler({});
+  int min_sdk_version_ = 0;
 };
 
 class ContextBuilder {
- private:
-  std::unique_ptr<Context> mContext = std::unique_ptr<Context>(new Context());
-
  public:
-  ContextBuilder& setCompilationPackage(const StringPiece& package) {
-    mContext->mCompilationPackage = package.toString();
+  ContextBuilder& SetCompilationPackage(const StringPiece& package) {
+    context_->compilation_package_ = package.ToString();
     return *this;
   }
 
-  ContextBuilder& setPackageId(uint8_t id) {
-    mContext->mPackageId = id;
+  ContextBuilder& SetPackageId(uint8_t id) {
+    context_->package_id_ = id;
     return *this;
   }
 
-  ContextBuilder& setNameManglerPolicy(const NameManglerPolicy& policy) {
-    mContext->mNameMangler = NameMangler(policy);
+  ContextBuilder& SetNameManglerPolicy(const NameManglerPolicy& policy) {
+    context_->name_mangler_ = NameMangler(policy);
     return *this;
   }
 
-  ContextBuilder& addSymbolSource(std::unique_ptr<ISymbolSource> src) {
-    mContext->getExternalSymbols()->appendSource(std::move(src));
+  ContextBuilder& AddSymbolSource(std::unique_ptr<ISymbolSource> src) {
+    context_->GetExternalSymbols()->AppendSource(std::move(src));
     return *this;
   }
 
-  ContextBuilder& setMinSdkVersion(int minSdk) {
-    mContext->mMinSdkVersion = minSdk;
+  ContextBuilder& SetMinSdkVersion(int min_sdk) {
+    context_->min_sdk_version_ = min_sdk;
     return *this;
   }
 
-  std::unique_ptr<Context> build() { return std::move(mContext); }
+  std::unique_ptr<Context> Build() { return std::move(context_); }
+
+ private:
+  std::unique_ptr<Context> context_ = std::unique_ptr<Context>(new Context());
 };
 
 class StaticSymbolSourceBuilder {
  public:
-  StaticSymbolSourceBuilder& addPublicSymbol(
+  StaticSymbolSourceBuilder& AddPublicSymbol(
       const StringPiece& name, ResourceId id,
       std::unique_ptr<Attribute> attr = {}) {
     std::unique_ptr<SymbolTable::Symbol> symbol =
         util::make_unique<SymbolTable::Symbol>(id, std::move(attr), true);
-    mSymbolSource->mNameMap[parseNameOrDie(name)] = symbol.get();
-    mSymbolSource->mIdMap[id] = symbol.get();
-    mSymbolSource->mSymbols.push_back(std::move(symbol));
+    symbol_source_->name_map_[ParseNameOrDie(name)] = symbol.get();
+    symbol_source_->id_map_[id] = symbol.get();
+    symbol_source_->symbols_.push_back(std::move(symbol));
     return *this;
   }
 
-  StaticSymbolSourceBuilder& addSymbol(const StringPiece& name, ResourceId id,
+  StaticSymbolSourceBuilder& AddSymbol(const StringPiece& name, ResourceId id,
                                        std::unique_ptr<Attribute> attr = {}) {
     std::unique_ptr<SymbolTable::Symbol> symbol =
         util::make_unique<SymbolTable::Symbol>(id, std::move(attr), false);
-    mSymbolSource->mNameMap[parseNameOrDie(name)] = symbol.get();
-    mSymbolSource->mIdMap[id] = symbol.get();
-    mSymbolSource->mSymbols.push_back(std::move(symbol));
+    symbol_source_->name_map_[ParseNameOrDie(name)] = symbol.get();
+    symbol_source_->id_map_[id] = symbol.get();
+    symbol_source_->symbols_.push_back(std::move(symbol));
     return *this;
   }
 
-  std::unique_ptr<ISymbolSource> build() { return std::move(mSymbolSource); }
+  std::unique_ptr<ISymbolSource> Build() { return std::move(symbol_source_); }
 
  private:
   class StaticSymbolSource : public ISymbolSource {
    public:
     StaticSymbolSource() = default;
 
-    std::unique_ptr<SymbolTable::Symbol> findByName(
+    std::unique_ptr<SymbolTable::Symbol> FindByName(
         const ResourceName& name) override {
-      auto iter = mNameMap.find(name);
-      if (iter != mNameMap.end()) {
-        return cloneSymbol(iter->second);
+      auto iter = name_map_.find(name);
+      if (iter != name_map_.end()) {
+        return CloneSymbol(iter->second);
       }
       return nullptr;
     }
 
-    std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) override {
-      auto iter = mIdMap.find(id);
-      if (iter != mIdMap.end()) {
-        return cloneSymbol(iter->second);
+    std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) override {
+      auto iter = id_map_.find(id);
+      if (iter != id_map_.end()) {
+        return CloneSymbol(iter->second);
       }
       return nullptr;
     }
 
-    std::list<std::unique_ptr<SymbolTable::Symbol>> mSymbols;
-    std::map<ResourceName, SymbolTable::Symbol*> mNameMap;
-    std::map<ResourceId, SymbolTable::Symbol*> mIdMap;
+    std::list<std::unique_ptr<SymbolTable::Symbol>> symbols_;
+    std::map<ResourceName, SymbolTable::Symbol*> name_map_;
+    std::map<ResourceId, SymbolTable::Symbol*> id_map_;
 
    private:
-    std::unique_ptr<SymbolTable::Symbol> cloneSymbol(SymbolTable::Symbol* sym) {
+    std::unique_ptr<SymbolTable::Symbol> CloneSymbol(SymbolTable::Symbol* sym) {
       std::unique_ptr<SymbolTable::Symbol> clone =
           util::make_unique<SymbolTable::Symbol>();
       clone->id = sym->id;
       if (sym->attribute) {
         clone->attribute =
-            std::unique_ptr<Attribute>(sym->attribute->clone(nullptr));
+            std::unique_ptr<Attribute>(sym->attribute->Clone(nullptr));
       }
-      clone->isPublic = sym->isPublic;
+      clone->is_public = sym->is_public;
       return clone;
     }
 
     DISALLOW_COPY_AND_ASSIGN(StaticSymbolSource);
   };
 
-  std::unique_ptr<StaticSymbolSource> mSymbolSource =
+  std::unique_ptr<StaticSymbolSource> symbol_source_ =
       util::make_unique<StaticSymbolSource>();
 };
 
diff --git a/tools/aapt2/test/Test.h b/tools/aapt2/test/Test.h
index c9188bf..ec07432 100644
--- a/tools/aapt2/test/Test.h
+++ b/tools/aapt2/test/Test.h
@@ -17,14 +17,10 @@
 #ifndef AAPT_TEST_TEST_H
 #define AAPT_TEST_TEST_H
 
+#include "gtest/gtest.h"
+
 #include "test/Builders.h"
 #include "test/Common.h"
 #include "test/Context.h"
 
-#include <gtest/gtest.h>
-
-namespace aapt {
-namespace test {}  // namespace test
-}  // namespace aapt
-
 #endif  // AAPT_TEST_TEST_H
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp
index 4fd77c8..aeabcff 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -14,22 +14,25 @@
  * limitations under the License.
  */
 
+#include "unflatten/BinaryResourceParser.h"
+
+#include <algorithm>
+#include <map>
+#include <string>
+
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+#include "androidfw/ResourceTypes.h"
+#include "androidfw/TypeWrappers.h"
+
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
 #include "Source.h"
 #include "ValueVisitor.h"
-#include "unflatten/BinaryResourceParser.h"
 #include "unflatten/ResChunkPullParser.h"
 #include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
-#include <androidfw/TypeWrappers.h>
-#include <android-base/macros.h>
-#include <algorithm>
-#include <map>
-#include <string>
-
 namespace aapt {
 
 using namespace android;
@@ -41,533 +44,552 @@
  * given a mapping from resource ID to resource name.
  */
 class ReferenceIdToNameVisitor : public ValueVisitor {
-private:
-    const std::map<ResourceId, ResourceName>* mMapping;
+ public:
+  using ValueVisitor::Visit;
 
-public:
-    using ValueVisitor::visit;
+  explicit ReferenceIdToNameVisitor(
+      const std::map<ResourceId, ResourceName>* mapping)
+      : mapping_(mapping) {
+    CHECK(mapping_ != nullptr);
+  }
 
-    explicit ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceName>* mapping) :
-            mMapping(mapping) {
-        assert(mMapping);
+  void Visit(Reference* reference) override {
+    if (!reference->id || !reference->id.value().is_valid()) {
+      return;
     }
 
-    void visit(Reference* reference) override {
-        if (!reference->id || !reference->id.value().isValid()) {
-            return;
-        }
-
-        ResourceId id = reference->id.value();
-        auto cacheIter = mMapping->find(id);
-        if (cacheIter != mMapping->end()) {
-            reference->name = cacheIter->second;
-        }
+    ResourceId id = reference->id.value();
+    auto cache_iter = mapping_->find(id);
+    if (cache_iter != mapping_->end()) {
+      reference->name = cache_iter->second;
     }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ReferenceIdToNameVisitor);
+
+  const std::map<ResourceId, ResourceName>* mapping_;
 };
 
-} // namespace
+}  // namespace
 
-BinaryResourceParser::BinaryResourceParser(IAaptContext* context, ResourceTable* table,
-                                           const Source& source, const void* data, size_t len) :
-        mContext(context), mTable(table), mSource(source), mData(data), mDataLen(len) {
-}
+BinaryResourceParser::BinaryResourceParser(IAaptContext* context,
+                                           ResourceTable* table,
+                                           const Source& source,
+                                           const void* data, size_t len)
+    : context_(context),
+      table_(table),
+      source_(source),
+      data_(data),
+      data_len_(len) {}
 
-bool BinaryResourceParser::parse() {
-    ResChunkPullParser parser(mData, mDataLen);
+bool BinaryResourceParser::Parse() {
+  ResChunkPullParser parser(data_, data_len_);
 
-    bool error = false;
-    while(ResChunkPullParser::isGoodEvent(parser.next())) {
-        if (parser.getChunk()->type != android::RES_TABLE_TYPE) {
-            mContext->getDiagnostics()->warn(DiagMessage(mSource)
-                                             << "unknown chunk of type '"
-                                             << (int) parser.getChunk()->type << "'");
-            continue;
-        }
-
-        if (!parseTable(parser.getChunk())) {
-            error = true;
-        }
+  bool error = false;
+  while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
+    if (parser.chunk()->type != android::RES_TABLE_TYPE) {
+      context_->GetDiagnostics()->Warn(DiagMessage(source_)
+                                       << "unknown chunk of type '"
+                                       << (int)parser.chunk()->type << "'");
+      continue;
     }
 
-    if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "corrupt resource table: "
-                                          << parser.getLastError());
-        return false;
+    if (!ParseTable(parser.chunk())) {
+      error = true;
     }
-    return !error;
+  }
+
+  if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
+    context_->GetDiagnostics()->Error(
+        DiagMessage(source_) << "corrupt resource table: " << parser.error());
+    return false;
+  }
+  return !error;
 }
 
 /**
- * Parses the resource table, which contains all the packages, types, and entries.
+ * Parses the resource table, which contains all the packages, types, and
+ * entries.
  */
-bool BinaryResourceParser::parseTable(const ResChunk_header* chunk) {
-    const ResTable_header* tableHeader = convertTo<ResTable_header>(chunk);
-    if (!tableHeader) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource) << "corrupt ResTable_header chunk");
-        return false;
-    }
+bool BinaryResourceParser::ParseTable(const ResChunk_header* chunk) {
+  const ResTable_header* table_header = ConvertTo<ResTable_header>(chunk);
+  if (!table_header) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                      << "corrupt ResTable_header chunk");
+    return false;
+  }
 
-    ResChunkPullParser parser(getChunkData(&tableHeader->header),
-                              getChunkDataLen(&tableHeader->header));
-    while (ResChunkPullParser::isGoodEvent(parser.next())) {
-        switch (util::deviceToHost16(parser.getChunk()->type)) {
-        case android::RES_STRING_POOL_TYPE:
-            if (mValuePool.getError() == NO_INIT) {
-                status_t err = mValuePool.setTo(parser.getChunk(),
-                                                util::deviceToHost32(parser.getChunk()->size));
-                if (err != NO_ERROR) {
-                    mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                                      << "corrupt string pool in ResTable: "
-                                                      << mValuePool.getError());
-                    return false;
-                }
+  ResChunkPullParser parser(GetChunkData(&table_header->header),
+                            GetChunkDataLen(&table_header->header));
+  while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
+    switch (util::DeviceToHost16(parser.chunk()->type)) {
+      case android::RES_STRING_POOL_TYPE:
+        if (value_pool_.getError() == NO_INIT) {
+          status_t err = value_pool_.setTo(
+              parser.chunk(), util::DeviceToHost32(parser.chunk()->size));
+          if (err != NO_ERROR) {
+            context_->GetDiagnostics()->Error(
+                DiagMessage(source_) << "corrupt string pool in ResTable: "
+                                     << value_pool_.getError());
+            return false;
+          }
 
-                // Reserve some space for the strings we are going to add.
-                mTable->stringPool.hintWillAdd(mValuePool.size(), mValuePool.styleCount());
-            } else {
-                mContext->getDiagnostics()->warn(DiagMessage(mSource)
-                                                 << "unexpected string pool in ResTable");
-            }
-            break;
-
-        case android::RES_TABLE_PACKAGE_TYPE:
-            if (!parsePackage(parser.getChunk())) {
-                return false;
-            }
-            break;
-
-        default:
-            mContext->getDiagnostics()
-                    ->warn(DiagMessage(mSource)
-                           << "unexpected chunk type "
-                           << (int) util::deviceToHost16(parser.getChunk()->type));
-            break;
+          // Reserve some space for the strings we are going to add.
+          table_->string_pool.HintWillAdd(value_pool_.size(),
+                                          value_pool_.styleCount());
+        } else {
+          context_->GetDiagnostics()->Warn(
+              DiagMessage(source_) << "unexpected string pool in ResTable");
         }
-    }
+        break;
 
-    if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "corrupt resource table: " << parser.getLastError());
-        return false;
-    }
-    return true;
-}
-
-
-bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) {
-    const ResTable_package* packageHeader = convertTo<ResTable_package>(chunk);
-    if (!packageHeader) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "corrupt ResTable_package chunk");
-        return false;
-    }
-
-    uint32_t packageId = util::deviceToHost32(packageHeader->id);
-    if (packageId > std::numeric_limits<uint8_t>::max()) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "package ID is too big (" << packageId << ")");
-        return false;
-    }
-
-    // Extract the package name.
-    size_t len = strnlen16((const char16_t*) packageHeader->name, arraysize(packageHeader->name));
-    std::u16string packageName;
-    packageName.resize(len);
-    for (size_t i = 0; i < len; i++) {
-        packageName[i] = util::deviceToHost16(packageHeader->name[i]);
-    }
-
-    ResourceTablePackage* package = mTable->createPackage(util::utf16ToUtf8(packageName),
-                                                          static_cast<uint8_t>(packageId));
-    if (!package) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "incompatible package '" << packageName
-                                          << "' with ID " << packageId);
-        return false;
-    }
-
-    // There can be multiple packages in a table, so
-    // clear the type and key pool in case they were set from a previous package.
-    mTypePool.uninit();
-    mKeyPool.uninit();
-
-    ResChunkPullParser parser(getChunkData(&packageHeader->header),
-                              getChunkDataLen(&packageHeader->header));
-    while (ResChunkPullParser::isGoodEvent(parser.next())) {
-        switch (util::deviceToHost16(parser.getChunk()->type)) {
-        case android::RES_STRING_POOL_TYPE:
-            if (mTypePool.getError() == NO_INIT) {
-                status_t err = mTypePool.setTo(parser.getChunk(),
-                                               util::deviceToHost32(parser.getChunk()->size));
-                if (err != NO_ERROR) {
-                    mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                                      << "corrupt type string pool in "
-                                                      << "ResTable_package: "
-                                                      << mTypePool.getError());
-                    return false;
-                }
-            } else if (mKeyPool.getError() == NO_INIT) {
-                status_t err = mKeyPool.setTo(parser.getChunk(),
-                                              util::deviceToHost32(parser.getChunk()->size));
-                if (err != NO_ERROR) {
-                    mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                                      << "corrupt key string pool in "
-                                                      << "ResTable_package: "
-                                                      << mKeyPool.getError());
-                    return false;
-                }
-            } else {
-                mContext->getDiagnostics()->warn(DiagMessage(mSource) << "unexpected string pool");
-            }
-            break;
-
-        case android::RES_TABLE_TYPE_SPEC_TYPE:
-            if (!parseTypeSpec(parser.getChunk())) {
-                return false;
-            }
-            break;
-
-        case android::RES_TABLE_TYPE_TYPE:
-            if (!parseType(package, parser.getChunk())) {
-                return false;
-            }
-            break;
-
-        default:
-            mContext->getDiagnostics()
-                    ->warn(DiagMessage(mSource)
-                           << "unexpected chunk type "
-                           << (int) util::deviceToHost16(parser.getChunk()->type));
-            break;
+      case android::RES_TABLE_PACKAGE_TYPE:
+        if (!ParsePackage(parser.chunk())) {
+          return false;
         }
-    }
+        break;
 
-    if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "corrupt ResTable_package: "
-                                          << parser.getLastError());
-        return false;
+      default:
+        context_->GetDiagnostics()->Warn(
+            DiagMessage(source_)
+            << "unexpected chunk type "
+            << (int)util::DeviceToHost16(parser.chunk()->type));
+        break;
     }
+  }
 
-    // Now go through the table and change local resource ID references to
-    // symbolic references.
-    ReferenceIdToNameVisitor visitor(&mIdIndex);
-    visitAllValuesInTable(mTable, &visitor);
-    return true;
+  if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
+    context_->GetDiagnostics()->Error(
+        DiagMessage(source_) << "corrupt resource table: " << parser.error());
+    return false;
+  }
+  return true;
 }
 
-bool BinaryResourceParser::parseTypeSpec(const ResChunk_header* chunk) {
-    if (mTypePool.getError() != NO_ERROR) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "missing type string pool");
-        return false;
-    }
+bool BinaryResourceParser::ParsePackage(const ResChunk_header* chunk) {
+  const ResTable_package* package_header = ConvertTo<ResTable_package>(chunk);
+  if (!package_header) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                      << "corrupt ResTable_package chunk");
+    return false;
+  }
 
-    const ResTable_typeSpec* typeSpec = convertTo<ResTable_typeSpec>(chunk);
-    if (!typeSpec) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "corrupt ResTable_typeSpec chunk");
-        return false;
-    }
+  uint32_t package_id = util::DeviceToHost32(package_header->id);
+  if (package_id > std::numeric_limits<uint8_t>::max()) {
+    context_->GetDiagnostics()->Error(
+        DiagMessage(source_) << "package ID is too big (" << package_id << ")");
+    return false;
+  }
 
-    if (typeSpec->id == 0) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "ResTable_typeSpec has invalid id: " << typeSpec->id);
-        return false;
+  // Extract the package name.
+  size_t len = strnlen16((const char16_t*)package_header->name,
+                         arraysize(package_header->name));
+  std::u16string package_name;
+  package_name.resize(len);
+  for (size_t i = 0; i < len; i++) {
+    package_name[i] = util::DeviceToHost16(package_header->name[i]);
+  }
+
+  ResourceTablePackage* package = table_->CreatePackage(
+      util::Utf16ToUtf8(package_name), static_cast<uint8_t>(package_id));
+  if (!package) {
+    context_->GetDiagnostics()->Error(
+        DiagMessage(source_) << "incompatible package '" << package_name
+                             << "' with ID " << package_id);
+    return false;
+  }
+
+  // There can be multiple packages in a table, so
+  // clear the type and key pool in case they were set from a previous package.
+  type_pool_.uninit();
+  key_pool_.uninit();
+
+  ResChunkPullParser parser(GetChunkData(&package_header->header),
+                            GetChunkDataLen(&package_header->header));
+  while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
+    switch (util::DeviceToHost16(parser.chunk()->type)) {
+      case android::RES_STRING_POOL_TYPE:
+        if (type_pool_.getError() == NO_INIT) {
+          status_t err = type_pool_.setTo(
+              parser.chunk(), util::DeviceToHost32(parser.chunk()->size));
+          if (err != NO_ERROR) {
+            context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                              << "corrupt type string pool in "
+                                              << "ResTable_package: "
+                                              << type_pool_.getError());
+            return false;
+          }
+        } else if (key_pool_.getError() == NO_INIT) {
+          status_t err = key_pool_.setTo(
+              parser.chunk(), util::DeviceToHost32(parser.chunk()->size));
+          if (err != NO_ERROR) {
+            context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                              << "corrupt key string pool in "
+                                              << "ResTable_package: "
+                                              << key_pool_.getError());
+            return false;
+          }
+        } else {
+          context_->GetDiagnostics()->Warn(DiagMessage(source_)
+                                           << "unexpected string pool");
+        }
+        break;
+
+      case android::RES_TABLE_TYPE_SPEC_TYPE:
+        if (!ParseTypeSpec(parser.chunk())) {
+          return false;
+        }
+        break;
+
+      case android::RES_TABLE_TYPE_TYPE:
+        if (!ParseType(package, parser.chunk())) {
+          return false;
+        }
+        break;
+
+      default:
+        context_->GetDiagnostics()->Warn(
+            DiagMessage(source_)
+            << "unexpected chunk type "
+            << (int)util::DeviceToHost16(parser.chunk()->type));
+        break;
     }
-    return true;
+  }
+
+  if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
+    context_->GetDiagnostics()->Error(
+        DiagMessage(source_) << "corrupt ResTable_package: " << parser.error());
+    return false;
+  }
+
+  // Now go through the table and change local resource ID references to
+  // symbolic references.
+  ReferenceIdToNameVisitor visitor(&id_index_);
+  VisitAllValuesInTable(table_, &visitor);
+  return true;
 }
 
-bool BinaryResourceParser::parseType(const ResourceTablePackage* package,
+bool BinaryResourceParser::ParseTypeSpec(const ResChunk_header* chunk) {
+  if (type_pool_.getError() != NO_ERROR) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                      << "missing type string pool");
+    return false;
+  }
+
+  const ResTable_typeSpec* type_spec = ConvertTo<ResTable_typeSpec>(chunk);
+  if (!type_spec) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                      << "corrupt ResTable_typeSpec chunk");
+    return false;
+  }
+
+  if (type_spec->id == 0) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                      << "ResTable_typeSpec has invalid id: "
+                                      << type_spec->id);
+    return false;
+  }
+  return true;
+}
+
+bool BinaryResourceParser::ParseType(const ResourceTablePackage* package,
                                      const ResChunk_header* chunk) {
-    if (mTypePool.getError() != NO_ERROR) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "missing type string pool");
+  if (type_pool_.getError() != NO_ERROR) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                      << "missing type string pool");
+    return false;
+  }
+
+  if (key_pool_.getError() != NO_ERROR) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                      << "missing key string pool");
+    return false;
+  }
+
+  const ResTable_type* type = ConvertTo<ResTable_type>(chunk);
+  if (!type) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                      << "corrupt ResTable_type chunk");
+    return false;
+  }
+
+  if (type->id == 0) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                      << "ResTable_type has invalid id: "
+                                      << (int)type->id);
+    return false;
+  }
+
+  ConfigDescription config;
+  config.copyFromDtoH(type->config);
+
+  const std::string type_str = util::GetString(type_pool_, type->id - 1);
+
+  const ResourceType* parsed_type = ParseResourceType(type_str);
+  if (!parsed_type) {
+    context_->GetDiagnostics()->Error(
+        DiagMessage(source_) << "invalid type name '" << type_str
+                             << "' for type with ID " << (int)type->id);
+    return false;
+  }
+
+  TypeVariant tv(type);
+  for (auto it = tv.beginEntries(); it != tv.endEntries(); ++it) {
+    const ResTable_entry* entry = *it;
+    if (!entry) {
+      continue;
+    }
+
+    const ResourceName name(
+        package->name, *parsed_type,
+        util::GetString(key_pool_, util::DeviceToHost32(entry->key.index)));
+
+    const ResourceId res_id(package->id.value(), type->id,
+                            static_cast<uint16_t>(it.index()));
+
+    std::unique_ptr<Value> resource_value;
+    if (entry->flags & ResTable_entry::FLAG_COMPLEX) {
+      const ResTable_map_entry* mapEntry =
+          static_cast<const ResTable_map_entry*>(entry);
+
+      // TODO(adamlesinski): Check that the entry count is valid.
+      resource_value = ParseMapEntry(name, config, mapEntry);
+    } else {
+      const Res_value* value =
+          (const Res_value*)((const uint8_t*)entry +
+                             util::DeviceToHost32(entry->size));
+      resource_value = ParseValue(name, config, value, entry->flags);
+    }
+
+    if (!resource_value) {
+      context_->GetDiagnostics()->Error(
+          DiagMessage(source_) << "failed to parse value for resource " << name
+                               << " (" << res_id << ") with configuration '"
+                               << config << "'");
+      return false;
+    }
+
+    if (!table_->AddResourceAllowMangled(name, config, {},
+                                         std::move(resource_value),
+                                         context_->GetDiagnostics())) {
+      return false;
+    }
+
+    if ((entry->flags & ResTable_entry::FLAG_PUBLIC) != 0) {
+      Symbol symbol;
+      symbol.state = SymbolState::kPublic;
+      symbol.source = source_.WithLine(0);
+      if (!table_->SetSymbolStateAllowMangled(name, res_id, symbol,
+                                              context_->GetDiagnostics())) {
         return false;
+      }
     }
 
-    if (mKeyPool.getError() != NO_ERROR) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "missing key string pool");
-        return false;
+    // Add this resource name->id mapping to the index so
+    // that we can resolve all ID references to name references.
+    auto cache_iter = id_index_.find(res_id);
+    if (cache_iter == id_index_.end()) {
+      id_index_.insert({res_id, name});
     }
-
-    const ResTable_type* type = convertTo<ResTable_type>(chunk);
-    if (!type) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "corrupt ResTable_type chunk");
-        return false;
-    }
-
-    if (type->id == 0) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "ResTable_type has invalid id: " << (int) type->id);
-        return false;
-    }
-
-    ConfigDescription config;
-    config.copyFromDtoH(type->config);
-
-    const std::string typeStr = util::getString(mTypePool, type->id - 1);
-
-    const ResourceType* parsedType = parseResourceType(typeStr);
-    if (!parsedType) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "invalid type name '" << typeStr
-                                          << "' for type with ID " << (int) type->id);
-        return false;
-    }
-
-    TypeVariant tv(type);
-    for (auto it = tv.beginEntries(); it != tv.endEntries(); ++it) {
-        const ResTable_entry* entry = *it;
-        if (!entry) {
-            continue;
-        }
-
-        const ResourceName name(package->name, *parsedType,
-                                util::getString(mKeyPool,
-                                                util::deviceToHost32(entry->key.index)));
-
-        const ResourceId resId(package->id.value(), type->id, static_cast<uint16_t>(it.index()));
-
-        std::unique_ptr<Value> resourceValue;
-        if (entry->flags & ResTable_entry::FLAG_COMPLEX) {
-            const ResTable_map_entry* mapEntry = static_cast<const ResTable_map_entry*>(entry);
-
-            // TODO(adamlesinski): Check that the entry count is valid.
-            resourceValue = parseMapEntry(name, config, mapEntry);
-        } else {
-            const Res_value* value = (const Res_value*)(
-                    (const uint8_t*) entry + util::deviceToHost32(entry->size));
-            resourceValue = parseValue(name, config, value, entry->flags);
-        }
-
-        if (!resourceValue) {
-            mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                              << "failed to parse value for resource " << name
-                                              << " (" << resId << ") with configuration '"
-                                              << config << "'");
-            return false;
-        }
-
-        if (!mTable->addResourceAllowMangled(name, config, {}, std::move(resourceValue),
-                                             mContext->getDiagnostics())) {
-            return false;
-        }
-
-        if ((entry->flags & ResTable_entry::FLAG_PUBLIC) != 0) {
-            Symbol symbol;
-            symbol.state = SymbolState::kPublic;
-            symbol.source = mSource.withLine(0);
-            if (!mTable->setSymbolStateAllowMangled(name, resId, symbol,
-                                                    mContext->getDiagnostics())) {
-                return false;
-            }
-        }
-
-        // Add this resource name->id mapping to the index so
-        // that we can resolve all ID references to name references.
-        auto cacheIter = mIdIndex.find(resId);
-        if (cacheIter == mIdIndex.end()) {
-            mIdIndex.insert({ resId, name });
-        }
-    }
-    return true;
+  }
+  return true;
 }
 
-std::unique_ptr<Item> BinaryResourceParser::parseValue(const ResourceNameRef& name,
-                                                       const ConfigDescription& config,
-                                                       const Res_value* value,
-                                                       uint16_t flags) {
-    if (name.type == ResourceType::kId) {
-        return util::make_unique<Id>();
+std::unique_ptr<Item> BinaryResourceParser::ParseValue(
+    const ResourceNameRef& name, const ConfigDescription& config,
+    const Res_value* value, uint16_t flags) {
+  if (name.type == ResourceType::kId) {
+    return util::make_unique<Id>();
+  }
+
+  const uint32_t data = util::DeviceToHost32(value->data);
+
+  if (value->dataType == Res_value::TYPE_STRING) {
+    const std::string str = util::GetString(value_pool_, data);
+
+    const ResStringPool_span* spans = value_pool_.styleAt(data);
+
+    // Check if the string has a valid style associated with it.
+    if (spans != nullptr && spans->name.index != ResStringPool_span::END) {
+      StyleString style_str = {str};
+      while (spans->name.index != ResStringPool_span::END) {
+        style_str.spans.push_back(
+            Span{util::GetString(value_pool_, spans->name.index),
+                 spans->firstChar, spans->lastChar});
+        spans++;
+      }
+      return util::make_unique<StyledString>(table_->string_pool.MakeRef(
+          style_str,
+          StringPool::Context(StringPool::Context::kStylePriority, config)));
+    } else {
+      if (name.type != ResourceType::kString && util::StartsWith(str, "res/")) {
+        // This must be a FileReference.
+        return util::make_unique<FileReference>(table_->string_pool.MakeRef(
+            str,
+            StringPool::Context(StringPool::Context::kHighPriority, config)));
+      }
+
+      // There are no styles associated with this string, so treat it as
+      // a simple string.
+      return util::make_unique<String>(
+          table_->string_pool.MakeRef(str, StringPool::Context(config)));
+    }
+  }
+
+  if (value->dataType == Res_value::TYPE_REFERENCE ||
+      value->dataType == Res_value::TYPE_ATTRIBUTE) {
+    const Reference::Type type = (value->dataType == Res_value::TYPE_REFERENCE)
+                                     ? Reference::Type::kResource
+                                     : Reference::Type::kAttribute;
+
+    if (data == 0) {
+      // A reference of 0, must be the magic @null reference.
+      Res_value null_type = {};
+      null_type.dataType = Res_value::TYPE_REFERENCE;
+      return util::make_unique<BinaryPrimitive>(null_type);
     }
 
-    const uint32_t data = util::deviceToHost32(value->data);
+    // This is a normal reference.
+    return util::make_unique<Reference>(data, type);
+  }
 
-    if (value->dataType == Res_value::TYPE_STRING) {
-        const std::string str = util::getString(mValuePool, data);
-
-        const ResStringPool_span* spans = mValuePool.styleAt(data);
-
-        // Check if the string has a valid style associated with it.
-        if (spans != nullptr && spans->name.index != ResStringPool_span::END) {
-            StyleString styleStr = { str };
-            while (spans->name.index != ResStringPool_span::END) {
-                styleStr.spans.push_back(Span{
-                        util::getString(mValuePool, spans->name.index),
-                        spans->firstChar,
-                        spans->lastChar
-                });
-                spans++;
-            }
-            return util::make_unique<StyledString>(mTable->stringPool.makeRef(
-                    styleStr, StringPool::Context{1, config}));
-        } else {
-            if (name.type != ResourceType::kString &&
-                    util::stringStartsWith(str, "res/")) {
-                // This must be a FileReference.
-                return util::make_unique<FileReference>(mTable->stringPool.makeRef(
-                            str, StringPool::Context{ 0, config }));
-            }
-
-            // There are no styles associated with this string, so treat it as
-            // a simple string.
-            return util::make_unique<String>(mTable->stringPool.makeRef(
-                    str, StringPool::Context{1, config}));
-        }
-    }
-
-    if (value->dataType == Res_value::TYPE_REFERENCE ||
-            value->dataType == Res_value::TYPE_ATTRIBUTE) {
-        const Reference::Type type = (value->dataType == Res_value::TYPE_REFERENCE) ?
-                Reference::Type::kResource : Reference::Type::kAttribute;
-
-        if (data == 0) {
-            // A reference of 0, must be the magic @null reference.
-            Res_value nullType = {};
-            nullType.dataType = Res_value::TYPE_REFERENCE;
-            return util::make_unique<BinaryPrimitive>(nullType);
-        }
-
-        // This is a normal reference.
-        return util::make_unique<Reference>(data, type);
-    }
-
-    // Treat this as a raw binary primitive.
-    return util::make_unique<BinaryPrimitive>(*value);
+  // Treat this as a raw binary primitive.
+  return util::make_unique<BinaryPrimitive>(*value);
 }
 
-std::unique_ptr<Value> BinaryResourceParser::parseMapEntry(const ResourceNameRef& name,
-                                                           const ConfigDescription& config,
-                                                           const ResTable_map_entry* map) {
-    switch (name.type) {
-        case ResourceType::kStyle:
-            return parseStyle(name, config, map);
-        case ResourceType::kAttrPrivate:
-            // fallthrough
-        case ResourceType::kAttr:
-            return parseAttr(name, config, map);
-        case ResourceType::kArray:
-            return parseArray(name, config, map);
-        case ResourceType::kPlurals:
-            return parsePlural(name, config, map);
-        default:
-            assert(false && "unknown map type");
-            break;
-    }
-    return {};
+std::unique_ptr<Value> BinaryResourceParser::ParseMapEntry(
+    const ResourceNameRef& name, const ConfigDescription& config,
+    const ResTable_map_entry* map) {
+  switch (name.type) {
+    case ResourceType::kStyle:
+      return ParseStyle(name, config, map);
+    case ResourceType::kAttrPrivate:
+    // fallthrough
+    case ResourceType::kAttr:
+      return ParseAttr(name, config, map);
+    case ResourceType::kArray:
+      return ParseArray(name, config, map);
+    case ResourceType::kPlurals:
+      return ParsePlural(name, config, map);
+    default:
+      LOG(FATAL) << "unknown map type";
+      break;
+  }
+  return {};
 }
 
-std::unique_ptr<Style> BinaryResourceParser::parseStyle(const ResourceNameRef& name,
-                                                        const ConfigDescription& config,
-                                                        const ResTable_map_entry* map) {
-    std::unique_ptr<Style> style = util::make_unique<Style>();
-    if (util::deviceToHost32(map->parent.ident) != 0) {
-        // The parent is a regular reference to a resource.
-        style->parent = Reference(util::deviceToHost32(map->parent.ident));
+std::unique_ptr<Style> BinaryResourceParser::ParseStyle(
+    const ResourceNameRef& name, const ConfigDescription& config,
+    const ResTable_map_entry* map) {
+  std::unique_ptr<Style> style = util::make_unique<Style>();
+  if (util::DeviceToHost32(map->parent.ident) != 0) {
+    // The parent is a regular reference to a resource.
+    style->parent = Reference(util::DeviceToHost32(map->parent.ident));
+  }
+
+  for (const ResTable_map& map_entry : map) {
+    if (Res_INTERNALID(util::DeviceToHost32(map_entry.name.ident))) {
+      continue;
     }
 
-    for (const ResTable_map& mapEntry : map) {
-        if (Res_INTERNALID(util::deviceToHost32(mapEntry.name.ident))) {
-            continue;
-        }
-
-        Style::Entry styleEntry;
-        styleEntry.key = Reference(util::deviceToHost32(mapEntry.name.ident));
-        styleEntry.value = parseValue(name, config, &mapEntry.value, 0);
-        if (!styleEntry.value) {
-            return {};
-        }
-        style->entries.push_back(std::move(styleEntry));
+    Style::Entry style_entry;
+    style_entry.key = Reference(util::DeviceToHost32(map_entry.name.ident));
+    style_entry.value = ParseValue(name, config, &map_entry.value, 0);
+    if (!style_entry.value) {
+      return {};
     }
-    return style;
+    style->entries.push_back(std::move(style_entry));
+  }
+  return style;
 }
 
-std::unique_ptr<Attribute> BinaryResourceParser::parseAttr(const ResourceNameRef& name,
-                                                           const ConfigDescription& config,
-                                                           const ResTable_map_entry* map) {
-    const bool isWeak = (util::deviceToHost16(map->flags) & ResTable_entry::FLAG_WEAK) != 0;
-    std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(isWeak);
+std::unique_ptr<Attribute> BinaryResourceParser::ParseAttr(
+    const ResourceNameRef& name, const ConfigDescription& config,
+    const ResTable_map_entry* map) {
+  const bool is_weak =
+      (util::DeviceToHost16(map->flags) & ResTable_entry::FLAG_WEAK) != 0;
+  std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(is_weak);
 
-    // First we must discover what type of attribute this is. Find the type mask.
-    auto typeMaskIter = std::find_if(begin(map), end(map), [](const ResTable_map& entry) -> bool {
-        return util::deviceToHost32(entry.name.ident) == ResTable_map::ATTR_TYPE;
-    });
+  // First we must discover what type of attribute this is. Find the type mask.
+  auto type_mask_iter =
+      std::find_if(begin(map), end(map), [](const ResTable_map& entry) -> bool {
+        return util::DeviceToHost32(entry.name.ident) ==
+               ResTable_map::ATTR_TYPE;
+      });
 
-    if (typeMaskIter != end(map)) {
-        attr->typeMask = util::deviceToHost32(typeMaskIter->value.data);
+  if (type_mask_iter != end(map)) {
+    attr->type_mask = util::DeviceToHost32(type_mask_iter->value.data);
+  }
+
+  for (const ResTable_map& map_entry : map) {
+    if (Res_INTERNALID(util::DeviceToHost32(map_entry.name.ident))) {
+      switch (util::DeviceToHost32(map_entry.name.ident)) {
+        case ResTable_map::ATTR_MIN:
+          attr->min_int = static_cast<int32_t>(map_entry.value.data);
+          break;
+        case ResTable_map::ATTR_MAX:
+          attr->max_int = static_cast<int32_t>(map_entry.value.data);
+          break;
+      }
+      continue;
     }
 
-    for (const ResTable_map& mapEntry : map) {
-        if (Res_INTERNALID(util::deviceToHost32(mapEntry.name.ident))) {
-            switch (util::deviceToHost32(mapEntry.name.ident)) {
-            case ResTable_map::ATTR_MIN:
-                attr->minInt = static_cast<int32_t>(mapEntry.value.data);
-                break;
-            case ResTable_map::ATTR_MAX:
-                attr->maxInt = static_cast<int32_t>(mapEntry.value.data);
-                break;
-            }
-            continue;
-        }
-
-        if (attr->typeMask & (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) {
-            Attribute::Symbol symbol;
-            symbol.value = util::deviceToHost32(mapEntry.value.data);
-            symbol.symbol = Reference(util::deviceToHost32(mapEntry.name.ident));
-            attr->symbols.push_back(std::move(symbol));
-        }
+    if (attr->type_mask &
+        (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) {
+      Attribute::Symbol symbol;
+      symbol.value = util::DeviceToHost32(map_entry.value.data);
+      symbol.symbol = Reference(util::DeviceToHost32(map_entry.name.ident));
+      attr->symbols.push_back(std::move(symbol));
     }
+  }
 
-    // TODO(adamlesinski): Find i80n, attributes.
-    return attr;
+  // TODO(adamlesinski): Find i80n, attributes.
+  return attr;
 }
 
-std::unique_ptr<Array> BinaryResourceParser::parseArray(const ResourceNameRef& name,
-                                                        const ConfigDescription& config,
-                                                        const ResTable_map_entry* map) {
-    std::unique_ptr<Array> array = util::make_unique<Array>();
-    for (const ResTable_map& mapEntry : map) {
-        array->items.push_back(parseValue(name, config, &mapEntry.value, 0));
-    }
-    return array;
+std::unique_ptr<Array> BinaryResourceParser::ParseArray(
+    const ResourceNameRef& name, const ConfigDescription& config,
+    const ResTable_map_entry* map) {
+  std::unique_ptr<Array> array = util::make_unique<Array>();
+  for (const ResTable_map& map_entry : map) {
+    array->items.push_back(ParseValue(name, config, &map_entry.value, 0));
+  }
+  return array;
 }
 
-std::unique_ptr<Plural> BinaryResourceParser::parsePlural(const ResourceNameRef& name,
-                                                          const ConfigDescription& config,
-                                                          const ResTable_map_entry* map) {
-    std::unique_ptr<Plural> plural = util::make_unique<Plural>();
-    for (const ResTable_map& mapEntry : map) {
-        std::unique_ptr<Item> item = parseValue(name, config, &mapEntry.value, 0);
-        if (!item) {
-            return {};
-        }
-
-        switch (util::deviceToHost32(mapEntry.name.ident)) {
-            case ResTable_map::ATTR_ZERO:
-                plural->values[Plural::Zero] = std::move(item);
-                break;
-            case ResTable_map::ATTR_ONE:
-                plural->values[Plural::One] = std::move(item);
-                break;
-            case ResTable_map::ATTR_TWO:
-                plural->values[Plural::Two] = std::move(item);
-                break;
-            case ResTable_map::ATTR_FEW:
-                plural->values[Plural::Few] = std::move(item);
-                break;
-            case ResTable_map::ATTR_MANY:
-                plural->values[Plural::Many] = std::move(item);
-                break;
-            case ResTable_map::ATTR_OTHER:
-                plural->values[Plural::Other] = std::move(item);
-                break;
-        }
+std::unique_ptr<Plural> BinaryResourceParser::ParsePlural(
+    const ResourceNameRef& name, const ConfigDescription& config,
+    const ResTable_map_entry* map) {
+  std::unique_ptr<Plural> plural = util::make_unique<Plural>();
+  for (const ResTable_map& map_entry : map) {
+    std::unique_ptr<Item> item = ParseValue(name, config, &map_entry.value, 0);
+    if (!item) {
+      return {};
     }
-    return plural;
+
+    switch (util::DeviceToHost32(map_entry.name.ident)) {
+      case ResTable_map::ATTR_ZERO:
+        plural->values[Plural::Zero] = std::move(item);
+        break;
+      case ResTable_map::ATTR_ONE:
+        plural->values[Plural::One] = std::move(item);
+        break;
+      case ResTable_map::ATTR_TWO:
+        plural->values[Plural::Two] = std::move(item);
+        break;
+      case ResTable_map::ATTR_FEW:
+        plural->values[Plural::Few] = std::move(item);
+        break;
+      case ResTable_map::ATTR_MANY:
+        plural->values[Plural::Many] = std::move(item);
+        break;
+      case ResTable_map::ATTR_OTHER:
+        plural->values[Plural::Other] = std::move(item);
+        break;
+    }
+  }
+  return plural;
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.h b/tools/aapt2/unflatten/BinaryResourceParser.h
index 99f2bd4..dc668fd 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.h
+++ b/tools/aapt2/unflatten/BinaryResourceParser.h
@@ -17,16 +17,17 @@
 #ifndef AAPT_BINARY_RESOURCE_PARSER_H
 #define AAPT_BINARY_RESOURCE_PARSER_H
 
+#include <string>
+
+#include "android-base/macros.h"
+#include "androidfw/ResourceTypes.h"
+
 #include "ResourceTable.h"
 #include "ResourceValues.h"
 #include "Source.h"
-
 #include "process/IResourceTableConsumer.h"
 #include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
-#include <string>
-
 namespace aapt {
 
 struct SymbolTable_entry;
@@ -45,44 +46,44 @@
    * add any resources parsed to `table`. `source` is for logging purposes.
    */
   BinaryResourceParser(IAaptContext* context, ResourceTable* table,
-                       const Source& source, const void* data, size_t dataLen);
-
-  BinaryResourceParser(const BinaryResourceParser&) = delete;  // No copy.
+                       const Source& source, const void* data, size_t data_len);
 
   /*
    * Parses the binary resource table and returns true if successful.
    */
-  bool parse();
+  bool Parse();
 
  private:
-  bool parseTable(const android::ResChunk_header* chunk);
-  bool parsePackage(const android::ResChunk_header* chunk);
-  bool parseTypeSpec(const android::ResChunk_header* chunk);
-  bool parseType(const ResourceTablePackage* package,
+  DISALLOW_COPY_AND_ASSIGN(BinaryResourceParser);
+
+  bool ParseTable(const android::ResChunk_header* chunk);
+  bool ParsePackage(const android::ResChunk_header* chunk);
+  bool ParseTypeSpec(const android::ResChunk_header* chunk);
+  bool ParseType(const ResourceTablePackage* package,
                  const android::ResChunk_header* chunk);
 
-  std::unique_ptr<Item> parseValue(const ResourceNameRef& name,
+  std::unique_ptr<Item> ParseValue(const ResourceNameRef& name,
                                    const ConfigDescription& config,
                                    const android::Res_value* value,
                                    uint16_t flags);
 
-  std::unique_ptr<Value> parseMapEntry(const ResourceNameRef& name,
+  std::unique_ptr<Value> ParseMapEntry(const ResourceNameRef& name,
                                        const ConfigDescription& config,
                                        const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Style> parseStyle(const ResourceNameRef& name,
+  std::unique_ptr<Style> ParseStyle(const ResourceNameRef& name,
                                     const ConfigDescription& config,
                                     const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Attribute> parseAttr(const ResourceNameRef& name,
+  std::unique_ptr<Attribute> ParseAttr(const ResourceNameRef& name,
                                        const ConfigDescription& config,
                                        const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Array> parseArray(const ResourceNameRef& name,
+  std::unique_ptr<Array> ParseArray(const ResourceNameRef& name,
                                     const ConfigDescription& config,
                                     const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Plural> parsePlural(const ResourceNameRef& name,
+  std::unique_ptr<Plural> ParsePlural(const ResourceNameRef& name,
                                       const ConfigDescription& config,
                                       const android::ResTable_map_entry* map);
 
@@ -92,30 +93,30 @@
    * read and added to the Value.
    * Returns true if the mapEntry was meta data.
    */
-  bool collectMetaData(const android::ResTable_map& mapEntry, Value* value);
+  bool CollectMetaData(const android::ResTable_map& map_entry, Value* value);
 
-  IAaptContext* mContext;
-  ResourceTable* mTable;
+  IAaptContext* context_;
+  ResourceTable* table_;
 
-  const Source mSource;
+  const Source source_;
 
-  const void* mData;
-  const size_t mDataLen;
+  const void* data_;
+  const size_t data_len_;
 
   // The standard value string pool for resource values.
-  android::ResStringPool mValuePool;
+  android::ResStringPool value_pool_;
 
   // The string pool that holds the names of the types defined
   // in this table.
-  android::ResStringPool mTypePool;
+  android::ResStringPool type_pool_;
 
   // The string pool that holds the names of the entries defined
   // in this table.
-  android::ResStringPool mKeyPool;
+  android::ResStringPool key_pool_;
 
   // A mapping of resource ID to resource name. When we finish parsing
   // we use this to convert all resource IDs to symbolic references.
-  std::map<ResourceId, ResourceName> mIdIndex;
+  std::map<ResourceId, ResourceName> id_index_;
 };
 
 }  // namespace aapt
@@ -128,11 +129,11 @@
 
 inline const ResTable_map* begin(const ResTable_map_entry* map) {
   return (const ResTable_map*)((const uint8_t*)map +
-                               aapt::util::deviceToHost32(map->size));
+                               aapt::util::DeviceToHost32(map->size));
 }
 
 inline const ResTable_map* end(const ResTable_map_entry* map) {
-  return begin(map) + aapt::util::deviceToHost32(map->count);
+  return begin(map) + aapt::util::DeviceToHost32(map->count);
 }
 
 }  // namespace android
diff --git a/tools/aapt2/unflatten/ResChunkPullParser.cpp b/tools/aapt2/unflatten/ResChunkPullParser.cpp
index 6f8bb1b..5d71ff3 100644
--- a/tools/aapt2/unflatten/ResChunkPullParser.cpp
+++ b/tools/aapt2/unflatten/ResChunkPullParser.cpp
@@ -15,55 +15,60 @@
  */
 
 #include "unflatten/ResChunkPullParser.h"
-#include "util/Util.h"
 
-#include <androidfw/ResourceTypes.h>
 #include <cstddef>
 
+#include "android-base/logging.h"
+#include "androidfw/ResourceTypes.h"
+
+#include "util/Util.h"
+
 namespace aapt {
 
 using android::ResChunk_header;
 
-ResChunkPullParser::Event ResChunkPullParser::next() {
-    if (!isGoodEvent(mEvent)) {
-        return mEvent;
-    }
+ResChunkPullParser::Event ResChunkPullParser::Next() {
+  if (!IsGoodEvent(event_)) {
+    return event_;
+  }
 
-    if (mEvent == Event::StartDocument) {
-        mCurrentChunk = mData;
-    } else {
-        mCurrentChunk = (const ResChunk_header*)
-                (((const char*) mCurrentChunk) + util::deviceToHost32(mCurrentChunk->size));
-    }
+  if (event_ == Event::kStartDocument) {
+    current_chunk_ = data_;
+  } else {
+    current_chunk_ =
+        (const ResChunk_header*)(((const char*)current_chunk_) +
+                                 util::DeviceToHost32(current_chunk_->size));
+  }
 
-    const std::ptrdiff_t diff = (const char*) mCurrentChunk - (const char*) mData;
-    assert(diff >= 0 && "diff is negative");
-    const size_t offset = static_cast<const size_t>(diff);
+  const std::ptrdiff_t diff = (const char*)current_chunk_ - (const char*)data_;
+  CHECK(diff >= 0) << "diff is negative";
+  const size_t offset = static_cast<const size_t>(diff);
 
-    if (offset == mLen) {
-        mCurrentChunk = nullptr;
-        return (mEvent = Event::EndDocument);
-    } else if (offset + sizeof(ResChunk_header) > mLen) {
-        mLastError = "chunk is past the end of the document";
-        mCurrentChunk = nullptr;
-        return (mEvent = Event::BadDocument);
-    }
+  if (offset == len_) {
+    current_chunk_ = nullptr;
+    return (event_ = Event::kEndDocument);
+  } else if (offset + sizeof(ResChunk_header) > len_) {
+    error_ = "chunk is past the end of the document";
+    current_chunk_ = nullptr;
+    return (event_ = Event::kBadDocument);
+  }
 
-    if (util::deviceToHost16(mCurrentChunk->headerSize) < sizeof(ResChunk_header)) {
-        mLastError = "chunk has too small header";
-        mCurrentChunk = nullptr;
-        return (mEvent = Event::BadDocument);
-    } else if (util::deviceToHost32(mCurrentChunk->size) <
-            util::deviceToHost16(mCurrentChunk->headerSize)) {
-        mLastError = "chunk's total size is smaller than header";
-        mCurrentChunk = nullptr;
-        return (mEvent = Event::BadDocument);
-    } else if (offset + util::deviceToHost32(mCurrentChunk->size) > mLen) {
-        mLastError = "chunk's data extends past the end of the document";
-        mCurrentChunk = nullptr;
-        return (mEvent = Event::BadDocument);
-    }
-    return (mEvent = Event::Chunk);
+  if (util::DeviceToHost16(current_chunk_->headerSize) <
+      sizeof(ResChunk_header)) {
+    error_ = "chunk has too small header";
+    current_chunk_ = nullptr;
+    return (event_ = Event::kBadDocument);
+  } else if (util::DeviceToHost32(current_chunk_->size) <
+             util::DeviceToHost16(current_chunk_->headerSize)) {
+    error_ = "chunk's total size is smaller than header";
+    current_chunk_ = nullptr;
+    return (event_ = Event::kBadDocument);
+  } else if (offset + util::DeviceToHost32(current_chunk_->size) > len_) {
+    error_ = "chunk's data extends past the end of the document";
+    current_chunk_ = nullptr;
+    return (event_ = Event::kBadDocument);
+  }
+  return (event_ = Event::kChunk);
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/unflatten/ResChunkPullParser.h b/tools/aapt2/unflatten/ResChunkPullParser.h
index 24fa63d..437fc5c 100644
--- a/tools/aapt2/unflatten/ResChunkPullParser.h
+++ b/tools/aapt2/unflatten/ResChunkPullParser.h
@@ -17,11 +17,13 @@
 #ifndef AAPT_RES_CHUNK_PULL_PARSER_H
 #define AAPT_RES_CHUNK_PULL_PARSER_H
 
-#include "util/Util.h"
-
-#include <androidfw/ResourceTypes.h>
 #include <string>
 
+#include "android-base/macros.h"
+#include "androidfw/ResourceTypes.h"
+
+#include "util/Util.h"
+
 namespace aapt {
 
 /**
@@ -39,17 +41,17 @@
 class ResChunkPullParser {
  public:
   enum class Event {
-    StartDocument,
-    EndDocument,
-    BadDocument,
+    kStartDocument,
+    kEndDocument,
+    kBadDocument,
 
-    Chunk,
+    kChunk,
   };
 
   /**
    * Returns false if the event is EndDocument or BadDocument.
    */
-  static bool isGoodEvent(Event event);
+  static bool IsGoodEvent(Event event);
 
   /**
    * Create a ResChunkPullParser to read android::ResChunk_headers
@@ -57,68 +59,66 @@
    */
   ResChunkPullParser(const void* data, size_t len);
 
-  ResChunkPullParser(const ResChunkPullParser&) = delete;
-
-  Event getEvent() const;
-  const std::string& getLastError() const;
-  const android::ResChunk_header* getChunk() const;
+  Event event() const;
+  const std::string& error() const;
+  const android::ResChunk_header* chunk() const;
 
   /**
    * Move to the next android::ResChunk_header.
    */
-  Event next();
+  Event Next();
 
  private:
-  Event mEvent;
-  const android::ResChunk_header* mData;
-  size_t mLen;
-  const android::ResChunk_header* mCurrentChunk;
-  std::string mLastError;
+  DISALLOW_COPY_AND_ASSIGN(ResChunkPullParser);
+
+  Event event_;
+  const android::ResChunk_header* data_;
+  size_t len_;
+  const android::ResChunk_header* current_chunk_;
+  std::string error_;
 };
 
 template <typename T>
-inline static const T* convertTo(const android::ResChunk_header* chunk) {
-  if (util::deviceToHost16(chunk->headerSize) < sizeof(T)) {
+inline static const T* ConvertTo(const android::ResChunk_header* chunk) {
+  if (util::DeviceToHost16(chunk->headerSize) < sizeof(T)) {
     return nullptr;
   }
   return reinterpret_cast<const T*>(chunk);
 }
 
-inline static const uint8_t* getChunkData(
+inline static const uint8_t* GetChunkData(
     const android::ResChunk_header* chunk) {
   return reinterpret_cast<const uint8_t*>(chunk) +
-         util::deviceToHost16(chunk->headerSize);
+         util::DeviceToHost16(chunk->headerSize);
 }
 
-inline static uint32_t getChunkDataLen(const android::ResChunk_header* chunk) {
-  return util::deviceToHost32(chunk->size) -
-         util::deviceToHost16(chunk->headerSize);
+inline static uint32_t GetChunkDataLen(const android::ResChunk_header* chunk) {
+  return util::DeviceToHost32(chunk->size) -
+         util::DeviceToHost16(chunk->headerSize);
 }
 
 //
 // Implementation
 //
 
-inline bool ResChunkPullParser::isGoodEvent(ResChunkPullParser::Event event) {
-  return event != Event::EndDocument && event != Event::BadDocument;
+inline bool ResChunkPullParser::IsGoodEvent(ResChunkPullParser::Event event) {
+  return event != Event::kEndDocument && event != Event::kBadDocument;
 }
 
 inline ResChunkPullParser::ResChunkPullParser(const void* data, size_t len)
-    : mEvent(Event::StartDocument),
-      mData(reinterpret_cast<const android::ResChunk_header*>(data)),
-      mLen(len),
-      mCurrentChunk(nullptr) {}
+    : event_(Event::kStartDocument),
+      data_(reinterpret_cast<const android::ResChunk_header*>(data)),
+      len_(len),
+      current_chunk_(nullptr) {}
 
-inline ResChunkPullParser::Event ResChunkPullParser::getEvent() const {
-  return mEvent;
+inline ResChunkPullParser::Event ResChunkPullParser::event() const {
+  return event_;
 }
 
-inline const std::string& ResChunkPullParser::getLastError() const {
-  return mLastError;
-}
+inline const std::string& ResChunkPullParser::error() const { return error_; }
 
-inline const android::ResChunk_header* ResChunkPullParser::getChunk() const {
-  return mCurrentChunk;
+inline const android::ResChunk_header* ResChunkPullParser::chunk() const {
+  return current_chunk_;
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/util/BigBuffer.cpp b/tools/aapt2/util/BigBuffer.cpp
index de4ecd2..ef99dca 100644
--- a/tools/aapt2/util/BigBuffer.cpp
+++ b/tools/aapt2/util/BigBuffer.cpp
@@ -20,58 +20,60 @@
 #include <memory>
 #include <vector>
 
+#include "android-base/logging.h"
+
 namespace aapt {
 
-void* BigBuffer::nextBlockImpl(size_t size) {
-    if (!mBlocks.empty()) {
-        Block& block = mBlocks.back();
-        if (block.mBlockSize - block.size >= size) {
-            void* outBuffer = block.buffer.get() + block.size;
-            block.size += size;
-            mSize += size;
-            return outBuffer;
-        }
+void* BigBuffer::NextBlockImpl(size_t size) {
+  if (!blocks_.empty()) {
+    Block& block = blocks_.back();
+    if (block.block_size_ - block.size >= size) {
+      void* out_buffer = block.buffer.get() + block.size;
+      block.size += size;
+      size_ += size;
+      return out_buffer;
     }
+  }
 
-    const size_t actualSize = std::max(mBlockSize, size);
+  const size_t actual_size = std::max(block_size_, size);
 
-    Block block = {};
+  Block block = {};
 
-    // Zero-allocate the block's buffer.
-    block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[actualSize]());
-    assert(block.buffer);
+  // Zero-allocate the block's buffer.
+  block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[actual_size]());
+  CHECK(block.buffer);
 
-    block.size = size;
-    block.mBlockSize = actualSize;
+  block.size = size;
+  block.block_size_ = actual_size;
 
-    mBlocks.push_back(std::move(block));
-    mSize += size;
-    return mBlocks.back().buffer.get();
+  blocks_.push_back(std::move(block));
+  size_ += size;
+  return blocks_.back().buffer.get();
 }
 
-void* BigBuffer::nextBlock(size_t* outSize) {
-    if (!mBlocks.empty()) {
-        Block& block = mBlocks.back();
-        if (block.size != block.mBlockSize) {
-            void* outBuffer = block.buffer.get() + block.size;
-            size_t size = block.mBlockSize - block.size;
-            block.size = block.mBlockSize;
-            mSize += size;
-            *outSize = size;
-            return outBuffer;
-        }
+void* BigBuffer::NextBlock(size_t* out_size) {
+  if (!blocks_.empty()) {
+    Block& block = blocks_.back();
+    if (block.size != block.block_size_) {
+      void* out_buffer = block.buffer.get() + block.size;
+      size_t size = block.block_size_ - block.size;
+      block.size = block.block_size_;
+      size_ += size;
+      *out_size = size;
+      return out_buffer;
     }
+  }
 
-    // Zero-allocate the block's buffer.
-    Block block = {};
-    block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[mBlockSize]());
-    assert(block.buffer);
-    block.size = mBlockSize;
-    block.mBlockSize = mBlockSize;
-    mBlocks.push_back(std::move(block));
-    mSize += mBlockSize;
-    *outSize = mBlockSize;
-    return mBlocks.back().buffer.get();
+  // Zero-allocate the block's buffer.
+  Block block = {};
+  block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[block_size_]());
+  CHECK(block.buffer);
+  block.size = block_size_;
+  block.block_size_ = block_size_;
+  blocks_.push_back(std::move(block));
+  size_ += block_size_;
+  *out_size = block_size_;
+  return blocks_.back().buffer.get();
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/util/BigBuffer.h b/tools/aapt2/util/BigBuffer.h
index b273733..d23c41d 100644
--- a/tools/aapt2/util/BigBuffer.h
+++ b/tools/aapt2/util/BigBuffer.h
@@ -17,12 +17,14 @@
 #ifndef AAPT_BIG_BUFFER_H
 #define AAPT_BIG_BUFFER_H
 
-#include <cassert>
 #include <cstring>
 #include <memory>
 #include <type_traits>
 #include <vector>
 
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+
 namespace aapt {
 
 /**
@@ -54,18 +56,16 @@
     /**
      * The size of the memory block allocation.
      */
-    size_t mBlockSize;
+    size_t block_size_;
   };
 
   typedef std::vector<Block>::const_iterator const_iterator;
 
   /**
    * Create a BigBuffer with block allocation sizes
-   * of blockSize.
+   * of block_size.
    */
-  explicit BigBuffer(size_t blockSize);
-
-  BigBuffer(const BigBuffer&) = delete;  // No copying.
+  explicit BigBuffer(size_t block_size);
 
   BigBuffer(BigBuffer&& rhs);
 
@@ -79,104 +79,106 @@
    * a POD type. The elements are zero-initialized.
    */
   template <typename T>
-  T* nextBlock(size_t count = 1);
+  T* NextBlock(size_t count = 1);
 
   /**
-   * Returns the next block available and puts the size in outCount.
+   * Returns the next block available and puts the size in out_count.
    * This is useful for grabbing blocks where the size doesn't matter.
-   * Use backUp() to give back any bytes that were not used.
+   * Use BackUp() to give back any bytes that were not used.
    */
-  void* nextBlock(size_t* outCount);
+  void* NextBlock(size_t* out_count);
 
   /**
-   * Backs up count bytes. This must only be called after nextBlock()
-   * and can not be larger than sizeof(T) * count of the last nextBlock()
+   * Backs up count bytes. This must only be called after NextBlock()
+   * and can not be larger than sizeof(T) * count of the last NextBlock()
    * call.
    */
-  void backUp(size_t count);
+  void BackUp(size_t count);
 
   /**
    * Moves the specified BigBuffer into this one. When this method
    * returns, buffer is empty.
    */
-  void appendBuffer(BigBuffer&& buffer);
+  void AppendBuffer(BigBuffer&& buffer);
 
   /**
    * Pads the block with 'bytes' bytes of zero values.
    */
-  void pad(size_t bytes);
+  void Pad(size_t bytes);
 
   /**
    * Pads the block so that it aligns on a 4 byte boundary.
    */
-  void align4();
+  void Align4();
 
-  size_t getBlockSize() const;
+  size_t block_size() const;
 
   const_iterator begin() const;
   const_iterator end() const;
 
  private:
+  DISALLOW_COPY_AND_ASSIGN(BigBuffer);
+
   /**
    * Returns a pointer to a buffer of the requested size.
    * The buffer is zero-initialized.
    */
-  void* nextBlockImpl(size_t size);
+  void* NextBlockImpl(size_t size);
 
-  size_t mBlockSize;
-  size_t mSize;
-  std::vector<Block> mBlocks;
+  size_t block_size_;
+  size_t size_;
+  std::vector<Block> blocks_;
 };
 
-inline BigBuffer::BigBuffer(size_t blockSize)
-    : mBlockSize(blockSize), mSize(0) {}
+inline BigBuffer::BigBuffer(size_t block_size)
+    : block_size_(block_size), size_(0) {}
 
 inline BigBuffer::BigBuffer(BigBuffer&& rhs)
-    : mBlockSize(rhs.mBlockSize),
-      mSize(rhs.mSize),
-      mBlocks(std::move(rhs.mBlocks)) {}
+    : block_size_(rhs.block_size_),
+      size_(rhs.size_),
+      blocks_(std::move(rhs.blocks_)) {}
 
-inline size_t BigBuffer::size() const { return mSize; }
+inline size_t BigBuffer::size() const { return size_; }
 
-inline size_t BigBuffer::getBlockSize() const { return mBlockSize; }
+inline size_t BigBuffer::block_size() const { return block_size_; }
 
 template <typename T>
-inline T* BigBuffer::nextBlock(size_t count) {
+inline T* BigBuffer::NextBlock(size_t count) {
   static_assert(std::is_standard_layout<T>::value,
                 "T must be standard_layout type");
-  assert(count != 0);
-  return reinterpret_cast<T*>(nextBlockImpl(sizeof(T) * count));
+  CHECK(count != 0);
+  return reinterpret_cast<T*>(NextBlockImpl(sizeof(T) * count));
 }
 
-inline void BigBuffer::backUp(size_t count) {
-  Block& block = mBlocks.back();
+inline void BigBuffer::BackUp(size_t count) {
+  Block& block = blocks_.back();
   block.size -= count;
-  mSize -= count;
+  size_ -= count;
 }
 
-inline void BigBuffer::appendBuffer(BigBuffer&& buffer) {
-  std::move(buffer.mBlocks.begin(), buffer.mBlocks.end(),
-            std::back_inserter(mBlocks));
-  mSize += buffer.mSize;
-  buffer.mBlocks.clear();
-  buffer.mSize = 0;
+inline void BigBuffer::AppendBuffer(BigBuffer&& buffer) {
+  std::move(buffer.blocks_.begin(), buffer.blocks_.end(),
+            std::back_inserter(blocks_));
+  size_ += buffer.size_;
+  buffer.blocks_.clear();
+  buffer.size_ = 0;
 }
 
-inline void BigBuffer::pad(size_t bytes) { nextBlock<char>(bytes); }
+inline void BigBuffer::Pad(size_t bytes) { NextBlock<char>(bytes); }
 
-inline void BigBuffer::align4() {
-  const size_t unaligned = mSize % 4;
+inline void BigBuffer::Align4() {
+  const size_t unaligned = size_ % 4;
   if (unaligned != 0) {
-    pad(4 - unaligned);
+    Pad(4 - unaligned);
   }
 }
 
 inline BigBuffer::const_iterator BigBuffer::begin() const {
-  return mBlocks.begin();
+  return blocks_.begin();
 }
 
 inline BigBuffer::const_iterator BigBuffer::end() const {
-  return mBlocks.end();
+  return blocks_.end();
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/util/BigBuffer_test.cpp b/tools/aapt2/util/BigBuffer_test.cpp
index 2a24f12..12c0b3e 100644
--- a/tools/aapt2/util/BigBuffer_test.cpp
+++ b/tools/aapt2/util/BigBuffer_test.cpp
@@ -16,83 +16,83 @@
 
 #include "util/BigBuffer.h"
 
-#include <gtest/gtest.h>
+#include "test/Test.h"
 
 namespace aapt {
 
 TEST(BigBufferTest, AllocateSingleBlock) {
-    BigBuffer buffer(4);
+  BigBuffer buffer(4);
 
-    EXPECT_NE(nullptr, buffer.nextBlock<char>(2));
-    EXPECT_EQ(2u, buffer.size());
+  EXPECT_NE(nullptr, buffer.NextBlock<char>(2));
+  EXPECT_EQ(2u, buffer.size());
 }
 
 TEST(BigBufferTest, ReturnSameBlockIfNextAllocationFits) {
-    BigBuffer buffer(16);
+  BigBuffer buffer(16);
 
-    char* b1 = buffer.nextBlock<char>(8);
-    EXPECT_NE(nullptr, b1);
+  char* b1 = buffer.NextBlock<char>(8);
+  EXPECT_NE(nullptr, b1);
 
-    char* b2 = buffer.nextBlock<char>(4);
-    EXPECT_NE(nullptr, b2);
+  char* b2 = buffer.NextBlock<char>(4);
+  EXPECT_NE(nullptr, b2);
 
-    EXPECT_EQ(b1 + 8, b2);
+  EXPECT_EQ(b1 + 8, b2);
 }
 
 TEST(BigBufferTest, AllocateExactSizeBlockIfLargerThanBlockSize) {
-    BigBuffer buffer(16);
+  BigBuffer buffer(16);
 
-    EXPECT_NE(nullptr, buffer.nextBlock<char>(32));
-    EXPECT_EQ(32u, buffer.size());
+  EXPECT_NE(nullptr, buffer.NextBlock<char>(32));
+  EXPECT_EQ(32u, buffer.size());
 }
 
 TEST(BigBufferTest, AppendAndMoveBlock) {
-    BigBuffer buffer(16);
+  BigBuffer buffer(16);
 
-    uint32_t* b1 = buffer.nextBlock<uint32_t>();
+  uint32_t* b1 = buffer.NextBlock<uint32_t>();
+  ASSERT_NE(nullptr, b1);
+  *b1 = 33;
+
+  {
+    BigBuffer buffer2(16);
+    b1 = buffer2.NextBlock<uint32_t>();
     ASSERT_NE(nullptr, b1);
-    *b1 = 33;
+    *b1 = 44;
 
-    {
-        BigBuffer buffer2(16);
-        b1 = buffer2.nextBlock<uint32_t>();
-        ASSERT_NE(nullptr, b1);
-        *b1 = 44;
+    buffer.AppendBuffer(std::move(buffer2));
+    EXPECT_EQ(0u, buffer2.size());
+    EXPECT_EQ(buffer2.begin(), buffer2.end());
+  }
 
-        buffer.appendBuffer(std::move(buffer2));
-        EXPECT_EQ(0u, buffer2.size());
-        EXPECT_EQ(buffer2.begin(), buffer2.end());
-    }
+  EXPECT_EQ(2 * sizeof(uint32_t), buffer.size());
 
-    EXPECT_EQ(2 * sizeof(uint32_t), buffer.size());
+  auto b = buffer.begin();
+  ASSERT_NE(b, buffer.end());
+  ASSERT_EQ(sizeof(uint32_t), b->size);
+  ASSERT_EQ(33u, *reinterpret_cast<uint32_t*>(b->buffer.get()));
+  ++b;
 
-    auto b = buffer.begin();
-    ASSERT_NE(b, buffer.end());
-    ASSERT_EQ(sizeof(uint32_t), b->size);
-    ASSERT_EQ(33u, *reinterpret_cast<uint32_t*>(b->buffer.get()));
-    ++b;
+  ASSERT_NE(b, buffer.end());
+  ASSERT_EQ(sizeof(uint32_t), b->size);
+  ASSERT_EQ(44u, *reinterpret_cast<uint32_t*>(b->buffer.get()));
+  ++b;
 
-    ASSERT_NE(b, buffer.end());
-    ASSERT_EQ(sizeof(uint32_t), b->size);
-    ASSERT_EQ(44u, *reinterpret_cast<uint32_t*>(b->buffer.get()));
-    ++b;
-
-    ASSERT_EQ(b, buffer.end());
+  ASSERT_EQ(b, buffer.end());
 }
 
 TEST(BigBufferTest, PadAndAlignProperly) {
-    BigBuffer buffer(16);
+  BigBuffer buffer(16);
 
-    ASSERT_NE(buffer.nextBlock<char>(2), nullptr);
-    ASSERT_EQ(2u, buffer.size());
-    buffer.pad(2);
-    ASSERT_EQ(4u, buffer.size());
-    buffer.align4();
-    ASSERT_EQ(4u, buffer.size());
-    buffer.pad(2);
-    ASSERT_EQ(6u, buffer.size());
-    buffer.align4();
-    ASSERT_EQ(8u, buffer.size());
+  ASSERT_NE(buffer.NextBlock<char>(2), nullptr);
+  ASSERT_EQ(2u, buffer.size());
+  buffer.Pad(2);
+  ASSERT_EQ(4u, buffer.size());
+  buffer.Align4();
+  ASSERT_EQ(4u, buffer.size());
+  buffer.Pad(2);
+  ASSERT_EQ(6u, buffer.size());
+  buffer.Align4();
+  ASSERT_EQ(8u, buffer.size());
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp
index 4cba921..f034607 100644
--- a/tools/aapt2/util/Files.cpp
+++ b/tools/aapt2/util/Files.cpp
@@ -15,15 +15,20 @@
  */
 
 #include "util/Files.h"
-#include "util/Util.h"
+
+#include <dirent.h>
+#include <sys/stat.h>
 
 #include <algorithm>
-#include <android-base/file.h>
 #include <cerrno>
 #include <cstdio>
-#include <dirent.h>
 #include <string>
-#include <sys/stat.h>
+
+#include "android-base/errors.h"
+#include "android-base/file.h"
+#include "android-base/logging.h"
+
+#include "util/Util.h"
 
 #ifdef _WIN32
 // Windows includes.
@@ -33,244 +38,230 @@
 namespace aapt {
 namespace file {
 
-FileType getFileType(const StringPiece& path) {
-    struct stat sb;
-    if (stat(path.data(), &sb) < 0) {
-        if (errno == ENOENT || errno == ENOTDIR) {
-            return FileType::kNonexistant;
-        }
-        return FileType::kUnknown;
+FileType GetFileType(const StringPiece& path) {
+  struct stat sb;
+  if (stat(path.data(), &sb) < 0) {
+    if (errno == ENOENT || errno == ENOTDIR) {
+      return FileType::kNonexistant;
     }
+    return FileType::kUnknown;
+  }
 
-    if (S_ISREG(sb.st_mode)) {
-        return FileType::kRegular;
-    } else if (S_ISDIR(sb.st_mode)) {
-        return FileType::kDirectory;
-    } else if (S_ISCHR(sb.st_mode)) {
-        return FileType::kCharDev;
-    } else if (S_ISBLK(sb.st_mode)) {
-        return FileType::kBlockDev;
-    } else if (S_ISFIFO(sb.st_mode)) {
-        return FileType::kFifo;
+  if (S_ISREG(sb.st_mode)) {
+    return FileType::kRegular;
+  } else if (S_ISDIR(sb.st_mode)) {
+    return FileType::kDirectory;
+  } else if (S_ISCHR(sb.st_mode)) {
+    return FileType::kCharDev;
+  } else if (S_ISBLK(sb.st_mode)) {
+    return FileType::kBlockDev;
+  } else if (S_ISFIFO(sb.st_mode)) {
+    return FileType::kFifo;
 #if defined(S_ISLNK)
-    } else if (S_ISLNK(sb.st_mode)) {
-        return FileType::kSymlink;
+  } else if (S_ISLNK(sb.st_mode)) {
+    return FileType::kSymlink;
 #endif
 #if defined(S_ISSOCK)
-    } else if (S_ISSOCK(sb.st_mode)) {
-        return FileType::kSocket;
+  } else if (S_ISSOCK(sb.st_mode)) {
+    return FileType::kSocket;
 #endif
-    } else {
-        return FileType::kUnknown;
-    }
+  } else {
+    return FileType::kUnknown;
+  }
 }
 
-std::vector<std::string> listFiles(const StringPiece& root, std::string* outError) {
-    DIR* dir = opendir(root.data());
-    if (dir == nullptr) {
-        if (outError) {
-            std::stringstream errorStr;
-            errorStr << "unable to open file: " << strerror(errno);
-            *outError = errorStr.str();
-        }
-        return {};
-    }
-
-    std::vector<std::string> files;
-    dirent* entry;
-    while ((entry = readdir(dir))) {
-        files.emplace_back(entry->d_name);
-    }
-
-    closedir(dir);
-    return files;
-}
-
-inline static int mkdirImpl(const StringPiece& path) {
+inline static int MkdirImpl(const StringPiece& path) {
 #ifdef _WIN32
-    return _mkdir(path.toString().c_str());
+  return _mkdir(path.ToString().c_str());
 #else
-    return mkdir(path.toString().c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
+  return mkdir(path.ToString().c_str(),
+               S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP);
 #endif
 }
 
 bool mkdirs(const StringPiece& path) {
-    const char* start = path.begin();
-    const char* end = path.end();
-    for (const char* current = start; current != end; ++current) {
-        if (*current == sDirSep && current != start) {
-            StringPiece parentPath(start, current - start);
-            int result = mkdirImpl(parentPath);
-            if (result < 0 && errno != EEXIST) {
-                return false;
-            }
-        }
-    }
-    return mkdirImpl(path) == 0 || errno == EEXIST;
-}
-
-StringPiece getStem(const StringPiece& path) {
-    const char* start = path.begin();
-    const char* end = path.end();
-    for (const char* current = end - 1; current != start - 1; --current) {
-        if (*current == sDirSep) {
-            return StringPiece(start, current - start);
-        }
-    }
-    return {};
-}
-
-StringPiece getFilename(const StringPiece& path) {
-    const char* end = path.end();
-    const char* lastDirSep = path.begin();
-    for (const char* c = path.begin(); c != end; ++c) {
-        if (*c == sDirSep) {
-            lastDirSep = c + 1;
-        }
-    }
-    return StringPiece(lastDirSep, end - lastDirSep);
-}
-
-StringPiece getExtension(const StringPiece& path) {
-    StringPiece filename = getFilename(path);
-    const char* const end = filename.end();
-    const char* c = std::find(filename.begin(), end, '.');
-    if (c != end) {
-        return StringPiece(c, end - c);
-    }
-    return {};
-}
-
-void appendPath(std::string* base, StringPiece part) {
-    assert(base);
-    const bool baseHasTrailingSep = (!base->empty() && *(base->end() - 1) == sDirSep);
-    const bool partHasLeadingSep = (!part.empty() && *(part.begin()) == sDirSep);
-    if (baseHasTrailingSep && partHasLeadingSep) {
-        // Remove the part's leading sep
-        part = part.substr(1, part.size() - 1);
-    } else if (!baseHasTrailingSep && !partHasLeadingSep) {
-        // None of the pieces has a separator.
-        *base += sDirSep;
-    }
-    base->append(part.data(), part.size());
-}
-
-std::string packageToPath(const StringPiece& package) {
-    std::string outPath;
-    for (StringPiece part : util::tokenize(package, '.')) {
-        appendPath(&outPath, part);
-    }
-    return outPath;
-}
-
-Maybe<android::FileMap> mmapPath(const StringPiece& path, std::string* outError) {
-    std::unique_ptr<FILE, decltype(fclose)*> f = { fopen(path.data(), "rb"), fclose };
-    if (!f) {
-        if (outError) *outError = strerror(errno);
-        return {};
-    }
-
-    int fd = fileno(f.get());
-
-    struct stat fileStats = {};
-    if (fstat(fd, &fileStats) != 0) {
-        if (outError) *outError = strerror(errno);
-        return {};
-    }
-
-    android::FileMap fileMap;
-    if (fileStats.st_size == 0) {
-        // mmap doesn't like a length of 0. Instead we return an empty FileMap.
-        return std::move(fileMap);
-    }
-
-    if (!fileMap.create(path.data(), fd, 0, fileStats.st_size, true)) {
-        if (outError) *outError = strerror(errno);
-        return {};
-    }
-    return std::move(fileMap);
-}
-
-bool appendArgsFromFile(const StringPiece& path, std::vector<std::string>* outArgList,
-                        std::string* outError) {
-    std::string contents;
-    if (!android::base::ReadFileToString(path.toString(), &contents)) {
-        if (outError) *outError = "failed to read argument-list file";
+  const char* start = path.begin();
+  const char* end = path.end();
+  for (const char* current = start; current != end; ++current) {
+    if (*current == sDirSep && current != start) {
+      StringPiece parent_path(start, current - start);
+      int result = MkdirImpl(parent_path);
+      if (result < 0 && errno != EEXIST) {
         return false;
+      }
     }
-
-    for (StringPiece line : util::tokenize(contents, ' ')) {
-        line = util::trimWhitespace(line);
-        if (!line.empty()) {
-            outArgList->push_back(line.toString());
-        }
-    }
-    return true;
+  }
+  return MkdirImpl(path) == 0 || errno == EEXIST;
 }
 
-bool FileFilter::setPattern(const StringPiece& pattern) {
-    mPatternTokens = util::splitAndLowercase(pattern, ':');
-    return true;
+StringPiece GetStem(const StringPiece& path) {
+  const char* start = path.begin();
+  const char* end = path.end();
+  for (const char* current = end - 1; current != start - 1; --current) {
+    if (*current == sDirSep) {
+      return StringPiece(start, current - start);
+    }
+  }
+  return {};
+}
+
+StringPiece GetFilename(const StringPiece& path) {
+  const char* end = path.end();
+  const char* last_dir_sep = path.begin();
+  for (const char* c = path.begin(); c != end; ++c) {
+    if (*c == sDirSep) {
+      last_dir_sep = c + 1;
+    }
+  }
+  return StringPiece(last_dir_sep, end - last_dir_sep);
+}
+
+StringPiece GetExtension(const StringPiece& path) {
+  StringPiece filename = GetFilename(path);
+  const char* const end = filename.end();
+  const char* c = std::find(filename.begin(), end, '.');
+  if (c != end) {
+    return StringPiece(c, end - c);
+  }
+  return {};
+}
+
+void AppendPath(std::string* base, StringPiece part) {
+  CHECK(base != nullptr);
+  const bool base_has_trailing_sep =
+      (!base->empty() && *(base->end() - 1) == sDirSep);
+  const bool part_has_leading_sep =
+      (!part.empty() && *(part.begin()) == sDirSep);
+  if (base_has_trailing_sep && part_has_leading_sep) {
+    // Remove the part's leading sep
+    part = part.substr(1, part.size() - 1);
+  } else if (!base_has_trailing_sep && !part_has_leading_sep) {
+    // None of the pieces has a separator.
+    *base += sDirSep;
+  }
+  base->append(part.data(), part.size());
+}
+
+std::string PackageToPath(const StringPiece& package) {
+  std::string out_path;
+  for (StringPiece part : util::Tokenize(package, '.')) {
+    AppendPath(&out_path, part);
+  }
+  return out_path;
+}
+
+Maybe<android::FileMap> MmapPath(const StringPiece& path,
+                                 std::string* out_error) {
+  std::unique_ptr<FILE, decltype(fclose)*> f = {fopen(path.data(), "rb"),
+                                                fclose};
+  if (!f) {
+    if (out_error) *out_error = android::base::SystemErrorCodeToString(errno);
+    return {};
+  }
+
+  int fd = fileno(f.get());
+
+  struct stat filestats = {};
+  if (fstat(fd, &filestats) != 0) {
+    if (out_error) *out_error = android::base::SystemErrorCodeToString(errno);
+    return {};
+  }
+
+  android::FileMap filemap;
+  if (filestats.st_size == 0) {
+    // mmap doesn't like a length of 0. Instead we return an empty FileMap.
+    return std::move(filemap);
+  }
+
+  if (!filemap.create(path.data(), fd, 0, filestats.st_size, true)) {
+    if (out_error) *out_error = android::base::SystemErrorCodeToString(errno);
+    return {};
+  }
+  return std::move(filemap);
+}
+
+bool AppendArgsFromFile(const StringPiece& path,
+                        std::vector<std::string>* out_arglist,
+                        std::string* out_error) {
+  std::string contents;
+  if (!android::base::ReadFileToString(path.ToString(), &contents)) {
+    if (out_error) *out_error = "failed to read argument-list file";
+    return false;
+  }
+
+  for (StringPiece line : util::Tokenize(contents, ' ')) {
+    line = util::TrimWhitespace(line);
+    if (!line.empty()) {
+      out_arglist->push_back(line.ToString());
+    }
+  }
+  return true;
+}
+
+bool FileFilter::SetPattern(const StringPiece& pattern) {
+  pattern_tokens_ = util::SplitAndLowercase(pattern, ':');
+  return true;
 }
 
 bool FileFilter::operator()(const std::string& filename, FileType type) const {
-    if (filename == "." || filename == "..") {
-        return false;
+  if (filename == "." || filename == "..") {
+    return false;
+  }
+
+  const char kDir[] = "dir";
+  const char kFile[] = "file";
+  const size_t filename_len = filename.length();
+  bool chatty = true;
+  for (const std::string& token : pattern_tokens_) {
+    const char* token_str = token.c_str();
+    if (*token_str == '!') {
+      chatty = false;
+      token_str++;
     }
 
-    const char kDir[] = "dir";
-    const char kFile[] = "file";
-    const size_t filenameLen = filename.length();
-    bool chatty = true;
-    for (const std::string& token : mPatternTokens) {
-        const char* tokenStr = token.c_str();
-        if (*tokenStr == '!') {
-            chatty = false;
-            tokenStr++;
-        }
-
-        if (strncasecmp(tokenStr, kDir, sizeof(kDir)) == 0) {
-            if (type != FileType::kDirectory) {
-                continue;
-            }
-            tokenStr += sizeof(kDir);
-        }
-
-        if (strncasecmp(tokenStr, kFile, sizeof(kFile)) == 0) {
-            if (type != FileType::kRegular) {
-                continue;
-            }
-            tokenStr += sizeof(kFile);
-        }
-
-        bool ignore = false;
-        size_t n = strlen(tokenStr);
-        if (*tokenStr == '*') {
-            // Math suffix.
-            tokenStr++;
-            n--;
-            if (n <= filenameLen) {
-                ignore = strncasecmp(tokenStr, filename.c_str() + filenameLen - n, n) == 0;
-            }
-        } else if (n > 1 && tokenStr[n - 1] == '*') {
-            // Match prefix.
-            ignore = strncasecmp(tokenStr, filename.c_str(), n - 1) == 0;
-        } else {
-            ignore = strcasecmp(tokenStr, filename.c_str()) == 0;
-        }
-
-        if (ignore) {
-            if (chatty) {
-                mDiag->warn(DiagMessage() << "skipping "
-                            << (type == FileType::kDirectory ? "dir '" : "file '")
-                            << filename << "' due to ignore pattern '"
-                            << token << "'");
-            }
-            return false;
-        }
+    if (strncasecmp(token_str, kDir, sizeof(kDir)) == 0) {
+      if (type != FileType::kDirectory) {
+        continue;
+      }
+      token_str += sizeof(kDir);
     }
-    return true;
+
+    if (strncasecmp(token_str, kFile, sizeof(kFile)) == 0) {
+      if (type != FileType::kRegular) {
+        continue;
+      }
+      token_str += sizeof(kFile);
+    }
+
+    bool ignore = false;
+    size_t n = strlen(token_str);
+    if (*token_str == '*') {
+      // Math suffix.
+      token_str++;
+      n--;
+      if (n <= filename_len) {
+        ignore =
+            strncasecmp(token_str, filename.c_str() + filename_len - n, n) == 0;
+      }
+    } else if (n > 1 && token_str[n - 1] == '*') {
+      // Match prefix.
+      ignore = strncasecmp(token_str, filename.c_str(), n - 1) == 0;
+    } else {
+      ignore = strcasecmp(token_str, filename.c_str()) == 0;
+    }
+
+    if (ignore) {
+      if (chatty) {
+        diag_->Warn(DiagMessage()
+                    << "skipping "
+                    << (type == FileType::kDirectory ? "dir '" : "file '")
+                    << filename << "' due to ignore pattern '" << token << "'");
+      }
+      return false;
+    }
+  }
+  return true;
 }
 
-} // namespace file
-} // namespace aapt
+}  // namespace file
+}  // namespace aapt
diff --git a/tools/aapt2/util/Files.h b/tools/aapt2/util/Files.h
index d90c6b6..a157dbd 100644
--- a/tools/aapt2/util/Files.h
+++ b/tools/aapt2/util/Files.h
@@ -17,18 +17,18 @@
 #ifndef AAPT_FILES_H
 #define AAPT_FILES_H
 
-#include "Diagnostics.h"
-#include "Maybe.h"
-#include "Source.h"
-
-#include "util/StringPiece.h"
-
-#include <utils/FileMap.h>
-#include <cassert>
 #include <memory>
 #include <string>
 #include <vector>
 
+#include "android-base/macros.h"
+#include "utils/FileMap.h"
+
+#include "Diagnostics.h"
+#include "Maybe.h"
+#include "Source.h"
+#include "util/StringPiece.h"
+
 namespace aapt {
 namespace file {
 
@@ -50,18 +50,12 @@
   kSocket,
 };
 
-FileType getFileType(const StringPiece& path);
-
-/*
- * Lists files under the directory `root`. Files are listed
- * with just their leaf (filename) names.
- */
-std::vector<std::string> listFiles(const StringPiece& root);
+FileType GetFileType(const StringPiece& path);
 
 /*
  * Appends a path to `base`, separated by the directory separator.
  */
-void appendPath(std::string* base, StringPiece part);
+void AppendPath(std::string* base, StringPiece part);
 
 /*
  * Makes all the directories in `path`. The last element in the path
@@ -72,46 +66,45 @@
 /**
  * Returns all but the last part of the path.
  */
-StringPiece getStem(const StringPiece& path);
+StringPiece GetStem(const StringPiece& path);
 
 /**
  * Returns the last part of the path with extension.
  */
-StringPiece getFilename(const StringPiece& path);
+StringPiece GetFilename(const StringPiece& path);
 
 /**
  * Returns the extension of the path. This is the entire string after
  * the first '.' of the last part of the path.
  */
-StringPiece getExtension(const StringPiece& path);
+StringPiece GetExtension(const StringPiece& path);
 
 /**
  * Converts a package name (com.android.app) to a path: com/android/app
  */
-std::string packageToPath(const StringPiece& package);
+std::string PackageToPath(const StringPiece& package);
 
 /**
  * Creates a FileMap for the file at path.
  */
-Maybe<android::FileMap> mmapPath(const StringPiece& path,
-                                 std::string* outError);
+Maybe<android::FileMap> MmapPath(const StringPiece& path,
+                                 std::string* out_error);
 
 /**
  * Reads the file at path and appends each line to the outArgList vector.
  */
-bool appendArgsFromFile(const StringPiece& path,
-                        std::vector<std::string>* outArgList,
-                        std::string* outError);
+bool AppendArgsFromFile(const StringPiece& path,
+                        std::vector<std::string>* out_arglist,
+                        std::string* out_error);
 
 /*
  * Filter that determines which resource files/directories are
  * processed by AAPT. Takes a pattern string supplied by the user.
- * Pattern format is specified in the
- * FileFilter::setPattern(const std::string&) method.
+ * Pattern format is specified in the FileFilter::SetPattern() method.
  */
 class FileFilter {
  public:
-  explicit FileFilter(IDiagnostics* diag) : mDiag(diag) {}
+  explicit FileFilter(IDiagnostics* diag) : diag_(diag) {}
 
   /*
    * Patterns syntax:
@@ -127,7 +120,7 @@
    * - Otherwise the full string is matched.
    * - match is not case-sensitive.
    */
-  bool setPattern(const StringPiece& pattern);
+  bool SetPattern(const StringPiece& pattern);
 
   /**
    * Applies the filter, returning true for pass, false for fail.
@@ -135,8 +128,10 @@
   bool operator()(const std::string& filename, FileType type) const;
 
  private:
-  IDiagnostics* mDiag;
-  std::vector<std::string> mPatternTokens;
+  DISALLOW_COPY_AND_ASSIGN(FileFilter);
+
+  IDiagnostics* diag_;
+  std::vector<std::string> pattern_tokens_;
 };
 
 }  // namespace file
diff --git a/tools/aapt2/util/Files_test.cpp b/tools/aapt2/util/Files_test.cpp
index efb0459..219c183 100644
--- a/tools/aapt2/util/Files_test.cpp
+++ b/tools/aapt2/util/Files_test.cpp
@@ -14,45 +14,46 @@
  * limitations under the License.
  */
 
-#include "test/Test.h"
 #include "util/Files.h"
 
 #include <sstream>
 
+#include "test/Test.h"
+
 namespace aapt {
 namespace file {
 
 class FilesTest : public ::testing::Test {
-public:
-    void SetUp() override {
-        std::stringstream builder;
-        builder << "hello" << sDirSep << "there";
-        mExpectedPath = builder.str();
-    }
+ public:
+  void SetUp() override {
+    std::stringstream builder;
+    builder << "hello" << sDirSep << "there";
+    expected_path_ = builder.str();
+  }
 
-protected:
-    std::string mExpectedPath;
+ protected:
+  std::string expected_path_;
 };
 
-TEST_F(FilesTest, appendPath) {
-    std::string base = "hello";
-    appendPath(&base, "there");
-    EXPECT_EQ(mExpectedPath, base);
+TEST_F(FilesTest, AppendPath) {
+  std::string base = "hello";
+  AppendPath(&base, "there");
+  EXPECT_EQ(expected_path_, base);
 }
 
-TEST_F(FilesTest, appendPathWithLeadingOrTrailingSeparators) {
-    std::string base = "hello/";
-    appendPath(&base, "there");
-    EXPECT_EQ(mExpectedPath, base);
+TEST_F(FilesTest, AppendPathWithLeadingOrTrailingSeparators) {
+  std::string base = "hello/";
+  AppendPath(&base, "there");
+  EXPECT_EQ(expected_path_, base);
 
-    base = "hello";
-    appendPath(&base, "/there");
-    EXPECT_EQ(mExpectedPath, base);
+  base = "hello";
+  AppendPath(&base, "/there");
+  EXPECT_EQ(expected_path_, base);
 
-    base = "hello/";
-    appendPath(&base, "/there");
-    EXPECT_EQ(mExpectedPath, base);
+  base = "hello/";
+  AppendPath(&base, "/there");
+  EXPECT_EQ(expected_path_, base);
 }
 
-} // namespace files
-} // namespace aapt
+}  // namespace files
+}  // namespace aapt
diff --git a/tools/aapt2/util/ImmutableMap.h b/tools/aapt2/util/ImmutableMap.h
index 6f48764..59858e4 100644
--- a/tools/aapt2/util/ImmutableMap.h
+++ b/tools/aapt2/util/ImmutableMap.h
@@ -17,39 +17,31 @@
 #ifndef AAPT_UTIL_IMMUTABLEMAP_H
 #define AAPT_UTIL_IMMUTABLEMAP_H
 
-#include "util/TypeTraits.h"
-
 #include <utility>
 #include <vector>
 
+#include "util/TypeTraits.h"
+
 namespace aapt {
 
 template <typename TKey, typename TValue>
 class ImmutableMap {
   static_assert(is_comparable<TKey, TKey>::value, "key is not comparable");
 
- private:
-  std::vector<std::pair<TKey, TValue>> mData;
-
-  explicit ImmutableMap(std::vector<std::pair<TKey, TValue>> data)
-      : mData(std::move(data)) {}
-
  public:
-  using const_iterator = typename decltype(mData)::const_iterator;
+  using const_iterator =
+      typename std::vector<std::pair<TKey, TValue>>::const_iterator;
 
   ImmutableMap(ImmutableMap&&) = default;
   ImmutableMap& operator=(ImmutableMap&&) = default;
 
-  ImmutableMap(const ImmutableMap&) = delete;
-  ImmutableMap& operator=(const ImmutableMap&) = delete;
-
-  static ImmutableMap<TKey, TValue> createPreSorted(
+  static ImmutableMap<TKey, TValue> CreatePreSorted(
       std::initializer_list<std::pair<TKey, TValue>> list) {
     return ImmutableMap(
         std::vector<std::pair<TKey, TValue>>(list.begin(), list.end()));
   }
 
-  static ImmutableMap<TKey, TValue> createAndSort(
+  static ImmutableMap<TKey, TValue> CreateAndSort(
       std::initializer_list<std::pair<TKey, TValue>> list) {
     std::vector<std::pair<TKey, TValue>> data(list.begin(), list.end());
     std::sort(data.begin(), data.end());
@@ -64,17 +56,25 @@
       return candidate.first < target;
     };
 
-    const_iterator endIter = end();
-    auto iter = std::lower_bound(mData.begin(), endIter, key, cmp);
-    if (iter == endIter || iter->first == key) {
+    const_iterator end_iter = end();
+    auto iter = std::lower_bound(data_.begin(), end_iter, key, cmp);
+    if (iter == end_iter || iter->first == key) {
       return iter;
     }
-    return endIter;
+    return end_iter;
   }
 
-  const_iterator begin() const { return mData.begin(); }
+  const_iterator begin() const { return data_.begin(); }
 
-  const_iterator end() const { return mData.end(); }
+  const_iterator end() const { return data_.end(); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ImmutableMap);
+
+  explicit ImmutableMap(std::vector<std::pair<TKey, TValue>> data)
+      : data_(std::move(data)) {}
+
+  std::vector<std::pair<TKey, TValue>> data_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/util/Maybe.h b/tools/aapt2/util/Maybe.h
index 90a0198..b43f8e8 100644
--- a/tools/aapt2/util/Maybe.h
+++ b/tools/aapt2/util/Maybe.h
@@ -17,12 +17,13 @@
 #ifndef AAPT_MAYBE_H
 #define AAPT_MAYBE_H
 
-#include "util/TypeTraits.h"
-
-#include <cassert>
 #include <type_traits>
 #include <utility>
 
+#include "android-base/logging.h"
+
+#include "util/TypeTraits.h"
+
 namespace aapt {
 
 /**
@@ -88,7 +89,7 @@
    */
   const T& value() const;
 
-  T valueOrDefault(const T& def) const;
+  T value_or_default(const T& def) const;
 
  private:
   template <typename U>
@@ -102,55 +103,55 @@
 
   void destroy();
 
-  bool mNothing;
+  bool nothing_;
 
-  typename std::aligned_storage<sizeof(T), alignof(T)>::type mStorage;
+  typename std::aligned_storage<sizeof(T), alignof(T)>::type storage_;
 };
 
 template <typename T>
-Maybe<T>::Maybe() : mNothing(true) {}
+Maybe<T>::Maybe() : nothing_(true) {}
 
 template <typename T>
 Maybe<T>::~Maybe() {
-  if (!mNothing) {
+  if (!nothing_) {
     destroy();
   }
 }
 
 template <typename T>
-Maybe<T>::Maybe(const Maybe& rhs) : mNothing(rhs.mNothing) {
-  if (!rhs.mNothing) {
-    new (&mStorage) T(reinterpret_cast<const T&>(rhs.mStorage));
+Maybe<T>::Maybe(const Maybe& rhs) : nothing_(rhs.nothing_) {
+  if (!rhs.nothing_) {
+    new (&storage_) T(reinterpret_cast<const T&>(rhs.storage_));
   }
 }
 
 template <typename T>
 template <typename U>
-Maybe<T>::Maybe(const Maybe<U>& rhs) : mNothing(rhs.mNothing) {
-  if (!rhs.mNothing) {
-    new (&mStorage) T(reinterpret_cast<const U&>(rhs.mStorage));
+Maybe<T>::Maybe(const Maybe<U>& rhs) : nothing_(rhs.nothing_) {
+  if (!rhs.nothing_) {
+    new (&storage_) T(reinterpret_cast<const U&>(rhs.storage_));
   }
 }
 
 template <typename T>
-Maybe<T>::Maybe(Maybe&& rhs) : mNothing(rhs.mNothing) {
-  if (!rhs.mNothing) {
-    rhs.mNothing = true;
+Maybe<T>::Maybe(Maybe&& rhs) : nothing_(rhs.nothing_) {
+  if (!rhs.nothing_) {
+    rhs.nothing_ = true;
 
     // Move the value from rhs.
-    new (&mStorage) T(std::move(reinterpret_cast<T&>(rhs.mStorage)));
+    new (&storage_) T(std::move(reinterpret_cast<T&>(rhs.storage_)));
     rhs.destroy();
   }
 }
 
 template <typename T>
 template <typename U>
-Maybe<T>::Maybe(Maybe<U>&& rhs) : mNothing(rhs.mNothing) {
-  if (!rhs.mNothing) {
-    rhs.mNothing = true;
+Maybe<T>::Maybe(Maybe<U>&& rhs) : nothing_(rhs.nothing_) {
+  if (!rhs.nothing_) {
+    rhs.nothing_ = true;
 
     // Move the value from rhs.
-    new (&mStorage) T(std::move(reinterpret_cast<U&>(rhs.mStorage)));
+    new (&storage_) T(std::move(reinterpret_cast<U&>(rhs.storage_)));
     rhs.destroy();
   }
 }
@@ -170,21 +171,21 @@
 template <typename T>
 template <typename U>
 Maybe<T>& Maybe<T>::copy(const Maybe<U>& rhs) {
-  if (mNothing && rhs.mNothing) {
+  if (nothing_ && rhs.nothing_) {
     // Both are nothing, nothing to do.
     return *this;
-  } else if (!mNothing && !rhs.mNothing) {
+  } else if (!nothing_ && !rhs.nothing_) {
     // We both are something, so assign rhs to us.
-    reinterpret_cast<T&>(mStorage) = reinterpret_cast<const U&>(rhs.mStorage);
-  } else if (mNothing) {
+    reinterpret_cast<T&>(storage_) = reinterpret_cast<const U&>(rhs.storage_);
+  } else if (nothing_) {
     // We are nothing but rhs is something.
-    mNothing = rhs.mNothing;
+    nothing_ = rhs.nothing_;
 
     // Copy the value from rhs.
-    new (&mStorage) T(reinterpret_cast<const U&>(rhs.mStorage));
+    new (&storage_) T(reinterpret_cast<const U&>(rhs.storage_));
   } else {
     // We are something but rhs is nothing, so destroy our value.
-    mNothing = rhs.mNothing;
+    nothing_ = rhs.nothing_;
     destroy();
   }
   return *this;
@@ -205,69 +206,69 @@
 template <typename T>
 template <typename U>
 Maybe<T>& Maybe<T>::move(Maybe<U>&& rhs) {
-  if (mNothing && rhs.mNothing) {
+  if (nothing_ && rhs.nothing_) {
     // Both are nothing, nothing to do.
     return *this;
-  } else if (!mNothing && !rhs.mNothing) {
+  } else if (!nothing_ && !rhs.nothing_) {
     // We both are something, so move assign rhs to us.
-    rhs.mNothing = true;
-    reinterpret_cast<T&>(mStorage) =
-        std::move(reinterpret_cast<U&>(rhs.mStorage));
+    rhs.nothing_ = true;
+    reinterpret_cast<T&>(storage_) =
+        std::move(reinterpret_cast<U&>(rhs.storage_));
     rhs.destroy();
-  } else if (mNothing) {
+  } else if (nothing_) {
     // We are nothing but rhs is something.
-    mNothing = false;
-    rhs.mNothing = true;
+    nothing_ = false;
+    rhs.nothing_ = true;
 
     // Move the value from rhs.
-    new (&mStorage) T(std::move(reinterpret_cast<U&>(rhs.mStorage)));
+    new (&storage_) T(std::move(reinterpret_cast<U&>(rhs.storage_)));
     rhs.destroy();
   } else {
     // We are something but rhs is nothing, so destroy our value.
-    mNothing = true;
+    nothing_ = true;
     destroy();
   }
   return *this;
 }
 
 template <typename T>
-Maybe<T>::Maybe(const T& value) : mNothing(false) {
-  new (&mStorage) T(value);
+Maybe<T>::Maybe(const T& value) : nothing_(false) {
+  new (&storage_) T(value);
 }
 
 template <typename T>
-Maybe<T>::Maybe(T&& value) : mNothing(false) {
-  new (&mStorage) T(std::forward<T>(value));
+Maybe<T>::Maybe(T&& value) : nothing_(false) {
+  new (&storage_) T(std::forward<T>(value));
 }
 
 template <typename T>
 Maybe<T>::operator bool() const {
-  return !mNothing;
+  return !nothing_;
 }
 
 template <typename T>
 T& Maybe<T>::value() {
-  assert(!mNothing && "Maybe<T>::value() called on Nothing");
-  return reinterpret_cast<T&>(mStorage);
+  CHECK(!nothing_) << "Maybe<T>::value() called on Nothing";
+  return reinterpret_cast<T&>(storage_);
 }
 
 template <typename T>
 const T& Maybe<T>::value() const {
-  assert(!mNothing && "Maybe<T>::value() called on Nothing");
-  return reinterpret_cast<const T&>(mStorage);
+  CHECK(!nothing_) << "Maybe<T>::value() called on Nothing";
+  return reinterpret_cast<const T&>(storage_);
 }
 
 template <typename T>
-T Maybe<T>::valueOrDefault(const T& def) const {
-  if (mNothing) {
+T Maybe<T>::value_or_default(const T& def) const {
+  if (nothing_) {
     return def;
   }
-  return reinterpret_cast<const T&>(mStorage);
+  return reinterpret_cast<const T&>(storage_);
 }
 
 template <typename T>
 void Maybe<T>::destroy() {
-  reinterpret_cast<T&>(mStorage).~T();
+  reinterpret_cast<T&>(storage_).~T();
 }
 
 template <typename T>
diff --git a/tools/aapt2/util/Maybe_test.cpp b/tools/aapt2/util/Maybe_test.cpp
index 5d42dc3..ca14793 100644
--- a/tools/aapt2/util/Maybe_test.cpp
+++ b/tools/aapt2/util/Maybe_test.cpp
@@ -14,122 +14,116 @@
  * limitations under the License.
  */
 
-#include "test/Common.h"
 #include "util/Maybe.h"
 
-#include <gtest/gtest.h>
 #include <string>
 
+#include "test/Test.h"
+
 namespace aapt {
 
 struct Dummy {
-    Dummy() {
-        data = new int;
-        *data = 1;
-        std::cerr << "Construct Dummy{0x" << (void *) this
-                  << "} with data=0x" << (void*) data
-                  << std::endl;
+  Dummy() {
+    data = new int;
+    *data = 1;
+    std::cerr << "Construct Dummy{0x" << (void*)this << "} with data=0x"
+              << (void*)data << std::endl;
+  }
+
+  Dummy(const Dummy& rhs) {
+    data = nullptr;
+    if (rhs.data) {
+      data = new int;
+      *data = *rhs.data;
     }
+    std::cerr << "CopyConstruct Dummy{0x" << (void*)this << "} from Dummy{0x"
+              << (const void*)&rhs << "}" << std::endl;
+  }
 
-    Dummy(const Dummy& rhs) {
-        data = nullptr;
-        if (rhs.data) {
-            data = new int;
-            *data = *rhs.data;
-        }
-        std::cerr << "CopyConstruct Dummy{0x" << (void *) this
-                  << "} from Dummy{0x" << (const void*) &rhs
-                  << "}" << std::endl;
+  Dummy(Dummy&& rhs) {
+    data = rhs.data;
+    rhs.data = nullptr;
+    std::cerr << "MoveConstruct Dummy{0x" << (void*)this << "} from Dummy{0x"
+              << (const void*)&rhs << "}" << std::endl;
+  }
+
+  Dummy& operator=(const Dummy& rhs) {
+    delete data;
+    data = nullptr;
+
+    if (rhs.data) {
+      data = new int;
+      *data = *rhs.data;
     }
+    std::cerr << "CopyAssign Dummy{0x" << (void*)this << "} from Dummy{0x"
+              << (const void*)&rhs << "}" << std::endl;
+    return *this;
+  }
 
-    Dummy(Dummy&& rhs) {
-        data = rhs.data;
-        rhs.data = nullptr;
-        std::cerr << "MoveConstruct Dummy{0x" << (void *) this
-                  << "} from Dummy{0x" << (const void*) &rhs
-                  << "}" << std::endl;
-    }
+  Dummy& operator=(Dummy&& rhs) {
+    delete data;
+    data = rhs.data;
+    rhs.data = nullptr;
+    std::cerr << "MoveAssign Dummy{0x" << (void*)this << "} from Dummy{0x"
+              << (const void*)&rhs << "}" << std::endl;
+    return *this;
+  }
 
-    Dummy& operator=(const Dummy& rhs) {
-        delete data;
-        data = nullptr;
+  ~Dummy() {
+    std::cerr << "Destruct Dummy{0x" << (void*)this << "} with data=0x"
+              << (void*)data << std::endl;
+    delete data;
+  }
 
-        if (rhs.data) {
-            data = new int;
-            *data = *rhs.data;
-        }
-        std::cerr << "CopyAssign Dummy{0x" << (void *) this
-                  << "} from Dummy{0x" << (const void*) &rhs
-                  << "}" << std::endl;
-        return *this;
-    }
-
-    Dummy& operator=(Dummy&& rhs) {
-        delete data;
-        data = rhs.data;
-        rhs.data = nullptr;
-        std::cerr << "MoveAssign Dummy{0x" << (void *) this
-                  << "} from Dummy{0x" << (const void*) &rhs
-                  << "}" << std::endl;
-        return *this;
-    }
-
-    ~Dummy() {
-        std::cerr << "Destruct Dummy{0x" << (void *) this
-                  << "} with data=0x" << (void*) data
-                  << std::endl;
-        delete data;
-    }
-
-    int* data;
+  int* data;
 };
 
 TEST(MaybeTest, MakeNothing) {
-    Maybe<int> val = make_nothing<int>();
-    AAPT_EXPECT_FALSE(val);
+  Maybe<int> val = make_nothing<int>();
+  AAPT_EXPECT_FALSE(val);
 
-    Maybe<std::string> val2 = make_nothing<std::string>();
-    AAPT_EXPECT_FALSE(val2);
+  Maybe<std::string> val2 = make_nothing<std::string>();
+  AAPT_EXPECT_FALSE(val2);
 
-    val2 = make_nothing<std::string>();
-    AAPT_EXPECT_FALSE(val2);
+  val2 = make_nothing<std::string>();
+  AAPT_EXPECT_FALSE(val2);
 }
 
 TEST(MaybeTest, MakeSomething) {
-    Maybe<int> val = make_value(23);
-    AAPT_ASSERT_TRUE(val);
-    EXPECT_EQ(23, val.value());
+  Maybe<int> val = make_value(23);
+  AAPT_ASSERT_TRUE(val);
+  EXPECT_EQ(23, val.value());
 
-    Maybe<std::string> val2 = make_value(std::string("hey"));
-    AAPT_ASSERT_TRUE(val2);
-    EXPECT_EQ(std::string("hey"), val2.value());
+  Maybe<std::string> val2 = make_value(std::string("hey"));
+  AAPT_ASSERT_TRUE(val2);
+  EXPECT_EQ(std::string("hey"), val2.value());
 }
 
 TEST(MaybeTest, Lifecycle) {
-    Maybe<Dummy> val = make_nothing<Dummy>();
+  Maybe<Dummy> val = make_nothing<Dummy>();
 
-    Maybe<Dummy> val2 = make_value(Dummy());
+  Maybe<Dummy> val2 = make_value(Dummy());
 }
 
 TEST(MaybeTest, MoveAssign) {
-    Maybe<Dummy> val;
-    {
-        Maybe<Dummy> val2 = Dummy();
-        val = std::move(val2);
-    }
+  Maybe<Dummy> val;
+  {
+    Maybe<Dummy> val2 = Dummy();
+    val = std::move(val2);
+  }
 }
 
 TEST(MaybeTest, Equality) {
-    Maybe<int> a = 1;
-    Maybe<int> b = 1;
-    Maybe<int> c;
+  Maybe<int> a = 1;
+  Maybe<int> b = 1;
+  Maybe<int> c;
 
-    Maybe<int> emptyA, emptyB;
+  Maybe<int> emptyA, emptyB;
 
-    EXPECT_EQ(a, b);
-    EXPECT_EQ(b, a);
-    EXPECT_NE(a, c);
-    EXPECT_EQ(emptyA, emptyB);
+  EXPECT_EQ(a, b);
+  EXPECT_EQ(b, a);
+  EXPECT_NE(a, c);
+  EXPECT_EQ(emptyA, emptyB);
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/util/StringPiece.h b/tools/aapt2/util/StringPiece.h
index de93822..5144b1f 100644
--- a/tools/aapt2/util/StringPiece.h
+++ b/tools/aapt2/util/StringPiece.h
@@ -17,12 +17,13 @@
 #ifndef AAPT_STRING_PIECE_H
 #define AAPT_STRING_PIECE_H
 
-#include <utils/JenkinsHash.h>
-#include <utils/String8.h>
-#include <utils/Unicode.h>
 #include <ostream>
 #include <string>
 
+#include "utils/JenkinsHash.h"
+#include "utils/String8.h"
+#include "utils/Unicode.h"
+
 namespace aapt {
 
 /**
@@ -60,7 +61,7 @@
   size_t length() const;
   size_t size() const;
   bool empty() const;
-  std::basic_string<TChar> toString() const;
+  std::basic_string<TChar> ToString() const;
 
   bool contains(const BasicStringPiece<TChar>& rhs) const;
   int compare(const BasicStringPiece<TChar>& rhs) const;
@@ -73,8 +74,8 @@
   const_iterator end() const;
 
  private:
-  const TChar* mData;
-  size_t mLength;
+  const TChar* data_;
+  size_t length_;
 };
 
 using StringPiece = BasicStringPiece<char>;
@@ -89,43 +90,43 @@
 
 template <typename TChar>
 inline BasicStringPiece<TChar>::BasicStringPiece()
-    : mData(nullptr), mLength(0) {}
+    : data_(nullptr), length_(0) {}
 
 template <typename TChar>
 inline BasicStringPiece<TChar>::BasicStringPiece(
     const BasicStringPiece<TChar>& str)
-    : mData(str.mData), mLength(str.mLength) {}
+    : data_(str.data_), length_(str.length_) {}
 
 template <typename TChar>
 inline BasicStringPiece<TChar>::BasicStringPiece(
     const std::basic_string<TChar>& str)
-    : mData(str.data()), mLength(str.length()) {}
+    : data_(str.data()), length_(str.length()) {}
 
 template <>
 inline BasicStringPiece<char>::BasicStringPiece(const char* str)
-    : mData(str), mLength(str != nullptr ? strlen(str) : 0) {}
+    : data_(str), length_(str != nullptr ? strlen(str) : 0) {}
 
 template <>
 inline BasicStringPiece<char16_t>::BasicStringPiece(const char16_t* str)
-    : mData(str), mLength(str != nullptr ? strlen16(str) : 0) {}
+    : data_(str), length_(str != nullptr ? strlen16(str) : 0) {}
 
 template <typename TChar>
 inline BasicStringPiece<TChar>::BasicStringPiece(const TChar* str, size_t len)
-    : mData(str), mLength(len) {}
+    : data_(str), length_(len) {}
 
 template <typename TChar>
 inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::operator=(
     const BasicStringPiece<TChar>& rhs) {
-  mData = rhs.mData;
-  mLength = rhs.mLength;
+  data_ = rhs.data_;
+  length_ = rhs.length_;
   return *this;
 }
 
 template <typename TChar>
 inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::assign(
     const TChar* str, size_t len) {
-  mData = str;
-  mLength = len;
+  data_ = str;
+  length_ = len;
   return *this;
 }
 
@@ -133,13 +134,13 @@
 inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr(
     size_t start, size_t len) const {
   if (len == npos) {
-    len = mLength - start;
+    len = length_ - start;
   }
 
-  if (start > mLength || start + len > mLength) {
+  if (start > length_ || start + len > length_) {
     return BasicStringPiece<TChar>();
   }
-  return BasicStringPiece<TChar>(mData + start, len);
+  return BasicStringPiece<TChar>(data_ + start, len);
 }
 
 template <typename TChar>
@@ -151,49 +152,49 @@
 
 template <typename TChar>
 inline const TChar* BasicStringPiece<TChar>::data() const {
-  return mData;
+  return data_;
 }
 
 template <typename TChar>
 inline size_t BasicStringPiece<TChar>::length() const {
-  return mLength;
+  return length_;
 }
 
 template <typename TChar>
 inline size_t BasicStringPiece<TChar>::size() const {
-  return mLength;
+  return length_;
 }
 
 template <typename TChar>
 inline bool BasicStringPiece<TChar>::empty() const {
-  return mLength == 0;
+  return length_ == 0;
 }
 
 template <typename TChar>
-inline std::basic_string<TChar> BasicStringPiece<TChar>::toString() const {
-  return std::basic_string<TChar>(mData, mLength);
+inline std::basic_string<TChar> BasicStringPiece<TChar>::ToString() const {
+  return std::basic_string<TChar>(data_, length_);
 }
 
 template <>
 inline bool BasicStringPiece<char>::contains(
     const BasicStringPiece<char>& rhs) const {
-  if (!mData || !rhs.mData) {
+  if (!data_ || !rhs.data_) {
     return false;
   }
-  if (rhs.mLength > mLength) {
+  if (rhs.length_ > length_) {
     return false;
   }
-  return strstr(mData, rhs.mData) != nullptr;
+  return strstr(data_, rhs.data_) != nullptr;
 }
 
 template <>
 inline int BasicStringPiece<char>::compare(
     const BasicStringPiece<char>& rhs) const {
   const char nullStr = '\0';
-  const char* b1 = mData != nullptr ? mData : &nullStr;
-  const char* e1 = b1 + mLength;
-  const char* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr;
-  const char* e2 = b2 + rhs.mLength;
+  const char* b1 = data_ != nullptr ? data_ : &nullStr;
+  const char* e1 = b1 + length_;
+  const char* b2 = rhs.data_ != nullptr ? rhs.data_ : &nullStr;
+  const char* e2 = b2 + rhs.length_;
 
   while (b1 < e1 && b2 < e2) {
     const int d = static_cast<int>(*b1++) - static_cast<int>(*b2++);
@@ -201,7 +202,7 @@
       return d;
     }
   }
-  return static_cast<int>(mLength - rhs.mLength);
+  return static_cast<int>(length_ - rhs.length_);
 }
 
 inline ::std::ostream& operator<<(::std::ostream& out,
@@ -213,22 +214,22 @@
 template <>
 inline bool BasicStringPiece<char16_t>::contains(
     const BasicStringPiece<char16_t>& rhs) const {
-  if (!mData || !rhs.mData) {
+  if (!data_ || !rhs.data_) {
     return false;
   }
-  if (rhs.mLength > mLength) {
+  if (rhs.length_ > length_) {
     return false;
   }
-  return strstr16(mData, rhs.mData) != nullptr;
+  return strstr16(data_, rhs.data_) != nullptr;
 }
 
 template <>
 inline int BasicStringPiece<char16_t>::compare(
     const BasicStringPiece<char16_t>& rhs) const {
   const char16_t nullStr = u'\0';
-  const char16_t* b1 = mData != nullptr ? mData : &nullStr;
-  const char16_t* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr;
-  return strzcmp16(b1, mLength, b2, rhs.mLength);
+  const char16_t* b1 = data_ != nullptr ? data_ : &nullStr;
+  const char16_t* b2 = rhs.data_ != nullptr ? rhs.data_ : &nullStr;
+  return strzcmp16(b1, length_, b2, rhs.length_);
 }
 
 template <typename TChar>
@@ -258,13 +259,13 @@
 template <typename TChar>
 inline typename BasicStringPiece<TChar>::const_iterator
 BasicStringPiece<TChar>::begin() const {
-  return mData;
+  return data_;
 }
 
 template <typename TChar>
 inline typename BasicStringPiece<TChar>::const_iterator
 BasicStringPiece<TChar>::end() const {
-  return mData + mLength;
+  return data_ + length_;
 }
 
 inline ::std::ostream& operator<<(::std::ostream& out,
diff --git a/tools/aapt2/util/StringPiece_test.cpp b/tools/aapt2/util/StringPiece_test.cpp
index a87065a..048961d 100644
--- a/tools/aapt2/util/StringPiece_test.cpp
+++ b/tools/aapt2/util/StringPiece_test.cpp
@@ -14,81 +14,82 @@
  * limitations under the License.
  */
 
+#include "util/StringPiece.h"
+
 #include <algorithm>
-#include <gtest/gtest.h>
 #include <string>
 #include <vector>
 
-#include "util/StringPiece.h"
+#include "test/Test.h"
 
 namespace aapt {
 
 TEST(StringPieceTest, CompareNonNullTerminatedPiece) {
-    StringPiece a("hello world", 5);
-    StringPiece b("hello moon", 5);
-    EXPECT_EQ(a, b);
+  StringPiece a("hello world", 5);
+  StringPiece b("hello moon", 5);
+  EXPECT_EQ(a, b);
 
-    StringPiece16 a16(u"hello world", 5);
-    StringPiece16 b16(u"hello moon", 5);
-    EXPECT_EQ(a16, b16);
+  StringPiece16 a16(u"hello world", 5);
+  StringPiece16 b16(u"hello moon", 5);
+  EXPECT_EQ(a16, b16);
 }
 
 TEST(StringPieceTest, PiecesHaveCorrectSortOrder) {
-    std::string testing("testing");
-    std::string banana("banana");
-    std::string car("car");
+  std::string testing("testing");
+  std::string banana("banana");
+  std::string car("car");
 
-    EXPECT_TRUE(StringPiece(testing) > banana);
-    EXPECT_TRUE(StringPiece(testing) > car);
-    EXPECT_TRUE(StringPiece(banana) < testing);
-    EXPECT_TRUE(StringPiece(banana) < car);
-    EXPECT_TRUE(StringPiece(car) < testing);
-    EXPECT_TRUE(StringPiece(car) > banana);
+  EXPECT_TRUE(StringPiece(testing) > banana);
+  EXPECT_TRUE(StringPiece(testing) > car);
+  EXPECT_TRUE(StringPiece(banana) < testing);
+  EXPECT_TRUE(StringPiece(banana) < car);
+  EXPECT_TRUE(StringPiece(car) < testing);
+  EXPECT_TRUE(StringPiece(car) > banana);
 }
 
 TEST(StringPieceTest, PiecesHaveCorrectSortOrderUtf8) {
-    std::string testing("testing");
-    std::string banana("banana");
-    std::string car("car");
+  std::string testing("testing");
+  std::string banana("banana");
+  std::string car("car");
 
-    EXPECT_TRUE(StringPiece(testing) > banana);
-    EXPECT_TRUE(StringPiece(testing) > car);
-    EXPECT_TRUE(StringPiece(banana) < testing);
-    EXPECT_TRUE(StringPiece(banana) < car);
-    EXPECT_TRUE(StringPiece(car) < testing);
-    EXPECT_TRUE(StringPiece(car) > banana);
+  EXPECT_TRUE(StringPiece(testing) > banana);
+  EXPECT_TRUE(StringPiece(testing) > car);
+  EXPECT_TRUE(StringPiece(banana) < testing);
+  EXPECT_TRUE(StringPiece(banana) < car);
+  EXPECT_TRUE(StringPiece(car) < testing);
+  EXPECT_TRUE(StringPiece(car) > banana);
 }
 
 TEST(StringPieceTest, ContainsOtherStringPiece) {
-    StringPiece text("I am a leaf on the wind.");
-    StringPiece startNeedle("I am");
-    StringPiece endNeedle("wind.");
-    StringPiece middleNeedle("leaf");
-    StringPiece emptyNeedle("");
-    StringPiece missingNeedle("soar");
-    StringPiece longNeedle("This string is longer than the text.");
+  StringPiece text("I am a leaf on the wind.");
+  StringPiece start_needle("I am");
+  StringPiece end_needle("wind.");
+  StringPiece middle_needle("leaf");
+  StringPiece empty_needle("");
+  StringPiece missing_needle("soar");
+  StringPiece long_needle("This string is longer than the text.");
 
-    EXPECT_TRUE(text.contains(startNeedle));
-    EXPECT_TRUE(text.contains(endNeedle));
-    EXPECT_TRUE(text.contains(middleNeedle));
-    EXPECT_TRUE(text.contains(emptyNeedle));
-    EXPECT_FALSE(text.contains(missingNeedle));
-    EXPECT_FALSE(text.contains(longNeedle));
+  EXPECT_TRUE(text.contains(start_needle));
+  EXPECT_TRUE(text.contains(end_needle));
+  EXPECT_TRUE(text.contains(middle_needle));
+  EXPECT_TRUE(text.contains(empty_needle));
+  EXPECT_FALSE(text.contains(missing_needle));
+  EXPECT_FALSE(text.contains(long_needle));
 
-    StringPiece16 text16(u"I am a leaf on the wind.");
-    StringPiece16 startNeedle16(u"I am");
-    StringPiece16 endNeedle16(u"wind.");
-    StringPiece16 middleNeedle16(u"leaf");
-    StringPiece16 emptyNeedle16(u"");
-    StringPiece16 missingNeedle16(u"soar");
-    StringPiece16 longNeedle16(u"This string is longer than the text.");
+  StringPiece16 text16(u"I am a leaf on the wind.");
+  StringPiece16 start_needle16(u"I am");
+  StringPiece16 end_needle16(u"wind.");
+  StringPiece16 middle_needle16(u"leaf");
+  StringPiece16 empty_needle16(u"");
+  StringPiece16 missing_needle16(u"soar");
+  StringPiece16 long_needle16(u"This string is longer than the text.");
 
-    EXPECT_TRUE(text16.contains(startNeedle16));
-    EXPECT_TRUE(text16.contains(endNeedle16));
-    EXPECT_TRUE(text16.contains(middleNeedle16));
-    EXPECT_TRUE(text16.contains(emptyNeedle16));
-    EXPECT_FALSE(text16.contains(missingNeedle16));
-    EXPECT_FALSE(text16.contains(longNeedle16));
+  EXPECT_TRUE(text16.contains(start_needle16));
+  EXPECT_TRUE(text16.contains(end_needle16));
+  EXPECT_TRUE(text16.contains(middle_needle16));
+  EXPECT_TRUE(text16.contains(empty_needle16));
+  EXPECT_FALSE(text16.contains(missing_needle16));
+  EXPECT_FALSE(text16.contains(long_needle16));
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/util/Util.cpp b/tools/aapt2/util/Util.cpp
index b0bec62..d5c0c8a 100644
--- a/tools/aapt2/util/Util.cpp
+++ b/tools/aapt2/util/Util.cpp
@@ -14,559 +14,558 @@
  * limitations under the License.
  */
 
+#include "util/Util.h"
 #include "util/BigBuffer.h"
 #include "util/Maybe.h"
 #include "util/StringPiece.h"
-#include "util/Util.h"
 
+#include <utils/Unicode.h>
 #include <algorithm>
 #include <ostream>
 #include <string>
-#include <utils/Unicode.h>
 #include <vector>
 
 namespace aapt {
 namespace util {
 
-static std::vector<std::string> splitAndTransform(const StringPiece& str, char sep,
-        const std::function<char(char)>& f) {
-    std::vector<std::string> parts;
-    const StringPiece::const_iterator end = std::end(str);
-    StringPiece::const_iterator start = std::begin(str);
-    StringPiece::const_iterator current;
-    do {
-        current = std::find(start, end, sep);
-        parts.emplace_back(str.substr(start, current).toString());
-        if (f) {
-            std::string& part = parts.back();
-            std::transform(part.begin(), part.end(), part.begin(), f);
-        }
-        start = current + 1;
-    } while (current != end);
-    return parts;
+static std::vector<std::string> SplitAndTransform(
+    const StringPiece& str, char sep, const std::function<char(char)>& f) {
+  std::vector<std::string> parts;
+  const StringPiece::const_iterator end = std::end(str);
+  StringPiece::const_iterator start = std::begin(str);
+  StringPiece::const_iterator current;
+  do {
+    current = std::find(start, end, sep);
+    parts.emplace_back(str.substr(start, current).ToString());
+    if (f) {
+      std::string& part = parts.back();
+      std::transform(part.begin(), part.end(), part.begin(), f);
+    }
+    start = current + 1;
+  } while (current != end);
+  return parts;
 }
 
-std::vector<std::string> split(const StringPiece& str, char sep) {
-    return splitAndTransform(str, sep, nullptr);
+std::vector<std::string> Split(const StringPiece& str, char sep) {
+  return SplitAndTransform(str, sep, nullptr);
 }
 
-std::vector<std::string> splitAndLowercase(const StringPiece& str, char sep) {
-    return splitAndTransform(str, sep, ::tolower);
+std::vector<std::string> SplitAndLowercase(const StringPiece& str, char sep) {
+  return SplitAndTransform(str, sep, ::tolower);
 }
 
-bool stringStartsWith(const StringPiece& str, const StringPiece& prefix) {
-    if (str.size() < prefix.size()) {
-        return false;
-    }
-    return str.substr(0, prefix.size()) == prefix;
+bool StartsWith(const StringPiece& str, const StringPiece& prefix) {
+  if (str.size() < prefix.size()) {
+    return false;
+  }
+  return str.substr(0, prefix.size()) == prefix;
 }
 
-bool stringEndsWith(const StringPiece& str, const StringPiece& suffix) {
-    if (str.size() < suffix.size()) {
-        return false;
-    }
-    return str.substr(str.size() - suffix.size(), suffix.size()) == suffix;
+bool EndsWith(const StringPiece& str, const StringPiece& suffix) {
+  if (str.size() < suffix.size()) {
+    return false;
+  }
+  return str.substr(str.size() - suffix.size(), suffix.size()) == suffix;
 }
 
-StringPiece trimWhitespace(const StringPiece& str) {
-    if (str.size() == 0 || str.data() == nullptr) {
-        return str;
-    }
+StringPiece TrimWhitespace(const StringPiece& str) {
+  if (str.size() == 0 || str.data() == nullptr) {
+    return str;
+  }
 
-    const char* start = str.data();
-    const char* end = str.data() + str.length();
+  const char* start = str.data();
+  const char* end = str.data() + str.length();
 
-    while (start != end && isspace(*start)) {
-        start++;
-    }
+  while (start != end && isspace(*start)) {
+    start++;
+  }
 
-    while (end != start && isspace(*(end - 1))) {
-        end--;
-    }
+  while (end != start && isspace(*(end - 1))) {
+    end--;
+  }
 
-    return StringPiece(start, end - start);
+  return StringPiece(start, end - start);
 }
 
-StringPiece::const_iterator findNonAlphaNumericAndNotInSet(const StringPiece& str,
-                                                           const StringPiece& allowedChars) {
-    const auto endIter = str.end();
-    for (auto iter = str.begin(); iter != endIter; ++iter) {
-        char c = *iter;
-        if ((c >= u'a' && c <= u'z') ||
-                (c >= u'A' && c <= u'Z') ||
-                (c >= u'0' && c <= u'9')) {
-            continue;
-        }
-
-        bool match = false;
-        for (char i : allowedChars) {
-            if (c == i) {
-                match = true;
-                break;
-            }
-        }
-
-        if (!match) {
-            return iter;
-        }
+StringPiece::const_iterator FindNonAlphaNumericAndNotInSet(
+    const StringPiece& str, const StringPiece& allowed_chars) {
+  const auto end_iter = str.end();
+  for (auto iter = str.begin(); iter != end_iter; ++iter) {
+    char c = *iter;
+    if ((c >= u'a' && c <= u'z') || (c >= u'A' && c <= u'Z') ||
+        (c >= u'0' && c <= u'9')) {
+      continue;
     }
-    return endIter;
+
+    bool match = false;
+    for (char i : allowed_chars) {
+      if (c == i) {
+        match = true;
+        break;
+      }
+    }
+
+    if (!match) {
+      return iter;
+    }
+  }
+  return end_iter;
 }
 
-bool isJavaClassName(const StringPiece& str) {
-    size_t pieces = 0;
-    for (const StringPiece& piece : tokenize(str, '.')) {
-        pieces++;
-        if (piece.empty()) {
-            return false;
-        }
-
-        // Can't have starting or trailing $ character.
-        if (piece.data()[0] == '$' || piece.data()[piece.size() - 1] == '$') {
-            return false;
-        }
-
-        if (findNonAlphaNumericAndNotInSet(piece, "$_") != piece.end()) {
-            return false;
-        }
+bool IsJavaClassName(const StringPiece& str) {
+  size_t pieces = 0;
+  for (const StringPiece& piece : Tokenize(str, '.')) {
+    pieces++;
+    if (piece.empty()) {
+      return false;
     }
-    return pieces >= 2;
+
+    // Can't have starting or trailing $ character.
+    if (piece.data()[0] == '$' || piece.data()[piece.size() - 1] == '$') {
+      return false;
+    }
+
+    if (FindNonAlphaNumericAndNotInSet(piece, "$_") != piece.end()) {
+      return false;
+    }
+  }
+  return pieces >= 2;
 }
 
-bool isJavaPackageName(const StringPiece& str) {
-    if (str.empty()) {
-        return false;
+bool IsJavaPackageName(const StringPiece& str) {
+  if (str.empty()) {
+    return false;
+  }
+
+  size_t pieces = 0;
+  for (const StringPiece& piece : Tokenize(str, '.')) {
+    pieces++;
+    if (piece.empty()) {
+      return false;
     }
 
-    size_t pieces = 0;
-    for (const StringPiece& piece : tokenize(str, '.')) {
-        pieces++;
-        if (piece.empty()) {
-            return false;
-        }
-
-        if (piece.data()[0] == '_' || piece.data()[piece.size() - 1] == '_') {
-            return false;
-        }
-
-        if (findNonAlphaNumericAndNotInSet(piece, "_") != piece.end()) {
-            return false;
-        }
+    if (piece.data()[0] == '_' || piece.data()[piece.size() - 1] == '_') {
+      return false;
     }
-    return pieces >= 1;
+
+    if (FindNonAlphaNumericAndNotInSet(piece, "_") != piece.end()) {
+      return false;
+    }
+  }
+  return pieces >= 1;
 }
 
-Maybe<std::string> getFullyQualifiedClassName(const StringPiece& package,
-                                              const StringPiece& className) {
-    if (className.empty()) {
-        return {};
-    }
+Maybe<std::string> GetFullyQualifiedClassName(const StringPiece& package,
+                                              const StringPiece& classname) {
+  if (classname.empty()) {
+    return {};
+  }
 
-    if (util::isJavaClassName(className)) {
-        return className.toString();
-    }
+  if (util::IsJavaClassName(classname)) {
+    return classname.ToString();
+  }
 
-    if (package.empty()) {
-        return {};
-    }
+  if (package.empty()) {
+    return {};
+  }
 
-    std::string result(package.data(), package.size());
-    if (className.data()[0] != '.') {
-        result += '.';
-    }
+  std::string result(package.data(), package.size());
+  if (classname.data()[0] != '.') {
+    result += '.';
+  }
 
-    result.append(className.data(), className.size());
-    if (!isJavaClassName(result)) {
-        return {};
-    }
-    return result;
+  result.append(classname.data(), classname.size());
+  if (!IsJavaClassName(result)) {
+    return {};
+  }
+  return result;
 }
 
-static size_t consumeDigits(const char* start, const char* end) {
-    const char* c = start;
-    for (; c != end && *c >= '0' && *c <= '9'; c++) {}
-    return static_cast<size_t>(c - start);
+static size_t ConsumeDigits(const char* start, const char* end) {
+  const char* c = start;
+  for (; c != end && *c >= '0' && *c <= '9'; c++) {
+  }
+  return static_cast<size_t>(c - start);
 }
 
-bool verifyJavaStringFormat(const StringPiece& str) {
-    const char* c = str.begin();
-    const char* const end = str.end();
+bool VerifyJavaStringFormat(const StringPiece& str) {
+  const char* c = str.begin();
+  const char* const end = str.end();
 
-    size_t argCount = 0;
-    bool nonpositional = false;
-    while (c != end) {
-        if (*c == '%' && c + 1 < end) {
-            c++;
+  size_t arg_count = 0;
+  bool nonpositional = false;
+  while (c != end) {
+    if (*c == '%' && c + 1 < end) {
+      c++;
 
-            if (*c == '%') {
-                c++;
-                continue;
-            }
+      if (*c == '%') {
+        c++;
+        continue;
+      }
 
-            argCount++;
+      arg_count++;
 
-            size_t numDigits = consumeDigits(c, end);
-            if (numDigits > 0) {
-                c += numDigits;
-                if (c != end && *c != '$') {
-                    // The digits were a size, but not a positional argument.
-                    nonpositional = true;
-                }
-            } else if (*c == '<') {
-                // Reusing last argument, bad idea since positions can be moved around
-                // during translation.
-                nonpositional = true;
-
-                c++;
-
-                // Optionally we can have a $ after
-                if (c != end && *c == '$') {
-                    c++;
-                }
-            } else {
-                nonpositional = true;
-            }
-
-            // Ignore size, width, flags, etc.
-            while (c != end && (*c == '-' ||
-                    *c == '#' ||
-                    *c == '+' ||
-                    *c == ' ' ||
-                    *c == ',' ||
-                    *c == '(' ||
-                    (*c >= '0' && *c <= '9'))) {
-                c++;
-            }
-
-            /*
-             * This is a shortcut to detect strings that are going to Time.format()
-             * instead of String.format()
-             *
-             * Comparison of String.format() and Time.format() args:
-             *
-             * String: ABC E GH  ST X abcdefgh  nost x
-             *   Time:    DEFGHKMS W Za  d   hkm  s w yz
-             *
-             * Therefore we know it's definitely Time if we have:
-             *     DFKMWZkmwyz
-             */
-            if (c != end) {
-                switch (*c) {
-                case 'D':
-                case 'F':
-                case 'K':
-                case 'M':
-                case 'W':
-                case 'Z':
-                case 'k':
-                case 'm':
-                case 'w':
-                case 'y':
-                case 'z':
-                    return true;
-                }
-            }
+      size_t num_digits = ConsumeDigits(c, end);
+      if (num_digits > 0) {
+        c += num_digits;
+        if (c != end && *c != '$') {
+          // The digits were a size, but not a positional argument.
+          nonpositional = true;
         }
+      } else if (*c == '<') {
+        // Reusing last argument, bad idea since positions can be moved around
+        // during translation.
+        nonpositional = true;
 
-        if (c != end) {
-            c++;
+        c++;
+
+        // Optionally we can have a $ after
+        if (c != end && *c == '$') {
+          c++;
         }
+      } else {
+        nonpositional = true;
+      }
+
+      // Ignore size, width, flags, etc.
+      while (c != end && (*c == '-' || *c == '#' || *c == '+' || *c == ' ' ||
+                          *c == ',' || *c == '(' || (*c >= '0' && *c <= '9'))) {
+        c++;
+      }
+
+      /*
+       * This is a shortcut to detect strings that are going to Time.format()
+       * instead of String.format()
+       *
+       * Comparison of String.format() and Time.format() args:
+       *
+       * String: ABC E GH  ST X abcdefgh  nost x
+       *   Time:    DEFGHKMS W Za  d   hkm  s w yz
+       *
+       * Therefore we know it's definitely Time if we have:
+       *     DFKMWZkmwyz
+       */
+      if (c != end) {
+        switch (*c) {
+          case 'D':
+          case 'F':
+          case 'K':
+          case 'M':
+          case 'W':
+          case 'Z':
+          case 'k':
+          case 'm':
+          case 'w':
+          case 'y':
+          case 'z':
+            return true;
+        }
+      }
     }
 
-    if (argCount > 1 && nonpositional) {
-        // Multiple arguments were specified, but some or all were non positional. Translated
-        // strings may rearrange the order of the arguments, which will break the string.
-        return false;
+    if (c != end) {
+      c++;
     }
-    return true;
+  }
+
+  if (arg_count > 1 && nonpositional) {
+    // Multiple arguments were specified, but some or all were non positional.
+    // Translated
+    // strings may rearrange the order of the arguments, which will break the
+    // string.
+    return false;
+  }
+  return true;
 }
 
-static Maybe<std::string> parseUnicodeCodepoint(const char** start, const char* end) {
-    char32_t code = 0;
-    for (size_t i = 0; i < 4 && *start != end; i++, (*start)++) {
-        char c = **start;
-        char32_t a;
-        if (c >= '0' && c <= '9') {
-            a = c - '0';
-        } else if (c >= 'a' && c <= 'f') {
-            a = c - 'a' + 10;
-        } else if (c >= 'A' && c <= 'F') {
-            a = c - 'A' + 10;
-        } else {
-            return {};
-        }
-        code = (code << 4) | a;
+static Maybe<std::string> ParseUnicodeCodepoint(const char** start,
+                                                const char* end) {
+  char32_t code = 0;
+  for (size_t i = 0; i < 4 && *start != end; i++, (*start)++) {
+    char c = **start;
+    char32_t a;
+    if (c >= '0' && c <= '9') {
+      a = c - '0';
+    } else if (c >= 'a' && c <= 'f') {
+      a = c - 'a' + 10;
+    } else if (c >= 'A' && c <= 'F') {
+      a = c - 'A' + 10;
+    } else {
+      return {};
     }
+    code = (code << 4) | a;
+  }
 
-    ssize_t len = utf32_to_utf8_length(&code, 1);
-    if (len < 0) {
-        return {};
-    }
+  ssize_t len = utf32_to_utf8_length(&code, 1);
+  if (len < 0) {
+    return {};
+  }
 
-    std::string resultUtf8;
-    resultUtf8.resize(len);
-    utf32_to_utf8(&code, 1, &*resultUtf8.begin(), len + 1);
-    return resultUtf8;
+  std::string result_utf8;
+  result_utf8.resize(len);
+  utf32_to_utf8(&code, 1, &*result_utf8.begin(), len + 1);
+  return result_utf8;
 }
 
-StringBuilder& StringBuilder::append(const StringPiece& str) {
-    if (!mError.empty()) {
-        return *this;
-    }
-
-    // Where the new data will be appended to.
-    size_t newDataIndex = mStr.size();
-
-    const char* const end = str.end();
-    const char* start = str.begin();
-    const char* current = start;
-    while (current != end) {
-        if (mLastCharWasEscape) {
-            switch (*current) {
-                case 't':
-                    mStr += '\t';
-                    break;
-                case 'n':
-                    mStr += '\n';
-                    break;
-                case '#':
-                    mStr += '#';
-                    break;
-                case '@':
-                    mStr += '@';
-                    break;
-                case '?':
-                    mStr += '?';
-                    break;
-                case '"':
-                    mStr += '"';
-                    break;
-                case '\'':
-                    mStr += '\'';
-                    break;
-                case '\\':
-                    mStr += '\\';
-                    break;
-                case 'u': {
-                    current++;
-                    Maybe<std::string> c = parseUnicodeCodepoint(&current, end);
-                    if (!c) {
-                        mError = "invalid unicode escape sequence";
-                        return *this;
-                    }
-                    mStr += c.value();
-                    current -= 1;
-                    break;
-                }
-
-                default:
-                    // Ignore.
-                    break;
-            }
-            mLastCharWasEscape = false;
-            start = current + 1;
-        } else if (*current == '"') {
-            if (!mQuote && mTrailingSpace) {
-                // We found an opening quote, and we have
-                // trailing space, so we should append that
-                // space now.
-                if (mTrailingSpace) {
-                    // We had trailing whitespace, so
-                    // replace with a single space.
-                    if (!mStr.empty()) {
-                        mStr += ' ';
-                    }
-                    mTrailingSpace = false;
-                }
-            }
-            mQuote = !mQuote;
-            mStr.append(start, current - start);
-            start = current + 1;
-        } else if (*current == '\'' && !mQuote) {
-            // This should be escaped.
-            mError = "unescaped apostrophe";
-            return *this;
-        } else if (*current == '\\') {
-            // This is an escape sequence, convert to the real value.
-            if (!mQuote && mTrailingSpace) {
-                // We had trailing whitespace, so
-                // replace with a single space.
-                if (!mStr.empty()) {
-                    mStr += ' ';
-                }
-                mTrailingSpace = false;
-            }
-            mStr.append(start, current - start);
-            start = current + 1;
-            mLastCharWasEscape = true;
-        } else if (!mQuote) {
-            // This is not quoted text, so look for whitespace.
-            if (isspace(*current)) {
-                // We found whitespace, see if we have seen some
-                // before.
-                if (!mTrailingSpace) {
-                    // We didn't see a previous adjacent space,
-                    // so mark that we did.
-                    mTrailingSpace = true;
-                    mStr.append(start, current - start);
-                }
-
-                // Keep skipping whitespace.
-                start = current + 1;
-            } else if (mTrailingSpace) {
-                // We saw trailing space before, so replace all
-                // that trailing space with one space.
-                if (!mStr.empty()) {
-                    mStr += ' ';
-                }
-                mTrailingSpace = false;
-            }
-        }
-        current++;
-    }
-    mStr.append(start, end - start);
-
-    // Accumulate the added string's UTF-16 length.
-    ssize_t len = utf8_to_utf16_length(
-            reinterpret_cast<const uint8_t*>(mStr.data()) + newDataIndex,
-            mStr.size() - newDataIndex);
-    if (len < 0) {
-        mError = "invalid unicode code point";
-        return *this;
-    }
-    mUtf16Len += len;
+StringBuilder& StringBuilder::Append(const StringPiece& str) {
+  if (!error_.empty()) {
     return *this;
-}
+  }
 
-std::u16string utf8ToUtf16(const StringPiece& utf8) {
-    ssize_t utf16Length = utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(utf8.data()),
-            utf8.length());
-    if (utf16Length <= 0) {
-        return {};
-    }
+  // Where the new data will be appended to.
+  size_t new_data_index = str_.size();
 
-    std::u16string utf16;
-    utf16.resize(utf16Length);
-    utf8_to_utf16(reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length(),
-                  &*utf16.begin(), utf16Length + 1);
-    return utf16;
-}
-
-std::string utf16ToUtf8(const StringPiece16& utf16) {
-    ssize_t utf8Length = utf16_to_utf8_length(utf16.data(), utf16.length());
-    if (utf8Length <= 0) {
-        return {};
-    }
-
-    std::string utf8;
-    utf8.resize(utf8Length);
-    utf16_to_utf8(utf16.data(), utf16.length(), &*utf8.begin(), utf8Length + 1);
-    return utf8;
-}
-
-bool writeAll(std::ostream& out, const BigBuffer& buffer) {
-    for (const auto& b : buffer) {
-        if (!out.write(reinterpret_cast<const char*>(b.buffer.get()), b.size)) {
-            return false;
+  const char* const end = str.end();
+  const char* start = str.begin();
+  const char* current = start;
+  while (current != end) {
+    if (last_char_was_escape_) {
+      switch (*current) {
+        case 't':
+          str_ += '\t';
+          break;
+        case 'n':
+          str_ += '\n';
+          break;
+        case '#':
+          str_ += '#';
+          break;
+        case '@':
+          str_ += '@';
+          break;
+        case '?':
+          str_ += '?';
+          break;
+        case '"':
+          str_ += '"';
+          break;
+        case '\'':
+          str_ += '\'';
+          break;
+        case '\\':
+          str_ += '\\';
+          break;
+        case 'u': {
+          current++;
+          Maybe<std::string> c = ParseUnicodeCodepoint(&current, end);
+          if (!c) {
+            error_ = "invalid unicode escape sequence";
+            return *this;
+          }
+          str_ += c.value();
+          current -= 1;
+          break;
         }
+
+        default:
+          // Ignore.
+          break;
+      }
+      last_char_was_escape_ = false;
+      start = current + 1;
+    } else if (*current == '"') {
+      if (!quote_ && trailing_space_) {
+        // We found an opening quote, and we have
+        // trailing space, so we should append that
+        // space now.
+        if (trailing_space_) {
+          // We had trailing whitespace, so
+          // replace with a single space.
+          if (!str_.empty()) {
+            str_ += ' ';
+          }
+          trailing_space_ = false;
+        }
+      }
+      quote_ = !quote_;
+      str_.append(start, current - start);
+      start = current + 1;
+    } else if (*current == '\'' && !quote_) {
+      // This should be escaped.
+      error_ = "unescaped apostrophe";
+      return *this;
+    } else if (*current == '\\') {
+      // This is an escape sequence, convert to the real value.
+      if (!quote_ && trailing_space_) {
+        // We had trailing whitespace, so
+        // replace with a single space.
+        if (!str_.empty()) {
+          str_ += ' ';
+        }
+        trailing_space_ = false;
+      }
+      str_.append(start, current - start);
+      start = current + 1;
+      last_char_was_escape_ = true;
+    } else if (!quote_) {
+      // This is not quoted text, so look for whitespace.
+      if (isspace(*current)) {
+        // We found whitespace, see if we have seen some
+        // before.
+        if (!trailing_space_) {
+          // We didn't see a previous adjacent space,
+          // so mark that we did.
+          trailing_space_ = true;
+          str_.append(start, current - start);
+        }
+
+        // Keep skipping whitespace.
+        start = current + 1;
+      } else if (trailing_space_) {
+        // We saw trailing space before, so replace all
+        // that trailing space with one space.
+        if (!str_.empty()) {
+          str_ += ' ';
+        }
+        trailing_space_ = false;
+      }
     }
-    return true;
+    current++;
+  }
+  str_.append(start, end - start);
+
+  // Accumulate the added string's UTF-16 length.
+  ssize_t len = utf8_to_utf16_length(
+      reinterpret_cast<const uint8_t*>(str_.data()) + new_data_index,
+      str_.size() - new_data_index);
+  if (len < 0) {
+    error_ = "invalid unicode code point";
+    return *this;
+  }
+  utf16_len_ += len;
+  return *this;
 }
 
-std::unique_ptr<uint8_t[]> copy(const BigBuffer& buffer) {
-    std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(new uint8_t[buffer.size()]);
-    uint8_t* p = data.get();
-    for (const auto& block : buffer) {
-        memcpy(p, block.buffer.get(), block.size);
-        p += block.size;
+std::u16string Utf8ToUtf16(const StringPiece& utf8) {
+  ssize_t utf16_length = utf8_to_utf16_length(
+      reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length());
+  if (utf16_length <= 0) {
+    return {};
+  }
+
+  std::u16string utf16;
+  utf16.resize(utf16_length);
+  utf8_to_utf16(reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length(),
+                &*utf16.begin(), utf16_length + 1);
+  return utf16;
+}
+
+std::string Utf16ToUtf8(const StringPiece16& utf16) {
+  ssize_t utf8_length = utf16_to_utf8_length(utf16.data(), utf16.length());
+  if (utf8_length <= 0) {
+    return {};
+  }
+
+  std::string utf8;
+  utf8.resize(utf8_length);
+  utf16_to_utf8(utf16.data(), utf16.length(), &*utf8.begin(), utf8_length + 1);
+  return utf8;
+}
+
+bool WriteAll(std::ostream& out, const BigBuffer& buffer) {
+  for (const auto& b : buffer) {
+    if (!out.write(reinterpret_cast<const char*>(b.buffer.get()), b.size)) {
+      return false;
     }
-    return data;
+  }
+  return true;
+}
+
+std::unique_ptr<uint8_t[]> Copy(const BigBuffer& buffer) {
+  std::unique_ptr<uint8_t[]> data =
+      std::unique_ptr<uint8_t[]>(new uint8_t[buffer.size()]);
+  uint8_t* p = data.get();
+  for (const auto& block : buffer) {
+    memcpy(p, block.buffer.get(), block.size);
+    p += block.size;
+  }
+  return data;
 }
 
 typename Tokenizer::iterator& Tokenizer::iterator::operator++() {
-    const char* start = mToken.end();
-    const char* end = mStr.end();
-    if (start == end) {
-        mEnd = true;
-        mToken.assign(mToken.end(), 0);
-        return *this;
-    }
-
-    start += 1;
-    const char* current = start;
-    while (current != end) {
-        if (*current == mSeparator) {
-            mToken.assign(start, current - start);
-            return *this;
-        }
-        ++current;
-    }
-    mToken.assign(start, end - start);
+  const char* start = token_.end();
+  const char* end = str_.end();
+  if (start == end) {
+    end_ = true;
+    token_.assign(token_.end(), 0);
     return *this;
+  }
+
+  start += 1;
+  const char* current = start;
+  while (current != end) {
+    if (*current == separator_) {
+      token_.assign(start, current - start);
+      return *this;
+    }
+    ++current;
+  }
+  token_.assign(start, end - start);
+  return *this;
 }
 
 bool Tokenizer::iterator::operator==(const iterator& rhs) const {
-    // We check equality here a bit differently.
-    // We need to know that the addresses are the same.
-    return mToken.begin() == rhs.mToken.begin() && mToken.end() == rhs.mToken.end() &&
-            mEnd == rhs.mEnd;
+  // We check equality here a bit differently.
+  // We need to know that the addresses are the same.
+  return token_.begin() == rhs.token_.begin() &&
+         token_.end() == rhs.token_.end() && end_ == rhs.end_;
 }
 
 bool Tokenizer::iterator::operator!=(const iterator& rhs) const {
-    return !(*this == rhs);
+  return !(*this == rhs);
 }
 
-Tokenizer::iterator::iterator(StringPiece s, char sep, StringPiece tok, bool end) :
-        mStr(s), mSeparator(sep), mToken(tok), mEnd(end) {
-}
+Tokenizer::iterator::iterator(StringPiece s, char sep, StringPiece tok,
+                              bool end)
+    : str_(s), separator_(sep), token_(tok), end_(end) {}
 
-Tokenizer::Tokenizer(StringPiece str, char sep) :
-        mBegin(++iterator(str, sep, StringPiece(str.begin() - 1, 0), false)),
-        mEnd(str, sep, StringPiece(str.end(), 0), true) {
-}
+Tokenizer::Tokenizer(StringPiece str, char sep)
+    : begin_(++iterator(str, sep, StringPiece(str.begin() - 1, 0), false)),
+      end_(str, sep, StringPiece(str.end(), 0), true) {}
 
-bool extractResFilePathParts(const StringPiece& path, StringPiece* outPrefix,
-                             StringPiece* outEntry, StringPiece* outSuffix) {
-    const StringPiece resPrefix("res/");
-    if (!stringStartsWith(path, resPrefix)) {
-        return false;
+bool ExtractResFilePathParts(const StringPiece& path, StringPiece* out_prefix,
+                             StringPiece* out_entry, StringPiece* out_suffix) {
+  const StringPiece res_prefix("res/");
+  if (!StartsWith(path, res_prefix)) {
+    return false;
+  }
+
+  StringPiece::const_iterator last_occurence = path.end();
+  for (auto iter = path.begin() + res_prefix.size(); iter != path.end();
+       ++iter) {
+    if (*iter == '/') {
+      last_occurence = iter;
     }
+  }
 
-    StringPiece::const_iterator lastOccurence = path.end();
-    for (auto iter = path.begin() + resPrefix.size(); iter != path.end(); ++iter) {
-        if (*iter == '/') {
-            lastOccurence = iter;
-        }
-    }
+  if (last_occurence == path.end()) {
+    return false;
+  }
 
-    if (lastOccurence == path.end()) {
-        return false;
-    }
-
-    auto iter = std::find(lastOccurence, path.end(), '.');
-    *outSuffix = StringPiece(iter, path.end() - iter);
-    *outEntry = StringPiece(lastOccurence + 1, iter - lastOccurence - 1);
-    *outPrefix = StringPiece(path.begin(), lastOccurence - path.begin() + 1);
-    return true;
+  auto iter = std::find(last_occurence, path.end(), '.');
+  *out_suffix = StringPiece(iter, path.end() - iter);
+  *out_entry = StringPiece(last_occurence + 1, iter - last_occurence - 1);
+  *out_prefix = StringPiece(path.begin(), last_occurence - path.begin() + 1);
+  return true;
 }
 
-StringPiece16 getString16(const android::ResStringPool& pool, size_t idx) {
-    size_t len;
-    const char16_t* str = pool.stringAt(idx, &len);
-    if (str != nullptr) {
-        return StringPiece16(str, len);
-    }
-    return StringPiece16();
+StringPiece16 GetString16(const android::ResStringPool& pool, size_t idx) {
+  size_t len;
+  const char16_t* str = pool.stringAt(idx, &len);
+  if (str != nullptr) {
+    return StringPiece16(str, len);
+  }
+  return StringPiece16();
 }
 
-std::string getString(const android::ResStringPool& pool, size_t idx) {
-    size_t len;
-    const char* str = pool.string8At(idx, &len);
-    if (str != nullptr) {
-        return std::string(str, len);
-    }
-    return utf16ToUtf8(getString16(pool, idx));
+std::string GetString(const android::ResStringPool& pool, size_t idx) {
+  size_t len;
+  const char* str = pool.string8At(idx, &len);
+  if (str != nullptr) {
+    return std::string(str, len);
+  }
+  return Utf16ToUtf8(GetString16(pool, idx));
 }
 
-} // namespace util
-} // namespace aapt
+}  // namespace util
+}  // namespace aapt
diff --git a/tools/aapt2/util/Util.h b/tools/aapt2/util/Util.h
index 077e193..05e9cc5 100644
--- a/tools/aapt2/util/Util.h
+++ b/tools/aapt2/util/Util.h
@@ -17,40 +17,53 @@
 #ifndef AAPT_UTIL_H
 #define AAPT_UTIL_H
 
-#include "util/BigBuffer.h"
-#include "util/Maybe.h"
-#include "util/StringPiece.h"
-
-#include <androidfw/ResourceTypes.h>
 #include <functional>
 #include <memory>
 #include <ostream>
 #include <string>
 #include <vector>
 
+#include "androidfw/ResourceTypes.h"
+#include "utils/ByteOrder.h"
+
+#include "util/BigBuffer.h"
+#include "util/Maybe.h"
+#include "util/StringPiece.h"
+
+#ifdef _WIN32
+// TODO(adamlesinski): remove once http://b/32447322 is resolved.
+// utils/ByteOrder.h includes winsock2.h on WIN32,
+// which will pull in the ERROR definition. This conflicts
+// with android-base/logging.h, which takes care of undefining
+// ERROR, but it gets included too early (before winsock2.h).
+#ifdef ERROR
+#undef ERROR
+#endif
+#endif
+
 namespace aapt {
 namespace util {
 
-std::vector<std::string> split(const StringPiece& str, char sep);
-std::vector<std::string> splitAndLowercase(const StringPiece& str, char sep);
+std::vector<std::string> Split(const StringPiece& str, char sep);
+std::vector<std::string> SplitAndLowercase(const StringPiece& str, char sep);
 
 /**
  * Returns true if the string starts with prefix.
  */
-bool stringStartsWith(const StringPiece& str, const StringPiece& prefix);
+bool StartsWith(const StringPiece& str, const StringPiece& prefix);
 
 /**
  * Returns true if the string ends with suffix.
  */
-bool stringEndsWith(const StringPiece& str, const StringPiece& suffix);
+bool EndsWith(const StringPiece& str, const StringPiece& suffix);
 
 /**
  * Creates a new StringPiece16 that points to a substring
  * of the original string without leading or trailing whitespace.
  */
-StringPiece trimWhitespace(const StringPiece& str);
+StringPiece TrimWhitespace(const StringPiece& str);
 
-StringPiece trimWhitespace(const StringPiece& str);
+StringPiece TrimWhitespace(const StringPiece& str);
 
 /**
  * UTF-16 isspace(). It basically checks for lower range characters that are
@@ -62,18 +75,18 @@
  * Returns an iterator to the first character that is not alpha-numeric and that
  * is not in the allowedChars set.
  */
-StringPiece::const_iterator findNonAlphaNumericAndNotInSet(
-    const StringPiece& str, const StringPiece& allowedChars);
+StringPiece::const_iterator FindNonAlphaNumericAndNotInSet(
+    const StringPiece& str, const StringPiece& allowed_chars);
 
 /**
  * Tests that the string is a valid Java class name.
  */
-bool isJavaClassName(const StringPiece& str);
+bool IsJavaClassName(const StringPiece& str);
 
 /**
  * Tests that the string is a valid Java package name.
  */
-bool isJavaPackageName(const StringPiece& str);
+bool IsJavaPackageName(const StringPiece& str);
 
 /**
  * Converts the class name to a fully qualified class name from the given
@@ -84,8 +97,8 @@
  * .a.b         --> package.a.b
  * asdf.adsf    --> asdf.adsf
  */
-Maybe<std::string> getFullyQualifiedClassName(const StringPiece& package,
-                                              const StringPiece& className);
+Maybe<std::string> GetFullyQualifiedClassName(const StringPiece& package,
+                                              const StringPiece& class_name);
 
 /**
  * Makes a std::unique_ptr<> with the template parameter inferred by the
@@ -103,15 +116,15 @@
  * separator.
  */
 template <typename Container>
-::std::function<::std::ostream&(::std::ostream&)> joiner(
+::std::function<::std::ostream&(::std::ostream&)> Joiner(
     const Container& container, const char* sep) {
   using std::begin;
   using std::end;
-  const auto beginIter = begin(container);
-  const auto endIter = end(container);
-  return [beginIter, endIter, sep](::std::ostream& out) -> ::std::ostream& {
-    for (auto iter = beginIter; iter != endIter; ++iter) {
-      if (iter != beginIter) {
+  const auto begin_iter = begin(container);
+  const auto end_iter = end(container);
+  return [begin_iter, end_iter, sep](::std::ostream& out) -> ::std::ostream& {
+    for (auto iter = begin_iter; iter != end_iter; ++iter) {
+      if (iter != begin_iter) {
         out << sep;
       }
       out << *iter;
@@ -120,31 +133,12 @@
   };
 }
 
-inline ::std::function<::std::ostream&(::std::ostream&)> formatSize(
-    size_t size) {
-  return [size](::std::ostream& out) -> ::std::ostream& {
-    constexpr size_t K = 1024u;
-    constexpr size_t M = K * K;
-    constexpr size_t G = M * K;
-    if (size < K) {
-      out << size << "B";
-    } else if (size < M) {
-      out << (double(size) / K) << " KiB";
-    } else if (size < G) {
-      out << (double(size) / M) << " MiB";
-    } else {
-      out << (double(size) / G) << " GiB";
-    }
-    return out;
-  };
-}
-
 /**
  * Helper method to extract a UTF-16 string from a StringPool. If the string is
  * stored as UTF-8,
  * the conversion to UTF-16 happens within ResStringPool.
  */
-StringPiece16 getString16(const android::ResStringPool& pool, size_t idx);
+StringPiece16 GetString16(const android::ResStringPool& pool, size_t idx);
 
 /**
  * Helper method to extract a UTF-8 string from a StringPool. If the string is
@@ -154,7 +148,7 @@
  * which maintains no state or cache. This means we must return an std::string
  * copy.
  */
-std::string getString(const android::ResStringPool& pool, size_t idx);
+std::string GetString(const android::ResStringPool& pool, size_t idx);
 
 /**
  * Checks that the Java string format contains no non-positional arguments
@@ -165,53 +159,53 @@
  * which will
  * break the string interpolation.
  */
-bool verifyJavaStringFormat(const StringPiece& str);
+bool VerifyJavaStringFormat(const StringPiece& str);
 
 class StringBuilder {
  public:
-  StringBuilder& append(const StringPiece& str);
-  const std::string& str() const;
-  const std::string& error() const;
+  StringBuilder& Append(const StringPiece& str);
+  const std::string& ToString() const;
+  const std::string& Error() const;
 
   // When building StyledStrings, we need UTF-16 indices into the string,
   // which is what the Java layer expects when dealing with java
   // String.charAt().
-  size_t utf16Len() const;
+  size_t Utf16Len() const;
 
-  operator bool() const;
+  explicit operator bool() const;
 
  private:
-  std::string mStr;
-  size_t mUtf16Len = 0;
-  bool mQuote = false;
-  bool mTrailingSpace = false;
-  bool mLastCharWasEscape = false;
-  std::string mError;
+  std::string str_;
+  size_t utf16_len_ = 0;
+  bool quote_ = false;
+  bool trailing_space_ = false;
+  bool last_char_was_escape_ = false;
+  std::string error_;
 };
 
-inline const std::string& StringBuilder::str() const { return mStr; }
+inline const std::string& StringBuilder::ToString() const { return str_; }
 
-inline const std::string& StringBuilder::error() const { return mError; }
+inline const std::string& StringBuilder::Error() const { return error_; }
 
-inline size_t StringBuilder::utf16Len() const { return mUtf16Len; }
+inline size_t StringBuilder::Utf16Len() const { return utf16_len_; }
 
-inline StringBuilder::operator bool() const { return mError.empty(); }
+inline StringBuilder::operator bool() const { return error_.empty(); }
 
 /**
  * Converts a UTF8 string to a UTF16 string.
  */
-std::u16string utf8ToUtf16(const StringPiece& utf8);
-std::string utf16ToUtf8(const StringPiece16& utf16);
+std::u16string Utf8ToUtf16(const StringPiece& utf8);
+std::string Utf16ToUtf8(const StringPiece16& utf16);
 
 /**
  * Writes the entire BigBuffer to the output stream.
  */
-bool writeAll(std::ostream& out, const BigBuffer& buffer);
+bool WriteAll(std::ostream& out, const BigBuffer& buffer);
 
 /*
  * Copies the entire BigBuffer into a single buffer.
  */
-std::unique_ptr<uint8_t[]> copy(const BigBuffer& buffer);
+std::unique_ptr<uint8_t[]> Copy(const BigBuffer& buffer);
 
 /**
  * A Tokenizer implemented as an iterable collection. It does not allocate
@@ -226,7 +220,7 @@
 
     iterator& operator++();
 
-    StringPiece operator*() { return mToken; }
+    StringPiece operator*() { return token_; }
     bool operator==(const iterator& rhs) const;
     bool operator!=(const iterator& rhs) const;
 
@@ -235,34 +229,34 @@
 
     iterator(StringPiece s, char sep, StringPiece tok, bool end);
 
-    StringPiece mStr;
-    char mSeparator;
-    StringPiece mToken;
-    bool mEnd;
+    StringPiece str_;
+    char separator_;
+    StringPiece token_;
+    bool end_;
   };
 
   Tokenizer(StringPiece str, char sep);
 
-  iterator begin() { return mBegin; }
+  iterator begin() { return begin_; }
 
-  iterator end() { return mEnd; }
+  iterator end() { return end_; }
 
  private:
-  const iterator mBegin;
-  const iterator mEnd;
+  const iterator begin_;
+  const iterator end_;
 };
 
-inline Tokenizer tokenize(const StringPiece& str, char sep) {
+inline Tokenizer Tokenize(const StringPiece& str, char sep) {
   return Tokenizer(str, sep);
 }
 
-inline uint16_t hostToDevice16(uint16_t value) { return htods(value); }
+inline uint16_t HostToDevice16(uint16_t value) { return htods(value); }
 
-inline uint32_t hostToDevice32(uint32_t value) { return htodl(value); }
+inline uint32_t HostToDevice32(uint32_t value) { return htodl(value); }
 
-inline uint16_t deviceToHost16(uint16_t value) { return dtohs(value); }
+inline uint16_t DeviceToHost16(uint16_t value) { return dtohs(value); }
 
-inline uint32_t deviceToHost32(uint32_t value) { return dtohl(value); }
+inline uint32_t DeviceToHost32(uint32_t value) { return dtohl(value); }
 
 /**
  * Given a path like: res/xml-sw600dp/foo.xml
@@ -273,8 +267,8 @@
  *
  * Returns true if successful.
  */
-bool extractResFilePathParts(const StringPiece& path, StringPiece* outPrefix,
-                             StringPiece* outEntry, StringPiece* outSuffix);
+bool ExtractResFilePathParts(const StringPiece& path, StringPiece* out_prefix,
+                             StringPiece* out_entry, StringPiece* out_suffix);
 
 }  // namespace util
 
diff --git a/tools/aapt2/util/Util_test.cpp b/tools/aapt2/util/Util_test.cpp
index 0e27213..cac3de4 100644
--- a/tools/aapt2/util/Util_test.cpp
+++ b/tools/aapt2/util/Util_test.cpp
@@ -14,191 +14,196 @@
  * limitations under the License.
  */
 
-#include "test/Test.h"
-#include "util/StringPiece.h"
 #include "util/Util.h"
 
 #include <string>
 
+#include "test/Test.h"
+
 namespace aapt {
 
 TEST(UtilTest, TrimOnlyWhitespace) {
-    const std::string full = "\n        ";
+  const std::string full = "\n        ";
 
-    StringPiece trimmed = util::trimWhitespace(full);
-    EXPECT_TRUE(trimmed.empty());
-    EXPECT_EQ(0u, trimmed.size());
+  StringPiece trimmed = util::TrimWhitespace(full);
+  EXPECT_TRUE(trimmed.empty());
+  EXPECT_EQ(0u, trimmed.size());
 }
 
 TEST(UtilTest, StringEndsWith) {
-    EXPECT_TRUE(util::stringEndsWith("hello.xml", ".xml"));
+  EXPECT_TRUE(util::EndsWith("hello.xml", ".xml"));
 }
 
 TEST(UtilTest, StringStartsWith) {
-    EXPECT_TRUE(util::stringStartsWith("hello.xml", "he"));
+  EXPECT_TRUE(util::StartsWith("hello.xml", "he"));
 }
 
 TEST(UtilTest, StringBuilderSplitEscapeSequence) {
-    EXPECT_EQ(StringPiece("this is a new\nline."),
-              util::StringBuilder().append("this is a new\\")
-                                   .append("nline.")
-                                   .str());
+  EXPECT_EQ(StringPiece("this is a new\nline."), util::StringBuilder()
+                                                     .Append("this is a new\\")
+                                                     .Append("nline.")
+                                                     .ToString());
 }
 
 TEST(UtilTest, StringBuilderWhitespaceRemoval) {
-    EXPECT_EQ(StringPiece("hey guys this is so cool"),
-              util::StringBuilder().append("    hey guys ")
-                                   .append(" this is so cool ")
-                                   .str());
+  EXPECT_EQ(StringPiece("hey guys this is so cool"),
+            util::StringBuilder()
+                .Append("    hey guys ")
+                .Append(" this is so cool ")
+                .ToString());
 
-    EXPECT_EQ(StringPiece(" wow,  so many \t spaces. what?"),
-              util::StringBuilder().append(" \" wow,  so many \t ")
-                                   .append("spaces. \"what? ")
-                                   .str());
+  EXPECT_EQ(StringPiece(" wow,  so many \t spaces. what?"),
+            util::StringBuilder()
+                .Append(" \" wow,  so many \t ")
+                .Append("spaces. \"what? ")
+                .ToString());
 
-    EXPECT_EQ(StringPiece("where is the pie?"),
-              util::StringBuilder().append("  where \t ")
-                                   .append(" \nis the "" pie?")
-                                   .str());
+  EXPECT_EQ(StringPiece("where is the pie?"), util::StringBuilder()
+                                                  .Append("  where \t ")
+                                                  .Append(" \nis the "
+                                                          " pie?")
+                                                  .ToString());
 }
 
 TEST(UtilTest, StringBuilderEscaping) {
-    EXPECT_EQ(StringPiece("hey guys\n this \t is so\\ cool"),
-              util::StringBuilder().append("    hey guys\\n ")
-                                   .append(" this \\t is so\\\\ cool ")
-                                   .str());
+  EXPECT_EQ(StringPiece("hey guys\n this \t is so\\ cool"),
+            util::StringBuilder()
+                .Append("    hey guys\\n ")
+                .Append(" this \\t is so\\\\ cool ")
+                .ToString());
 
-    EXPECT_EQ(StringPiece("@?#\\\'"),
-              util::StringBuilder().append("\\@\\?\\#\\\\\\'")
-                                   .str());
+  EXPECT_EQ(StringPiece("@?#\\\'"),
+            util::StringBuilder().Append("\\@\\?\\#\\\\\\'").ToString());
 }
 
 TEST(UtilTest, StringBuilderMisplacedQuote) {
-    util::StringBuilder builder{};
-    EXPECT_FALSE(builder.append("they're coming!"));
+  util::StringBuilder builder{};
+  EXPECT_FALSE(builder.Append("they're coming!"));
 }
 
 TEST(UtilTest, StringBuilderUnicodeCodes) {
-    EXPECT_EQ(std::string("\u00AF\u0AF0 woah"),
-              util::StringBuilder().append("\\u00AF\\u0AF0 woah")
-                                   .str());
+  EXPECT_EQ(std::string("\u00AF\u0AF0 woah"),
+            util::StringBuilder().Append("\\u00AF\\u0AF0 woah").ToString());
 
-    EXPECT_FALSE(util::StringBuilder().append("\\u00 yo"));
+  EXPECT_FALSE(util::StringBuilder().Append("\\u00 yo"));
 }
 
 TEST(UtilTest, TokenizeInput) {
-    auto tokenizer = util::tokenize(StringPiece("this| is|the|end"), '|');
-    auto iter = tokenizer.begin();
-    ASSERT_EQ(*iter, StringPiece("this"));
-    ++iter;
-    ASSERT_EQ(*iter, StringPiece(" is"));
-    ++iter;
-    ASSERT_EQ(*iter, StringPiece("the"));
-    ++iter;
-    ASSERT_EQ(*iter, StringPiece("end"));
-    ++iter;
-    ASSERT_EQ(tokenizer.end(), iter);
+  auto tokenizer = util::Tokenize(StringPiece("this| is|the|end"), '|');
+  auto iter = tokenizer.begin();
+  ASSERT_EQ(*iter, StringPiece("this"));
+  ++iter;
+  ASSERT_EQ(*iter, StringPiece(" is"));
+  ++iter;
+  ASSERT_EQ(*iter, StringPiece("the"));
+  ++iter;
+  ASSERT_EQ(*iter, StringPiece("end"));
+  ++iter;
+  ASSERT_EQ(tokenizer.end(), iter);
 }
 
 TEST(UtilTest, TokenizeEmptyString) {
-    auto tokenizer = util::tokenize(StringPiece(""), '|');
-    auto iter = tokenizer.begin();
-    ASSERT_NE(tokenizer.end(), iter);
-    ASSERT_EQ(StringPiece(), *iter);
-    ++iter;
-    ASSERT_EQ(tokenizer.end(), iter);
+  auto tokenizer = util::Tokenize(StringPiece(""), '|');
+  auto iter = tokenizer.begin();
+  ASSERT_NE(tokenizer.end(), iter);
+  ASSERT_EQ(StringPiece(), *iter);
+  ++iter;
+  ASSERT_EQ(tokenizer.end(), iter);
 }
 
 TEST(UtilTest, TokenizeAtEnd) {
-    auto tokenizer = util::tokenize(StringPiece("one."), '.');
-    auto iter = tokenizer.begin();
-    ASSERT_EQ(*iter, StringPiece("one"));
-    ++iter;
-    ASSERT_NE(iter, tokenizer.end());
-    ASSERT_EQ(*iter, StringPiece());
+  auto tokenizer = util::Tokenize(StringPiece("one."), '.');
+  auto iter = tokenizer.begin();
+  ASSERT_EQ(*iter, StringPiece("one"));
+  ++iter;
+  ASSERT_NE(iter, tokenizer.end());
+  ASSERT_EQ(*iter, StringPiece());
 }
 
 TEST(UtilTest, IsJavaClassName) {
-    EXPECT_TRUE(util::isJavaClassName("android.test.Class"));
-    EXPECT_TRUE(util::isJavaClassName("android.test.Class$Inner"));
-    EXPECT_TRUE(util::isJavaClassName("android_test.test.Class"));
-    EXPECT_TRUE(util::isJavaClassName("_android_.test._Class_"));
-    EXPECT_FALSE(util::isJavaClassName("android.test.$Inner"));
-    EXPECT_FALSE(util::isJavaClassName("android.test.Inner$"));
-    EXPECT_FALSE(util::isJavaClassName(".test.Class"));
-    EXPECT_FALSE(util::isJavaClassName("android"));
+  EXPECT_TRUE(util::IsJavaClassName("android.test.Class"));
+  EXPECT_TRUE(util::IsJavaClassName("android.test.Class$Inner"));
+  EXPECT_TRUE(util::IsJavaClassName("android_test.test.Class"));
+  EXPECT_TRUE(util::IsJavaClassName("_android_.test._Class_"));
+  EXPECT_FALSE(util::IsJavaClassName("android.test.$Inner"));
+  EXPECT_FALSE(util::IsJavaClassName("android.test.Inner$"));
+  EXPECT_FALSE(util::IsJavaClassName(".test.Class"));
+  EXPECT_FALSE(util::IsJavaClassName("android"));
 }
 
 TEST(UtilTest, IsJavaPackageName) {
-    EXPECT_TRUE(util::isJavaPackageName("android"));
-    EXPECT_TRUE(util::isJavaPackageName("android.test"));
-    EXPECT_TRUE(util::isJavaPackageName("android.test_thing"));
-    EXPECT_FALSE(util::isJavaPackageName("_android"));
-    EXPECT_FALSE(util::isJavaPackageName("android_"));
-    EXPECT_FALSE(util::isJavaPackageName("android."));
-    EXPECT_FALSE(util::isJavaPackageName(".android"));
-    EXPECT_FALSE(util::isJavaPackageName("android._test"));
-    EXPECT_FALSE(util::isJavaPackageName(".."));
+  EXPECT_TRUE(util::IsJavaPackageName("android"));
+  EXPECT_TRUE(util::IsJavaPackageName("android.test"));
+  EXPECT_TRUE(util::IsJavaPackageName("android.test_thing"));
+  EXPECT_FALSE(util::IsJavaPackageName("_android"));
+  EXPECT_FALSE(util::IsJavaPackageName("android_"));
+  EXPECT_FALSE(util::IsJavaPackageName("android."));
+  EXPECT_FALSE(util::IsJavaPackageName(".android"));
+  EXPECT_FALSE(util::IsJavaPackageName("android._test"));
+  EXPECT_FALSE(util::IsJavaPackageName(".."));
 }
 
 TEST(UtilTest, FullyQualifiedClassName) {
-    Maybe<std::string> res = util::getFullyQualifiedClassName("android", ".asdf");
-    AAPT_ASSERT_TRUE(res);
-    EXPECT_EQ(res.value(), "android.asdf");
+  Maybe<std::string> res = util::GetFullyQualifiedClassName("android", ".asdf");
+  AAPT_ASSERT_TRUE(res);
+  EXPECT_EQ(res.value(), "android.asdf");
 
-    res = util::getFullyQualifiedClassName("android", ".a.b");
-    AAPT_ASSERT_TRUE(res);
-    EXPECT_EQ(res.value(), "android.a.b");
+  res = util::GetFullyQualifiedClassName("android", ".a.b");
+  AAPT_ASSERT_TRUE(res);
+  EXPECT_EQ(res.value(), "android.a.b");
 
-    res = util::getFullyQualifiedClassName("android", "a.b");
-    AAPT_ASSERT_TRUE(res);
-    EXPECT_EQ(res.value(), "a.b");
+  res = util::GetFullyQualifiedClassName("android", "a.b");
+  AAPT_ASSERT_TRUE(res);
+  EXPECT_EQ(res.value(), "a.b");
 
-    res = util::getFullyQualifiedClassName("", "a.b");
-    AAPT_ASSERT_TRUE(res);
-    EXPECT_EQ(res.value(), "a.b");
+  res = util::GetFullyQualifiedClassName("", "a.b");
+  AAPT_ASSERT_TRUE(res);
+  EXPECT_EQ(res.value(), "a.b");
 
-    res = util::getFullyQualifiedClassName("android", "Class");
-    AAPT_ASSERT_TRUE(res);
-    EXPECT_EQ(res.value(), "android.Class");
+  res = util::GetFullyQualifiedClassName("android", "Class");
+  AAPT_ASSERT_TRUE(res);
+  EXPECT_EQ(res.value(), "android.Class");
 
-    res = util::getFullyQualifiedClassName("", "");
-    AAPT_ASSERT_FALSE(res);
+  res = util::GetFullyQualifiedClassName("", "");
+  AAPT_ASSERT_FALSE(res);
 
-    res = util::getFullyQualifiedClassName("android", "./Apple");
-    AAPT_ASSERT_FALSE(res);
+  res = util::GetFullyQualifiedClassName("android", "./Apple");
+  AAPT_ASSERT_FALSE(res);
 }
 
 TEST(UtilTest, ExtractResourcePathComponents) {
-    StringPiece prefix, entry, suffix;
-    ASSERT_TRUE(util::extractResFilePathParts("res/xml-sw600dp/entry.xml", &prefix, &entry,
-                                              &suffix));
-    EXPECT_EQ(prefix, "res/xml-sw600dp/");
-    EXPECT_EQ(entry, "entry");
-    EXPECT_EQ(suffix, ".xml");
+  StringPiece prefix, entry, suffix;
+  ASSERT_TRUE(util::ExtractResFilePathParts("res/xml-sw600dp/entry.xml",
+                                            &prefix, &entry, &suffix));
+  EXPECT_EQ(prefix, "res/xml-sw600dp/");
+  EXPECT_EQ(entry, "entry");
+  EXPECT_EQ(suffix, ".xml");
 
-    ASSERT_TRUE(util::extractResFilePathParts("res/xml-sw600dp/entry.9.png", &prefix, &entry,
-                                              &suffix));
+  ASSERT_TRUE(util::ExtractResFilePathParts("res/xml-sw600dp/entry.9.png",
+                                            &prefix, &entry, &suffix));
 
-    EXPECT_EQ(prefix, "res/xml-sw600dp/");
-    EXPECT_EQ(entry, "entry");
-    EXPECT_EQ(suffix, ".9.png");
+  EXPECT_EQ(prefix, "res/xml-sw600dp/");
+  EXPECT_EQ(entry, "entry");
+  EXPECT_EQ(suffix, ".9.png");
 
-    EXPECT_FALSE(util::extractResFilePathParts("AndroidManifest.xml", &prefix, &entry, &suffix));
-    EXPECT_FALSE(util::extractResFilePathParts("res/.xml", &prefix, &entry, &suffix));
+  EXPECT_FALSE(util::ExtractResFilePathParts("AndroidManifest.xml", &prefix,
+                                             &entry, &suffix));
+  EXPECT_FALSE(
+      util::ExtractResFilePathParts("res/.xml", &prefix, &entry, &suffix));
 
-    ASSERT_TRUE(util::extractResFilePathParts("res//.", &prefix, &entry, &suffix));
-    EXPECT_EQ(prefix, "res//");
-    EXPECT_EQ(entry, "");
-    EXPECT_EQ(suffix, ".");
+  ASSERT_TRUE(
+      util::ExtractResFilePathParts("res//.", &prefix, &entry, &suffix));
+  EXPECT_EQ(prefix, "res//");
+  EXPECT_EQ(entry, "");
+  EXPECT_EQ(suffix, ".");
 }
 
 TEST(UtilTest, VerifyJavaStringFormat) {
-    ASSERT_TRUE(util::verifyJavaStringFormat("%09.34f"));
-    ASSERT_TRUE(util::verifyJavaStringFormat("%9$.34f %8$"));
-    ASSERT_TRUE(util::verifyJavaStringFormat("%% %%"));
-    ASSERT_FALSE(util::verifyJavaStringFormat("%09$f %f"));
-    ASSERT_FALSE(util::verifyJavaStringFormat("%09f %08s"));
+  ASSERT_TRUE(util::VerifyJavaStringFormat("%09.34f"));
+  ASSERT_TRUE(util::VerifyJavaStringFormat("%9$.34f %8$"));
+  ASSERT_TRUE(util::VerifyJavaStringFormat("%% %%"));
+  ASSERT_FALSE(util::VerifyJavaStringFormat("%09$f %f"));
+  ASSERT_FALSE(util::VerifyJavaStringFormat("%09f %08s"));
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/xml/XmlActionExecutor.cpp b/tools/aapt2/xml/XmlActionExecutor.cpp
index 745079c..7580b46 100644
--- a/tools/aapt2/xml/XmlActionExecutor.cpp
+++ b/tools/aapt2/xml/XmlActionExecutor.cpp
@@ -19,93 +19,94 @@
 namespace aapt {
 namespace xml {
 
-static bool wrapperOne(XmlNodeAction::ActionFunc& f, Element* el, SourcePathDiagnostics*) {
-    return f(el);
+static bool wrapper_one(XmlNodeAction::ActionFunc& f, Element* el,
+                        SourcePathDiagnostics*) {
+  return f(el);
 }
 
-static bool wrapperTwo(XmlNodeAction::ActionFuncWithDiag& f, Element* el,
-                       SourcePathDiagnostics* diag) {
-    return f(el, diag);
+static bool wrapper_two(XmlNodeAction::ActionFuncWithDiag& f, Element* el,
+                        SourcePathDiagnostics* diag) {
+  return f(el, diag);
 }
 
-void XmlNodeAction::action(XmlNodeAction::ActionFunc f) {
-    mActions.emplace_back(std::bind(wrapperOne, std::move(f),
-                                    std::placeholders::_1,
-                                    std::placeholders::_2));
+void XmlNodeAction::Action(XmlNodeAction::ActionFunc f) {
+  actions_.emplace_back(std::bind(
+      wrapper_one, std::move(f), std::placeholders::_1, std::placeholders::_2));
 }
 
-void XmlNodeAction::action(XmlNodeAction::ActionFuncWithDiag f) {
-    mActions.emplace_back(std::bind(wrapperTwo, std::move(f),
-                                    std::placeholders::_1,
-                                    std::placeholders::_2));
+void XmlNodeAction::Action(XmlNodeAction::ActionFuncWithDiag f) {
+  actions_.emplace_back(std::bind(
+      wrapper_two, std::move(f), std::placeholders::_1, std::placeholders::_2));
 }
 
-static void printElementToDiagMessage(const Element* el, DiagMessage* msg) {
-    *msg << "<";
-    if (!el->namespaceUri.empty()) {
-        *msg << el->namespaceUri << ":";
-    }
-    *msg << el->name << ">";
+static void PrintElementToDiagMessage(const Element* el, DiagMessage* msg) {
+  *msg << "<";
+  if (!el->namespace_uri.empty()) {
+    *msg << el->namespace_uri << ":";
+  }
+  *msg << el->name << ">";
 }
 
-bool XmlNodeAction::execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag,
-                            Element* el) const {
-    bool error = false;
-    for (const ActionFuncWithDiag& action : mActions) {
-        error |= !action(el, diag);
+bool XmlNodeAction::Execute(XmlActionExecutorPolicy policy,
+                            SourcePathDiagnostics* diag, Element* el) const {
+  bool error = false;
+  for (const ActionFuncWithDiag& action : actions_) {
+    error |= !action(el, diag);
+  }
+
+  for (Element* child_el : el->GetChildElements()) {
+    if (child_el->namespace_uri.empty()) {
+      std::map<std::string, XmlNodeAction>::const_iterator iter =
+          map_.find(child_el->name);
+      if (iter != map_.end()) {
+        error |= !iter->second.Execute(policy, diag, child_el);
+        continue;
+      }
     }
 
-    for (Element* childEl : el->getChildElements()) {
-        if (childEl->namespaceUri.empty()) {
-            std::map<std::string, XmlNodeAction>::const_iterator iter = mMap.find(childEl->name);
-            if (iter != mMap.end()) {
-                error |= !iter->second.execute(policy, diag, childEl);
-                continue;
-            }
-        }
-
-        if (policy == XmlActionExecutorPolicy::Whitelist) {
-            DiagMessage errorMsg(childEl->lineNumber);
-            errorMsg << "unknown element ";
-            printElementToDiagMessage(childEl, &errorMsg);
-            errorMsg << " found";
-            diag->error(errorMsg);
-            error = true;
-        }
+    if (policy == XmlActionExecutorPolicy::kWhitelist) {
+      DiagMessage error_msg(child_el->line_number);
+      error_msg << "unknown element ";
+      PrintElementToDiagMessage(child_el, &error_msg);
+      error_msg << " found";
+      diag->Error(error_msg);
+      error = true;
     }
-    return !error;
+  }
+  return !error;
 }
 
-bool XmlActionExecutor::execute(XmlActionExecutorPolicy policy, IDiagnostics* diag,
-                                XmlResource* doc) const {
-    SourcePathDiagnostics sourceDiag(doc->file.source, diag);
+bool XmlActionExecutor::Execute(XmlActionExecutorPolicy policy,
+                                IDiagnostics* diag, XmlResource* doc) const {
+  SourcePathDiagnostics source_diag(doc->file.source, diag);
 
-    Element* el = findRootElement(doc);
-    if (!el) {
-        if (policy == XmlActionExecutorPolicy::Whitelist) {
-            sourceDiag.error(DiagMessage() << "no root XML tag found");
-            return false;
-        }
-        return true;
-    }
-
-    if (el->namespaceUri.empty()) {
-        std::map<std::string, XmlNodeAction>::const_iterator iter = mMap.find(el->name);
-        if (iter != mMap.end()) {
-            return iter->second.execute(policy, &sourceDiag, el);
-        }
-    }
-
-    if (policy == XmlActionExecutorPolicy::Whitelist) {
-        DiagMessage errorMsg(el->lineNumber);
-        errorMsg << "unknown element ";
-        printElementToDiagMessage(el, &errorMsg);
-        errorMsg << " found";
-        sourceDiag.error(errorMsg);
-        return false;
+  Element* el = FindRootElement(doc);
+  if (!el) {
+    if (policy == XmlActionExecutorPolicy::kWhitelist) {
+      source_diag.Error(DiagMessage() << "no root XML tag found");
+      return false;
     }
     return true;
+  }
+
+  if (el->namespace_uri.empty()) {
+    std::map<std::string, XmlNodeAction>::const_iterator iter =
+        map_.find(el->name);
+    if (iter != map_.end()) {
+      return iter->second.Execute(policy, &source_diag, el);
+    }
+  }
+
+  if (policy == XmlActionExecutorPolicy::kWhitelist) {
+    DiagMessage error_msg(el->line_number);
+    error_msg << "unknown element ";
+    PrintElementToDiagMessage(el, &error_msg);
+    error_msg << " found";
+    source_diag.Error(error_msg);
+    return false;
+  }
+  return true;
 }
 
-} // namespace xml
-} // namespace aapt
+}  // namespace xml
+}  // namespace aapt
diff --git a/tools/aapt2/xml/XmlActionExecutor.h b/tools/aapt2/xml/XmlActionExecutor.h
index ca21b08..68e3563 100644
--- a/tools/aapt2/xml/XmlActionExecutor.h
+++ b/tools/aapt2/xml/XmlActionExecutor.h
@@ -17,15 +17,16 @@
 #ifndef AAPT_XML_XMLPATTERN_H
 #define AAPT_XML_XMLPATTERN_H
 
-#include "Diagnostics.h"
-#include "xml/XmlDom.h"
-
-#include <android-base/macros.h>
 #include <functional>
 #include <map>
 #include <string>
 #include <vector>
 
+#include "android-base/macros.h"
+
+#include "Diagnostics.h"
+#include "xml/XmlDom.h"
+
 namespace aapt {
 namespace xml {
 
@@ -34,14 +35,14 @@
    * Actions on run if elements are matched, errors occur only when actions
    * return false.
    */
-  None,
+  kNone,
 
   /**
    * The actions defined must match and run. If an element is found that does
    * not match
    * an action, an error occurs.
    */
-  Whitelist,
+  kWhitelist,
 };
 
 /**
@@ -60,22 +61,22 @@
    * element
    * with the name `name`.
    */
-  XmlNodeAction& operator[](const std::string& name) { return mMap[name]; }
+  XmlNodeAction& operator[](const std::string& name) { return map_[name]; }
 
   /**
    * Add an action to be performed at this XmlNodeAction.
    */
-  void action(ActionFunc f);
-  void action(ActionFuncWithDiag);
+  void Action(ActionFunc f);
+  void Action(ActionFuncWithDiag);
 
  private:
   friend class XmlActionExecutor;
 
-  bool execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag,
+  bool Execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag,
                Element* el) const;
 
-  std::map<std::string, XmlNodeAction> mMap;
-  std::vector<ActionFuncWithDiag> mActions;
+  std::map<std::string, XmlNodeAction> map_;
+  std::vector<ActionFuncWithDiag> actions_;
 };
 
 /**
@@ -89,20 +90,19 @@
 
   /**
    * Find or create a root XmlNodeAction that will be performed for the root XML
-   * element
-   * with the name `name`.
+   * element with the name `name`.
    */
-  XmlNodeAction& operator[](const std::string& name) { return mMap[name]; }
+  XmlNodeAction& operator[](const std::string& name) { return map_[name]; }
 
   /**
    * Execute the defined actions for this XmlResource.
    * Returns true if all actions return true, otherwise returns false.
    */
-  bool execute(XmlActionExecutorPolicy policy, IDiagnostics* diag,
+  bool Execute(XmlActionExecutorPolicy policy, IDiagnostics* diag,
                XmlResource* doc) const;
 
  private:
-  std::map<std::string, XmlNodeAction> mMap;
+  std::map<std::string, XmlNodeAction> map_;
 
   DISALLOW_COPY_AND_ASSIGN(XmlActionExecutor);
 };
diff --git a/tools/aapt2/xml/XmlActionExecutor_test.cpp b/tools/aapt2/xml/XmlActionExecutor_test.cpp
index 106e856..7110c90 100644
--- a/tools/aapt2/xml/XmlActionExecutor_test.cpp
+++ b/tools/aapt2/xml/XmlActionExecutor_test.cpp
@@ -14,49 +14,53 @@
  * limitations under the License.
  */
 
-#include "test/Test.h"
 #include "xml/XmlActionExecutor.h"
 
+#include "test/Test.h"
+
 namespace aapt {
 namespace xml {
 
 TEST(XmlActionExecutorTest, BuildsAccessibleNestedPattern) {
-    XmlActionExecutor executor;
-    XmlNodeAction& manifestAction = executor["manifest"];
-    XmlNodeAction& applicationAction = manifestAction["application"];
+  XmlActionExecutor executor;
+  XmlNodeAction& manifest_action = executor["manifest"];
+  XmlNodeAction& application_action = manifest_action["application"];
 
-    Element* manifestEl = nullptr;
-    manifestAction.action([&](Element* manifest) -> bool {
-        manifestEl = manifest;
-        return true;
-    });
+  Element* manifest_el = nullptr;
+  manifest_action.Action([&](Element* manifest) -> bool {
+    manifest_el = manifest;
+    return true;
+  });
 
-    Element* applicationEl = nullptr;
-    applicationAction.action([&](Element* application) -> bool {
-        applicationEl = application;
-        return true;
-    });
+  Element* application_el = nullptr;
+  application_action.Action([&](Element* application) -> bool {
+    application_el = application;
+    return true;
+  });
 
-    std::unique_ptr<XmlResource> doc = test::buildXmlDom("<manifest><application /></manifest>");
+  std::unique_ptr<XmlResource> doc =
+      test::BuildXmlDom("<manifest><application /></manifest>");
 
-    StdErrDiagnostics diag;
-    ASSERT_TRUE(executor.execute(XmlActionExecutorPolicy::None, &diag, doc.get()));
-    ASSERT_NE(nullptr, manifestEl);
-    EXPECT_EQ(std::string("manifest"), manifestEl->name);
+  StdErrDiagnostics diag;
+  ASSERT_TRUE(
+      executor.Execute(XmlActionExecutorPolicy::kNone, &diag, doc.get()));
+  ASSERT_NE(nullptr, manifest_el);
+  EXPECT_EQ(std::string("manifest"), manifest_el->name);
 
-    ASSERT_NE(nullptr, applicationEl);
-    EXPECT_EQ(std::string("application"), applicationEl->name);
+  ASSERT_NE(nullptr, application_el);
+  EXPECT_EQ(std::string("application"), application_el->name);
 }
 
 TEST(XmlActionExecutorTest, FailsWhenUndefinedHierarchyExists) {
-    XmlActionExecutor executor;
-    executor["manifest"]["application"];
+  XmlActionExecutor executor;
+  executor["manifest"]["application"];
 
-    std::unique_ptr<XmlResource> doc = test::buildXmlDom(
-            "<manifest><application /><activity /></manifest>");
-    StdErrDiagnostics diag;
-    ASSERT_FALSE(executor.execute(XmlActionExecutorPolicy::Whitelist, &diag, doc.get()));
+  std::unique_ptr<XmlResource> doc =
+      test::BuildXmlDom("<manifest><application /><activity /></manifest>");
+  StdErrDiagnostics diag;
+  ASSERT_FALSE(
+      executor.Execute(XmlActionExecutorPolicy::kWhitelist, &diag, doc.get()));
 }
 
-} // namespace xml
-} // namespace aapt
+}  // namespace xml
+}  // namespace aapt
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index 28de78a..960d361 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -15,475 +15,501 @@
  */
 
 #include "XmlDom.h"
-#include "XmlPullParser.h"
-#include "util/Util.h"
+
+#include <expat.h>
 
 #include <cassert>
-#include <expat.h>
 #include <memory>
 #include <stack>
 #include <string>
 #include <tuple>
 
+#include "android-base/logging.h"
+
+#include "XmlPullParser.h"
+#include "util/Util.h"
+
 namespace aapt {
 namespace xml {
 
 constexpr char kXmlNamespaceSep = 1;
 
 struct Stack {
-    std::unique_ptr<xml::Node> root;
-    std::stack<xml::Node*> nodeStack;
-    std::string pendingComment;
+  std::unique_ptr<xml::Node> root;
+  std::stack<xml::Node*> node_stack;
+  std::string pending_comment;
 };
 
 /**
  * Extracts the namespace and name of an expanded element or attribute name.
  */
-static void splitName(const char* name, std::string* outNs, std::string* outName) {
-    const char* p = name;
-    while (*p != 0 && *p != kXmlNamespaceSep) {
-        p++;
-    }
+static void SplitName(const char* name, std::string* out_ns,
+                      std::string* out_name) {
+  const char* p = name;
+  while (*p != 0 && *p != kXmlNamespaceSep) {
+    p++;
+  }
 
-    if (*p == 0) {
-        outNs->clear();
-        *outName = StringPiece(name).toString();
-    } else {
-        *outNs = StringPiece(name, (p - name)).toString();
-        *outName = StringPiece(p + 1).toString();
-    }
+  if (*p == 0) {
+    out_ns->clear();
+    *out_name = StringPiece(name).ToString();
+  } else {
+    *out_ns = StringPiece(name, (p - name)).ToString();
+    *out_name = StringPiece(p + 1).ToString();
+  }
 }
 
-static void addToStack(Stack* stack, XML_Parser parser, std::unique_ptr<Node> node) {
-    node->lineNumber = XML_GetCurrentLineNumber(parser);
-    node->columnNumber = XML_GetCurrentColumnNumber(parser);
+static void AddToStack(Stack* stack, XML_Parser parser,
+                       std::unique_ptr<Node> node) {
+  node->line_number = XML_GetCurrentLineNumber(parser);
+  node->column_number = XML_GetCurrentColumnNumber(parser);
 
-    Node* thisNode = node.get();
-    if (!stack->nodeStack.empty()) {
-        stack->nodeStack.top()->addChild(std::move(node));
-    } else {
-        stack->root = std::move(node);
-    }
+  Node* this_node = node.get();
+  if (!stack->node_stack.empty()) {
+    stack->node_stack.top()->AppendChild(std::move(node));
+  } else {
+    stack->root = std::move(node);
+  }
 
-    if (!nodeCast<Text>(thisNode)) {
-        stack->nodeStack.push(thisNode);
-    }
+  if (!NodeCast<Text>(this_node)) {
+    stack->node_stack.push(this_node);
+  }
 }
 
-static void XMLCALL startNamespaceHandler(void* userData, const char* prefix, const char* uri) {
-    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
-    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+static void XMLCALL StartNamespaceHandler(void* user_data, const char* prefix,
+                                          const char* uri) {
+  XML_Parser parser = reinterpret_cast<XML_Parser>(user_data);
+  Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
 
-    std::unique_ptr<Namespace> ns = util::make_unique<Namespace>();
-    if (prefix) {
-        ns->namespacePrefix = StringPiece(prefix).toString();
-    }
+  std::unique_ptr<Namespace> ns = util::make_unique<Namespace>();
+  if (prefix) {
+    ns->namespace_prefix = StringPiece(prefix).ToString();
+  }
 
-    if (uri) {
-        ns->namespaceUri = StringPiece(uri).toString();
-    }
+  if (uri) {
+    ns->namespace_uri = StringPiece(uri).ToString();
+  }
 
-    addToStack(stack, parser, std::move(ns));
+  AddToStack(stack, parser, std::move(ns));
 }
 
-static void XMLCALL endNamespaceHandler(void* userData, const char* prefix) {
-    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
-    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+static void XMLCALL EndNamespaceHandler(void* user_data, const char* prefix) {
+  XML_Parser parser = reinterpret_cast<XML_Parser>(user_data);
+  Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
 
-    assert(!stack->nodeStack.empty());
-    stack->nodeStack.pop();
+  CHECK(!stack->node_stack.empty());
+  stack->node_stack.pop();
 }
 
-static bool lessAttribute(const Attribute& lhs, const Attribute& rhs) {
-    return std::tie(lhs.namespaceUri, lhs.name, lhs.value) <
-            std::tie(rhs.namespaceUri, rhs.name, rhs.value);
+static bool less_attribute(const Attribute& lhs, const Attribute& rhs) {
+  return std::tie(lhs.namespace_uri, lhs.name, lhs.value) <
+         std::tie(rhs.namespace_uri, rhs.name, rhs.value);
 }
 
-static void XMLCALL startElementHandler(void* userData, const char* name, const char** attrs) {
-    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
-    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+static void XMLCALL StartElementHandler(void* user_data, const char* name,
+                                        const char** attrs) {
+  XML_Parser parser = reinterpret_cast<XML_Parser>(user_data);
+  Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
 
-    std::unique_ptr<Element> el = util::make_unique<Element>();
-    splitName(name, &el->namespaceUri, &el->name);
+  std::unique_ptr<Element> el = util::make_unique<Element>();
+  SplitName(name, &el->namespace_uri, &el->name);
 
-    while (*attrs) {
-        Attribute attribute;
-        splitName(*attrs++, &attribute.namespaceUri, &attribute.name);
-        attribute.value = StringPiece(*attrs++).toString();
+  while (*attrs) {
+    Attribute attribute;
+    SplitName(*attrs++, &attribute.namespace_uri, &attribute.name);
+    attribute.value = StringPiece(*attrs++).ToString();
 
-        // Insert in sorted order.
-        auto iter = std::lower_bound(el->attributes.begin(), el->attributes.end(), attribute,
-                                     lessAttribute);
-        el->attributes.insert(iter, std::move(attribute));
-    }
+    // Insert in sorted order.
+    auto iter = std::lower_bound(el->attributes.begin(), el->attributes.end(),
+                                 attribute, less_attribute);
+    el->attributes.insert(iter, std::move(attribute));
+  }
 
-    el->comment = std::move(stack->pendingComment);
-    addToStack(stack, parser, std::move(el));
+  el->comment = std::move(stack->pending_comment);
+  AddToStack(stack, parser, std::move(el));
 }
 
-static void XMLCALL endElementHandler(void* userData, const char* name) {
-    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
-    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+static void XMLCALL EndElementHandler(void* user_data, const char* name) {
+  XML_Parser parser = reinterpret_cast<XML_Parser>(user_data);
+  Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
 
-    assert(!stack->nodeStack.empty());
-    //stack->nodeStack.top()->comment = std::move(stack->pendingComment);
-    stack->nodeStack.pop();
+  CHECK(!stack->node_stack.empty());
+  // stack->nodeStack.top()->comment = std::move(stack->pendingComment);
+  stack->node_stack.pop();
 }
 
-static void XMLCALL characterDataHandler(void* userData, const char* s, int len) {
-    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
-    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+static void XMLCALL CharacterDataHandler(void* user_data, const char* s,
+                                         int len) {
+  XML_Parser parser = reinterpret_cast<XML_Parser>(user_data);
+  Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
 
-    if (!s || len <= 0) {
+  if (!s || len <= 0) {
+    return;
+  }
+
+  // See if we can just append the text to a previous text node.
+  if (!stack->node_stack.empty()) {
+    Node* currentParent = stack->node_stack.top();
+    if (!currentParent->children.empty()) {
+      Node* last_child = currentParent->children.back().get();
+      if (Text* text = NodeCast<Text>(last_child)) {
+        text->text += StringPiece(s, len).ToString();
         return;
+      }
     }
+  }
 
-    // See if we can just append the text to a previous text node.
-    if (!stack->nodeStack.empty()) {
-        Node* currentParent = stack->nodeStack.top();
-        if (!currentParent->children.empty()) {
-            Node* lastChild = currentParent->children.back().get();
-            if (Text* text = nodeCast<Text>(lastChild)) {
-                text->text += StringPiece(s, len).toString();
-                return;
-            }
-        }
-    }
-
-    std::unique_ptr<Text> text = util::make_unique<Text>();
-    text->text = StringPiece(s, len).toString();
-    addToStack(stack, parser, std::move(text));
+  std::unique_ptr<Text> text = util::make_unique<Text>();
+  text->text = StringPiece(s, len).ToString();
+  AddToStack(stack, parser, std::move(text));
 }
 
-static void XMLCALL commentDataHandler(void* userData, const char* comment) {
-    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
-    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+static void XMLCALL CommentDataHandler(void* user_data, const char* comment) {
+  XML_Parser parser = reinterpret_cast<XML_Parser>(user_data);
+  Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
 
-    if (!stack->pendingComment.empty()) {
-        stack->pendingComment += '\n';
-    }
-    stack->pendingComment += comment;
+  if (!stack->pending_comment.empty()) {
+    stack->pending_comment += '\n';
+  }
+  stack->pending_comment += comment;
 }
 
-std::unique_ptr<XmlResource> inflate(std::istream* in, IDiagnostics* diag, const Source& source) {
-    Stack stack;
-
-    XML_Parser parser = XML_ParserCreateNS(nullptr, kXmlNamespaceSep);
-    XML_SetUserData(parser, &stack);
-    XML_UseParserAsHandlerArg(parser);
-    XML_SetElementHandler(parser, startElementHandler, endElementHandler);
-    XML_SetNamespaceDeclHandler(parser, startNamespaceHandler, endNamespaceHandler);
-    XML_SetCharacterDataHandler(parser, characterDataHandler);
-    XML_SetCommentHandler(parser, commentDataHandler);
-
-    char buffer[1024];
-    while (!in->eof()) {
-        in->read(buffer, sizeof(buffer) / sizeof(buffer[0]));
-        if (in->bad() && !in->eof()) {
-            stack.root = {};
-            diag->error(DiagMessage(source) << strerror(errno));
-            break;
-        }
-
-        if (XML_Parse(parser, buffer, in->gcount(), in->eof()) == XML_STATUS_ERROR) {
-            stack.root = {};
-            diag->error(DiagMessage(source.withLine(XML_GetCurrentLineNumber(parser)))
-                        << XML_ErrorString(XML_GetErrorCode(parser)));
-            break;
-        }
-    }
-
-    XML_ParserFree(parser);
-    if (stack.root) {
-        return util::make_unique<XmlResource>(ResourceFile{ {}, {}, source }, std::move(stack.root));
-    }
-    return {};
-}
-
-static void copyAttributes(Element* el, android::ResXMLParser* parser) {
-    const size_t attrCount = parser->getAttributeCount();
-    if (attrCount > 0) {
-        el->attributes.reserve(attrCount);
-        for (size_t i = 0; i < attrCount; i++) {
-            Attribute attr;
-            size_t len;
-            const char16_t* str16 = parser->getAttributeNamespace(i, &len);
-            if (str16) {
-                attr.namespaceUri = util::utf16ToUtf8(StringPiece16(str16, len));
-            }
-
-            str16 = parser->getAttributeName(i, &len);
-            if (str16) {
-                attr.name = util::utf16ToUtf8(StringPiece16(str16, len));
-            }
-
-            str16 = parser->getAttributeStringValue(i, &len);
-            if (str16) {
-                attr.value = util::utf16ToUtf8(StringPiece16(str16, len));
-            }
-            el->attributes.push_back(std::move(attr));
-        }
-    }
-}
-
-std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnostics* diag,
+std::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag,
                                      const Source& source) {
-    // We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which
-    // causes errors when qualifying it with android::
-    using namespace android;
+  Stack stack;
 
-    std::unique_ptr<Node> root;
-    std::stack<Node*> nodeStack;
+  XML_Parser parser = XML_ParserCreateNS(nullptr, kXmlNamespaceSep);
+  XML_SetUserData(parser, &stack);
+  XML_UseParserAsHandlerArg(parser);
+  XML_SetElementHandler(parser, StartElementHandler, EndElementHandler);
+  XML_SetNamespaceDeclHandler(parser, StartNamespaceHandler,
+                              EndNamespaceHandler);
+  XML_SetCharacterDataHandler(parser, CharacterDataHandler);
+  XML_SetCommentHandler(parser, CommentDataHandler);
 
-    ResXMLTree tree;
-    if (tree.setTo(data, dataLen) != NO_ERROR) {
-        return {};
+  char buffer[1024];
+  while (!in->eof()) {
+    in->read(buffer, sizeof(buffer) / sizeof(buffer[0]));
+    if (in->bad() && !in->eof()) {
+      stack.root = {};
+      diag->Error(DiagMessage(source) << strerror(errno));
+      break;
     }
 
-    ResXMLParser::event_code_t code;
-    while ((code = tree.next()) != ResXMLParser::BAD_DOCUMENT &&
-            code != ResXMLParser::END_DOCUMENT) {
-        std::unique_ptr<Node> newNode;
-        switch (code) {
-            case ResXMLParser::START_NAMESPACE: {
-                std::unique_ptr<Namespace> node = util::make_unique<Namespace>();
-                size_t len;
-                const char16_t* str16 = tree.getNamespacePrefix(&len);
-                if (str16) {
-                    node->namespacePrefix = util::utf16ToUtf8(StringPiece16(str16, len));
-                }
+    if (XML_Parse(parser, buffer, in->gcount(), in->eof()) ==
+        XML_STATUS_ERROR) {
+      stack.root = {};
+      diag->Error(DiagMessage(source.WithLine(XML_GetCurrentLineNumber(parser)))
+                  << XML_ErrorString(XML_GetErrorCode(parser)));
+      break;
+    }
+  }
 
-                str16 = tree.getNamespaceUri(&len);
-                if (str16) {
-                    node->namespaceUri = util::utf16ToUtf8(StringPiece16(str16, len));
-                }
-                newNode = std::move(node);
-                break;
-            }
+  XML_ParserFree(parser);
+  if (stack.root) {
+    return util::make_unique<XmlResource>(ResourceFile{{}, {}, source},
+                                          std::move(stack.root));
+  }
+  return {};
+}
 
-            case ResXMLParser::START_TAG: {
-                std::unique_ptr<Element> node = util::make_unique<Element>();
-                size_t len;
-                const char16_t* str16 = tree.getElementNamespace(&len);
-                if (str16) {
-                    node->namespaceUri = util::utf16ToUtf8(StringPiece16(str16, len));
-                }
+static void CopyAttributes(Element* el, android::ResXMLParser* parser) {
+  const size_t attr_count = parser->getAttributeCount();
+  if (attr_count > 0) {
+    el->attributes.reserve(attr_count);
+    for (size_t i = 0; i < attr_count; i++) {
+      Attribute attr;
+      size_t len;
+      const char16_t* str16 = parser->getAttributeNamespace(i, &len);
+      if (str16) {
+        attr.namespace_uri = util::Utf16ToUtf8(StringPiece16(str16, len));
+      }
 
-                str16 = tree.getElementName(&len);
-                if (str16) {
-                    node->name = util::utf16ToUtf8(StringPiece16(str16, len));
-                }
+      str16 = parser->getAttributeName(i, &len);
+      if (str16) {
+        attr.name = util::Utf16ToUtf8(StringPiece16(str16, len));
+      }
 
-                copyAttributes(node.get(), &tree);
+      str16 = parser->getAttributeStringValue(i, &len);
+      if (str16) {
+        attr.value = util::Utf16ToUtf8(StringPiece16(str16, len));
+      }
+      el->attributes.push_back(std::move(attr));
+    }
+  }
+}
 
-                newNode = std::move(node);
-                break;
-            }
+std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len,
+                                     IDiagnostics* diag, const Source& source) {
+  // We import the android namespace because on Windows NO_ERROR is a macro, not
+  // an enum, which
+  // causes errors when qualifying it with android::
+  using namespace android;
 
-            case ResXMLParser::TEXT: {
-                std::unique_ptr<Text> node = util::make_unique<Text>();
-                size_t len;
-                const char16_t* str16 = tree.getText(&len);
-                if (str16) {
-                    node->text = util::utf16ToUtf8(StringPiece16(str16, len));
-                }
-                newNode = std::move(node);
-                break;
-            }
+  std::unique_ptr<Node> root;
+  std::stack<Node*> node_stack;
 
-            case ResXMLParser::END_NAMESPACE:
-            case ResXMLParser::END_TAG:
-                assert(!nodeStack.empty());
-                nodeStack.pop();
-                break;
+  ResXMLTree tree;
+  if (tree.setTo(data, data_len) != NO_ERROR) {
+    return {};
+  }
 
-            default:
-                assert(false);
-                break;
+  ResXMLParser::event_code_t code;
+  while ((code = tree.next()) != ResXMLParser::BAD_DOCUMENT &&
+         code != ResXMLParser::END_DOCUMENT) {
+    std::unique_ptr<Node> new_node;
+    switch (code) {
+      case ResXMLParser::START_NAMESPACE: {
+        std::unique_ptr<Namespace> node = util::make_unique<Namespace>();
+        size_t len;
+        const char16_t* str16 = tree.getNamespacePrefix(&len);
+        if (str16) {
+          node->namespace_prefix = util::Utf16ToUtf8(StringPiece16(str16, len));
         }
 
-        if (newNode) {
-            newNode->lineNumber = tree.getLineNumber();
-
-            Node* thisNode = newNode.get();
-            if (!root) {
-                assert(nodeStack.empty());
-                root = std::move(newNode);
-            } else {
-                assert(!nodeStack.empty());
-                nodeStack.top()->addChild(std::move(newNode));
-            }
-
-            if (!nodeCast<Text>(thisNode)) {
-                nodeStack.push(thisNode);
-            }
+        str16 = tree.getNamespaceUri(&len);
+        if (str16) {
+          node->namespace_uri = util::Utf16ToUtf8(StringPiece16(str16, len));
         }
-    }
-    return util::make_unique<XmlResource>(ResourceFile{}, std::move(root));
-}
+        new_node = std::move(node);
+        break;
+      }
 
-std::unique_ptr<Node> Namespace::clone() {
-    auto ns = util::make_unique<Namespace>();
-    ns->comment = comment;
-    ns->lineNumber = lineNumber;
-    ns->columnNumber = columnNumber;
-    ns->namespacePrefix = namespacePrefix;
-    ns->namespaceUri = namespaceUri;
-
-    ns->children.reserve(children.size());
-    for (const std::unique_ptr<xml::Node>& child : children) {
-        ns->addChild(child->clone());
-    }
-    return std::move(ns);
-}
-
-Element* findRootElement(XmlResource* doc) {
-    return findRootElement(doc->root.get());
-}
-
-Element* findRootElement(Node* node) {
-    if (!node) {
-        return nullptr;
-    }
-
-    Element* el = nullptr;
-    while ((el = nodeCast<Element>(node)) == nullptr) {
-        if (node->children.empty()) {
-            return nullptr;
+      case ResXMLParser::START_TAG: {
+        std::unique_ptr<Element> node = util::make_unique<Element>();
+        size_t len;
+        const char16_t* str16 = tree.getElementNamespace(&len);
+        if (str16) {
+          node->namespace_uri = util::Utf16ToUtf8(StringPiece16(str16, len));
         }
-        // We are looking for the first element, and namespaces can only have one child.
-        node = node->children.front().get();
-    }
-    return el;
-}
 
-void Node::addChild(std::unique_ptr<Node> child) {
-    child->parent = this;
-    children.push_back(std::move(child));
-}
-
-Attribute* Element::findAttribute(const StringPiece& ns, const StringPiece& name) {
-    for (auto& attr : attributes) {
-        if (ns == attr.namespaceUri && name == attr.name) {
-            return &attr;
+        str16 = tree.getElementName(&len);
+        if (str16) {
+          node->name = util::Utf16ToUtf8(StringPiece16(str16, len));
         }
+
+        CopyAttributes(node.get(), &tree);
+
+        new_node = std::move(node);
+        break;
+      }
+
+      case ResXMLParser::TEXT: {
+        std::unique_ptr<Text> node = util::make_unique<Text>();
+        size_t len;
+        const char16_t* str16 = tree.getText(&len);
+        if (str16) {
+          node->text = util::Utf16ToUtf8(StringPiece16(str16, len));
+        }
+        new_node = std::move(node);
+        break;
+      }
+
+      case ResXMLParser::END_NAMESPACE:
+      case ResXMLParser::END_TAG:
+        CHECK(!node_stack.empty());
+        node_stack.pop();
+        break;
+
+      default:
+        LOG(FATAL) << "unhandled XML chunk type";
+        break;
     }
+
+    if (new_node) {
+      new_node->line_number = tree.getLineNumber();
+
+      Node* this_node = new_node.get();
+      if (!root) {
+        CHECK(node_stack.empty()) << "node stack should be empty";
+        root = std::move(new_node);
+      } else {
+        CHECK(!node_stack.empty()) << "node stack should not be empty";
+        node_stack.top()->AppendChild(std::move(new_node));
+      }
+
+      if (!NodeCast<Text>(this_node)) {
+        node_stack.push(this_node);
+      }
+    }
+  }
+  return util::make_unique<XmlResource>(ResourceFile{}, std::move(root));
+}
+
+std::unique_ptr<Node> Namespace::Clone() {
+  auto ns = util::make_unique<Namespace>();
+  ns->comment = comment;
+  ns->line_number = line_number;
+  ns->column_number = column_number;
+  ns->namespace_prefix = namespace_prefix;
+  ns->namespace_uri = namespace_uri;
+
+  ns->children.reserve(children.size());
+  for (const std::unique_ptr<xml::Node>& child : children) {
+    ns->AppendChild(child->Clone());
+  }
+  return std::move(ns);
+}
+
+Element* FindRootElement(XmlResource* doc) {
+  return FindRootElement(doc->root.get());
+}
+
+Element* FindRootElement(Node* node) {
+  if (!node) {
     return nullptr;
-}
+  }
 
-Element* Element::findChild(const StringPiece& ns, const StringPiece& name) {
-    return findChildWithAttribute(ns, name, {}, {}, {});
-}
-
-Element* Element::findChildWithAttribute(const StringPiece& ns, const StringPiece& name,
-                                         const StringPiece& attrNs, const StringPiece& attrName,
-                                         const StringPiece& attrValue) {
-    for (auto& childNode : children) {
-        Node* child = childNode.get();
-        while (nodeCast<Namespace>(child)) {
-            if (child->children.empty()) {
-                break;
-            }
-            child = child->children[0].get();
-        }
-
-        if (Element* el = nodeCast<Element>(child)) {
-            if (ns == el->namespaceUri && name == el->name) {
-                if (attrNs.empty() && attrName.empty()) {
-                    return el;
-                }
-
-                Attribute* attr = el->findAttribute(attrNs, attrName);
-                if (attr && attrValue == attr->value) {
-                    return el;
-                }
-            }
-        }
+  Element* el = nullptr;
+  while ((el = NodeCast<Element>(node)) == nullptr) {
+    if (node->children.empty()) {
+      return nullptr;
     }
-    return nullptr;
+    // We are looking for the first element, and namespaces can only have one
+    // child.
+    node = node->children.front().get();
+  }
+  return el;
 }
 
-std::vector<Element*> Element::getChildElements() {
-    std::vector<Element*> elements;
-    for (auto& childNode : children) {
-        Node* child = childNode.get();
-        while (nodeCast<Namespace>(child)) {
-            if (child->children.empty()) {
-                break;
-            }
-            child = child->children[0].get();
-        }
+void Node::AppendChild(std::unique_ptr<Node> child) {
+  child->parent = this;
+  children.push_back(std::move(child));
+}
 
-        if (Element* el = nodeCast<Element>(child)) {
-            elements.push_back(el);
-        }
+void Node::InsertChild(size_t index, std::unique_ptr<Node> child) {
+  child->parent = this;
+  children.insert(children.begin() + index, std::move(child));
+}
+
+Attribute* Element::FindAttribute(const StringPiece& ns,
+                                  const StringPiece& name) {
+  for (auto& attr : attributes) {
+    if (ns == attr.namespace_uri && name == attr.name) {
+      return &attr;
     }
-    return elements;
+  }
+  return nullptr;
 }
 
-std::unique_ptr<Node> Element::clone() {
-    auto el = util::make_unique<Element>();
-    el->comment = comment;
-    el->lineNumber = lineNumber;
-    el->columnNumber = columnNumber;
-    el->name = name;
-    el->namespaceUri = namespaceUri;
+Element* Element::FindChild(const StringPiece& ns, const StringPiece& name) {
+  return FindChildWithAttribute(ns, name, {}, {}, {});
+}
 
-    el->attributes.reserve(attributes.size());
-    for (xml::Attribute& attr : attributes) {
-        // Don't copy compiled values or attributes.
-        el->attributes.push_back(xml::Attribute{ attr.namespaceUri, attr.name, attr.value });
+Element* Element::FindChildWithAttribute(const StringPiece& ns,
+                                         const StringPiece& name,
+                                         const StringPiece& attr_ns,
+                                         const StringPiece& attr_name,
+                                         const StringPiece& attr_value) {
+  for (auto& child_node : children) {
+    Node* child = child_node.get();
+    while (NodeCast<Namespace>(child)) {
+      if (child->children.empty()) {
+        break;
+      }
+      child = child->children[0].get();
     }
 
-    el->children.reserve(children.size());
-    for (const std::unique_ptr<xml::Node>& child : children) {
-        el->addChild(child->clone());
+    if (Element* el = NodeCast<Element>(child)) {
+      if (ns == el->namespace_uri && name == el->name) {
+        if (attr_ns.empty() && attr_name.empty()) {
+          return el;
+        }
+
+        Attribute* attr = el->FindAttribute(attr_ns, attr_name);
+        if (attr && attr_value == attr->value) {
+          return el;
+        }
+      }
     }
-    return std::move(el);
+  }
+  return nullptr;
 }
 
-std::unique_ptr<Node> Text::clone() {
-    auto t = util::make_unique<Text>();
-    t->comment = comment;
-    t->lineNumber = lineNumber;
-    t->columnNumber = columnNumber;
-    t->text = text;
-    return std::move(t);
+std::vector<Element*> Element::GetChildElements() {
+  std::vector<Element*> elements;
+  for (auto& child_node : children) {
+    Node* child = child_node.get();
+    while (NodeCast<Namespace>(child)) {
+      if (child->children.empty()) {
+        break;
+      }
+      child = child->children[0].get();
+    }
+
+    if (Element* el = NodeCast<Element>(child)) {
+      elements.push_back(el);
+    }
+  }
+  return elements;
 }
 
-void PackageAwareVisitor::visit(Namespace* ns) {
-   bool added = false;
-   if (Maybe<ExtractedPackage> maybePackage = extractPackageFromNamespace(ns->namespaceUri)) {
-       ExtractedPackage& package = maybePackage.value();
-       mPackageDecls.push_back(PackageDecl{ ns->namespacePrefix, std::move(package) });
-       added = true;
-   }
+std::unique_ptr<Node> Element::Clone() {
+  auto el = util::make_unique<Element>();
+  el->comment = comment;
+  el->line_number = line_number;
+  el->column_number = column_number;
+  el->name = name;
+  el->namespace_uri = namespace_uri;
 
-   Visitor::visit(ns);
+  el->attributes.reserve(attributes.size());
+  for (xml::Attribute& attr : attributes) {
+    // Don't copy compiled values or attributes.
+    el->attributes.push_back(
+        xml::Attribute{attr.namespace_uri, attr.name, attr.value});
+  }
 
-   if (added) {
-       mPackageDecls.pop_back();
-   }
+  el->children.reserve(children.size());
+  for (const std::unique_ptr<xml::Node>& child : children) {
+    el->AppendChild(child->Clone());
+  }
+  return std::move(el);
 }
 
-Maybe<ExtractedPackage> PackageAwareVisitor::transformPackageAlias(
-       const StringPiece& alias, const StringPiece& localPackage) const {
-   if (alias.empty()) {
-       return ExtractedPackage{ localPackage.toString(), false /* private */ };
-   }
-
-   const auto rend = mPackageDecls.rend();
-   for (auto iter = mPackageDecls.rbegin(); iter != rend; ++iter) {
-       if (alias == iter->prefix) {
-           if (iter->package.package.empty()) {
-               return ExtractedPackage{ localPackage.toString(),
-                                              iter->package.privateNamespace };
-           }
-           return iter->package;
-       }
-   }
-   return {};
+std::unique_ptr<Node> Text::Clone() {
+  auto t = util::make_unique<Text>();
+  t->comment = comment;
+  t->line_number = line_number;
+  t->column_number = column_number;
+  t->text = text;
+  return std::move(t);
 }
 
-} // namespace xml
-} // namespace aapt
+void PackageAwareVisitor::Visit(Namespace* ns) {
+  bool added = false;
+  if (Maybe<ExtractedPackage> maybe_package =
+          ExtractPackageFromNamespace(ns->namespace_uri)) {
+    ExtractedPackage& package = maybe_package.value();
+    package_decls_.push_back(
+        PackageDecl{ns->namespace_prefix, std::move(package)});
+    added = true;
+  }
+
+  Visitor::Visit(ns);
+
+  if (added) {
+    package_decls_.pop_back();
+  }
+}
+
+Maybe<ExtractedPackage> PackageAwareVisitor::TransformPackageAlias(
+    const StringPiece& alias, const StringPiece& local_package) const {
+  if (alias.empty()) {
+    return ExtractedPackage{local_package.ToString(), false /* private */};
+  }
+
+  const auto rend = package_decls_.rend();
+  for (auto iter = package_decls_.rbegin(); iter != rend; ++iter) {
+    if (alias == iter->prefix) {
+      if (iter->package.package.empty()) {
+        return ExtractedPackage{local_package.ToString(),
+                                iter->package.private_namespace};
+      }
+      return iter->package;
+    }
+  }
+  return {};
+}
+
+}  // namespace xml
+}  // namespace aapt
diff --git a/tools/aapt2/xml/XmlDom.h b/tools/aapt2/xml/XmlDom.h
index 932303e..720fe35 100644
--- a/tools/aapt2/xml/XmlDom.h
+++ b/tools/aapt2/xml/XmlDom.h
@@ -17,6 +17,11 @@
 #ifndef AAPT_XML_DOM_H
 #define AAPT_XML_DOM_H
 
+#include <istream>
+#include <memory>
+#include <string>
+#include <vector>
+
 #include "Diagnostics.h"
 #include "Resource.h"
 #include "ResourceValues.h"
@@ -24,11 +29,6 @@
 #include "util/Util.h"
 #include "xml/XmlUtil.h"
 
-#include <istream>
-#include <memory>
-#include <string>
-#include <vector>
-
 namespace aapt {
 namespace xml {
 
@@ -40,16 +40,17 @@
 class Node {
  public:
   Node* parent = nullptr;
-  size_t lineNumber = 0;
-  size_t columnNumber = 0;
+  size_t line_number = 0;
+  size_t column_number = 0;
   std::string comment;
   std::vector<std::unique_ptr<Node>> children;
 
   virtual ~Node() = default;
 
-  void addChild(std::unique_ptr<Node> child);
-  virtual void accept(RawVisitor* visitor) = 0;
-  virtual std::unique_ptr<Node> clone() = 0;
+  void AppendChild(std::unique_ptr<Node> child);
+  void InsertChild(size_t index, std::unique_ptr<Node> child);
+  virtual void Accept(RawVisitor* visitor) = 0;
+  virtual std::unique_ptr<Node> Clone() = 0;
 };
 
 /**
@@ -59,7 +60,7 @@
 template <typename Derived>
 class BaseNode : public Node {
  public:
-  virtual void accept(RawVisitor* visitor) override;
+  virtual void Accept(RawVisitor* visitor) override;
 };
 
 /**
@@ -67,10 +68,10 @@
  */
 class Namespace : public BaseNode<Namespace> {
  public:
-  std::string namespacePrefix;
-  std::string namespaceUri;
+  std::string namespace_prefix;
+  std::string namespace_uri;
 
-  std::unique_ptr<Node> clone() override;
+  std::unique_ptr<Node> Clone() override;
 };
 
 struct AaptAttribute {
@@ -82,12 +83,12 @@
  * An XML attribute.
  */
 struct Attribute {
-  std::string namespaceUri;
+  std::string namespace_uri;
   std::string name;
   std::string value;
 
-  Maybe<AaptAttribute> compiledAttribute;
-  std::unique_ptr<Item> compiledValue;
+  Maybe<AaptAttribute> compiled_attribute;
+  std::unique_ptr<Item> compiled_value;
 };
 
 /**
@@ -95,19 +96,19 @@
  */
 class Element : public BaseNode<Element> {
  public:
-  std::string namespaceUri;
+  std::string namespace_uri;
   std::string name;
   std::vector<Attribute> attributes;
 
-  Attribute* findAttribute(const StringPiece& ns, const StringPiece& name);
-  xml::Element* findChild(const StringPiece& ns, const StringPiece& name);
-  xml::Element* findChildWithAttribute(const StringPiece& ns,
+  Attribute* FindAttribute(const StringPiece& ns, const StringPiece& name);
+  xml::Element* FindChild(const StringPiece& ns, const StringPiece& name);
+  xml::Element* FindChildWithAttribute(const StringPiece& ns,
                                        const StringPiece& name,
-                                       const StringPiece& attrNs,
-                                       const StringPiece& attrName,
-                                       const StringPiece& attrValue);
-  std::vector<xml::Element*> getChildElements();
-  std::unique_ptr<Node> clone() override;
+                                       const StringPiece& attr_ns,
+                                       const StringPiece& attr_name,
+                                       const StringPiece& attr_value);
+  std::vector<xml::Element*> GetChildElements();
+  std::unique_ptr<Node> Clone() override;
 };
 
 /**
@@ -117,7 +118,7 @@
  public:
   std::string text;
 
-  std::unique_ptr<Node> clone() override;
+  std::unique_ptr<Node> Clone() override;
 };
 
 /**
@@ -133,18 +134,18 @@
  * Inflates an XML DOM from a text stream, logging errors to the logger.
  * Returns the root node on success, or nullptr on failure.
  */
-std::unique_ptr<XmlResource> inflate(std::istream* in, IDiagnostics* diag,
+std::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag,
                                      const Source& source);
 
 /**
  * Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger.
  * Returns the root node on success, or nullptr on failure.
  */
-std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen,
+std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len,
                                      IDiagnostics* diag, const Source& source);
 
-Element* findRootElement(XmlResource* doc);
-Element* findRootElement(Node* node);
+Element* FindRootElement(XmlResource* doc);
+Element* FindRootElement(Node* node);
 
 /**
  * A visitor interface for the different XML Node subtypes. This will not
@@ -155,9 +156,9 @@
  public:
   virtual ~RawVisitor() = default;
 
-  virtual void visit(Namespace* node) {}
-  virtual void visit(Element* node) {}
-  virtual void visit(Text* text) {}
+  virtual void Visit(Namespace* node) {}
+  virtual void Visit(Element* node) {}
+  virtual void Visit(Text* text) {}
 };
 
 /**
@@ -165,17 +166,17 @@
  */
 class Visitor : public RawVisitor {
  public:
-  using RawVisitor::visit;
+  using RawVisitor::Visit;
 
-  void visit(Namespace* node) override { visitChildren(node); }
+  void Visit(Namespace* node) override { VisitChildren(node); }
 
-  void visit(Element* node) override { visitChildren(node); }
+  void Visit(Element* node) override { VisitChildren(node); }
 
-  void visit(Text* text) override { visitChildren(text); }
+  void Visit(Text* text) override { VisitChildren(text); }
 
-  void visitChildren(Node* node) {
+  void VisitChildren(Node* node) {
     for (auto& child : node->children) {
-      child->accept(this);
+      child->Accept(this);
     }
   }
 };
@@ -185,11 +186,12 @@
  */
 class PackageAwareVisitor : public Visitor, public IPackageDeclStack {
  public:
-  using Visitor::visit;
+  using Visitor::Visit;
 
-  void visit(Namespace* ns) override;
-  Maybe<ExtractedPackage> transformPackageAlias(
-      const StringPiece& alias, const StringPiece& localPackage) const override;
+  void Visit(Namespace* ns) override;
+  Maybe<ExtractedPackage> TransformPackageAlias(
+      const StringPiece& alias,
+      const StringPiece& local_package) const override;
 
  private:
   struct PackageDecl {
@@ -197,30 +199,30 @@
     ExtractedPackage package;
   };
 
-  std::vector<PackageDecl> mPackageDecls;
+  std::vector<PackageDecl> package_decls_;
 };
 
 // Implementations
 
 template <typename Derived>
-void BaseNode<Derived>::accept(RawVisitor* visitor) {
-  visitor->visit(static_cast<Derived*>(this));
+void BaseNode<Derived>::Accept(RawVisitor* visitor) {
+  visitor->Visit(static_cast<Derived*>(this));
 }
 
 template <typename T>
 class NodeCastImpl : public RawVisitor {
  public:
-  using RawVisitor::visit;
+  using RawVisitor::Visit;
 
   T* value = nullptr;
 
-  void visit(T* v) override { value = v; }
+  void Visit(T* v) override { value = v; }
 };
 
 template <typename T>
-T* nodeCast(Node* node) {
+T* NodeCast(Node* node) {
   NodeCastImpl<T> visitor;
-  node->accept(&visitor);
+  node->Accept(&visitor);
   return visitor.value;
 }
 
diff --git a/tools/aapt2/xml/XmlDom_test.cpp b/tools/aapt2/xml/XmlDom_test.cpp
index 1909f75..a414afe 100644
--- a/tools/aapt2/xml/XmlDom_test.cpp
+++ b/tools/aapt2/xml/XmlDom_test.cpp
@@ -16,17 +16,19 @@
 
 #include "xml/XmlDom.h"
 
-#include <gtest/gtest.h>
 #include <sstream>
 #include <string>
 
+#include "test/Test.h"
+
 namespace aapt {
 
-constexpr const char* kXmlPreamble = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+constexpr const char* kXmlPreamble =
+    "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
 
 TEST(XmlDomTest, Inflate) {
-    std::stringstream in(kXmlPreamble);
-    in << R"EOF(
+  std::stringstream in(kXmlPreamble);
+  in << R"EOF(
         <Layout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content">
@@ -36,15 +38,15 @@
         </Layout>
     )EOF";
 
-    const Source source = { "test.xml" };
-    StdErrDiagnostics diag;
-    std::unique_ptr<xml::XmlResource> doc = xml::inflate(&in, &diag, source);
-    ASSERT_NE(doc, nullptr);
+  const Source source = {"test.xml"};
+  StdErrDiagnostics diag;
+  std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, &diag, source);
+  ASSERT_NE(doc, nullptr);
 
-    xml::Namespace* ns = xml::nodeCast<xml::Namespace>(doc->root.get());
-    ASSERT_NE(ns, nullptr);
-    EXPECT_EQ(ns->namespaceUri, xml::kSchemaAndroid);
-    EXPECT_EQ(ns->namespacePrefix, "android");
+  xml::Namespace* ns = xml::NodeCast<xml::Namespace>(doc->root.get());
+  ASSERT_NE(ns, nullptr);
+  EXPECT_EQ(ns->namespace_uri, xml::kSchemaAndroid);
+  EXPECT_EQ(ns->namespace_prefix, "android");
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/xml/XmlPullParser.cpp b/tools/aapt2/xml/XmlPullParser.cpp
index 4a944f1..e59fa86 100644
--- a/tools/aapt2/xml/XmlPullParser.cpp
+++ b/tools/aapt2/xml/XmlPullParser.cpp
@@ -14,295 +14,295 @@
  * limitations under the License.
  */
 
+#include <iostream>
+#include <string>
+
 #include "util/Maybe.h"
 #include "util/Util.h"
 #include "xml/XmlPullParser.h"
 #include "xml/XmlUtil.h"
 
-#include <iostream>
-#include <string>
-
 namespace aapt {
 namespace xml {
 
 constexpr char kXmlNamespaceSep = 1;
 
-XmlPullParser::XmlPullParser(std::istream& in) : mIn(in), mEmpty(), mDepth(0) {
-    mParser = XML_ParserCreateNS(nullptr, kXmlNamespaceSep);
-    XML_SetUserData(mParser, this);
-    XML_SetElementHandler(mParser, startElementHandler, endElementHandler);
-    XML_SetNamespaceDeclHandler(mParser, startNamespaceHandler, endNamespaceHandler);
-    XML_SetCharacterDataHandler(mParser, characterDataHandler);
-    XML_SetCommentHandler(mParser, commentDataHandler);
-    mEventQueue.push(EventData{ Event::kStartDocument, 0, mDepth++ });
+XmlPullParser::XmlPullParser(std::istream& in) : in_(in), empty_(), depth_(0) {
+  parser_ = XML_ParserCreateNS(nullptr, kXmlNamespaceSep);
+  XML_SetUserData(parser_, this);
+  XML_SetElementHandler(parser_, StartElementHandler, EndElementHandler);
+  XML_SetNamespaceDeclHandler(parser_, StartNamespaceHandler,
+                              EndNamespaceHandler);
+  XML_SetCharacterDataHandler(parser_, CharacterDataHandler);
+  XML_SetCommentHandler(parser_, CommentDataHandler);
+  event_queue_.push(EventData{Event::kStartDocument, 0, depth_++});
 }
 
-XmlPullParser::~XmlPullParser() {
-    XML_ParserFree(mParser);
-}
+XmlPullParser::~XmlPullParser() { XML_ParserFree(parser_); }
 
-XmlPullParser::Event XmlPullParser::next() {
-    const Event currentEvent = getEvent();
-    if (currentEvent == Event::kBadDocument || currentEvent == Event::kEndDocument) {
-        return currentEvent;
+XmlPullParser::Event XmlPullParser::Next() {
+  const Event currentEvent = event();
+  if (currentEvent == Event::kBadDocument ||
+      currentEvent == Event::kEndDocument) {
+    return currentEvent;
+  }
+
+  event_queue_.pop();
+  while (event_queue_.empty()) {
+    in_.read(buffer_, sizeof(buffer_) / sizeof(*buffer_));
+
+    const bool done = in_.eof();
+    if (in_.bad() && !done) {
+      error_ = strerror(errno);
+      event_queue_.push(EventData{Event::kBadDocument});
+      continue;
     }
 
-    mEventQueue.pop();
-    while (mEventQueue.empty()) {
-        mIn.read(mBuffer, sizeof(mBuffer) / sizeof(*mBuffer));
-
-        const bool done = mIn.eof();
-        if (mIn.bad() && !done) {
-            mLastError = strerror(errno);
-            mEventQueue.push(EventData{ Event::kBadDocument });
-            continue;
-        }
-
-        if (XML_Parse(mParser, mBuffer, mIn.gcount(), done) == XML_STATUS_ERROR) {
-            mLastError = XML_ErrorString(XML_GetErrorCode(mParser));
-            mEventQueue.push(EventData{ Event::kBadDocument });
-            continue;
-        }
-
-        if (done) {
-            mEventQueue.push(EventData{ Event::kEndDocument, 0, 0 });
-        }
+    if (XML_Parse(parser_, buffer_, in_.gcount(), done) == XML_STATUS_ERROR) {
+      error_ = XML_ErrorString(XML_GetErrorCode(parser_));
+      event_queue_.push(EventData{Event::kBadDocument});
+      continue;
     }
 
-    Event event = getEvent();
-
-    // Record namespace prefixes and package names so that we can do our own
-    // handling of references that use namespace aliases.
-    if (event == Event::kStartNamespace || event == Event::kEndNamespace) {
-        Maybe<ExtractedPackage> result = extractPackageFromNamespace(getNamespaceUri());
-        if (event == Event::kStartNamespace) {
-            if (result) {
-                mPackageAliases.emplace_back(
-                        PackageDecl{ getNamespacePrefix(), std::move(result.value()) });
-            }
-        } else {
-            if (result) {
-                mPackageAliases.pop_back();
-            }
-        }
+    if (done) {
+      event_queue_.push(EventData{Event::kEndDocument, 0, 0});
     }
+  }
 
-    return event;
-}
+  Event next_event = event();
 
-XmlPullParser::Event XmlPullParser::getEvent() const {
-    return mEventQueue.front().event;
-}
-
-const std::string& XmlPullParser::getLastError() const {
-    return mLastError;
-}
-
-const std::string& XmlPullParser::getComment() const {
-    return mEventQueue.front().data1;
-}
-
-size_t XmlPullParser::getLineNumber() const {
-    return mEventQueue.front().lineNumber;
-}
-
-size_t XmlPullParser::getDepth() const {
-    return mEventQueue.front().depth;
-}
-
-const std::string& XmlPullParser::getText() const {
-    if (getEvent() != Event::kText) {
-        return mEmpty;
+  // Record namespace prefixes and package names so that we can do our own
+  // handling of references that use namespace aliases.
+  if (next_event == Event::kStartNamespace ||
+      next_event == Event::kEndNamespace) {
+    Maybe<ExtractedPackage> result =
+        ExtractPackageFromNamespace(namespace_uri());
+    if (next_event == Event::kStartNamespace) {
+      if (result) {
+        package_aliases_.emplace_back(
+            PackageDecl{namespace_prefix(), std::move(result.value())});
+      }
+    } else {
+      if (result) {
+        package_aliases_.pop_back();
+      }
     }
-    return mEventQueue.front().data1;
+  }
+
+  return next_event;
 }
 
-const std::string& XmlPullParser::getNamespacePrefix() const {
-    const Event currentEvent = getEvent();
-    if (currentEvent != Event::kStartNamespace && currentEvent != Event::kEndNamespace) {
-        return mEmpty;
+XmlPullParser::Event XmlPullParser::event() const {
+  return event_queue_.front().event;
+}
+
+const std::string& XmlPullParser::error() const { return error_; }
+
+const std::string& XmlPullParser::comment() const {
+  return event_queue_.front().data1;
+}
+
+size_t XmlPullParser::line_number() const {
+  return event_queue_.front().line_number;
+}
+
+size_t XmlPullParser::depth() const { return event_queue_.front().depth; }
+
+const std::string& XmlPullParser::text() const {
+  if (event() != Event::kText) {
+    return empty_;
+  }
+  return event_queue_.front().data1;
+}
+
+const std::string& XmlPullParser::namespace_prefix() const {
+  const Event current_event = event();
+  if (current_event != Event::kStartNamespace &&
+      current_event != Event::kEndNamespace) {
+    return empty_;
+  }
+  return event_queue_.front().data1;
+}
+
+const std::string& XmlPullParser::namespace_uri() const {
+  const Event current_event = event();
+  if (current_event != Event::kStartNamespace &&
+      current_event != Event::kEndNamespace) {
+    return empty_;
+  }
+  return event_queue_.front().data2;
+}
+
+Maybe<ExtractedPackage> XmlPullParser::TransformPackageAlias(
+    const StringPiece& alias, const StringPiece& local_package) const {
+  if (alias.empty()) {
+    return ExtractedPackage{local_package.ToString(), false /* private */};
+  }
+
+  const auto end_iter = package_aliases_.rend();
+  for (auto iter = package_aliases_.rbegin(); iter != end_iter; ++iter) {
+    if (alias == iter->prefix) {
+      if (iter->package.package.empty()) {
+        return ExtractedPackage{local_package.ToString(),
+                                iter->package.private_namespace};
+      }
+      return iter->package;
     }
-    return mEventQueue.front().data1;
+  }
+  return {};
 }
 
-const std::string& XmlPullParser::getNamespaceUri() const {
-    const Event currentEvent = getEvent();
-    if (currentEvent != Event::kStartNamespace && currentEvent != Event::kEndNamespace) {
-        return mEmpty;
-    }
-    return mEventQueue.front().data2;
+const std::string& XmlPullParser::element_namespace() const {
+  const Event current_event = event();
+  if (current_event != Event::kStartElement &&
+      current_event != Event::kEndElement) {
+    return empty_;
+  }
+  return event_queue_.front().data1;
 }
 
-Maybe<ExtractedPackage> XmlPullParser::transformPackageAlias(
-        const StringPiece& alias, const StringPiece& localPackage) const {
-    if (alias.empty()) {
-        return ExtractedPackage{ localPackage.toString(), false /* private */ };
-    }
-
-    const auto endIter = mPackageAliases.rend();
-    for (auto iter = mPackageAliases.rbegin(); iter != endIter; ++iter) {
-        if (alias == iter->prefix) {
-            if (iter->package.package.empty()) {
-                return ExtractedPackage{ localPackage.toString(),
-                                         iter->package.privateNamespace };
-            }
-            return iter->package;
-        }
-    }
-    return {};
+const std::string& XmlPullParser::element_name() const {
+  const Event current_event = event();
+  if (current_event != Event::kStartElement &&
+      current_event != Event::kEndElement) {
+    return empty_;
+  }
+  return event_queue_.front().data2;
 }
 
-const std::string& XmlPullParser::getElementNamespace() const {
-    const Event currentEvent = getEvent();
-    if (currentEvent != Event::kStartElement && currentEvent != Event::kEndElement) {
-        return mEmpty;
-    }
-    return mEventQueue.front().data1;
+XmlPullParser::const_iterator XmlPullParser::begin_attributes() const {
+  return event_queue_.front().attributes.begin();
 }
 
-const std::string& XmlPullParser::getElementName() const {
-    const Event currentEvent = getEvent();
-    if (currentEvent != Event::kStartElement && currentEvent != Event::kEndElement) {
-        return mEmpty;
-    }
-    return mEventQueue.front().data2;
+XmlPullParser::const_iterator XmlPullParser::end_attributes() const {
+  return event_queue_.front().attributes.end();
 }
 
-XmlPullParser::const_iterator XmlPullParser::beginAttributes() const {
-    return mEventQueue.front().attributes.begin();
-}
-
-XmlPullParser::const_iterator XmlPullParser::endAttributes() const {
-    return mEventQueue.front().attributes.end();
-}
-
-size_t XmlPullParser::getAttributeCount() const {
-    if (getEvent() != Event::kStartElement) {
-        return 0;
-    }
-    return mEventQueue.front().attributes.size();
+size_t XmlPullParser::attribute_count() const {
+  if (event() != Event::kStartElement) {
+    return 0;
+  }
+  return event_queue_.front().attributes.size();
 }
 
 /**
  * Extracts the namespace and name of an expanded element or attribute name.
  */
-static void splitName(const char* name, std::string& outNs, std::string& outName) {
-    const char* p = name;
-    while (*p != 0 && *p != kXmlNamespaceSep) {
-        p++;
+static void SplitName(const char* name, std::string& out_ns,
+                      std::string& out_name) {
+  const char* p = name;
+  while (*p != 0 && *p != kXmlNamespaceSep) {
+    p++;
+  }
+
+  if (*p == 0) {
+    out_ns = std::string();
+    out_name = name;
+  } else {
+    out_ns = StringPiece(name, (p - name)).ToString();
+    out_name = p + 1;
+  }
+}
+
+void XMLCALL XmlPullParser::StartNamespaceHandler(void* user_data,
+                                                  const char* prefix,
+                                                  const char* uri) {
+  XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data);
+  std::string namespace_uri = uri != nullptr ? uri : std::string();
+  parser->namespace_uris_.push(namespace_uri);
+  parser->event_queue_.push(
+      EventData{Event::kStartNamespace,
+                XML_GetCurrentLineNumber(parser->parser_), parser->depth_++,
+                prefix != nullptr ? prefix : std::string(), namespace_uri});
+}
+
+void XMLCALL XmlPullParser::StartElementHandler(void* user_data,
+                                                const char* name,
+                                                const char** attrs) {
+  XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data);
+
+  EventData data = {Event::kStartElement,
+                    XML_GetCurrentLineNumber(parser->parser_),
+                    parser->depth_++};
+  SplitName(name, data.data1, data.data2);
+
+  while (*attrs) {
+    Attribute attribute;
+    SplitName(*attrs++, attribute.namespace_uri, attribute.name);
+    attribute.value = *attrs++;
+
+    // Insert in sorted order.
+    auto iter = std::lower_bound(data.attributes.begin(), data.attributes.end(),
+                                 attribute);
+    data.attributes.insert(iter, std::move(attribute));
+  }
+
+  // Move the structure into the queue (no copy).
+  parser->event_queue_.push(std::move(data));
+}
+
+void XMLCALL XmlPullParser::CharacterDataHandler(void* user_data, const char* s,
+                                                 int len) {
+  XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data);
+
+  parser->event_queue_.push(
+      EventData{Event::kText, XML_GetCurrentLineNumber(parser->parser_),
+                parser->depth_, StringPiece(s, len).ToString()});
+}
+
+void XMLCALL XmlPullParser::EndElementHandler(void* user_data,
+                                              const char* name) {
+  XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data);
+
+  EventData data = {Event::kEndElement,
+                    XML_GetCurrentLineNumber(parser->parser_),
+                    --(parser->depth_)};
+  SplitName(name, data.data1, data.data2);
+
+  // Move the data into the queue (no copy).
+  parser->event_queue_.push(std::move(data));
+}
+
+void XMLCALL XmlPullParser::EndNamespaceHandler(void* user_data,
+                                                const char* prefix) {
+  XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data);
+
+  parser->event_queue_.push(
+      EventData{Event::kEndNamespace, XML_GetCurrentLineNumber(parser->parser_),
+                --(parser->depth_), prefix != nullptr ? prefix : std::string(),
+                parser->namespace_uris_.top()});
+  parser->namespace_uris_.pop();
+}
+
+void XMLCALL XmlPullParser::CommentDataHandler(void* user_data,
+                                               const char* comment) {
+  XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data);
+
+  parser->event_queue_.push(EventData{Event::kComment,
+                                      XML_GetCurrentLineNumber(parser->parser_),
+                                      parser->depth_, comment});
+}
+
+Maybe<StringPiece> FindAttribute(const XmlPullParser* parser,
+                                 const StringPiece& name) {
+  auto iter = parser->FindAttribute("", name);
+  if (iter != parser->end_attributes()) {
+    return StringPiece(util::TrimWhitespace(iter->value));
+  }
+  return {};
+}
+
+Maybe<StringPiece> FindNonEmptyAttribute(const XmlPullParser* parser,
+                                         const StringPiece& name) {
+  auto iter = parser->FindAttribute("", name);
+  if (iter != parser->end_attributes()) {
+    StringPiece trimmed = util::TrimWhitespace(iter->value);
+    if (!trimmed.empty()) {
+      return trimmed;
     }
-
-    if (*p == 0) {
-        outNs = std::string();
-        outName = name;
-    } else {
-        outNs = StringPiece(name, (p - name)).toString();
-        outName = p + 1;
-    }
+  }
+  return {};
 }
 
-void XMLCALL XmlPullParser::startNamespaceHandler(void* userData, const char* prefix,
-        const char* uri) {
-    XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData);
-    std::string namespaceUri = uri != nullptr ? uri : std::string();
-    parser->mNamespaceUris.push(namespaceUri);
-    parser->mEventQueue.push(EventData{
-            Event::kStartNamespace,
-            XML_GetCurrentLineNumber(parser->mParser),
-            parser->mDepth++,
-            prefix != nullptr ? prefix : std::string(),
-            namespaceUri
-    });
-}
-
-void XMLCALL XmlPullParser::startElementHandler(void* userData, const char* name,
-        const char** attrs) {
-    XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData);
-
-    EventData data = {
-            Event::kStartElement, XML_GetCurrentLineNumber(parser->mParser), parser->mDepth++
-    };
-    splitName(name, data.data1, data.data2);
-
-    while (*attrs) {
-        Attribute attribute;
-        splitName(*attrs++, attribute.namespaceUri, attribute.name);
-        attribute.value = *attrs++;
-
-        // Insert in sorted order.
-        auto iter = std::lower_bound(data.attributes.begin(), data.attributes.end(), attribute);
-        data.attributes.insert(iter, std::move(attribute));
-    }
-
-    // Move the structure into the queue (no copy).
-    parser->mEventQueue.push(std::move(data));
-}
-
-void XMLCALL XmlPullParser::characterDataHandler(void* userData, const char* s, int len) {
-    XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData);
-
-    parser->mEventQueue.push(EventData{
-            Event::kText,
-            XML_GetCurrentLineNumber(parser->mParser),
-            parser->mDepth,
-            StringPiece(s, len).toString()
-    });
-}
-
-void XMLCALL XmlPullParser::endElementHandler(void* userData, const char* name) {
-    XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData);
-
-    EventData data = {
-            Event::kEndElement, XML_GetCurrentLineNumber(parser->mParser), --(parser->mDepth)
-    };
-    splitName(name, data.data1, data.data2);
-
-    // Move the data into the queue (no copy).
-    parser->mEventQueue.push(std::move(data));
-}
-
-void XMLCALL XmlPullParser::endNamespaceHandler(void* userData, const char* prefix) {
-    XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData);
-
-    parser->mEventQueue.push(EventData{
-            Event::kEndNamespace,
-            XML_GetCurrentLineNumber(parser->mParser),
-            --(parser->mDepth),
-            prefix != nullptr ? prefix : std::string(),
-            parser->mNamespaceUris.top()
-    });
-    parser->mNamespaceUris.pop();
-}
-
-void XMLCALL XmlPullParser::commentDataHandler(void* userData, const char* comment) {
-    XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData);
-
-    parser->mEventQueue.push(EventData{
-            Event::kComment,
-            XML_GetCurrentLineNumber(parser->mParser),
-            parser->mDepth,
-            comment
-    });
-}
-
-Maybe<StringPiece> findAttribute(const XmlPullParser* parser, const StringPiece& name) {
-    auto iter = parser->findAttribute("", name);
-    if (iter != parser->endAttributes()) {
-        return StringPiece(util::trimWhitespace(iter->value));
-    }
-    return {};
-}
-
-Maybe<StringPiece> findNonEmptyAttribute(const XmlPullParser* parser, const StringPiece& name) {
-    auto iter = parser->findAttribute("", name);
-    if (iter != parser->endAttributes()) {
-        StringPiece trimmed = util::trimWhitespace(iter->value);
-        if (!trimmed.empty()) {
-            return trimmed;
-        }
-    }
-    return {};
-}
-
-} // namespace xml
-} // namespace aapt
+}  // namespace xml
+}  // namespace aapt
diff --git a/tools/aapt2/xml/XmlPullParser.h b/tools/aapt2/xml/XmlPullParser.h
index ce69df6..ff58d60 100644
--- a/tools/aapt2/xml/XmlPullParser.h
+++ b/tools/aapt2/xml/XmlPullParser.h
@@ -17,13 +17,8 @@
 #ifndef AAPT_XML_PULL_PARSER_H
 #define AAPT_XML_PULL_PARSER_H
 
-#include "Resource.h"
-#include "process/IResourceTableConsumer.h"
-#include "util/Maybe.h"
-#include "util/StringPiece.h"
-#include "xml/XmlUtil.h"
-
 #include <expat.h>
+
 #include <algorithm>
 #include <istream>
 #include <ostream>
@@ -32,6 +27,14 @@
 #include <string>
 #include <vector>
 
+#include "android-base/macros.h"
+
+#include "Resource.h"
+#include "process/IResourceTableConsumer.h"
+#include "util/Maybe.h"
+#include "util/StringPiece.h"
+#include "xml/XmlUtil.h"
+
 namespace aapt {
 namespace xml {
 
@@ -51,15 +54,15 @@
   };
 
   /**
-   * Skips to the next direct descendant node of the given startDepth,
+   * Skips to the next direct descendant node of the given start_depth,
    * skipping namespace nodes.
    *
-   * When nextChildNode returns true, you can expect Comments, Text, and
+   * When NextChildNode() returns true, you can expect Comments, Text, and
    * StartElement events.
    */
-  static bool nextChildNode(XmlPullParser* parser, size_t startDepth);
-  static bool skipCurrentElement(XmlPullParser* parser);
-  static bool isGoodEvent(Event event);
+  static bool NextChildNode(XmlPullParser* parser, size_t start_depth);
+  static bool SkipCurrentElement(XmlPullParser* parser);
+  static bool IsGoodEvent(Event event);
 
   explicit XmlPullParser(std::istream& in);
   ~XmlPullParser();
@@ -67,42 +70,42 @@
   /**
    * Returns the current event that is being processed.
    */
-  Event getEvent() const;
+  Event event() const;
 
-  const std::string& getLastError() const;
+  const std::string& error() const;
 
   /**
    * Note, unlike XmlPullParser, the first call to next() will return
    * StartElement of the first element.
    */
-  Event next();
+  Event Next();
 
   //
   // These are available for all nodes.
   //
 
-  const std::string& getComment() const;
-  size_t getLineNumber() const;
-  size_t getDepth() const;
+  const std::string& comment() const;
+  size_t line_number() const;
+  size_t depth() const;
 
   /**
    * Returns the character data for a Text event.
    */
-  const std::string& getText() const;
+  const std::string& text() const;
 
   //
   // Namespace prefix and URI are available for StartNamespace and EndNamespace.
   //
 
-  const std::string& getNamespacePrefix() const;
-  const std::string& getNamespaceUri() const;
+  const std::string& namespace_prefix() const;
+  const std::string& namespace_uri() const;
 
   //
   // These are available for StartElement and EndElement.
   //
 
-  const std::string& getElementNamespace() const;
-  const std::string& getElementName() const;
+  const std::string& element_namespace() const;
+  const std::string& element_name() const;
 
   /*
    * Uses the current stack of namespaces to resolve the package. Eg:
@@ -115,8 +118,9 @@
    * If xmlns:app="http://schemas.android.com/apk/res-auto", then
    * 'package' will be set to 'defaultPackage'.
    */
-  Maybe<ExtractedPackage> transformPackageAlias(
-      const StringPiece& alias, const StringPiece& localPackage) const override;
+  Maybe<ExtractedPackage> TransformPackageAlias(
+      const StringPiece& alias,
+      const StringPiece& local_package) const override;
 
   //
   // Remaining methods are for retrieving information about attributes
@@ -127,7 +131,7 @@
   //
 
   struct Attribute {
-    std::string namespaceUri;
+    std::string namespace_uri;
     std::string name;
     std::string value;
 
@@ -139,52 +143,54 @@
 
   using const_iterator = std::vector<Attribute>::const_iterator;
 
-  const_iterator beginAttributes() const;
-  const_iterator endAttributes() const;
-  size_t getAttributeCount() const;
-  const_iterator findAttribute(StringPiece namespaceUri,
+  const_iterator begin_attributes() const;
+  const_iterator end_attributes() const;
+  size_t attribute_count() const;
+  const_iterator FindAttribute(StringPiece namespace_uri,
                                StringPiece name) const;
 
  private:
-  static void XMLCALL startNamespaceHandler(void* userData, const char* prefix,
+  DISALLOW_COPY_AND_ASSIGN(XmlPullParser);
+
+  static void XMLCALL StartNamespaceHandler(void* user_data, const char* prefix,
                                             const char* uri);
-  static void XMLCALL startElementHandler(void* userData, const char* name,
+  static void XMLCALL StartElementHandler(void* user_data, const char* name,
                                           const char** attrs);
-  static void XMLCALL characterDataHandler(void* userData, const char* s,
+  static void XMLCALL CharacterDataHandler(void* user_data, const char* s,
                                            int len);
-  static void XMLCALL endElementHandler(void* userData, const char* name);
-  static void XMLCALL endNamespaceHandler(void* userData, const char* prefix);
-  static void XMLCALL commentDataHandler(void* userData, const char* comment);
+  static void XMLCALL EndElementHandler(void* user_data, const char* name);
+  static void XMLCALL EndNamespaceHandler(void* user_data, const char* prefix);
+  static void XMLCALL CommentDataHandler(void* user_data, const char* comment);
 
   struct EventData {
     Event event;
-    size_t lineNumber;
+    size_t line_number;
     size_t depth;
     std::string data1;
     std::string data2;
     std::vector<Attribute> attributes;
   };
 
-  std::istream& mIn;
-  XML_Parser mParser;
-  char mBuffer[16384];
-  std::queue<EventData> mEventQueue;
-  std::string mLastError;
-  const std::string mEmpty;
-  size_t mDepth;
-  std::stack<std::string> mNamespaceUris;
+  std::istream& in_;
+  XML_Parser parser_;
+  char buffer_[16384];
+  std::queue<EventData> event_queue_;
+  std::string error_;
+  const std::string empty_;
+  size_t depth_;
+  std::stack<std::string> namespace_uris_;
 
   struct PackageDecl {
     std::string prefix;
     ExtractedPackage package;
   };
-  std::vector<PackageDecl> mPackageAliases;
+  std::vector<PackageDecl> package_aliases_;
 };
 
 /**
  * Finds the attribute in the current element within the global namespace.
  */
-Maybe<StringPiece> findAttribute(const XmlPullParser* parser,
+Maybe<StringPiece> FindAttribute(const XmlPullParser* parser,
                                  const StringPiece& name);
 
 /**
@@ -192,7 +198,7 @@
  * attribute's value
  * must not be the empty string.
  */
-Maybe<StringPiece> findNonEmptyAttribute(const XmlPullParser* parser,
+Maybe<StringPiece> FindNonEmptyAttribute(const XmlPullParser* parser,
                                          const StringPiece& name);
 
 //
@@ -224,18 +230,18 @@
   return out;
 }
 
-inline bool XmlPullParser::nextChildNode(XmlPullParser* parser,
-                                         size_t startDepth) {
+inline bool XmlPullParser::NextChildNode(XmlPullParser* parser,
+                                         size_t start_depth) {
   Event event;
 
   // First get back to the start depth.
-  while (isGoodEvent(event = parser->next()) &&
-         parser->getDepth() > startDepth + 1) {
+  while (IsGoodEvent(event = parser->Next()) &&
+         parser->depth() > start_depth + 1) {
   }
 
   // Now look for the first good node.
-  while ((event != Event::kEndElement || parser->getDepth() > startDepth) &&
-         isGoodEvent(event)) {
+  while ((event != Event::kEndElement || parser->depth() > start_depth) &&
+         IsGoodEvent(event)) {
     switch (event) {
       case Event::kText:
       case Event::kComment:
@@ -244,15 +250,15 @@
       default:
         break;
     }
-    event = parser->next();
+    event = parser->Next();
   }
   return false;
 }
 
-inline bool XmlPullParser::skipCurrentElement(XmlPullParser* parser) {
+inline bool XmlPullParser::SkipCurrentElement(XmlPullParser* parser) {
   int depth = 1;
   while (depth > 0) {
-    switch (parser->next()) {
+    switch (parser->Next()) {
       case Event::kEndDocument:
         return true;
       case Event::kBadDocument:
@@ -270,12 +276,12 @@
   return true;
 }
 
-inline bool XmlPullParser::isGoodEvent(XmlPullParser::Event event) {
+inline bool XmlPullParser::IsGoodEvent(XmlPullParser::Event event) {
   return event != Event::kBadDocument && event != Event::kEndDocument;
 }
 
 inline int XmlPullParser::Attribute::compare(const Attribute& rhs) const {
-  int cmp = namespaceUri.compare(rhs.namespaceUri);
+  int cmp = namespace_uri.compare(rhs.namespace_uri);
   if (cmp != 0) return cmp;
   return name.compare(rhs.name);
 }
@@ -292,16 +298,16 @@
   return compare(rhs) != 0;
 }
 
-inline XmlPullParser::const_iterator XmlPullParser::findAttribute(
-    StringPiece namespaceUri, StringPiece name) const {
-  const auto endIter = endAttributes();
+inline XmlPullParser::const_iterator XmlPullParser::FindAttribute(
+    StringPiece namespace_uri, StringPiece name) const {
+  const auto end_iter = end_attributes();
   const auto iter = std::lower_bound(
-      beginAttributes(), endIter,
-      std::pair<StringPiece, StringPiece>(namespaceUri, name),
+      begin_attributes(), end_iter,
+      std::pair<StringPiece, StringPiece>(namespace_uri, name),
       [](const Attribute& attr,
          const std::pair<StringPiece, StringPiece>& rhs) -> bool {
-        int cmp = attr.namespaceUri.compare(0, attr.namespaceUri.size(),
-                                            rhs.first.data(), rhs.first.size());
+        int cmp = attr.namespace_uri.compare(
+            0, attr.namespace_uri.size(), rhs.first.data(), rhs.first.size());
         if (cmp < 0) return true;
         if (cmp > 0) return false;
         cmp = attr.name.compare(0, attr.name.size(), rhs.second.data(),
@@ -310,11 +316,11 @@
         return false;
       });
 
-  if (iter != endIter && namespaceUri == iter->namespaceUri &&
+  if (iter != end_iter && namespace_uri == iter->namespace_uri &&
       name == iter->name) {
     return iter;
   }
-  return endIter;
+  return end_iter;
 }
 
 }  // namespace xml
diff --git a/tools/aapt2/xml/XmlPullParser_test.cpp b/tools/aapt2/xml/XmlPullParser_test.cpp
index 2c1fdc7..4f18cd2 100644
--- a/tools/aapt2/xml/XmlPullParser_test.cpp
+++ b/tools/aapt2/xml/XmlPullParser_test.cpp
@@ -14,42 +14,43 @@
  * limitations under the License.
  */
 
-#include "test/Test.h"
-#include "util/StringPiece.h"
 #include "xml/XmlPullParser.h"
 
 #include <sstream>
 
+#include "test/Test.h"
+#include "util/StringPiece.h"
+
 namespace aapt {
 
 TEST(XmlPullParserTest, NextChildNodeTraversesCorrectly) {
-    std::stringstream str;
-    str << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
-            "<a><b><c xmlns:a=\"http://schema.org\"><d/></c><e/></b></a>";
-    xml::XmlPullParser parser(str);
+  std::stringstream str;
+  str << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+         "<a><b><c xmlns:a=\"http://schema.org\"><d/></c><e/></b></a>";
+  xml::XmlPullParser parser(str);
 
-    const size_t depthOuter = parser.getDepth();
-    ASSERT_TRUE(xml::XmlPullParser::nextChildNode(&parser, depthOuter));
+  const size_t depth_outer = parser.depth();
+  ASSERT_TRUE(xml::XmlPullParser::NextChildNode(&parser, depth_outer));
 
-    EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.getEvent());
-    EXPECT_EQ(StringPiece("a"), StringPiece(parser.getElementName()));
+  EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.event());
+  EXPECT_EQ(StringPiece("a"), StringPiece(parser.element_name()));
 
-    const size_t depthA = parser.getDepth();
-    ASSERT_TRUE(xml::XmlPullParser::nextChildNode(&parser, depthA));
-    EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.getEvent());
-    EXPECT_EQ(StringPiece("b"), StringPiece(parser.getElementName()));
+  const size_t depth_a = parser.depth();
+  ASSERT_TRUE(xml::XmlPullParser::NextChildNode(&parser, depth_a));
+  EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.event());
+  EXPECT_EQ(StringPiece("b"), StringPiece(parser.element_name()));
 
-    const size_t depthB = parser.getDepth();
-    ASSERT_TRUE(xml::XmlPullParser::nextChildNode(&parser, depthB));
-    EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.getEvent());
-    EXPECT_EQ(StringPiece("c"), StringPiece(parser.getElementName()));
+  const size_t depth_b = parser.depth();
+  ASSERT_TRUE(xml::XmlPullParser::NextChildNode(&parser, depth_b));
+  EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.event());
+  EXPECT_EQ(StringPiece("c"), StringPiece(parser.element_name()));
 
-    ASSERT_TRUE(xml::XmlPullParser::nextChildNode(&parser, depthB));
-    EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.getEvent());
-    EXPECT_EQ(StringPiece("e"), StringPiece(parser.getElementName()));
+  ASSERT_TRUE(xml::XmlPullParser::NextChildNode(&parser, depth_b));
+  EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.event());
+  EXPECT_EQ(StringPiece("e"), StringPiece(parser.element_name()));
 
-    ASSERT_FALSE(xml::XmlPullParser::nextChildNode(&parser, depthOuter));
-    EXPECT_EQ(xml::XmlPullParser::Event::kEndDocument, parser.getEvent());
+  ASSERT_FALSE(xml::XmlPullParser::NextChildNode(&parser, depth_outer));
+  EXPECT_EQ(xml::XmlPullParser::Event::kEndDocument, parser.event());
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/aapt2/xml/XmlUtil.cpp b/tools/aapt2/xml/XmlUtil.cpp
index b570fd7..d00f7f2 100644
--- a/tools/aapt2/xml/XmlUtil.cpp
+++ b/tools/aapt2/xml/XmlUtil.cpp
@@ -14,60 +14,69 @@
  * limitations under the License.
  */
 
-#include "util/Maybe.h"
-#include "util/Util.h"
 #include "xml/XmlUtil.h"
 
 #include <string>
 
+#include "util/Maybe.h"
+#include "util/Util.h"
+
 namespace aapt {
 namespace xml {
 
-std::string buildPackageNamespace(const StringPiece& package, bool privateReference) {
-    std::string result = privateReference ? kSchemaPrivatePrefix : kSchemaPublicPrefix;
-    result.append(package.data(), package.size());
-    return result;
+std::string BuildPackageNamespace(const StringPiece& package,
+                                  bool private_reference) {
+  std::string result =
+      private_reference ? kSchemaPrivatePrefix : kSchemaPublicPrefix;
+  result.append(package.data(), package.size());
+  return result;
 }
 
-Maybe<ExtractedPackage> extractPackageFromNamespace(const std::string& namespaceUri) {
-    if (util::stringStartsWith(namespaceUri, kSchemaPublicPrefix)) {
-        StringPiece schemaPrefix = kSchemaPublicPrefix;
-        StringPiece package = namespaceUri;
-        package = package.substr(schemaPrefix.size(), package.size() - schemaPrefix.size());
-        if (package.empty()) {
-            return {};
-        }
-        return ExtractedPackage{ package.toString(), false /* isPrivate */ };
-
-    } else if (util::stringStartsWith(namespaceUri, kSchemaPrivatePrefix)) {
-        StringPiece schemaPrefix = kSchemaPrivatePrefix;
-        StringPiece package = namespaceUri;
-        package = package.substr(schemaPrefix.size(), package.size() - schemaPrefix.size());
-        if (package.empty()) {
-            return {};
-        }
-        return ExtractedPackage{ package.toString(), true /* isPrivate */ };
-
-    } else if (namespaceUri == kSchemaAuto) {
-        return ExtractedPackage{ std::string(), true /* isPrivate */ };
+Maybe<ExtractedPackage> ExtractPackageFromNamespace(
+    const std::string& namespace_uri) {
+  if (util::StartsWith(namespace_uri, kSchemaPublicPrefix)) {
+    StringPiece schema_prefix = kSchemaPublicPrefix;
+    StringPiece package = namespace_uri;
+    package = package.substr(schema_prefix.size(),
+                             package.size() - schema_prefix.size());
+    if (package.empty()) {
+      return {};
     }
-    return {};
-}
+    return ExtractedPackage{package.ToString(), false /* is_private */};
 
-void transformReferenceFromNamespace(IPackageDeclStack* declStack,
-                                     const StringPiece& localPackage, Reference* inRef) {
-    if (inRef->name) {
-        if (Maybe<ExtractedPackage> transformedPackage =
-                   declStack->transformPackageAlias(inRef->name.value().package, localPackage)) {
-            ExtractedPackage& extractedPackage = transformedPackage.value();
-            inRef->name.value().package = std::move(extractedPackage.package);
-
-            // If the reference was already private (with a * prefix) and the namespace is public,
-            // we keep the reference private.
-            inRef->privateReference |= extractedPackage.privateNamespace;
-        }
+  } else if (util::StartsWith(namespace_uri, kSchemaPrivatePrefix)) {
+    StringPiece schema_prefix = kSchemaPrivatePrefix;
+    StringPiece package = namespace_uri;
+    package = package.substr(schema_prefix.size(),
+                             package.size() - schema_prefix.size());
+    if (package.empty()) {
+      return {};
     }
+    return ExtractedPackage{package.ToString(), true /* is_private */};
+
+  } else if (namespace_uri == kSchemaAuto) {
+    return ExtractedPackage{std::string(), true /* is_private */};
+  }
+  return {};
 }
 
-} // namespace xml
-} // namespace aapt
+void TransformReferenceFromNamespace(IPackageDeclStack* decl_stack,
+                                     const StringPiece& local_package,
+                                     Reference* in_ref) {
+  if (in_ref->name) {
+    if (Maybe<ExtractedPackage> transformed_package =
+            decl_stack->TransformPackageAlias(in_ref->name.value().package,
+                                              local_package)) {
+      ExtractedPackage& extracted_package = transformed_package.value();
+      in_ref->name.value().package = std::move(extracted_package.package);
+
+      // If the reference was already private (with a * prefix) and the
+      // namespace is public,
+      // we keep the reference private.
+      in_ref->private_reference |= extracted_package.private_namespace;
+    }
+  }
+}
+
+}  // namespace xml
+}  // namespace aapt
diff --git a/tools/aapt2/xml/XmlUtil.h b/tools/aapt2/xml/XmlUtil.h
index 96de654..5365401 100644
--- a/tools/aapt2/xml/XmlUtil.h
+++ b/tools/aapt2/xml/XmlUtil.h
@@ -17,11 +17,11 @@
 #ifndef AAPT_XML_XMLUTIL_H
 #define AAPT_XML_XMLUTIL_H
 
+#include <string>
+
 #include "ResourceValues.h"
 #include "util/Maybe.h"
 
-#include <string>
-
 namespace aapt {
 namespace xml {
 
@@ -51,7 +51,7 @@
    * private resources
    * are made visible.
    */
-  bool privateNamespace;
+  bool private_namespace;
 };
 
 /**
@@ -62,8 +62,8 @@
  * Special case: if namespaceUri is http://schemas.android.com/apk/res-auto,
  * returns an empty package name.
  */
-Maybe<ExtractedPackage> extractPackageFromNamespace(
-    const std::string& namespaceUri);
+Maybe<ExtractedPackage> ExtractPackageFromNamespace(
+    const std::string& namespace_uri);
 
 /**
  * Returns an XML Android namespace for the given package of the form:
@@ -74,8 +74,8 @@
  *
  * http://schemas.android.com/apk/prv/res/<package>
  */
-std::string buildPackageNamespace(const StringPiece& package,
-                                  bool privateReference = false);
+std::string BuildPackageNamespace(const StringPiece& package,
+                                  bool private_reference = false);
 
 /**
  * Interface representing a stack of XML namespace declarations. When looking up
@@ -89,20 +89,19 @@
    * Returns an ExtractedPackage struct if the alias given corresponds with a
    * package declaration.
    */
-  virtual Maybe<ExtractedPackage> transformPackageAlias(
-      const StringPiece& alias, const StringPiece& localPackage) const = 0;
+  virtual Maybe<ExtractedPackage> TransformPackageAlias(
+      const StringPiece& alias, const StringPiece& local_package) const = 0;
 };
 
 /**
  * Helper function for transforming the original Reference inRef to a fully
  * qualified reference
  * via the IPackageDeclStack. This will also mark the Reference as private if
- * the namespace of
- * the package declaration was private.
+ * the namespace of the package declaration was private.
  */
-void transformReferenceFromNamespace(IPackageDeclStack* declStack,
-                                     const StringPiece& localPackage,
-                                     Reference* inRef);
+void TransformReferenceFromNamespace(IPackageDeclStack* decl_stack,
+                                     const StringPiece& local_package,
+                                     Reference* in_ref);
 
 }  // namespace xml
 }  // namespace aapt
diff --git a/tools/aapt2/xml/XmlUtil_test.cpp b/tools/aapt2/xml/XmlUtil_test.cpp
index cbeb8bc..5eecc8f 100644
--- a/tools/aapt2/xml/XmlUtil_test.cpp
+++ b/tools/aapt2/xml/XmlUtil_test.cpp
@@ -14,38 +14,46 @@
  * limitations under the License.
  */
 
-#include "test/Test.h"
 #include "xml/XmlUtil.h"
 
+#include "test/Test.h"
+
 namespace aapt {
 
 TEST(XmlUtilTest, ExtractPackageFromNamespace) {
-    AAPT_ASSERT_FALSE(xml::extractPackageFromNamespace("com.android"));
-    AAPT_ASSERT_FALSE(xml::extractPackageFromNamespace("http://schemas.android.com/apk"));
-    AAPT_ASSERT_FALSE(xml::extractPackageFromNamespace("http://schemas.android.com/apk/res"));
-    AAPT_ASSERT_FALSE(xml::extractPackageFromNamespace("http://schemas.android.com/apk/res/"));
-    AAPT_ASSERT_FALSE(xml::extractPackageFromNamespace("http://schemas.android.com/apk/prv/res/"));
+  AAPT_ASSERT_FALSE(xml::ExtractPackageFromNamespace("com.android"));
+  AAPT_ASSERT_FALSE(
+      xml::ExtractPackageFromNamespace("http://schemas.android.com/apk"));
+  AAPT_ASSERT_FALSE(
+      xml::ExtractPackageFromNamespace("http://schemas.android.com/apk/res"));
+  AAPT_ASSERT_FALSE(
+      xml::ExtractPackageFromNamespace("http://schemas.android.com/apk/res/"));
+  AAPT_ASSERT_FALSE(xml::ExtractPackageFromNamespace(
+      "http://schemas.android.com/apk/prv/res/"));
 
-    Maybe<xml::ExtractedPackage> p =
-            xml::extractPackageFromNamespace("http://schemas.android.com/apk/res/a");
-    AAPT_ASSERT_TRUE(p);
-    EXPECT_EQ(std::string("a"), p.value().package);
-    EXPECT_FALSE(p.value().privateNamespace);
+  Maybe<xml::ExtractedPackage> p =
+      xml::ExtractPackageFromNamespace("http://schemas.android.com/apk/res/a");
+  AAPT_ASSERT_TRUE(p);
+  EXPECT_EQ(std::string("a"), p.value().package);
+  EXPECT_FALSE(p.value().private_namespace);
 
-    p = xml::extractPackageFromNamespace("http://schemas.android.com/apk/prv/res/android");
-    AAPT_ASSERT_TRUE(p);
-    EXPECT_EQ(std::string("android"), p.value().package);
-    EXPECT_TRUE(p.value().privateNamespace);
+  p = xml::ExtractPackageFromNamespace(
+      "http://schemas.android.com/apk/prv/res/android");
+  AAPT_ASSERT_TRUE(p);
+  EXPECT_EQ(std::string("android"), p.value().package);
+  EXPECT_TRUE(p.value().private_namespace);
 
-    p = xml::extractPackageFromNamespace("http://schemas.android.com/apk/prv/res/com.test");
-    AAPT_ASSERT_TRUE(p);
-    EXPECT_EQ(std::string("com.test"), p.value().package);
-    EXPECT_TRUE(p.value().privateNamespace);
+  p = xml::ExtractPackageFromNamespace(
+      "http://schemas.android.com/apk/prv/res/com.test");
+  AAPT_ASSERT_TRUE(p);
+  EXPECT_EQ(std::string("com.test"), p.value().package);
+  EXPECT_TRUE(p.value().private_namespace);
 
-    p = xml::extractPackageFromNamespace("http://schemas.android.com/apk/res-auto");
-    AAPT_ASSERT_TRUE(p);
-    EXPECT_EQ(std::string(), p.value().package);
-    EXPECT_TRUE(p.value().privateNamespace);
+  p = xml::ExtractPackageFromNamespace(
+      "http://schemas.android.com/apk/res-auto");
+  AAPT_ASSERT_TRUE(p);
+  EXPECT_EQ(std::string(), p.value().package);
+  EXPECT_TRUE(p.value().private_namespace);
 }
 
-} // namespace aapt
+}  // namespace aapt
diff --git a/tools/bit/Android.mk b/tools/bit/Android.mk
new file mode 100644
index 0000000..1c1291f
--- /dev/null
+++ b/tools/bit/Android.mk
@@ -0,0 +1,46 @@
+#
+# 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.
+#
+LOCAL_PATH:= $(call my-dir)
+
+# ==========================================================
+# Build the host executable: protoc-gen-javastream
+# ==========================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := bit
+
+# This tool doesn't build on darwin.
+LOCAL_MODULE_HOST_OS := linux
+
+LOCAL_SRC_FILES := \
+    aapt.cpp \
+    adb.cpp \
+    command.cpp \
+    main.cpp \
+    make.cpp \
+    print.cpp \
+    util.cpp
+
+LOCAL_STATIC_LIBRARIES := \
+    libexpat \
+    libinstrumentation \
+    libjsoncpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libprotobuf-cpp-full
+
+include $(BUILD_HOST_EXECUTABLE)
+
diff --git a/tools/bit/aapt.cpp b/tools/bit/aapt.cpp
new file mode 100644
index 0000000..961b47c
--- /dev/null
+++ b/tools/bit/aapt.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2016 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 "aapt.h"
+
+#include "command.h"
+#include "print.h"
+#include "util.h"
+
+#include <regex>
+
+const regex NS_REGEX("( *)N: ([^=]+)=(.*)");
+const regex ELEMENT_REGEX("( *)E: ([^ ]+) \\(line=(\\d+)\\)");
+const regex ATTR_REGEX("( *)A: ([^\\(=]+)[^=]*=\"([^\"]+)\".*");
+
+const string ANDROID_NS("http://schemas.android.com/apk/res/android");
+
+bool
+Apk::HasActivity(const string& className)
+{
+    string fullClassName = full_class_name(package, className);
+    const size_t N = activities.size();
+    for (size_t i=0; i<N; i++) {
+        if (activities[i] == fullClassName) {
+            return true;
+        }
+    }
+    return false;
+}
+
+struct Attribute {
+    string ns;
+    string name;
+    string value;
+};
+
+struct Element {
+    Element* parent;
+    string ns;
+    string name;
+    int lineno;
+    vector<Attribute> attributes;
+    vector<Element*> children;
+
+    /**
+     * Indentation in the xmltree dump. Might not be equal to the distance
+     * from the root because namespace rows (scopes) have their own indentation.
+     */
+    int depth;
+
+    Element();
+    ~Element();
+
+    string GetAttr(const string& ns, const string& name) const;
+    void FindElements(const string& ns, const string& name, vector<Element*>* result, bool recurse);
+    
+};
+
+Element::Element()
+{
+}
+
+Element::~Element()
+{
+    const size_t N = children.size();
+    for (size_t i=0; i<N; i++) {
+        delete children[i];
+    }
+}
+
+string
+Element::GetAttr(const string& ns, const string& name) const
+{
+    const size_t N = attributes.size();
+    for (size_t i=0; i<N; i++) {
+        const Attribute& attr = attributes[i];
+        if (attr.ns == ns && attr.name == name) {
+            return attr.value;
+        }
+    }
+    return string();
+}
+
+void
+Element::FindElements(const string& ns, const string& name, vector<Element*>* result, bool recurse)
+{
+    const size_t N = children.size();
+    for (size_t i=0; i<N; i++) {
+        Element* child = children[i];
+        if (child->ns == ns && child->name == name) {
+            result->push_back(child);
+        }
+        if (recurse) {
+            child->FindElements(ns, name, result, recurse);
+        }
+    }
+}
+
+struct Scope {
+    Scope* parent;
+    int depth;
+    map<string,string> namespaces;
+
+    Scope(Scope* parent, int depth);
+};
+
+Scope::Scope(Scope* p, int d)
+    :parent(p),
+     depth(d)
+{
+     if (p != NULL) {
+         namespaces = p->namespaces;
+     }
+}
+
+
+string
+full_class_name(const string& packageName, const string& className)
+{
+    if (className.length() == 0) {
+        return "";
+    }
+    if (className[0] == '.') {
+        return packageName + className;
+    }
+    if (className.find('.') == string::npos) {
+        return packageName + "." + className;
+    }
+    return className;
+}
+
+string
+pretty_component_name(const string& packageName, const string& className)
+{
+    if (starts_with(packageName, className)) {
+        size_t pn = packageName.length();
+        size_t cn = className.length();
+        if (cn > pn && className[pn] == '.') {
+            return packageName + "/" + string(className, pn, string::npos);
+        }
+    }
+    return packageName + "/" + className;
+}
+
+int
+inspect_apk(Apk* apk, const string& filename)
+{
+    // Load the manifest xml
+    Command cmd("aapt");
+    cmd.AddArg("dump");
+    cmd.AddArg("xmltree");
+    cmd.AddArg(filename);
+    cmd.AddArg("AndroidManifest.xml");
+
+    int err;
+
+    string output = get_command_output(cmd, &err, false);
+    check_error(err);
+
+    // Parse the manifest xml
+    Scope* scope = new Scope(NULL, -1);
+    Element* root = NULL;
+    Element* current = NULL;
+    vector<string> lines;
+    split_lines(&lines, output);
+    for (size_t i=0; i<lines.size(); i++) {
+        const string& line = lines[i];
+        smatch match;
+        if (regex_match(line, match, NS_REGEX)) {
+            int depth = match[1].length() / 2;
+            while (depth < scope->depth) {
+                Scope* tmp = scope;
+                scope = scope->parent;
+                delete tmp;
+            }
+            scope = new Scope(scope, depth);
+            scope->namespaces[match[2]] = match[3];
+        } else if (regex_match(line, match, ELEMENT_REGEX)) {
+            Element* element = new Element();
+
+            string str = match[2];
+            size_t colon = str.find(':');
+            if (colon == string::npos) {
+                element->name = str;
+            } else {
+                element->ns = scope->namespaces[string(str, 0, colon)];
+                element->name.assign(str, colon+1, string::npos);
+            }
+            element->lineno = atoi(match[3].str().c_str());
+            element->depth = match[1].length() / 2;
+
+            if (root == NULL) {
+                current = element;
+                root = element;
+            } else {
+                while (element->depth <= current->depth && current->parent != NULL) {
+                    current = current->parent;
+                }
+                element->parent = current;
+                current->children.push_back(element);
+                current = element;
+            }
+        } else if (regex_match(line, match, ATTR_REGEX)) {
+            if (current != NULL) {
+                Attribute attr;
+                string str = match[2];
+                size_t colon = str.find(':');
+                if (colon == string::npos) {
+                    attr.name = str;
+                } else {
+                    attr.ns = scope->namespaces[string(str, 0, colon)];
+                    attr.name.assign(str, colon+1, string::npos);
+                }
+                attr.value = match[3];
+                current->attributes.push_back(attr);
+            }
+        }
+    }
+    while (scope != NULL) {
+        Scope* tmp = scope;
+        scope = scope->parent;
+        delete tmp;
+    }
+
+    // Package name
+    apk->package = root->GetAttr("", "package");
+    if (apk->package.size() == 0) {
+        print_error("%s:%d: Manifest root element doesn't contain a package attribute",
+                filename.c_str(), root->lineno);
+        delete root;
+        return 1;
+    }
+
+    // Instrumentation runner
+    vector<Element*> instrumentation;
+    root->FindElements("", "instrumentation", &instrumentation, true);
+    if (instrumentation.size() > 0) {
+        // TODO: How could we deal with multiple instrumentation tags?
+        // We'll just pick the first one.
+        apk->runner = instrumentation[0]->GetAttr(ANDROID_NS, "name");
+    }
+
+    // Activities
+    vector<Element*> activities;
+    root->FindElements("", "activity", &activities, true);
+    for (size_t i=0; i<activities.size(); i++) {
+        string name = activities[i]->GetAttr(ANDROID_NS, "name");
+        if (name.size() == 0) {
+            continue;
+        }
+        apk->activities.push_back(full_class_name(apk->package, name));
+    }
+
+    delete root;
+    return 0;
+}
+
diff --git a/tools/bit/aapt.h b/tools/bit/aapt.h
new file mode 100644
index 0000000..6aeb03f
--- /dev/null
+++ b/tools/bit/aapt.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 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 AAPT_H
+#define AAPT_H
+
+#include <string>
+#include <vector>
+
+using namespace std;
+
+struct Apk
+{
+    string package;
+    string runner;
+    vector<string> activities;
+
+    bool HasActivity(const string& className);
+};
+
+string full_class_name(const string& packageName, const string& className);
+string pretty_component_name(const string& packageName, const string& className);
+
+int inspect_apk(Apk* apk, const string& filename);
+
+#endif // AAPT_H
diff --git a/tools/bit/adb.cpp b/tools/bit/adb.cpp
new file mode 100644
index 0000000..0c8424d
--- /dev/null
+++ b/tools/bit/adb.cpp
@@ -0,0 +1,463 @@
+/*
+ * Copyright (C) 2016 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 "adb.h"
+
+#include "command.h"
+#include "print.h"
+#include "util.h"
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <limits.h>
+
+#include <iostream>
+#include <istream>
+#include <streambuf>
+
+using namespace std;
+
+struct Buffer: public streambuf
+{
+    Buffer(char* begin, size_t size);
+};
+
+Buffer::Buffer(char* begin, size_t size)
+{
+    this->setg(begin, begin, begin + size);
+}
+
+int
+run_adb(const char* first, ...)
+{
+    Command cmd("adb");
+
+    if (first == NULL) {
+        return 0;
+    }
+
+    cmd.AddArg(first);
+
+    va_list args;
+    va_start(args, first);
+    while (true) {
+        const char* arg = va_arg(args, char*);
+        if (arg == NULL) {
+            break;
+        }
+        cmd.AddArg(arg);
+    }
+    va_end(args);
+
+    return run_command(cmd);
+}
+
+string
+get_system_property(const string& name, int* err)
+{
+    Command cmd("adb");
+    cmd.AddArg("shell");
+    cmd.AddArg("getprop");
+    cmd.AddArg(name);
+
+    return trim(get_command_output(cmd, err, false));
+}
+
+
+static uint64_t
+read_varint(int fd, int* err, bool* done)
+{
+    uint32_t bits = 0;
+    uint64_t result = 0;
+    while (true) {
+        uint8_t byte;
+        ssize_t amt = read(fd, &byte, 1);
+        if (amt == 0) {
+            *done = true;
+            return result;
+        } else if (amt < 0) {
+            return *err = errno;
+        }
+        result |= uint64_t(byte & 0x7F) << bits;
+        if ((byte & 0x80) == 0) {
+            return result;
+        }
+        bits += 7;
+        if (bits > 64) {
+            *err = -1;
+            return 0;
+        }
+    }
+}
+
+static char*
+read_sized_buffer(int fd, int* err, size_t* resultSize)
+{
+    bool done = false;
+    uint64_t size = read_varint(fd, err, &done);
+    if (*err != 0 || done) {
+        return NULL;
+    }
+    if (size == 0) {
+        *resultSize = 0;
+        return NULL;
+    }
+    // 10 MB seems like a reasonable limit.
+    if (size > 10*1024*1024) {
+        print_error("result buffer too large: %llu", size);
+        return NULL;
+    }
+    char* buf = (char*)malloc(size);
+    if (buf == NULL) {
+        print_error("Can't allocate a buffer of size for test results: %llu", size);
+        return NULL;
+    }
+    int pos = 0;
+    while (size - pos > 0) {
+        ssize_t amt = read(fd, buf+pos, size-pos);
+        if (amt == 0) {
+            // early end of pipe
+            print_error("Early end of pipe.");
+            *err = -1;
+            free(buf);
+            return NULL;
+        } else if (amt < 0) {
+            // error
+            *err = errno;
+            free(buf);
+            return NULL;
+        }
+        pos += amt;
+    }
+    *resultSize = (size_t)size;
+    return buf;
+}
+
+static int
+read_sized_proto(int fd, Message* message)
+{
+    int err = 0;
+    size_t size;
+    char* buf = read_sized_buffer(fd, &err, &size);
+    if (err != 0) {
+        if (buf != NULL) {
+            free(buf);
+        }
+        return err;
+    } else if (size == 0) {
+        if (buf != NULL) {
+            free(buf);
+        }
+        return 0;
+    } else if (buf == NULL) {
+        return -1;
+    }
+    Buffer buffer(buf, size);
+    istream in(&buffer);
+
+    err = message->ParseFromIstream(&in) ? 0 : -1;
+
+    free(buf);
+    return err;
+}
+
+static int
+skip_bytes(int fd, ssize_t size, char* scratch, int scratchSize)
+{
+    while (size > 0) {
+        ssize_t amt = size < scratchSize ? size : scratchSize;
+        fprintf(stderr, "skipping %lu/%ld bytes\n", size, amt);
+        amt = read(fd, scratch, amt);
+        if (amt == 0) {
+            // early end of pipe
+            print_error("Early end of pipe.");
+            return -1;
+        } else if (amt < 0) {
+            // error
+            return errno;
+        }
+        size -= amt;
+    }
+    return 0;
+}
+
+static int
+skip_unknown_field(int fd, uint64_t tag, char* scratch, int scratchSize) {
+    bool done;
+    int err;
+    uint64_t size;
+    switch (tag & 0x7) {
+        case 0: // varint
+            read_varint(fd, &err, &done);
+            if (err != 0) {
+                return err;
+            } else if (done) {
+                return -1;
+            } else {
+                return 0;
+            }
+        case 1:
+            return skip_bytes(fd, 8, scratch, scratchSize);
+        case 2:
+            size = read_varint(fd, &err, &done);
+            if (err != 0) {
+                return err;
+            } else if (done) {
+                return -1;
+            }
+            if (size > INT_MAX) {
+                // we'll be here a long time but this keeps it from overflowing
+                return -1;
+            }
+            return skip_bytes(fd, (ssize_t)size, scratch, scratchSize);
+        case 5:
+            return skip_bytes(fd, 4, scratch, scratchSize);
+        default:
+            print_error("bad wire type for tag 0x%lx\n", tag);
+            return -1;
+    }
+}
+
+static int
+read_instrumentation_results(int fd, char* scratch, int scratchSize,
+        InstrumentationCallbacks* callbacks)
+{
+    bool done = false;
+    int err = 0;
+    string result;
+    while (true) {
+        uint64_t tag = read_varint(fd, &err, &done);
+        if (done) {
+            // Done reading input (this is the only place that a stream end isn't an error).
+            return 0;
+        } else if (err != 0) {
+            return err;
+        } else if (tag == 0xa) { // test_status
+            TestStatus status;
+            err = read_sized_proto(fd, &status);
+            if (err != 0) {
+                return err;
+            }
+            callbacks->OnTestStatus(status);
+        } else if (tag == 0x12) { // session_status
+            SessionStatus status;
+            err = read_sized_proto(fd, &status);
+            if (err != 0) {
+                return err;
+            }
+            callbacks->OnSessionStatus(status);
+        } else {
+            err = skip_unknown_field(fd, tag, scratch, scratchSize);
+            if (err != 0) {
+                return err;
+            }
+        }
+    }
+    return 0;
+}
+
+int
+run_instrumentation_test(const string& packageName, const string& runner, const string& className,
+        InstrumentationCallbacks* callbacks)
+{
+    Command cmd("adb");
+    cmd.AddArg("shell");
+    cmd.AddArg("am");
+    cmd.AddArg("instrument");
+    cmd.AddArg("-w");
+    cmd.AddArg("-m");
+    if (className.length() > 0) {
+        cmd.AddArg("-e");
+        cmd.AddArg("class");
+        cmd.AddArg(className);
+    }
+    cmd.AddArg(packageName + "/" + runner);
+
+    print_command(cmd);
+
+    int fds[2];
+    pipe(fds);
+
+    pid_t pid = fork();
+
+    if (pid == -1) {
+        // fork error
+        return errno;
+    } else if (pid == 0) {
+        // child
+        while ((dup2(fds[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
+        close(fds[1]);
+        close(fds[0]);
+        const char* prog = cmd.GetProg();
+        char* const* argv = cmd.GetArgv();
+        char* const* env = cmd.GetEnv();
+        exec_with_path_search(prog, argv, env);
+        print_error("Unable to run command: %s", prog);
+        exit(1);
+    } else {
+        // parent
+        close(fds[1]);
+        string result;
+        const int size = 16*1024;
+        char* buf = (char*)malloc(size);
+        int err = read_instrumentation_results(fds[0], buf, size, callbacks);
+        free(buf);
+        int status;
+        waitpid(pid, &status, 0);
+        if (err != 0) {
+            return err;
+        }
+        if (WIFEXITED(status)) {
+            return WEXITSTATUS(status);
+        } else {
+            return -1;
+        }
+    }
+}
+
+/**
+ * Get the second to last bundle in the args list. Stores the last name found
+ * in last. If the path is not found or if the args list is empty, returns NULL.
+ */
+static const ResultsBundleEntry *
+find_penultimate_entry(const ResultsBundle& bundle, va_list args)
+{
+    const ResultsBundle* b = &bundle;
+    const char* arg = va_arg(args, char*);
+    while (arg) {
+        string last = arg;
+        arg = va_arg(args, char*);
+        bool found = false;
+        for (int i=0; i<b->entries_size(); i++) {
+            const ResultsBundleEntry& e = b->entries(i);
+            if (e.key() == last) {
+                if (arg == NULL) {
+                    return &e;
+                } else if (e.has_value_bundle()) {
+                    b = &e.value_bundle();
+                    found = true;
+                }
+            }
+        }
+        if (!found) {
+            return NULL;
+        }
+        if (arg == NULL) {
+            return NULL;
+        }
+    }
+    return NULL;
+}
+
+string
+get_bundle_string(const ResultsBundle& bundle, bool* found, ...)
+{
+    va_list args;
+    va_start(args, found);
+    const ResultsBundleEntry* entry = find_penultimate_entry(bundle, args);
+    va_end(args);
+    if (entry == NULL) {
+        *found = false;
+        return string();
+    }
+    if (entry->has_value_string()) {
+        *found = true;
+        return entry->value_string();
+    }
+    *found = false;
+    return string();
+}
+
+int32_t
+get_bundle_int(const ResultsBundle& bundle, bool* found, ...)
+{
+    va_list args;
+    va_start(args, found);
+    const ResultsBundleEntry* entry = find_penultimate_entry(bundle, args);
+    va_end(args);
+    if (entry == NULL) {
+        *found = false;
+        return 0;
+    }
+    if (entry->has_value_int()) {
+        *found = true;
+        return entry->value_int();
+    }
+    *found = false;
+    return 0;
+}
+
+float
+get_bundle_float(const ResultsBundle& bundle, bool* found, ...)
+{
+    va_list args;
+    va_start(args, found);
+    const ResultsBundleEntry* entry = find_penultimate_entry(bundle, args);
+    va_end(args);
+    if (entry == NULL) {
+        *found = false;
+        return 0;
+    }
+    if (entry->has_value_float()) {
+        *found = true;
+        return entry->value_float();
+    }
+    *found = false;
+    return 0;
+}
+
+double
+get_bundle_double(const ResultsBundle& bundle, bool* found, ...)
+{
+    va_list args;
+    va_start(args, found);
+    const ResultsBundleEntry* entry = find_penultimate_entry(bundle, args);
+    va_end(args);
+    if (entry == NULL) {
+        *found = false;
+        return 0;
+    }
+    if (entry->has_value_double()) {
+        *found = true;
+        return entry->value_double();
+    }
+    *found = false;
+    return 0;
+}
+
+int64_t
+get_bundle_long(const ResultsBundle& bundle, bool* found, ...)
+{
+    va_list args;
+    va_start(args, found);
+    const ResultsBundleEntry* entry = find_penultimate_entry(bundle, args);
+    va_end(args);
+    if (entry == NULL) {
+        *found = false;
+        return 0;
+    }
+    if (entry->has_value_long()) {
+        *found = true;
+        return entry->value_long();
+    }
+    *found = false;
+    return 0;
+}
+
diff --git a/tools/bit/adb.h b/tools/bit/adb.h
new file mode 100644
index 0000000..dca80c8
--- /dev/null
+++ b/tools/bit/adb.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 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 ADB_H
+#define ADB_H
+
+#include "instrumentation_data.pb.h"
+
+#include <string>
+
+using namespace android::am;
+using namespace google::protobuf;
+using namespace std;
+
+class InstrumentationCallbacks {
+public:
+    virtual void OnTestStatus(TestStatus& status) = 0;
+    virtual void OnSessionStatus(SessionStatus& status) = 0;
+};
+
+int run_adb(const char* first, ...);
+
+string get_system_property(const string& name, int* err);
+
+int run_instrumentation_test(const string& packageName, const string& runner,
+        const string& className, InstrumentationCallbacks* callbacks);
+
+string get_bundle_string(const ResultsBundle& bundle, bool* found, ...);
+int32_t get_bundle_int(const ResultsBundle& bundle, bool* found, ...);
+float get_bundle_float(const ResultsBundle& bundle, bool* found, ...);
+double get_bundle_double(const ResultsBundle& bundle, bool* found, ...);
+int64_t get_bundle_long(const ResultsBundle& bundle, bool* found, ...);
+
+#endif // ADB_H
diff --git a/tools/bit/command.cpp b/tools/bit/command.cpp
new file mode 100644
index 0000000..9a8449b
--- /dev/null
+++ b/tools/bit/command.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2016 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 "command.h"
+
+#include "print.h"
+#include "util.h"
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+extern char **environ;
+
+Command::Command(const string& prog)
+    :prog(prog)
+{
+}
+
+Command::~Command()
+{
+}
+
+void
+Command::AddArg(const string& arg)
+{
+    args.push_back(arg);
+}
+
+void
+Command::AddEnv(const string& name, const string& value)
+{
+    env[name] = value;
+}
+
+const char*
+Command::GetProg() const
+{
+    return prog.c_str();
+}
+
+char *const *
+Command::GetArgv() const
+{
+    const int N = args.size();
+    char** result = (char**)malloc(sizeof(char*)*(N+2));
+    result[0] = strdup(prog.c_str());
+    for (int i=0; i<N; i++) {
+        result[i+1] = strdup(args[i].c_str());
+    }
+    result[N+1] = 0;
+    return result;
+}
+
+char *const *
+Command::GetEnv() const
+{
+    map<string,string> copy;
+    for (const char** p=(const char**)environ; *p != NULL; p++) {
+        char* name = strdup(*p);
+        char* value = strchr(name, '=');
+        *value = '\0';
+        value++;
+        copy[name] = value;
+        free(name);
+    }
+    for (map<string,string>::const_iterator it=env.begin(); it!=env.end(); it++) {
+        copy[it->first] = it->second;
+    }
+    char** result = (char**)malloc(sizeof(char*)*(copy.size()+1));
+    char** row = result;
+    for (map<string,string>::const_iterator it=copy.begin(); it!=copy.end(); it++) {
+        *row = (char*)malloc(it->first.size() + it->second.size() + 2);
+        strcpy(*row, it->first.c_str());
+        strcat(*row, "=");
+        strcat(*row, it->second.c_str());
+        row++;
+    }
+    *row = NULL;
+    return result;
+}
+
+string
+get_command_output(const Command& command, int* err, bool quiet)
+{
+    if (!quiet) {
+        print_command(command);
+    }
+
+    int fds[2];
+    pipe(fds);
+
+    pid_t pid = fork();
+
+    if (pid == -1) {
+        // fork error
+        *err = errno;
+        return string();
+    } else if (pid == 0) {
+        // child
+        while ((dup2(fds[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
+        close(fds[1]);
+        close(fds[0]);
+        const char* prog = command.GetProg();
+        char* const* argv = command.GetArgv();
+        char* const* env = command.GetEnv();
+        exec_with_path_search(prog, argv, env);
+        if (!quiet) {
+            print_error("Unable to run command: %s", prog);
+        }
+        exit(1);
+    } else {
+        // parent
+        close(fds[1]);
+        string result;
+        const int size = 16*1024;
+        char* buf = (char*)malloc(size);
+        while (true) {
+            ssize_t amt = read(fds[0], buf, size);
+            if (amt <= 0) {
+                break;
+            } else if (amt > 0) {
+                result.append(buf, amt);
+            }
+        }
+        free(buf);
+        int status;
+        waitpid(pid, &status, 0);
+        if (WIFEXITED(status)) {
+            *err = WEXITSTATUS(status);
+            return result;
+        } else {
+            *err = -1;
+            return string();
+        }
+    }
+}
+
+
+int
+run_command(const Command& command)
+{
+    print_command(command);
+
+    pid_t pid = fork();
+
+    if (pid == -1) {
+        // fork error
+        return errno;
+    } else if (pid == 0) {
+        // child
+        const char* prog = command.GetProg();
+        char* const* argv = command.GetArgv();
+        char* const* env = command.GetEnv();
+        exec_with_path_search(prog, argv, env);
+        print_error("Unable to run command: %s", prog);
+        exit(1);
+    } else {
+        // parent
+        int status;
+        waitpid(pid, &status, 0);
+        if (WIFEXITED(status)) {
+            return WEXITSTATUS(status);
+        } else {
+            return -1;
+        }
+    }
+}
+
+int
+exec_with_path_search(const char* prog, char const* const* argv, char const* const* envp)
+{
+    if (prog[0] == '/') {
+        return execve(prog, (char*const*)argv, (char*const*)envp);
+    } else {
+        char* pathEnv = strdup(getenv("PATH"));
+        if (pathEnv == NULL) {
+            return 1;
+        }
+        char* dir = pathEnv;
+        while (dir) {
+            char* next = strchr(dir, ':');
+            if (next != NULL) {
+                *next = '\0';
+                next++;
+            }
+            if (dir[0] == '/') {
+                struct stat st;
+                string executable = string(dir) + "/" + prog;
+                if (stat(executable.c_str(), &st) == 0) {
+                    execve(executable.c_str(), (char*const*)argv, (char*const*)envp);
+                }
+            }
+            dir = next;
+        }
+        free(pathEnv);
+        return 1;
+    }
+}
+
diff --git a/tools/bit/command.h b/tools/bit/command.h
new file mode 100644
index 0000000..fb44900
--- /dev/null
+++ b/tools/bit/command.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 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 COMMAND_H
+#define COMMAND_H
+
+#include <map>
+#include <string>
+#include <vector>
+
+using namespace std;
+
+struct Command
+{
+    Command(const string& prog);
+    ~Command();
+
+    void AddArg(const string& arg);
+    void AddEnv(const string& name, const string& value);
+
+    const char* GetProg() const;
+    char* const* GetArgv() const;
+    char* const* GetEnv() const;
+
+    string GetCommandline() const;
+
+    string prog;
+    vector<string> args;
+    map<string,string> env;
+};
+
+/**
+ * Run the command and collect stdout.
+ * Returns the exit code.
+ */
+string get_command_output(const Command& command, int* err, bool quiet=false);
+
+/**
+ * Run the command.
+ * Returns the exit code.
+ */
+int run_command(const Command& command);
+
+// Mac OS doesn't have execvpe. This is the same as execvpe.
+int exec_with_path_search(const char* prog, char const* const* argv, char const* const* envp);
+
+#endif // COMMAND_H
+
diff --git a/tools/bit/main.cpp b/tools/bit/main.cpp
new file mode 100644
index 0000000..4974a44
--- /dev/null
+++ b/tools/bit/main.cpp
@@ -0,0 +1,984 @@
+/*
+ * Copyright (C) 2016 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 "aapt.h"
+#include "adb.h"
+#include "make.h"
+#include "print.h"
+#include "util.h"
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <google/protobuf/stubs/common.h>
+
+using namespace std;
+
+/**
+ * An entry from the command line for something that will be built, installed,
+ * and/or tested.
+ */
+struct Target {
+    bool build;
+    bool install;
+    bool test;
+    string pattern;
+    string name;
+    vector<string> actions;
+    Module module;
+
+    int testActionCount;
+
+    int testPassCount;
+    int testFailCount;
+    bool actionsWithNoTests;
+
+    Target(bool b, bool i, bool t, const string& p);
+};
+
+Target::Target(bool b, bool i, bool t, const string& p)
+    :build(b),
+     install(i),
+     test(t),
+     pattern(p),
+     testActionCount(0),
+     testPassCount(0),
+     testFailCount(0),
+     actionsWithNoTests(false)
+{
+}
+
+/**
+ * Command line options.
+ */
+struct Options {
+    // For help
+    bool runHelp;
+
+    // For tab completion
+    bool runTab;
+    string tabPattern;
+
+    // For build/install/test
+    bool reboot;
+    vector<Target*> targets;
+
+    Options();
+    ~Options();
+};
+
+Options::Options()
+    :runHelp(false),
+     runTab(false),
+     reboot(false),
+     targets()
+{
+}
+
+Options::~Options()
+{
+}
+
+struct InstallApk
+{
+    TrackedFile file;
+    bool alwaysInstall;
+    bool installed;
+
+    InstallApk();
+    InstallApk(const InstallApk& that);
+    InstallApk(const string& filename, bool always);
+    ~InstallApk() {};
+};
+
+InstallApk::InstallApk()
+{
+}
+
+InstallApk::InstallApk(const InstallApk& that)
+    :file(that.file),
+     alwaysInstall(that.alwaysInstall),
+     installed(that.installed)
+{
+}
+
+InstallApk::InstallApk(const string& filename, bool always)
+    :file(filename),
+     alwaysInstall(always),
+     installed(false)
+{
+}
+
+
+/**
+ * Record for an test that is going to be launched.
+ */
+struct TestAction {
+    TestAction();
+
+    // The package name from the apk
+    string packageName;
+
+    // The test runner class
+    string runner;
+
+    // The test class, or none if all tests should be run
+    string className;
+
+    // The original target that requested this action
+    Target* target;
+
+    // The number of tests that passed
+    int passCount;
+
+    // The number of tests that failed
+    int failCount;
+};
+
+TestAction::TestAction()
+    :passCount(0),
+     failCount(0)
+{
+}
+
+/**
+ * Record for an activity that is going to be launched.
+ */
+struct ActivityAction {
+    // The package name from the apk
+    string packageName;
+
+    // The test class, or none if all tests should be run
+    string className;
+};
+
+/**
+ * Callback class for the am instrument command.
+ */
+class TestResults: public InstrumentationCallbacks
+{
+public:
+    virtual void OnTestStatus(TestStatus& status);
+    virtual void OnSessionStatus(SessionStatus& status);
+
+    /**
+     * Set the TestAction that the tests are for.
+     * It will be updated with statistics as the tests run.
+     */
+    void SetCurrentAction(TestAction* action);
+
+private:
+    TestAction* m_currentAction;
+};
+
+void
+TestResults::OnTestStatus(TestStatus& status)
+{
+    bool found;
+//    printf("OnTestStatus\n");
+//    status.PrintDebugString();
+    int32_t resultCode = status.has_results() ? status.result_code() : 0;
+
+    if (!status.has_results()) {
+        return;
+    }
+    const ResultsBundle &results = status.results();
+
+    int32_t currentTestNum = get_bundle_int(results, &found, "current", NULL);
+    if (!found) {
+        currentTestNum = -1;
+    }
+
+    int32_t testCount = get_bundle_int(results, &found, "numtests", NULL);
+    if (!found) {
+        testCount = -1;
+    }
+
+    string className = get_bundle_string(results, &found, "class", NULL);
+    if (!found) {
+        return;
+    }
+
+    string testName = get_bundle_string(results, &found, "test", NULL);
+    if (!found) {
+        return;
+    }
+
+    if (resultCode == 0) {
+        // test passed
+        m_currentAction->passCount++;
+        m_currentAction->target->testPassCount++;
+    } else if (resultCode == 1) {
+        // test starting
+        ostringstream line;
+        line << "Running";
+        if (currentTestNum > 0) {
+            line << ": " << currentTestNum;
+            if (testCount > 0) {
+                line << " of " << testCount;
+            }
+        }
+        line << ": " << m_currentAction->target->name << ':' << className << "\\#" << testName;
+        print_one_line("%s", line.str().c_str());
+    } else if (resultCode == -2) {
+        // test failed
+        m_currentAction->failCount++;
+        m_currentAction->target->testFailCount++;
+        printf("%s\n%sFailed: %s:%s\\#%s%s\n", g_escapeClearLine, g_escapeRedBold,
+                m_currentAction->target->name.c_str(), className.c_str(),
+                testName.c_str(), g_escapeEndColor);
+
+        string stack = get_bundle_string(results, &found, "stack", NULL);
+        if (found) {
+            printf("%s\n", stack.c_str());
+        }
+    }
+}
+
+void
+TestResults::OnSessionStatus(SessionStatus& /*status*/)
+{
+    //status.PrintDebugString();
+}
+
+void
+TestResults::SetCurrentAction(TestAction* action)
+{
+    m_currentAction = action;
+}
+
+/**
+ * Prints the usage statement / help text.
+ */
+static void
+print_usage(FILE* out) {
+    fprintf(out, "usage: bit OPTIONS PATTERN\n");
+    fprintf(out, "\n");
+    fprintf(out, "  Build, sync and test android code.\n");
+    fprintf(out, "\n");
+    fprintf(out, "  The -b -i and -t options allow you to specify which phases\n");
+    fprintf(out, "  you want to run. If none of those options are given, then\n");
+    fprintf(out, "  all phases are run. If any of these options are provided\n");
+    fprintf(out, "  then only the listed phases are run.\n");
+    fprintf(out, "\n");
+    fprintf(out, "  OPTIONS\n");
+    fprintf(out, "  -b     Run a build\n");
+    fprintf(out, "  -i     Install the targets\n");
+    fprintf(out, "  -t     Run the tests\n");
+    fprintf(out, "\n");
+    fprintf(out, "  -r     If the runtime needs to be restarted, do a full reboot\n");
+    fprintf(out, "         instead\n");
+    fprintf(out, "\n");
+    fprintf(out, "  PATTERN\n");
+    fprintf(out, "  One or more targets to build, install and test. The target\n");
+    fprintf(out, "  names are the names that appear in the LOCAL_MODULE or\n");
+    fprintf(out, "  LOCAL_PACKAGE_NAME variables in Android.mk or Android.bp files.\n");
+    fprintf(out, "\n");
+    fprintf(out, "  Building and installing\n");
+    fprintf(out, "  -----------------------\n");
+    fprintf(out, "  The modules specified will be built and then installed. If the\n");
+    fprintf(out, "  files are on the system partition, they will be synced and the\n");
+    fprintf(out, "  attached device rebooted. If they are APKs that aren't on the\n");
+    fprintf(out, "  system partition they are installed with adb install.\n");
+    fprintf(out, "\n");
+    fprintf(out, "  For example:\n");
+    fprintf(out, "    bit framework\n");
+    fprintf(out, "      Builds framework.jar, syncs the system partition and reboots.\n");
+    fprintf(out, "\n");
+    fprintf(out, "    bit SystemUI\n");
+    fprintf(out, "      Builds SystemUI.apk, syncs the system partition and reboots.\n");
+    fprintf(out, "\n");
+    fprintf(out, "    bit CtsProtoTestCases\n");
+    fprintf(out, "      Builds this CTS apk, adb installs it, but does not run any\n");
+    fprintf(out, "      tests.\n");
+    fprintf(out, "\n");
+    fprintf(out, "  Running Unit Tests\n");
+    fprintf(out, "  ------------------\n");
+    fprintf(out, "  To run a unit test, list the test class names and optionally the\n");
+    fprintf(out, "  test method after the module.\n");
+    fprintf(out, "\n");
+    fprintf(out, "  For example:\n");
+    fprintf(out, "    bit CtsProtoTestCases:*\n");
+    fprintf(out, "      Builds this CTS apk, adb installs it, and runs all the tests\n");
+    fprintf(out, "      contained in that apk.\n");
+    fprintf(out, "\n");
+    fprintf(out, "    bit framework CtsProtoTestCases:*\n");
+    fprintf(out, "      Builds the framework and the apk, syncs and reboots, then\n");
+    fprintf(out, "      adb installs CtsProtoTestCases.apk, and runs all tests \n");
+    fprintf(out, "      contained in that apk.\n");
+    fprintf(out, "\n");
+    fprintf(out, "    bit CtsProtoTestCases:.ProtoOutputStreamBoolTest\n");
+    fprintf(out, "    bit CtsProtoTestCases:android.util.proto.cts.ProtoOutputStreamBoolTest\n");
+    fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs all the\n");
+    fprintf(out, "      tests in the ProtoOutputStreamBoolTest class.\n");
+    fprintf(out, "\n");
+    fprintf(out, "    bit CtsProtoTestCases:.ProtoOutputStreamBoolTest\\#testWrite\n");
+    fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs the testWrite\n");
+    fprintf(out, "      test method on that class.\n");
+    fprintf(out, "\n");
+    fprintf(out, "    bit CtsProtoTestCases:.ProtoOutputStreamBoolTest\\#testWrite,.ProtoOutputStreamBoolTest\\#testRepeated\n");
+    fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs the testWrite\n");
+    fprintf(out, "      and testRepeated test methods on that class.\n");
+    fprintf(out, "\n");
+    fprintf(out, "  Launching an Activity\n");
+    fprintf(out, "  ---------------------\n");
+    fprintf(out, "  To launch an activity, specify the activity class name after\n");
+    fprintf(out, "  the module name.\n");
+    fprintf(out, "\n");
+    fprintf(out, "  For example:\n");
+    fprintf(out, "    bit StatusBarTest:NotificationBuilderTest\n");
+    fprintf(out, "    bit StatusBarTest:.NotificationBuilderTest\n");
+    fprintf(out, "    bit StatusBarTest:com.android.statusbartest.NotificationBuilderTest\n");
+    fprintf(out, "      Builds and installs StatusBarTest.apk, launches the\n");
+    fprintf(out, "      com.android.statusbartest/.NotificationBuilderTest activity.\n");
+    fprintf(out, "\n");
+    fprintf(out, "\n");
+    fprintf(out, "usage: bit --tab ...\n");
+    fprintf(out, "\n");
+    fprintf(out, "  Lists the targets in a format for tab completion. To get tab\n");
+    fprintf(out, "  completion, add this to your bash environment:\n");
+    fprintf(out, "\n");
+    fprintf(out, "     complete -C \"bit --tab\" bit\n");
+    fprintf(out, "\n");
+    fprintf(out, "  Sourcing android's build/envsetup.sh will do this for you\n");
+    fprintf(out, "  automatically.\n");
+    fprintf(out, "\n");
+    fprintf(out, "\n");
+    fprintf(out, "usage: bit --help\n");
+    fprintf(out, "usage: bit -h\n");
+    fprintf(out, "\n");
+    fprintf(out, "  Print this help message\n");
+    fprintf(out, "\n");
+}
+
+
+/**
+ * Sets the appropriate flag* variables. If there is a problem with the
+ * commandline arguments, prints the help message and exits with an error.
+ */
+static void
+parse_args(Options* options, int argc, const char** argv)
+{
+    // Help
+    if (argc == 2 && (strcmp(argv[1],  "-h") == 0 || strcmp(argv[1], "--help") == 0)) {
+        options->runHelp = true;
+        return;
+    }
+
+    // Tab
+    if (argc >= 4 && strcmp(argv[1], "--tab") == 0) {
+        options->runTab = true;
+        options->tabPattern = argv[3];
+        return;
+    }
+
+    // Normal usage
+    bool anyPhases = false;
+    bool gotPattern = false;
+    bool flagBuild = false;
+    bool flagInstall = false;
+    bool flagTest = false;
+    for (int i=1; i < argc; i++) {
+        string arg(argv[i]);
+        if (arg[0] == '-') {
+            for (size_t j=1; j<arg.size(); j++) {
+                switch (arg[j]) {
+                    case '-':
+                        break;
+                    case 'b':
+                        if (gotPattern) {
+                            gotPattern = false;
+                            flagInstall = false;
+                            flagTest = false;
+                        }
+                        flagBuild = true;
+                        anyPhases = true;
+                        break;
+                    case 'i':
+                        if (gotPattern) {
+                            gotPattern = false;
+                            flagBuild = false;
+                            flagTest = false;
+                        }
+                        flagInstall = true;
+                        anyPhases = true;
+                        break;
+                    case 't':
+                        if (gotPattern) {
+                            gotPattern = false;
+                            flagBuild = false;
+                            flagInstall = false;
+                        }
+                        flagTest = true;
+                        anyPhases = true;
+                        break;
+                    case 'r':
+                        options->reboot = true;
+                        break;
+                    default:
+                        fprintf(stderr, "Unrecognized option '%c'\n", arg[j]);
+                        print_usage(stderr);
+                        exit(1);
+                        break;
+                }
+            }
+        } else {
+            Target* target = new Target(flagBuild || !anyPhases, flagInstall || !anyPhases,
+                    flagTest || !anyPhases, arg);
+            size_t colonPos = arg.find(':');
+            if (colonPos == 0) {
+                fprintf(stderr, "Test / activity supplied without a module to build: %s\n",
+                        arg.c_str());
+                print_usage(stderr);
+                exit(1);
+            } else if (colonPos == string::npos) {
+                target->name = arg;
+            } else {
+                target->name.assign(arg, 0, colonPos);
+                size_t beginPos = colonPos+1;
+                size_t commaPos;
+                while (true) {
+                    commaPos = arg.find(',', beginPos);
+                    if (commaPos == string::npos) {
+                        if (beginPos != arg.size()) {
+                            target->actions.push_back(string(arg, beginPos, commaPos));
+                        }
+                        break;
+                    } else {
+                        if (commaPos != beginPos) {
+                            target->actions.push_back(string(arg, beginPos, commaPos-beginPos));
+                        }
+                        beginPos = commaPos+1;
+                    }
+                }
+            }
+            options->targets.push_back(target);
+            gotPattern = true;
+        }
+    }
+    // If no pattern was supplied, give an error
+    if (options->targets.size() == 0) {
+        fprintf(stderr, "No PATTERN supplied.\n\n");
+        print_usage(stderr);
+        exit(1);
+    }
+}
+
+/**
+ * Get an environment variable.
+ * Exits with an error if it is unset or the empty string.
+ */
+static string
+get_required_env(const char* name, bool quiet)
+{
+    const char* value = getenv(name);
+    if (value == NULL || value[0] == '\0') {
+        if (!quiet) {
+            fprintf(stderr, "%s not set. Did you source build/envsetup.sh,"
+                    " run lunch and do a build?\n", name);
+        }
+        exit(1);
+    }
+    return string(value);
+}
+
+/**
+ * Get the out directory.
+ *
+ * This duplicates the logic in build/make/core/envsetup.mk (which hasn't changed since 2011)
+ * so that we don't have to wait for get_build_var make invocation.
+ */
+string
+get_out_dir()
+{
+    const char* out_dir = getenv("OUT_DIR");
+    if (out_dir == NULL || out_dir[0] == '\0') {
+        const char* common_base = getenv("OUT_DIR_COMMON_BASE");
+        if (common_base == NULL || common_base[0] == '\0') {
+            // We don't prefix with buildTop because we cd there and it
+            // makes all the filenames long when being pretty printed.
+            return "out";
+        } else {
+            char pwd[PATH_MAX];
+            if (getcwd(pwd, PATH_MAX) == NULL) {
+                fprintf(stderr, "Your pwd is too long.\n");
+                exit(1);
+            }
+            const char* slash = strrchr(pwd, '/');
+            if (slash == NULL) {
+                slash = "";
+            }
+            string result(common_base);
+            result += slash;
+            return result;
+        }
+    }
+    return string(out_dir);
+}
+
+/**
+ * Check that a system property on the device matches the expected value.
+ * Exits with an error if they don't.
+ */
+static void
+check_device_property(const string& property, const string& expected)
+{
+    int err;
+    string deviceValue = get_system_property(property, &err);
+    check_error(err);
+    if (deviceValue != expected) {
+        print_error("There is a mismatch between the build you just did and the device you");
+        print_error("are trying to sync it to in the %s system property", property.c_str());
+        print_error("   build:  %s", expected.c_str());
+        print_error("   device: %s", deviceValue.c_str());
+        exit(1);
+    }
+}
+
+/**
+ * Run the build, install, and test actions.
+ */
+void
+run_phases(vector<Target*> targets, bool reboot)
+{
+    int err = 0;
+
+    //
+    // Initialization
+    //
+
+    print_status("Initializing");
+
+    const string buildTop = get_required_env("ANDROID_BUILD_TOP", false);
+    const string buildProduct = get_required_env("TARGET_PRODUCT", false);
+    const string buildVariant = get_required_env("TARGET_BUILD_VARIANT", false);
+    const string buildType = get_required_env("TARGET_BUILD_TYPE", false);
+    const string buildDevice = get_build_var(buildTop, "TARGET_DEVICE", false);
+    const string buildId = get_build_var(buildTop, "BUILD_ID", false);
+    const string buildOut = get_out_dir();
+
+    // TODO: print_command("cd", buildTop.c_str());
+    chdir(buildTop.c_str());
+
+    // Get the modules for the targets
+    map<string,Module> modules;
+    read_modules(buildOut, buildDevice, &modules, false);
+    for (size_t i=0; i<targets.size(); i++) {
+        Target* target = targets[i];
+        map<string,Module>::iterator mod = modules.find(target->name);
+        if (mod != modules.end()) {
+            target->module = mod->second;
+        } else {
+            print_error("Error: Could not find module: %s", target->name.c_str());
+            err = 1;
+        }
+    }
+    if (err != 0) {
+        exit(1);
+    }
+
+    // Choose the goals
+    vector<string> goals;
+    for (size_t i=0; i<targets.size(); i++) {
+        Target* target = targets[i];
+        if (target->build) {
+            goals.push_back(target->name);
+        }
+    }
+
+    // Figure out whether we need to sync the system and which apks to install
+    string systemPath = buildOut + "/target/product/" + buildDevice + "/system/";
+    string dataPath = buildOut + "/target/product/" + buildDevice + "/data/";
+    bool syncSystem = false;
+    bool alwaysSyncSystem = false;
+    vector<InstallApk> installApks;
+    for (size_t i=0; i<targets.size(); i++) {
+        Target* target = targets[i];
+        if (target->install) {
+            for (size_t j=0; j<target->module.installed.size(); j++) {
+                const string& file = target->module.installed[j];
+                // System partition
+                if (starts_with(file, systemPath)) {
+                    syncSystem = true;
+                    if (!target->build) {
+                        // If a system partition target didn't get built then
+                        // it won't change we will always need to do adb sync
+                        alwaysSyncSystem = true;
+                    }
+                    continue;
+                }
+                // Apk in the data partition
+                if (starts_with(file, dataPath) && ends_with(file, ".apk")) {
+                    // Always install it if we didn't build it because otherwise
+                    // it will never have changed.
+                    installApks.push_back(InstallApk(file, !target->build));
+                    continue;
+                }
+            }
+        }
+    }
+    map<string,FileInfo> systemFilesBefore;
+    if (syncSystem && !alwaysSyncSystem) {
+        get_directory_contents(systemPath, &systemFilesBefore);
+    }
+
+    //
+    // Build
+    //
+
+    // Run the build
+    if (goals.size() > 0) {
+        print_status("Building");
+        err = build_goals(goals);
+        check_error(err);
+    }
+
+    //
+    // Install
+    //
+
+    // Sync the system partition and reboot
+    bool skipSync = false;
+    if (syncSystem) {
+        print_status("Syncing /system");
+
+        if (!alwaysSyncSystem) {
+            // If nothing changed and we weren't forced to sync, skip the reboot for speed.
+            map<string,FileInfo> systemFilesAfter;
+            get_directory_contents(systemPath, &systemFilesAfter);
+            skipSync = !directory_contents_differ(systemFilesBefore, systemFilesAfter);
+        }
+        if (skipSync) {
+            printf("Skipping sync because no files changed.\n");
+        } else {
+            // Do some sanity checks
+            check_device_property("ro.build.product", buildProduct);
+            check_device_property("ro.build.type", buildVariant);
+            check_device_property("ro.build.id", buildId);
+
+            // Stop & Sync
+            err = run_adb("shell", "stop", NULL);
+            check_error(err);
+            err = run_adb("remount", NULL);
+            check_error(err);
+            err = run_adb("sync", "system", NULL);
+            check_error(err);
+
+            if (reboot) {
+                print_status("Rebooting");
+
+                err = run_adb("reboot", NULL);
+                check_error(err);
+                err = run_adb("wait-for-device", NULL);
+                check_error(err);
+            } else {
+                print_status("Restarting the runtime");
+
+                err = run_adb("shell", "setprop", "sys.boot_completed", "0", NULL);
+                check_error(err);
+                err = run_adb("shell", "start", NULL);
+                check_error(err);
+            }
+
+            while (true) {
+                string completed = get_system_property("sys.boot_completed", &err);
+                check_error(err);
+                if (completed == "1") {
+                    break;
+                }
+                sleep(2);
+            }
+            sleep(1);
+            err = run_adb("shell", "wm", "dismiss-keyguard", NULL);
+            check_error(err);
+        }
+    }
+
+    // Install APKs
+    if (installApks.size() > 0) {
+        print_status("Installing APKs");
+        for (size_t i=0; i<installApks.size(); i++) {
+            InstallApk& apk = installApks[i];
+            if (!apk.file.fileInfo.exists || apk.file.HasChanged()) {
+                // It didn't exist before or it changed, so int needs install
+                err = run_adb("install", "-r", apk.file.filename.c_str(), NULL);
+                check_error(err);
+                apk.installed = true;
+            } else {
+                printf("APK didn't change. Skipping install of %s\n", apk.file.filename.c_str());
+            }
+        }
+    }
+
+    //
+    // Actions
+    //
+
+    // Inspect the apks, and figure out what is an activity and what needs a test runner
+    bool printedInspecting = false;
+    vector<TestAction> testActions;
+    vector<ActivityAction> activityActions;
+    for (size_t i=0; i<targets.size(); i++) {
+        Target* target = targets[i];
+        if (target->test) {
+            for (size_t j=0; j<target->module.installed.size(); j++) {
+                string filename = target->module.installed[j];
+
+                if (!ends_with(filename, ".apk")) {
+                    continue;
+                }
+
+                if (!printedInspecting) {
+                    printedInspecting = true;
+                    print_status("Inspecting APKs");
+                }
+
+                Apk apk;
+                err = inspect_apk(&apk, filename);
+                check_error(err);
+
+                for (size_t k=0; k<target->actions.size(); k++) {
+                    string actionString = target->actions[k];
+                    if (actionString == "*") {
+                        if (apk.runner.length() == 0) {
+                            print_error("Error: Test requested for apk that doesn't"
+                                    " have an <instrumentation> tag: %s\n",
+                                    target->module.name.c_str());
+                            exit(1);
+                        }
+                        TestAction action;
+                        action.packageName = apk.package;
+                        action.runner = apk.runner;
+                        action.target = target;
+                        testActions.push_back(action);
+                        target->testActionCount++;
+                    } else if (apk.HasActivity(actionString)) {
+                        ActivityAction action;
+                        action.packageName = apk.package;
+                        action.className = full_class_name(apk.package, actionString);
+                        activityActions.push_back(action);
+                    } else {
+                        if (apk.runner.length() == 0) {
+                            print_error("Error: Test requested for apk that doesn't"
+                                    " have an <instrumentation> tag: %s\n",
+                                    target->module.name.c_str());
+                            exit(1);
+                        }
+                        TestAction action;
+                        action.packageName = apk.package;
+                        action.runner = apk.runner;
+                        action.className = full_class_name(apk.package, actionString);
+                        action.target = target;
+                        testActions.push_back(action);
+                        target->testActionCount++;
+                    }
+                }
+            }
+        }
+    }
+
+    // Run the instrumentation tests
+    TestResults testResults;
+    if (testActions.size() > 0) {
+        print_status("Running tests");
+        for (size_t i=0; i<testActions.size(); i++) {
+            TestAction& action = testActions[i];
+            testResults.SetCurrentAction(&action);
+            err = run_instrumentation_test(action.packageName, action.runner, action.className,
+                    &testResults);
+            check_error(err);
+            if (action.passCount == 0 && action.failCount == 0) {
+                action.target->actionsWithNoTests = true;
+            }
+            int total = action.passCount + action.failCount;
+            printf("%sRan %d test%s for %s. ", g_escapeClearLine,
+                    total, total > 1 ? "s" : "", action.target->name.c_str());
+            if (action.passCount == 0 && action.failCount == 0) {
+                printf("%s%d passed, %d failed%s\n", g_escapeYellowBold, action.passCount,
+                        action.failCount, g_escapeEndColor);
+            } else if (action.failCount >  0) {
+                printf("%d passed, %s%d failed%s\n", action.passCount, g_escapeRedBold,
+                        action.failCount, g_escapeEndColor);
+            } else {
+                printf("%s%d passed%s, %d failed\n", g_escapeGreenBold, action.passCount,
+                        g_escapeEndColor, action.failCount);
+            }
+        }
+    }
+
+    // Launch the activity
+    if (activityActions.size() > 0) {
+        print_status("Starting activity");
+
+        if (activityActions.size() > 1) {
+            print_warning("Multiple activities specified.  Will only start the first one:");
+            for (size_t i=0; i<activityActions.size(); i++) {
+                ActivityAction& action = activityActions[i];
+                print_warning("   %s",
+                        pretty_component_name(action.packageName, action.className).c_str());
+            }
+        }
+
+        const ActivityAction& action = activityActions[0];
+        string componentName = action.packageName + "/" + action.className;
+        err = run_adb("shell", "am", "start", componentName.c_str(), NULL);
+        check_error(err);
+    }
+
+    //
+    // Print summary
+    //
+
+    printf("\n%s--------------------------------------------%s\n", g_escapeBold, g_escapeEndColor);
+
+    // Build
+    if (goals.size() > 0) {
+        printf("%sBuilt:%s\n", g_escapeBold, g_escapeEndColor);
+        for (size_t i=0; i<goals.size(); i++) {
+            printf("   %s\n", goals[i].c_str());
+        }
+    }
+
+    // Install
+    if (syncSystem) {
+        if (skipSync) {
+            printf("%sSkipped syncing /system partition%s\n", g_escapeBold, g_escapeEndColor);
+        } else {
+            printf("%sSynced /system partition%s\n", g_escapeBold, g_escapeEndColor);
+        }
+    }
+    if (installApks.size() > 0) {
+        bool printedTitle = false;
+        for (size_t i=0; i<installApks.size(); i++) {
+            const InstallApk& apk = installApks[i];
+            if (apk.installed) {
+                if (!printedTitle) {
+                    printf("%sInstalled:%s\n", g_escapeBold, g_escapeEndColor);
+                    printedTitle = true;
+                }
+                printf("   %s\n", apk.file.filename.c_str());
+            }
+        }
+        printedTitle = false;
+        for (size_t i=0; i<installApks.size(); i++) {
+            const InstallApk& apk = installApks[i];
+            if (!apk.installed) {
+                if (!printedTitle) {
+                    printf("%sSkipped install:%s\n", g_escapeBold, g_escapeEndColor);
+                    printedTitle = true;
+                }
+                printf("   %s\n", apk.file.filename.c_str());
+            }
+        }
+    }
+
+    // Tests
+    if (testActions.size() > 0) {
+        printf("%sRan tests:%s\n", g_escapeBold, g_escapeEndColor);
+        size_t maxNameLength = 0;
+        for (size_t i=0; i<targets.size(); i++) {
+            Target* target = targets[i];
+            if (target->test) {
+                size_t len = target->name.length();
+                if (len > maxNameLength) {
+                    maxNameLength = len;
+                }
+            }
+        }
+        string padding(maxNameLength, ' ');
+        for (size_t i=0; i<targets.size(); i++) {
+            Target* target = targets[i];
+            if (target->testActionCount > 0) {
+                printf("   %s%s", target->name.c_str(), padding.c_str() + target->name.length());
+                if (target->actionsWithNoTests) {
+                    printf("     %s%d passed, %d failed%s\n", g_escapeYellowBold,
+                            target->testPassCount, target->testFailCount, g_escapeEndColor);
+                } else if (target->testFailCount > 0) {
+                    printf("     %d passed, %s%d failed%s\n", target->testPassCount,
+                            g_escapeRedBold, target->testFailCount, g_escapeEndColor);
+                } else {
+                    printf("     %s%d passed%s, %d failed\n", g_escapeGreenBold,
+                            target->testPassCount, g_escapeEndColor, target->testFailCount);
+                }
+            }
+        }
+    }
+    if (activityActions.size() > 1) {
+        printf("%sStarted Activity:%s\n", g_escapeBold, g_escapeEndColor);
+        const ActivityAction& action = activityActions[0];
+        printf("   %s\n", pretty_component_name(action.packageName, action.className).c_str());
+    }
+
+    printf("%s--------------------------------------------%s\n", g_escapeBold, g_escapeEndColor);
+}
+
+/**
+ * Implement tab completion of the target names from the all modules file.
+ */
+void
+run_tab_completion(const string& word)
+{
+    const string buildTop = get_required_env("ANDROID_BUILD_TOP", true);
+    const string buildProduct = get_required_env("TARGET_PRODUCT", false);
+    const string buildOut = get_out_dir();
+
+    chdir(buildTop.c_str());
+
+    string buildDevice = sniff_device_name(buildOut, buildProduct);
+
+    map<string,Module> modules;
+    read_modules(buildOut, buildDevice, &modules, true);
+
+    for (map<string,Module>::const_iterator it = modules.begin(); it != modules.end(); it++) {
+        if (starts_with(it->first, word)) {
+            printf("%s\n", it->first.c_str());
+        }
+    }
+}
+
+/**
+ * Main entry point.
+ */
+int
+main(int argc, const char** argv)
+{
+    GOOGLE_PROTOBUF_VERIFY_VERSION;
+    init_print();
+
+    Options options;
+    parse_args(&options, argc, argv);
+
+    if (options.runHelp) {
+        // Help
+        print_usage(stdout);
+        exit(0);
+    } else if (options.runTab) {
+        run_tab_completion(options.tabPattern);
+        exit(0);
+    } else {
+        // Normal run
+        run_phases(options.targets, options.reboot);
+    }
+
+    return 0;
+}
+
diff --git a/tools/bit/make.cpp b/tools/bit/make.cpp
new file mode 100644
index 0000000..60b5687
--- /dev/null
+++ b/tools/bit/make.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2016 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 "make.h"
+
+#include "command.h"
+#include "print.h"
+#include "util.h"
+
+#include <json/reader.h>
+#include <json/value.h>
+
+#include <fstream>
+#include <string>
+#include <map>
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <string.h>
+
+using namespace std;
+
+map<string,string> g_buildVars;
+
+string
+get_build_var(const string& buildTop, const string& name, bool quiet)
+{
+    int err;
+
+    map<string,string>::iterator it = g_buildVars.find(name);
+    if (it == g_buildVars.end()) {
+        Command cmd("make");
+        cmd.AddArg("--no-print-directory");
+        cmd.AddArg("-C");
+        cmd.AddArg(buildTop);
+        cmd.AddArg("-f");
+        cmd.AddArg("build/core/config.mk");
+        cmd.AddArg(string("dumpvar-") + name);
+        cmd.AddEnv("CALLED_FROM_SETUP", "true");
+        cmd.AddEnv("BUILD_SYSTEM", "build/core");
+
+        string output = trim(get_command_output(cmd, &err, quiet));
+        if (err == 0) {
+            g_buildVars[name] = output;
+            return output;
+        } else {
+            return string();
+        }
+    } else {
+        return it->second;
+    }
+}
+
+string
+sniff_device_name(const string& buildOut, const string& product)
+{
+    string match("ro.build.product=" + product);
+
+    string base(buildOut + "/target/product");
+    DIR* dir = opendir(base.c_str());
+    if (dir == NULL) {
+        return string();
+    }
+
+    dirent* entry;
+    while ((entry = readdir(dir)) != NULL) {
+        if (entry->d_name[0] == '.') {
+            continue;
+        }
+        if (entry->d_type == DT_DIR) {
+            string filename(base + "/" + entry->d_name + "/system/build.prop");
+            vector<string> lines;
+            split_lines(&lines, read_file(filename));
+            for (size_t i=0; i<lines.size(); i++) {
+                if (lines[i] == match) {
+                    return entry->d_name;
+                }
+            }
+        }
+    }
+
+    closedir(dir);
+    return string();
+}
+
+void
+json_error(const string& filename, const char* error, bool quiet)
+{
+    if (!quiet) {
+        print_error("Unable to parse module info file (%s): %s", error, filename.c_str());
+        print_error("Have you done a full build?");
+    }
+    exit(1);
+}
+
+static void
+get_values(const Json::Value& json, const string& name, vector<string>* result)
+{
+    Json::Value nullValue;
+
+    const Json::Value& value = json.get(name, nullValue);
+    if (!value.isArray()) {
+        return;
+    }
+
+    const int N = value.size();
+    for (int i=0; i<N; i++) {
+        const Json::Value& child = value[i];
+        if (child.isString()) {
+            result->push_back(child.asString());
+        }
+    }
+}
+
+void
+read_modules(const string& buildOut, const string& device, map<string,Module>* result, bool quiet)
+{
+    string filename(string(buildOut + "/target/product/") + device + "/module-info.json");
+    std::ifstream stream(filename, std::ifstream::binary);
+
+    if (stream.fail()) {
+        if (!quiet) {
+            print_error("Unable to open module info file: %s", filename.c_str());
+            print_error("Have you done a full build?");
+        }
+        exit(1);
+    }
+
+    Json::Value json;
+    Json::Reader reader;
+    if (!reader.parse(stream, json)) {
+        json_error(filename, "can't parse json format", quiet);
+        return;
+    }
+
+    if (!json.isObject()) {
+        json_error(filename, "root element not an object", quiet);
+        return;
+    }
+
+    vector<string> names = json.getMemberNames();
+    const int N = names.size();
+    for (int i=0; i<N; i++) {
+        const string& name = names[i];
+
+        const Json::Value& value = json[name];
+        if (!value.isObject()) {
+            continue;
+        }
+
+        Module module;
+
+        module.name = name;
+        get_values(value, "class", &module.classes);
+        get_values(value, "path", &module.paths);
+        get_values(value, "installed", &module.installed);
+
+        // Only keep classes we can handle
+        for (ssize_t i = module.classes.size() - 1; i >= 0; i--) {
+            string cl = module.classes[i];
+            if (!(cl == "JAVA_LIBRARIES" || cl == "EXECUTABLES" || cl == "SHARED_LIBRARIES"
+                    || cl == "APPS")) {
+                module.classes.erase(module.classes.begin() + i);
+            }
+        }
+        if (module.classes.size() == 0) {
+            continue;
+        }
+
+        // Only target modules (not host)
+        for (ssize_t i = module.installed.size() - 1; i >= 0; i--) {
+            string fn = module.installed[i];
+            if (!starts_with(fn, buildOut + "/target/")) {
+                module.installed.erase(module.installed.begin() + i);
+            }
+        }
+        if (module.installed.size() == 0) {
+            continue;
+        }
+
+        (*result)[name] = module;
+    }
+}
+
+int
+build_goals(const vector<string>& goals)
+{
+    Command cmd("make");
+    cmd.AddArg("-f");
+    cmd.AddArg("build/core/main.mk");
+    for (size_t i=0; i<goals.size(); i++) {
+        cmd.AddArg(goals[i]);
+    }
+
+    return run_command(cmd);
+}
+
diff --git a/tools/bit/make.h b/tools/bit/make.h
new file mode 100644
index 0000000..bb83c6e
--- /dev/null
+++ b/tools/bit/make.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 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 MAKE_H
+#define MAKE_H
+
+#include <map>
+#include <string>
+#include <vector>
+
+using namespace std;
+
+struct Module
+{
+    string name;
+    vector<string> classes;
+    vector<string> paths;
+    vector<string> installed;
+};
+
+string get_build_var(const string& buildTop, const string& name, bool quiet);
+
+/**
+ * Poke around in the out directory and try to find a device name that matches
+ * our product. This is faster than running get_build_var and good enough for
+ * tab completion.
+ *
+ * Returns the empty string if we can't find one.
+ */
+string sniff_device_name(const string& buildOut, const string& product);
+
+void read_modules(const string& buildOut, const string& buildDevice,
+        map<string,Module>* modules, bool quiet);
+
+int build_goals(const vector<string>& goals);
+
+#endif // MAKE_H
diff --git a/tools/bit/print.cpp b/tools/bit/print.cpp
new file mode 100644
index 0000000..790e0b4
--- /dev/null
+++ b/tools/bit/print.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2016 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 "print.h"
+
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "util.h"
+
+bool g_stdoutIsTty;
+char const* g_escapeBold;
+char const* g_escapeRedBold;
+char const* g_escapeGreenBold;
+char const* g_escapeYellowBold;
+char const* g_escapeUnderline;
+char const* g_escapeEndColor;
+char const* g_escapeClearLine;
+
+void
+init_print()
+{
+    if (isatty(fileno(stdout))) {
+		g_stdoutIsTty = true;
+		g_escapeBold = "\033[1m";
+		g_escapeRedBold = "\033[91m\033[1m";
+		g_escapeGreenBold = "\033[92m\033[1m";
+		g_escapeYellowBold = "\033[93m\033[1m";
+		g_escapeUnderline = "\033[4m";
+		g_escapeEndColor = "\033[0m";
+		g_escapeClearLine = "\033[K";
+	} else {
+		g_stdoutIsTty = false;
+		g_escapeBold = "";
+		g_escapeRedBold = "";
+		g_escapeGreenBold = "";
+		g_escapeYellowBold = "";
+		g_escapeUnderline = "";
+		g_escapeEndColor = "";
+		g_escapeClearLine = "";
+    }
+}
+
+void
+print_status(const char* format, ...)
+{
+    printf("\n%s%s", g_escapeBold, g_escapeUnderline);
+
+    va_list args;
+    va_start(args, format);
+    vfprintf(stdout, format, args);
+    va_end(args);
+
+    printf("%s\n", g_escapeEndColor);
+}
+
+void
+print_command(const Command& command)
+{
+    fputs(g_escapeBold, stdout);
+    for (map<string,string>::const_iterator it=command.env.begin(); it!=command.env.end(); it++) {
+        fputs(it->first.c_str(), stdout);
+        fputc('=', stdout);
+        fputs(escape_for_commandline(it->second.c_str()).c_str(), stdout);
+        putc(' ', stdout);
+    }
+    fputs(command.prog.c_str(), stdout);
+    for (vector<string>::const_iterator it=command.args.begin(); it!=command.args.end(); it++) {
+        putc(' ', stdout);
+        fputs(escape_for_commandline(it->c_str()).c_str(), stdout);
+    }
+    fputs(g_escapeEndColor, stdout);
+    fputc('\n', stdout);
+}
+
+void
+print_error(const char* format, ...)
+{
+    fputs(g_escapeRedBold, stderr);
+
+    va_list args;
+    va_start(args, format);
+    vfprintf(stderr, format, args);
+    va_end(args);
+
+    fputs(g_escapeEndColor, stderr);
+    fputc('\n', stderr);
+}
+
+void
+print_warning(const char* format, ...)
+{
+    fputs(g_escapeYellowBold, stderr);
+
+    va_list args;
+    va_start(args, format);
+    vfprintf(stderr, format, args);
+    va_end(args);
+
+    fputs(g_escapeEndColor, stderr);
+    fputc('\n', stderr);
+}
+
+void
+print_one_line(const char* format, ...)
+{
+    if (g_stdoutIsTty) {
+        struct winsize ws;
+        ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
+        int size = ws.ws_col + 1;
+        char* buf = (char*)malloc(size);
+
+        va_list args;
+        va_start(args, format);
+        vsnprintf(buf, size, format, args);
+        va_end(args);
+
+        printf("%s%s\r", buf, g_escapeClearLine);
+        free(buf);
+
+        fflush(stdout);
+    } else {
+        va_list args;
+        va_start(args, format);
+        vfprintf(stdout, format, args);
+        va_end(args);
+        printf("\n");
+    }
+}
+
+void
+check_error(int err)
+{
+    if (err != 0) {
+        fputc('\n', stderr);
+        print_error("Stopping due to errors.");
+        exit(1);
+    }
+}
+
+
diff --git a/tools/bit/print.h b/tools/bit/print.h
new file mode 100644
index 0000000..b6c3e9a
--- /dev/null
+++ b/tools/bit/print.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 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 PRINT_H
+#define PRINT_H
+
+#include "command.h"
+
+extern bool g_stdoutIsTty;
+extern char const* g_escapeBold;
+extern char const* g_escapeRedBold;
+extern char const* g_escapeGreenBold;
+extern char const* g_escapeYellowBold;
+extern char const* g_escapeUnderline;
+extern char const* g_escapeEndColor;
+extern char const* g_escapeClearLine;
+
+void init_print();
+void print_status(const char* format, ...);
+void print_command(const Command& command);
+void print_error(const char* format, ...);
+void print_warning(const char* format, ...);
+void print_one_line(const char* format, ...);
+void check_error(int err);
+
+#endif // PRINT_H
diff --git a/tools/bit/util.cpp b/tools/bit/util.cpp
new file mode 100644
index 0000000..fc93bcb
--- /dev/null
+++ b/tools/bit/util.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2016 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 "util.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <string.h>
+#include <unistd.h>
+
+
+FileInfo::FileInfo()
+{
+    memset(this, 0, sizeof(FileInfo));
+}
+
+FileInfo::FileInfo(const FileInfo& that)
+{
+    memcpy(this, &that, sizeof(FileInfo));
+}
+
+FileInfo::FileInfo(const string& filename)
+{
+    struct stat st;
+    int err = stat(filename.c_str(), &st);
+    if (err != 0) {
+        memset(this, 0, sizeof(FileInfo));
+    } else {
+        exists = true;
+        mtime = st.st_mtime;
+        ctime = st.st_ctime;
+        size = st.st_size;
+    }
+}
+
+bool
+FileInfo::operator==(const FileInfo& that) const
+{
+    return exists == that.exists
+            && mtime == that.mtime
+            && ctime == that.ctime
+            && size == that.size;
+}
+
+bool
+FileInfo::operator!=(const FileInfo& that) const
+{
+    return exists != that.exists
+            || mtime != that.mtime
+            || ctime != that.ctime
+            || size != that.size;
+}
+
+FileInfo::~FileInfo()
+{
+}
+
+TrackedFile::TrackedFile()
+    :filename(),
+     fileInfo()
+{
+}
+
+TrackedFile::TrackedFile(const TrackedFile& that)
+{
+    filename = that.filename;
+    fileInfo = that.fileInfo;
+}
+
+TrackedFile::TrackedFile(const string& file)
+    :filename(file),
+     fileInfo(file)
+{
+}
+
+TrackedFile::~TrackedFile()
+{
+}
+
+bool
+TrackedFile::HasChanged() const
+{
+    FileInfo updated(filename);
+    return !updated.exists || fileInfo != updated;
+}
+
+void
+get_directory_contents(const string& name, map<string,FileInfo>* results)
+{
+    int err;
+    DIR* dir = opendir(name.c_str());
+    if (dir == NULL) {
+        return;
+    }
+
+    dirent* entry;
+    while ((entry = readdir(dir)) != NULL) {
+        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
+            continue;
+        }
+        if (entry->d_type == DT_DIR) {
+            string subdir = name + "/" + entry->d_name;
+            get_directory_contents(subdir, results);
+        } else if (entry->d_type == DT_LNK || entry->d_type == DT_REG) {
+            string filename(name + "/" + entry->d_name);
+            (*results)[filename] = FileInfo(filename);
+        }
+    }
+
+    closedir(dir);
+}
+
+bool
+directory_contents_differ(const map<string,FileInfo>& before, const map<string,FileInfo>& after)
+{
+    if (before.size() != after.size()) {
+        return true;
+    }
+    map<string,FileInfo>::const_iterator b = before.begin();
+    map<string,FileInfo>::const_iterator a = after.begin();
+    while (b != before.end() && a != after.end()) {
+        if (b->first != a->first) {
+            return true;
+        }
+        if (a->second != b->second) {
+            return true;
+        }
+        a++;
+        b++;
+    }
+    return false;
+}
+
+string
+escape_quotes(const char* str)
+{
+    string result;
+    while (*str) {
+        if (*str == '"') {
+            result += '\\';
+            result += '"';
+        } else {
+            result += *str;
+        }
+    }
+    return result;
+}
+
+string
+escape_for_commandline(const char* str)
+{
+    if (strchr(str, '"') != NULL || strchr(str, ' ') != NULL
+            || strchr(str, '\t') != NULL) {
+        return escape_quotes(str);
+    } else {
+        return str;
+    }
+}
+
+static bool
+spacechr(char c)
+{
+    return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+}
+
+string
+trim(const string& str)
+{
+    const ssize_t N = (ssize_t)str.size();
+    ssize_t begin = 0;
+    while (begin < N && spacechr(str[begin])) {
+        begin++;
+    }
+    ssize_t end = N - 1;
+    while (end >= begin && spacechr(str[end])) {
+        end--;
+    }
+    return string(str, begin, end-begin+1);
+}
+
+bool
+starts_with(const string& str, const string& prefix)
+{
+    return str.compare(0, prefix.length(), prefix) == 0;
+}
+
+bool
+ends_with(const string& str, const string& suffix)
+{
+    if (str.length() < suffix.length()) {
+        return false;
+    } else {
+        return str.compare(str.length()-suffix.length(), suffix.length(), suffix) == 0;
+    }
+}
+
+void
+split_lines(vector<string>* result, const string& str)
+{
+    const int N = str.length();
+    int begin = 0;
+    int end = 0;
+    for (; end < N; end++) {
+        const char c = str[end];
+        if (c == '\r' || c == '\n') {
+            if (begin != end) {
+                result->push_back(string(str, begin, end-begin));
+            }
+            begin = end+1;
+        }
+    }
+    if (begin != end) {
+        result->push_back(string(str, begin, end-begin));
+    }
+}
+
+string
+read_file(const string& filename)
+{
+    FILE* file = fopen(filename.c_str(), "r");
+    if (file == NULL) {
+        return string();
+    }
+    
+    fseek(file, 0, SEEK_END);
+    int size = ftell(file);
+    fseek(file, 0, SEEK_SET);
+
+    char* buf = (char*)malloc(size);
+    fread(buf, 1, size, file);
+
+    string result(buf, size);
+
+    free(buf);
+    fclose(file);
+
+    return result;
+}
+
+
diff --git a/tools/bit/util.h b/tools/bit/util.h
new file mode 100644
index 0000000..718f147
--- /dev/null
+++ b/tools/bit/util.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 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 UTIL_H
+#define UTIL_H
+
+#include <map>
+#include <string>
+#include <vector>
+
+using namespace std;
+
+struct FileInfo
+{
+    bool exists;
+    time_t mtime;
+    time_t ctime;
+    off_t size;
+
+    FileInfo();
+    FileInfo(const FileInfo& that);
+    explicit FileInfo(const string& filename);
+    ~FileInfo();
+
+    bool operator==(const FileInfo& that) const;
+    bool operator!=(const FileInfo& that) const;
+};
+
+
+/**
+ * Record for a file that we are watching
+ */
+struct TrackedFile {
+    string filename;
+    FileInfo fileInfo;
+
+    TrackedFile();
+    TrackedFile(const TrackedFile& that);
+    explicit TrackedFile(const string& filename);
+    ~TrackedFile();
+
+    // Returns if the file has changed. If it doesn't currently exist, returns true.
+    bool HasChanged() const;
+};
+
+/**
+ * Get FileInfo structures recursively for all the files and symlinks in a directory.
+ * Does not traverse symlinks, but it does record them.
+ */
+void get_directory_contents(const string& dir, map<string,FileInfo>* results);
+
+bool directory_contents_differ(const map<string,FileInfo>& before,
+        const map<string,FileInfo>& after);
+
+string escape_quotes(const char* str);
+
+string escape_for_commandline(const char* str);
+
+string trim(const string& trim);
+
+bool starts_with(const string& str, const string& prefix);
+
+bool ends_with(const string& str, const string& suffix);
+
+void split_lines(vector<string>* result, const string& str);
+
+string read_file(const string& filename);
+
+#endif // UTIL_H
+
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index 090cee8..e1fc5ec 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -92,8 +92,7 @@
 
     @Nullable
     public static Bitmap_Delegate getDelegate(@Nullable Bitmap bitmap) {
-        // refSkPixelRef is a hack to get the native pointer: see #nativeRefPixelRef()
-        return bitmap == null ? null : getDelegate(bitmap.refSkPixelRef());
+        return bitmap == null ? null : getDelegate(bitmap.getNativeInstance());
     }
 
     /**
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 09ab657..9ec546e 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -413,7 +413,8 @@
     }
 
     @Override
-    public int[] setNewConfiguration(Configuration arg0) throws RemoteException {
+    public int[] setNewDisplayOverrideConfiguration(Configuration arg0, int displayId)
+            throws RemoteException {
         // TODO Auto-generated method stub
         return null;
     }
@@ -487,7 +488,7 @@
     }
 
     @Override
-    public Configuration updateOrientationFromAppTokens(Configuration arg0, IBinder arg1)
+    public Configuration updateOrientationFromAppTokens(Configuration arg0, IBinder arg1, int arg2)
             throws RemoteException {
         // TODO Auto-generated method stub
         return null;
@@ -590,6 +591,20 @@
     }
 
     @Override
+    public void registerPinnedStackListener(int displayId, IPinnedStackListener listener) throws RemoteException {
+    }
+
+    @Override
+    public Rect getPictureInPictureDefaultBounds(int displayId) {
+        return null;
+    }
+
+    @Override
+    public Rect getPictureInPictureMovementBounds(int displayId)  {
+        return null;
+    }
+
+    @Override
     public void setResizeDimLayer(boolean visible, int targetStackId, float alpha)
             throws RemoteException {
     }
@@ -604,7 +619,7 @@
     }
 
     @Override
-    public void getStableInsets(Rect outInsets) throws RemoteException {
+    public void getStableInsets(int displayId, Rect outInsets) throws RemoteException {
     }
 
     @Override
diff --git a/tools/streaming_proto/main.cpp b/tools/streaming_proto/main.cpp
index d286213..5435728 100644
--- a/tools/streaming_proto/main.cpp
+++ b/tools/streaming_proto/main.cpp
@@ -191,38 +191,55 @@
     switch (field.type()) {
         case FieldDescriptorProto::TYPE_DOUBLE:
             result |= FIELD_TYPE_DOUBLE;
+            break;
         case FieldDescriptorProto::TYPE_FLOAT:
             result |= FIELD_TYPE_FLOAT;
+            break;
         case FieldDescriptorProto::TYPE_INT64:
             result |= FIELD_TYPE_INT64;
+            break;
         case FieldDescriptorProto::TYPE_UINT64:
             result |= FIELD_TYPE_UINT64;
+            break;
         case FieldDescriptorProto::TYPE_INT32:
             result |= FIELD_TYPE_INT32;
+            break;
         case FieldDescriptorProto::TYPE_FIXED64:
             result |= FIELD_TYPE_FIXED64;
+            break;
         case FieldDescriptorProto::TYPE_FIXED32:
             result |= FIELD_TYPE_FIXED32;
+            break;
         case FieldDescriptorProto::TYPE_BOOL:
             result |= FIELD_TYPE_BOOL;
+            break;
         case FieldDescriptorProto::TYPE_STRING:
             result |= FIELD_TYPE_STRING;
+            break;
         case FieldDescriptorProto::TYPE_MESSAGE:
             result |= FIELD_TYPE_OBJECT;
+            break;
         case FieldDescriptorProto::TYPE_BYTES:
             result |= FIELD_TYPE_BYTES;
+            break;
         case FieldDescriptorProto::TYPE_UINT32:
             result |= FIELD_TYPE_UINT32;
+            break;
         case FieldDescriptorProto::TYPE_ENUM:
             result |= FIELD_TYPE_ENUM;
+            break;
         case FieldDescriptorProto::TYPE_SFIXED32:
             result |= FIELD_TYPE_SFIXED32;
+            break;
         case FieldDescriptorProto::TYPE_SFIXED64:
             result |= FIELD_TYPE_SFIXED64;
+            break;
         case FieldDescriptorProto::TYPE_SINT32:
             result |= FIELD_TYPE_SINT32;
+            break;
         case FieldDescriptorProto::TYPE_SINT64:
             result |= FIELD_TYPE_SINT64;
+            break;
         default:
             ;
     }
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl
new file mode 100644
index 0000000..6b1cea8
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.hotspot2;
+
+parcelable PasspointConfiguration;
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
new file mode 100644
index 0000000..18aae53
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.hotspot2;
+
+import android.net.wifi.hotspot2.pps.Credential;
+import android.net.wifi.hotspot2.pps.HomeSP;
+import android.os.Parcelable;
+import android.os.Parcel;
+
+/**
+ * Class representing Passpoint configuration.  This contains configurations specified in
+ * PerProviderSubscription (PPS) Management Object (MO) tree.
+ *
+ * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
+ * Release 2 Technical Specification.
+ *
+ * Currently, only HomeSP and Credential subtrees are supported.
+ *
+ * @hide
+ */
+public final class PasspointConfiguration implements Parcelable {
+    public HomeSP homeSp = null;
+    public Credential credential = null;
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(homeSp, flags);
+        dest.writeParcelable(credential, flags);
+    }
+
+    @Override
+    public boolean equals(Object thatObject) {
+        if (this == thatObject) {
+            return true;
+        }
+        if (!(thatObject instanceof PasspointConfiguration)) {
+            return false;
+        }
+        PasspointConfiguration that = (PasspointConfiguration) thatObject;
+        return (homeSp == null ? that.homeSp == null : homeSp.equals(that.homeSp)) &&
+                (credential == null ? that.credential == null :
+                    credential.equals(that.credential));
+    }
+
+    public static final Creator<PasspointConfiguration> CREATOR =
+        new Creator<PasspointConfiguration>() {
+            @Override
+            public PasspointConfiguration createFromParcel(Parcel in) {
+                PasspointConfiguration config = new PasspointConfiguration();
+                config.homeSp = in.readParcelable(null);
+                config.credential = in.readParcelable(null);
+                return config;
+            }
+            @Override
+            public PasspointConfiguration[] newArray(int size) {
+                return new PasspointConfiguration[size];
+            }
+        };
+}
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java
new file mode 100644
index 0000000..65a49ea
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java
@@ -0,0 +1,786 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.hotspot2.omadm;
+
+import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.pps.Credential;
+import android.net.wifi.hotspot2.pps.HomeSP;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.xml.sax.SAXException;
+
+/**
+ * Utility class for converting OMA-DM (Open Mobile Alliance's Device Management)
+ * PPS-MO (PerProviderSubscription Management Object) XML tree to a
+ * {@link PasspointConfiguration} object.
+ *
+ * Currently this only supports PerProviderSubscription/HomeSP and
+ * PerProviderSubscription/Credential subtree for Hotspot 2.0 Release 1 support.
+ *
+ * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
+ * Release 2 Technical Specification.
+ *
+ * Below is a sample XML string for a Release 1 PPS MO tree:
+ *
+ * <MgmtTree xmlns="syncml:dmddf1.2">
+ *   <VerDTD>1.2</VerDTD>
+ *   <Node>
+ *     <NodeName>PerProviderSubscription</NodeName>
+ *     <RTProperties>
+ *       <Type>
+ *         <DDFName>urn:wfa:mo:hotspot2dot0­perprovidersubscription:1.0</DDFName>
+ *       </Type>
+ *     </RTProperties>
+ *     <Node>
+ *       <NodeName>i001</NodeName>
+ *       <Node>
+ *         <NodeName>HomeSP</NodeName>
+ *         <Node>
+ *           <NodeName>FriendlyName</NodeName>
+ *           <Value>Century House</Value>
+ *         </Node>
+ *         <Node>
+ *           <NodeName>FQDN</NodeName>
+ *           <Value>mi6.co.uk</Value>
+ *         </Node>
+ *         <Node>
+ *           <NodeName>RoamingConsortiumOI</NodeName>
+ *           <Value>112233,445566</Value>
+ *         </Node>
+ *       </Node>
+ *       <Node>
+ *         <NodeName>Credential</NodeName>
+ *         <Node>
+ *           <NodeName>Realm</NodeName>
+ *           <Value>shaken.stirred.com</Value>
+ *         </Node>
+ *         <Node>
+ *           <NodeName>UsernamePassword</NodeName>
+ *           <Node>
+ *             <NodeName>Username</NodeName>
+ *             <Value>james</Value>
+ *           </Node>
+ *           <Node>
+ *             <NodeName>Password</NodeName>
+ *             <Value>Ym9uZDAwNw==</Value>
+ *           </Node>
+ *           <Node>
+ *             <NodeName>EAPMethod</NodeName>
+ *             <Node>
+ *               <NodeName>EAPType</NodeName>
+ *               <Value>21</Value>
+ *             </Node>
+ *             <Node>
+ *               <NodeName>InnerMethod</NodeName>
+ *               <Value>MS-CHAP-V2</Value>
+ *             </Node>
+ *           </Node>
+ *         </Node>
+ *       </Node>
+ *     </Node>
+ *   </Node>
+ * </MgmtTree>
+ *
+ * @hide
+ */
+public final class PPSMOParser {
+    private static final String TAG = "PPSMOParser";
+
+    /**
+     * XML tags expected in the PPS MO (PerProviderSubscription Management Object) XML tree.
+     */
+    private static final String TAG_MANAGEMENT_TREE = "MgmtTree";
+    private static final String TAG_VER_DTD = "VerDTD";
+    private static final String TAG_NODE = "Node";
+    private static final String TAG_NODE_NAME = "NodeName";
+    private static final String TAG_RT_PROPERTIES = "RTProperties";
+    private static final String TAG_TYPE = "Type";
+    private static final String TAG_DDF_NAME = "DDFName";
+    private static final String TAG_VALUE = "Value";
+
+    /**
+     * Name for PerProviderSubscription node.
+     */
+    private static final String NODE_PER_PROVIDER_SUBSCRIPTION = "PerProviderSubscription";
+
+    /**
+     * Fields under HomeSP subtree.
+     */
+    private static final String NODE_HOMESP = "HomeSP";
+    private static final String NODE_FQDN = "FQDN";
+    private static final String NODE_FRIENDLY_NAME = "FriendlyName";
+    private static final String NODE_ROAMING_CONSORTIUM_OI = "RoamingConsortiumOI";
+
+    /**
+     * Fields under Credential subtree.
+     */
+    private static final String NODE_CREDENTIAL = "Credential";
+    private static final String NODE_USERNAME_PASSWORD = "UsernamePassword";
+    private static final String NODE_USERNAME = "Username";
+    private static final String NODE_PASSWORD = "Password";
+    private static final String NODE_EAP_METHOD = "EAPMethod";
+    private static final String NODE_EAP_TYPE = "EAPType";
+    private static final String NODE_INNER_METHOD = "InnerMethod";
+    private static final String NODE_DIGITAL_CERTIFICATE = "DigitalCertificate";
+    private static final String NODE_CERTIFICATE_TYPE = "CertificateType";
+    private static final String NODE_CERT_SHA256_FINGERPRINT = "CertSHA256FingerPrint";
+    private static final String NODE_REALM = "Realm";
+    private static final String NODE_SIM = "SIM";
+    private static final String NODE_SIM_IMSI = "IMSI";
+
+    /**
+     * URN (Unique Resource Name) for PerProviderSubscription Management Object Tree.
+     */
+    private static final String PPS_MO_URN =
+            "urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0";
+
+    /**
+     * Exception for generic parsing errors.
+     */
+    private static class ParsingException extends Exception {
+        public ParsingException(String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * Class representing a node within the PerProviderSubscription tree.
+     * This is used to flatten out and eliminate the extra layering in the XMLNode tree,
+     * to make the data parsing easier and cleaner.
+     *
+     * A PPSNode can be an internal or a leaf node, but not both.
+     *
+     */
+    private static abstract class PPSNode {
+        private final String mName;
+        public PPSNode(String name) {
+            mName = name;
+        }
+
+        /**
+         * @return the name of the node
+         */
+        public String getName() {
+            return mName;
+        }
+
+        /**
+         * Applies for internal node only.
+         *
+         * @return the list of children nodes.
+         */
+        public abstract List<PPSNode> getChildren();
+
+        /**
+         * Applies for leaf node only.
+         *
+         * @return the string value of the node
+         */
+        public abstract String getValue();
+
+        /**
+         * @return a flag indicating if this is a leaf or an internal node
+         */
+        public abstract boolean isLeaf();
+    }
+
+    /**
+     * Class representing a leaf node in a PPS (PerProviderSubscription) tree.
+     */
+    private static class LeafNode extends PPSNode {
+        private final String mValue;
+        public LeafNode(String nodeName, String value) {
+            super(nodeName);
+            mValue = value;
+        }
+
+        @Override
+        public String getValue() {
+            return mValue;
+        }
+
+        @Override
+        public List<PPSNode> getChildren() {
+            return null;
+        }
+
+        @Override
+        public boolean isLeaf() {
+            return true;
+        }
+    }
+
+    /**
+     * Class representing an internal node in a PPS (PerProviderSubscription) tree.
+     */
+    private static class InternalNode extends PPSNode {
+        private final List<PPSNode> mChildren;
+        public InternalNode(String nodeName, List<PPSNode> children) {
+            super(nodeName);
+            mChildren = children;
+        }
+
+        @Override
+        public String getValue() {
+            return null;
+        }
+
+        @Override
+        public List<PPSNode> getChildren() {
+            return mChildren;
+        }
+
+        @Override
+        public boolean isLeaf() {
+            return false;
+        }
+    }
+
+    /**
+     * Convert a XML string representation of a PPS MO (PerProviderSubscription
+     * Management Object) tree to a {@link PasspointConfiguration} object.
+     *
+     * @param xmlString XML string representation of a PPS MO tree
+     * @return {@link PasspointConfiguration} or null
+     */
+    public static PasspointConfiguration parseMOText(String xmlString) {
+        // Convert the XML string to a XML tree.
+        XMLParser xmlParser = new XMLParser();
+        XMLNode root = null;
+        try {
+            root = xmlParser.parse(xmlString);
+        } catch(IOException | SAXException e) {
+            return null;
+        }
+        if (root == null) {
+            return null;
+        }
+
+        // Verify root node is a "MgmtTree" node.
+        if (root.getTag() != TAG_MANAGEMENT_TREE) {
+            Log.e(TAG, "Root is not a MgmtTree");
+            return null;
+        }
+
+        String verDtd = null;    // Used for detecting duplicate VerDTD element.
+        PasspointConfiguration config = null;
+        for (XMLNode child : root.getChildren()) {
+            switch(child.getTag()) {
+                case TAG_VER_DTD:
+                    if (verDtd != null) {
+                        Log.e(TAG, "Duplicate VerDTD element");
+                        return null;
+                    }
+                    verDtd = child.getText();
+                    break;
+                case TAG_NODE:
+                    if (config != null) {
+                        Log.e(TAG, "Unexpected multiple Node element under MgmtTree");
+                        return null;
+                    }
+                    try {
+                        config = parsePpsNode(child);
+                    } catch (ParsingException e) {
+                        Log.e(TAG, e.getMessage());
+                        return null;
+                    }
+                    break;
+                default:
+                    Log.e(TAG, "Unknown node: " + child.getTag());
+                    return null;
+            }
+        }
+        return config;
+    }
+
+    /**
+     * Parse a PerProviderSubscription node. Below is the format of the XML tree (with
+     * each XML element represent a node in the tree):
+     *
+     * <Node>
+     *   <NodeName>PerProviderSubscription</NodeName>
+     *   <RTProperties>
+     *     ...
+     *   </RTPProperties>
+     *   <Node>
+     *     ...
+     *   </Node>
+     * </Node>
+     *
+     * @param node XMLNode that contains PerProviderSubscription node.
+     * @return PasspointConfiguration or null
+     * @throws ParsingException
+     */
+    private static PasspointConfiguration parsePpsNode(XMLNode node)
+            throws ParsingException {
+        PasspointConfiguration config = null;
+        String nodeName = null;
+        for (XMLNode child : node.getChildren()) {
+            switch (child.getTag()) {
+                case TAG_NODE_NAME:
+                    if (nodeName != null) {
+                        throw new ParsingException("Duplicant NodeName: " + child.getText());
+                    }
+                    nodeName = child.getText();
+                    if (!TextUtils.equals(nodeName, NODE_PER_PROVIDER_SUBSCRIPTION)) {
+                        throw new ParsingException("Unexpected NodeName: " + nodeName);
+                    }
+                    break;
+                case TAG_NODE:
+                    // Only one PerProviderSubscription instance is expected and allowed.
+                    if (config != null) {
+                        throw new ParsingException("Multiple PPS instance");
+                    }
+                    // Convert the XML tree to a PPS tree.
+                    PPSNode ppsInstanceRoot = buildPpsNode(child);
+                    config = parsePpsInstance(ppsInstanceRoot);
+                    break;
+                case TAG_RT_PROPERTIES:
+                    // Parse and verify URN stored in the RT (Run Time) Properties.
+                    String urn = parseUrn(child);
+                    if (!TextUtils.equals(urn, PPS_MO_URN)) {
+                        throw new ParsingException("Unknown URN: " + urn);
+                    }
+                    break;
+                default:
+                    throw new ParsingException("Unknown tag under PPS node: " + child.getTag());
+            }
+        }
+        return config;
+    }
+
+    /**
+     * Parse the URN stored in the RTProperties. Below is the format of the RTPProperties node:
+     *
+     * <RTProperties>
+     *   <Type>
+     *     <DDFName>urn:...</DDFName>
+     *   </Type>
+     * </RTProperties>
+     *
+     * @param node XMLNode that contains RTProperties node.
+     * @return URN String of URN.
+     * @throws ParsingException
+     */
+    private static String parseUrn(XMLNode node) throws ParsingException {
+        if (node.getChildren().size() != 1)
+            throw new ParsingException("Expect RTPProperties node to only have one child");
+
+        XMLNode typeNode = node.getChildren().get(0);
+        if (typeNode.getChildren().size() != 1) {
+            throw new ParsingException("Expect Type node to only have one child");
+        }
+        if (!TextUtils.equals(typeNode.getTag(), TAG_TYPE)) {
+            throw new ParsingException("Unexpected tag for Type: " + typeNode.getTag());
+        }
+
+        XMLNode ddfNameNode = typeNode.getChildren().get(0);
+        if (!ddfNameNode.getChildren().isEmpty()) {
+            throw new ParsingException("Expect DDFName node to have no child");
+        }
+        if (!TextUtils.equals(ddfNameNode.getTag(), TAG_DDF_NAME)) {
+            throw new ParsingException("Unexpected tag for DDFName: " + ddfNameNode.getTag());
+        }
+
+        return ddfNameNode.getText();
+    }
+
+    /**
+     * Convert a XML tree represented by XMLNode to a PPS (PerProviderSubscription) instance tree
+     * represented by PPSNode.  This flattens out the XML tree to allow easier and cleaner parsing
+     * of the PPS configuration data.  Only three types of XML tag are expected: "NodeName",
+     * "Node", and "Value".
+     *
+     * The original XML tree (each XML element represent a node):
+     *
+     * <Node>
+     *   <NodeName>root</NodeName>
+     *   <Node>
+     *     <NodeName>child1</NodeName>
+     *     <Value>value1</Value>
+     *   </Node>
+     *   <Node>
+     *     <NodeName>child2</NodeName>
+     *     <Node>
+     *       <NodeName>grandchild1</NodeName>
+     *       ...
+     *     </Node>
+     *   </Node>
+     *   ...
+     * </Node>
+     *
+     * The converted PPS tree:
+     *
+     * [root] --- [child1, value1]
+     *   |
+     *   ---------[child2] --------[grandchild1] --- ...
+     *
+     * @param node XMLNode pointed to the root of a XML tree
+     * @return PPSNode pointing to the root of a PPS tree
+     * @throws ParsingException
+     */
+    private static PPSNode buildPpsNode(XMLNode node) throws ParsingException {
+        String nodeName = null;
+        String nodeValue = null;
+        List<PPSNode> childNodes = new ArrayList<PPSNode>();
+        // Names of parsed child nodes, use for detecting multiple child nodes with the same name.
+        Set<String> parsedNodes = new HashSet<String>();
+
+        for (XMLNode child : node.getChildren()) {
+            String tag = child.getTag();
+            if (TextUtils.equals(tag, TAG_NODE_NAME)) {
+                if (nodeName != null) {
+                    throw new ParsingException("Duplicate NodeName node");
+                }
+                nodeName = child.getText();
+            } else if (TextUtils.equals(tag, TAG_NODE)) {
+                PPSNode ppsNode = buildPpsNode(child);
+                if (parsedNodes.contains(ppsNode.getName())) {
+                    throw new ParsingException("Duplicate node: " + ppsNode.getName());
+                }
+                parsedNodes.add(ppsNode.getName());
+                childNodes.add(ppsNode);
+            } else if (TextUtils.equals(tag, TAG_VALUE)) {
+               if (nodeValue != null) {
+                   throw new ParsingException("Duplicate Value node");
+               }
+               nodeValue = child.getText();
+            } else {
+                throw new ParsingException("Unknown tag: " + tag);
+            }
+        }
+
+        if (nodeName == null) {
+            throw new ParsingException("Invalid node: missing NodeName");
+        }
+        if (nodeValue == null && childNodes.size() == 0) {
+            throw new ParsingException("Invalid node: " + nodeName +
+                    " missing both value and children");
+        }
+        if (nodeValue != null && childNodes.size() > 0) {
+            throw new ParsingException("Invalid node: " + nodeName +
+                    " contained both value and children");
+        }
+
+        if (nodeValue != null) {
+            return new LeafNode(nodeName, nodeValue);
+        }
+        return new InternalNode(nodeName, childNodes);
+    }
+
+    /**
+     * Return the value of a PPSNode.  An exception will be thrown if the given node
+     * is not a leaf node.
+     *
+     * @param node PPSNode to retrieve the value from
+     * @return String representing the value of the node
+     * @throws ParsingException
+     */
+    private static String getPpsNodeValue(PPSNode node) throws ParsingException {
+        if (!node.isLeaf()) {
+            throw new ParsingException("Cannot get value from a non-leaf node: " + node.getName());
+        }
+        return node.getValue();
+    }
+
+    /**
+     * Parse a PPS (PerProviderSubscription) configurations from a PPS tree.
+     *
+     * @param root PPSNode representing the root of the PPS tree
+     * @return PasspointConfiguration
+     * @throws ParsingException
+     */
+    private static PasspointConfiguration parsePpsInstance(PPSNode root)
+            throws ParsingException {
+        if (root.isLeaf()) {
+            throw new ParsingException("Leaf node not expected for PPS instance");
+        }
+
+        PasspointConfiguration config = new PasspointConfiguration();
+        for (PPSNode child : root.getChildren()) {
+            switch(child.getName()) {
+                case NODE_HOMESP:
+                    config.homeSp = parseHomeSP(child);
+                    break;
+                case NODE_CREDENTIAL:
+                    config.credential = parseCredential(child);
+                    break;
+                default:
+                    throw new ParsingException("Unknown node: " + child.getName());
+            }
+        }
+        return config;
+    }
+
+    /**
+     * Parse configurations under PerProviderSubscription/HomeSP subtree.
+     *
+     * @param node PPSNode representing the root of the PerProviderSubscription/HomeSP subtree
+     * @return HomeSP
+     * @throws ParsingException
+     */
+    private static HomeSP parseHomeSP(PPSNode node) throws ParsingException {
+        if (node.isLeaf()) {
+            throw new ParsingException("Leaf node not expected for HomeSP");
+        }
+
+        HomeSP homeSp = new HomeSP();
+        for (PPSNode child : node.getChildren()) {
+            switch (child.getName()) {
+                case NODE_FQDN:
+                    homeSp.fqdn = getPpsNodeValue(child);
+                    break;
+                case NODE_FRIENDLY_NAME:
+                    homeSp.friendlyName = getPpsNodeValue(child);
+                    break;
+                case NODE_ROAMING_CONSORTIUM_OI:
+                    homeSp.roamingConsortiumOIs =
+                            parseRoamingConsortiumOI(getPpsNodeValue(child));
+                    break;
+                default:
+                    throw new ParsingException("Unknown node under HomeSP: " + child.getName());
+            }
+        }
+        return homeSp;
+    }
+
+    /**
+     * Parse the roaming consortium OI string, which contains a list of OIs separated by ",".
+     *
+     * @param oiStr string containing list of OIs (Organization Identifiers) separated by ","
+     * @return long[]
+     * @throws ParsingException
+     */
+    private static long[] parseRoamingConsortiumOI(String oiStr)
+            throws ParsingException {
+        String[] oiStrArray = oiStr.split(",");
+        long[] oiArray = new long[oiStrArray.length];
+        for (int i = 0; i < oiStrArray.length; i++) {
+            try {
+                oiArray[i] = Long.parseLong(oiStrArray[i], 16);
+            } catch (NumberFormatException e) {
+                throw new ParsingException("Invalid OI: " + oiStrArray[i]);
+            }
+        }
+        return oiArray;
+    }
+
+    /**
+     * Parse configurations under PerProviderSubscription/Credential subtree.
+     *
+     * @param node PPSNode representing the root of the PerProviderSubscription/Credential subtree
+     * @return Credential
+     * @throws ParsingException
+     */
+    private static Credential parseCredential(PPSNode node) throws ParsingException {
+        if (node.isLeaf()) {
+            throw new ParsingException("Leaf node not expected for HomeSP");
+        }
+
+        Credential credential = new Credential();
+        for (PPSNode child: node.getChildren()) {
+            switch (child.getName()) {
+                case NODE_USERNAME_PASSWORD:
+                    credential.userCredential = parseUserCredential(child);
+                    break;
+                case NODE_DIGITAL_CERTIFICATE:
+                    credential.certCredential = parseCertificateCredential(child);
+                    break;
+                case NODE_REALM:
+                    credential.realm = getPpsNodeValue(child);
+                    break;
+                case NODE_SIM:
+                    credential.simCredential = parseSimCredential(child);
+                    break;
+                default:
+                    throw new ParsingException("Unknown node under Credential: " +
+                            child.getName());
+            }
+        }
+        return credential;
+    }
+
+    /**
+     * Parse configurations under PerProviderSubscription/Credential/UsernamePassword subtree.
+     *
+     * @param node PPSNode representing the root of the
+     *             PerProviderSubscription/Credential/UsernamePassword subtree
+     * @return Credential.UserCredential
+     * @throws ParsingException
+     */
+    private static Credential.UserCredential parseUserCredential(PPSNode node)
+            throws ParsingException {
+        if (node.isLeaf()) {
+            throw new ParsingException("Leaf node not expected for UsernamePassword");
+        }
+
+        Credential.UserCredential userCred = new Credential.UserCredential();
+        for (PPSNode child : node.getChildren()) {
+            switch (child.getName()) {
+                case NODE_USERNAME:
+                    userCred.username = getPpsNodeValue(child);
+                    break;
+                case NODE_PASSWORD:
+                    userCred.password = getPpsNodeValue(child);
+                    break;
+                case NODE_EAP_METHOD:
+                    parseEAPMethod(child, userCred);
+                    break;
+                default:
+                    throw new ParsingException("Unknown node under UsernamPassword: " +
+                            child.getName());
+            }
+        }
+        return userCred;
+    }
+
+    /**
+     * Parse configurations under PerProviderSubscription/Credential/UsernamePassword/EAPMethod
+     * subtree.
+     *
+     * @param node PPSNode representing the root of the
+     *             PerProviderSubscription/Credential/UsernamePassword/EAPMethod subtree
+     * @param userCred UserCredential to be updated with EAP method values.
+     * @throws ParsingException
+     */
+    private static void parseEAPMethod(PPSNode node, Credential.UserCredential userCred)
+            throws ParsingException {
+        if (node.isLeaf()) {
+            throw new ParsingException("Leaf node not expected for EAPMethod");
+        }
+
+        for (PPSNode child : node.getChildren()) {
+            switch(child.getName()) {
+                case NODE_EAP_TYPE:
+                    userCred.eapType = parseInteger(getPpsNodeValue(child));
+                    break;
+                case NODE_INNER_METHOD:
+                    userCred.nonEapInnerMethod = getPpsNodeValue(child);
+                    break;
+                default:
+                    throw new ParsingException("Unknown node under EAPMethod: " + child.getName());
+            }
+        }
+    }
+
+    /**
+     * Parse configurations under PerProviderSubscription/Credential/DigitalCertificate subtree.
+     *
+     * @param node PPSNode representing the root of the
+     *             PerProviderSubscription/Credential/DigitalCertificate subtree
+     * @return Credential.CertificateCredential
+     * @throws ParsingException
+     */
+    private static Credential.CertificateCredential parseCertificateCredential(PPSNode node)
+            throws ParsingException {
+        if (node.isLeaf()) {
+            throw new ParsingException("Leaf node not expected for DigitalCertificate");
+        }
+
+        Credential.CertificateCredential certCred = new Credential.CertificateCredential();
+        for (PPSNode child : node.getChildren()) {
+            switch (child.getName()) {
+                case NODE_CERTIFICATE_TYPE:
+                    certCred.certType = getPpsNodeValue(child);
+                    break;
+                case NODE_CERT_SHA256_FINGERPRINT:
+                    certCred.certSha256FingerPrint = parseHexString(getPpsNodeValue(child));
+                    break;
+                default:
+                    throw new ParsingException("Unknown node under DigitalCertificate: " +
+                            child.getName());
+            }
+        }
+        return certCred;
+    }
+
+    /**
+     * Parse configurations under PerProviderSubscription/Credential/SIM subtree.
+     *
+     * @param node PPSNode representing the root of the PerProviderSubscription/Credential/SIM
+     *             subtree
+     * @return Credential.SimCredential
+     * @throws ParsingException
+     */
+    private static Credential.SimCredential parseSimCredential(PPSNode node)
+            throws ParsingException {
+        if (node.isLeaf()) {
+            throw new ParsingException("Leaf node not expected for SIM");
+        }
+
+        Credential.SimCredential simCred = new Credential.SimCredential();
+        for (PPSNode child : node.getChildren()) {
+            switch (child.getName()) {
+                case NODE_SIM_IMSI:
+                    simCred.imsi = getPpsNodeValue(child);
+                    break;
+                case NODE_EAP_TYPE:
+                    simCred.eapType = parseInteger(getPpsNodeValue(child));
+                    break;
+                default:
+                    throw new ParsingException("Unknown node under SIM: " + child.getName());
+            }
+        }
+        return simCred;
+    }
+
+    /**
+     * Convert a hex string to a byte array.
+     *
+     * @param str String containing hex values
+     * @return byte[]
+     * @throws ParsingException
+     */
+    private static byte[] parseHexString(String str) throws ParsingException {
+        if ((str.length() & 1) == 1) {
+            throw new ParsingException("Odd length hex string: " + str.length());
+        }
+
+        byte[] result = new byte[str.length() / 2];
+        for (int i = 0; i < result.length; i++) {
+          int index = i * 2;
+          try {
+              result[i] = (byte) Integer.parseInt(str.substring(index, index + 2), 16);
+          } catch (NumberFormatException e) {
+              throw new ParsingException("Invalid hex string: " + str);
+          }
+        }
+        return result;
+    }
+
+    /**
+     * Parse an integer string.
+     *
+     * @param value String of integer value
+     * @return int
+     * @throws ParsingException
+     */
+    private static int parseInteger(String value) throws ParsingException {
+        try {
+            return Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            throw new ParsingException("Invalid integer value: " + value);
+        }
+    }
+}
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java b/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java
new file mode 100644
index 0000000..e87698c
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.hotspot2.omadm;
+
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A class represent a node in an XML tree. Each node is an XML element.
+ * Used by {@link XMLParser} for parsing/converting each XML element to XMLNode.
+ *
+ * @hide
+ */
+public class XMLNode {
+    private final String mTag;
+    private final List<XMLNode> mChildren;
+    private final XMLNode mParent;
+    private StringBuilder mTextBuilder;
+    private String mText;
+
+    public XMLNode(XMLNode parent, String tag) {
+        mTag = tag;
+        mParent = parent;
+        mChildren = new ArrayList<>();
+        mTextBuilder = new StringBuilder();
+        mText = null;
+    }
+
+    /**
+     * Adding a text to this node. Invoked by {@link XMLParser#characters}.
+     *
+     * @param text String to be added
+     */
+    public void addText(String text) {
+        mTextBuilder.append(text);
+    }
+
+    /**
+     * Adding a child node to this node. Invoked by {@link XMLParser#startElement}.
+     *
+     * @param child XMLNode to be added
+     */
+    public void addChild(XMLNode child) {
+        mChildren.add(child);
+    }
+
+    /**
+     * Invoked when the end of the XML element is detected. Used for further processing
+     * of the text enclosed within this XML element. Invoked by {@link XMLParser#endElement}.
+     */
+    public void close() {
+        // Remove the leading and the trailing whitespaces.
+        mText = mTextBuilder.toString().trim();
+        mTextBuilder = null;
+    }
+
+    public String getTag() {
+        return mTag;
+    }
+
+    public XMLNode getParent() {
+        return mParent;
+    }
+
+    public String getText() {
+        return mText;
+    }
+
+    public List<XMLNode> getChildren() {
+        return mChildren;
+    }
+
+    @Override
+    public boolean equals(Object thatObject) {
+        if (this == thatObject) {
+            return true;
+        }
+        if (!(thatObject instanceof XMLNode)) {
+            return false;
+        }
+        XMLNode that = (XMLNode) thatObject;
+
+        return TextUtils.equals(mTag, that.mTag) &&
+                TextUtils.equals(mText, that.mText) &&
+                mChildren.equals(that.mChildren);
+    }
+}
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java
new file mode 100644
index 0000000..948052c
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.hotspot2.omadm;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import android.text.TextUtils;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+/**
+ * Class for parsing an XML string to an XML tree represented by {@link XMLNode}.
+ *
+ * The original XML string:
+ * <root>
+ *   <tag1>text1</tag1>
+ *   <tag2>
+ *     <tag3>text3</tag3>
+ *   </tag2>
+ * </root>
+ *
+ * The XML tree representation:
+ *                  [root]
+ *                     |
+ *                     |
+ *   [tag1, text1]-----|-----[tag2]
+ *                             |
+ *                             |
+ *                       [tag3, text3]
+ *
+ * @hide
+ */
+public class XMLParser extends DefaultHandler {
+    private XMLNode mRoot = null;
+    private XMLNode mCurrent = null;
+
+    public XMLNode parse(String text) throws IOException, SAXException {
+        if (TextUtils.isEmpty(text)) {
+            throw new IOException("XML string not provided");
+        }
+
+        // Reset pointers.
+        mRoot = null;
+        mCurrent = null;
+
+        try {
+            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+            parser.parse(new InputSource(new StringReader(text)), this);
+            return mRoot;
+        } catch (ParserConfigurationException pce) {
+            throw new SAXException(pce);
+        }
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes attributes)
+            throws SAXException {
+        XMLNode parent = mCurrent;
+
+        mCurrent = new XMLNode(parent, qName);
+
+        if (mRoot == null) {
+            mRoot = mCurrent;
+        } else if (parent == null) {
+            throw new SAXException("More than one root nodes");
+        } else {
+            parent.addChild(mCurrent);
+        }
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        if (!qName.equals(mCurrent.getTag())) {
+            throw new SAXException("End tag '" + qName + "' doesn't match current node: " +
+                    mCurrent);
+        }
+
+        mCurrent.close();
+        mCurrent = mCurrent.getParent();
+    }
+
+    @Override
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        mCurrent.addText(new String(ch, start, length));
+    }
+}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl b/wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl
new file mode 100644
index 0000000..3d8e833
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.hotspot2.pps;
+
+parcelable Credential;
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
new file mode 100644
index 0000000..92dbd8a
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -0,0 +1,376 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.hotspot2.pps;
+
+import android.net.wifi.ParcelUtil;
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.text.TextUtils;
+
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+
+/**
+ * Class representing Credential subtree in the PerProviderSubscription (PPS)
+ * Management Object (MO) tree.
+ * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
+ * Release 2 Technical Specification.
+ *
+ * In addition to the fields in the Credential subtree, this will also maintain necessary
+ * information for the private key and certificates associated with this credential.
+ *
+ * Currently we only support the nodes that are used by Hotspot 2.0 Release 1.
+ *
+ * @hide
+ */
+public final class Credential implements Parcelable {
+    /**
+     * The realm associated with this credential.  It will be used to determine
+     * if this credential can be used to authenticate with a given hotspot by
+     * comparing the realm specified in that hotspot's ANQP element.
+     */
+    public String realm = null;
+
+    /**
+     * Username-password based credential.
+     * Contains the fields under PerProviderSubscription/Credential/UsernamePassword subtree.
+     */
+    public static final class UserCredential implements Parcelable {
+        /**
+         * Username of the credential.
+         */
+        public String username = null;
+
+        /**
+         * Base64-encoded password.
+         */
+        public String password = null;
+
+        /**
+         * EAP (Extensible Authentication Protocol) method type.
+         * Refer to http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4
+         * for valid values.
+         * Using Integer.MIN_VALUE to indicate unset value.
+         */
+        public int eapType = Integer.MIN_VALUE;
+
+        /**
+         * Non-EAP inner authentication method.
+         */
+        public String nonEapInnerMethod = null;
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(username);
+            dest.writeString(password);
+            dest.writeInt(eapType);
+            dest.writeString(nonEapInnerMethod);
+        }
+
+        @Override
+        public boolean equals(Object thatObject) {
+            if (this == thatObject) {
+                return true;
+            }
+            if (!(thatObject instanceof UserCredential)) {
+                return false;
+            }
+
+            UserCredential that = (UserCredential) thatObject;
+            return TextUtils.equals(username, that.username) &&
+                    TextUtils.equals(password, that.password) &&
+                    eapType == that.eapType &&
+                    TextUtils.equals(nonEapInnerMethod, that.nonEapInnerMethod);
+        }
+
+        public static final Creator<UserCredential> CREATOR =
+            new Creator<UserCredential>() {
+                @Override
+                public UserCredential createFromParcel(Parcel in) {
+                    UserCredential userCredential = new UserCredential();
+                    userCredential.username = in.readString();
+                    userCredential.password = in.readString();
+                    userCredential.eapType = in.readInt();
+                    userCredential.nonEapInnerMethod = in.readString();
+                    return userCredential;
+                }
+
+                @Override
+                public UserCredential[] newArray(int size) {
+                    return new UserCredential[size];
+                }
+            };
+    }
+    public UserCredential userCredential = null;
+
+    /**
+     * Certificate based credential.
+     * Contains fields under PerProviderSubscription/Credential/DigitalCertificate subtree.
+     */
+    public static final class CertificateCredential implements Parcelable {
+        /**
+         * Certificate type. Valid values are "802.1ar" and "x509v3".
+         */
+        public String certType = null;
+
+        /**
+         * The SHA-256 fingerprint of the certificate.
+         */
+        public byte[] certSha256FingerPrint = null;
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(certType);
+            dest.writeByteArray(certSha256FingerPrint);
+        }
+
+        @Override
+        public boolean equals(Object thatObject) {
+            if (this == thatObject) {
+                return true;
+            }
+            if (!(thatObject instanceof CertificateCredential)) {
+                return false;
+            }
+
+            CertificateCredential that = (CertificateCredential) thatObject;
+            return TextUtils.equals(certType, that.certType) &&
+                    Arrays.equals(certSha256FingerPrint, that.certSha256FingerPrint);
+        }
+
+        public static final Creator<CertificateCredential> CREATOR =
+            new Creator<CertificateCredential>() {
+                @Override
+                public CertificateCredential createFromParcel(Parcel in) {
+                    CertificateCredential certCredential = new CertificateCredential();
+                    certCredential.certType = in.readString();
+                    certCredential.certSha256FingerPrint = in.createByteArray();
+                    return certCredential;
+                }
+
+                @Override
+                public CertificateCredential[] newArray(int size) {
+                    return new CertificateCredential[size];
+                }
+            };
+    }
+    public CertificateCredential certCredential = null;
+
+    /**
+     * SIM (Subscriber Identify Module) based credential.
+     * Contains fields under PerProviderSubscription/Credential/SIM subtree.
+     */
+    public static final class SimCredential implements Parcelable {
+        /**
+         * International Mobile device Subscriber Identity.
+         */
+        public String imsi = null;
+
+        /**
+         * EAP (Extensible Authentication Protocol) method type for using SIM credential.
+         * Refer to http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4
+         * for valid values.
+         * Using Integer.MIN_VALUE to indicate unset value.
+         */
+        public int eapType = Integer.MIN_VALUE;
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public boolean equals(Object thatObject) {
+            if (this == thatObject) {
+                return true;
+            }
+            if (!(thatObject instanceof SimCredential)) {
+                return false;
+            }
+
+            SimCredential that = (SimCredential) thatObject;
+            return TextUtils.equals(imsi, that.imsi) &&
+                    eapType == that.eapType;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(imsi);
+            dest.writeInt(eapType);
+        }
+
+        public static final Creator<SimCredential> CREATOR =
+            new Creator<SimCredential>() {
+                @Override
+                public SimCredential createFromParcel(Parcel in) {
+                    SimCredential simCredential = new SimCredential();
+                    simCredential.imsi = in.readString();
+                    simCredential.eapType = in.readInt();
+                    return simCredential;
+                }
+
+                @Override
+                public SimCredential[] newArray(int size) {
+                    return new SimCredential[size];
+                }
+            };
+    }
+    public SimCredential simCredential = null;
+
+    /**
+     * CA (Certificate Authority) X509 certificate.
+     */
+    public X509Certificate caCertificate = null;
+
+    /**
+     * Client side X509 certificate chain.
+     */
+    public X509Certificate[] clientCertificateChain = null;
+
+    /**
+     * Client side private key.
+     */
+    public PrivateKey clientPrivateKey = null;
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(realm);
+        dest.writeParcelable(userCredential, flags);
+        dest.writeParcelable(certCredential, flags);
+        dest.writeParcelable(simCredential, flags);
+        ParcelUtil.writeCertificate(dest, caCertificate);
+        ParcelUtil.writeCertificates(dest, clientCertificateChain);
+        ParcelUtil.writePrivateKey(dest, clientPrivateKey);
+    }
+
+    @Override
+    public boolean equals(Object thatObject) {
+        if (this == thatObject) {
+            return true;
+        }
+        if (!(thatObject instanceof Credential)) {
+            return false;
+        }
+
+        Credential that = (Credential) thatObject;
+        return TextUtils.equals(realm, that.realm) &&
+                (userCredential == null ? that.userCredential == null :
+                    userCredential.equals(that.userCredential)) &&
+                (certCredential == null ? that.certCredential == null :
+                    certCredential.equals(that.certCredential)) &&
+                (simCredential == null ? that.simCredential == null :
+                    simCredential.equals(that.simCredential)) &&
+                isX509CertificateEquals(caCertificate, that.caCertificate) &&
+                isX509CertificatesEquals(clientCertificateChain, that.clientCertificateChain) &&
+                isPrivateKeyEquals(clientPrivateKey, that.clientPrivateKey);
+    }
+
+    public static final Creator<Credential> CREATOR =
+        new Creator<Credential>() {
+            @Override
+            public Credential createFromParcel(Parcel in) {
+                Credential credential = new Credential();
+                credential.realm = in.readString();
+                credential.userCredential = in.readParcelable(null);
+                credential.certCredential = in.readParcelable(null);
+                credential.simCredential = in.readParcelable(null);
+                credential.caCertificate = ParcelUtil.readCertificate(in);
+                credential.clientCertificateChain = ParcelUtil.readCertificates(in);
+                credential.clientPrivateKey = ParcelUtil.readPrivateKey(in);
+                return credential;
+            }
+
+            @Override
+            public Credential[] newArray(int size) {
+                return new Credential[size];
+            }
+        };
+
+    private static boolean isPrivateKeyEquals(PrivateKey key1, PrivateKey key2) {
+        if (key1 == null && key2 == null) {
+            return true;
+        }
+
+        /* Return false if only one of them is null */
+        if (key1 == null || key2 == null) {
+            return false;
+        }
+
+        return TextUtils.equals(key1.getAlgorithm(), key2.getAlgorithm()) &&
+                Arrays.equals(key1.getEncoded(), key2.getEncoded());
+    }
+
+    private static boolean isX509CertificateEquals(X509Certificate cert1, X509Certificate cert2) {
+        if (cert1 == null && cert2 == null) {
+            return true;
+        }
+
+        /* Return false if only one of them is null */
+        if (cert1 == null || cert2 == null) {
+            return false;
+        }
+
+        boolean result = false;
+        try {
+            result = Arrays.equals(cert1.getEncoded(), cert2.getEncoded());
+        } catch (CertificateEncodingException e) {
+            /* empty, return false. */
+        }
+        return result;
+    }
+
+    private static boolean isX509CertificatesEquals(X509Certificate[] certs1,
+                                                    X509Certificate[] certs2) {
+        if (certs1 == null && certs2 == null) {
+            return true;
+        }
+
+        /* Return false if only one of them is null */
+        if (certs1 == null || certs2 == null) {
+            return false;
+        }
+
+        if (certs1.length != certs2.length) {
+            return false;
+        }
+
+        for (int i = 0; i < certs1.length; i++) {
+            if (!isX509CertificateEquals(certs1[i], certs2[i])) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
new file mode 100644
index 0000000..62d5603
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.hotspot2.pps;
+
+parcelable HomeSP;
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
new file mode 100644
index 0000000..2acc8be
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.hotspot2.pps;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.text.TextUtils;
+
+import java.util.Arrays;
+
+/**
+ * Class representing HomeSP subtree in PerProviderSubscription (PPS)
+ * Management Object (MO) tree.
+ *
+ * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
+ * Release 2 Technical Specification.
+ *
+ * Currently we only support the nodes that are used by Hotspot 2.0 Release 1.
+ *
+ * @hide
+ */
+public final class HomeSP implements Parcelable {
+    /**
+     * FQDN (Fully Qualified Domain Name) of this home service provider.
+     */
+    public String fqdn = null;
+
+    /**
+     * Friendly name of this home service provider.
+     */
+    public String friendlyName = null;
+
+    /**
+     * List of Organization Identifiers (OIs) identifying a roaming consortium of
+     * which this provider is a member.
+     */
+    public long[] roamingConsortiumOIs = null;
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(fqdn);
+        dest.writeString(friendlyName);
+        dest.writeLongArray(roamingConsortiumOIs);
+    }
+
+    @Override
+    public boolean equals(Object thatObject) {
+        if (this == thatObject) {
+            return true;
+        }
+        if (!(thatObject instanceof HomeSP)) {
+            return false;
+        }
+        HomeSP that = (HomeSP) thatObject;
+
+        return TextUtils.equals(fqdn, that.fqdn) &&
+                TextUtils.equals(friendlyName, that.friendlyName) &&
+                Arrays.equals(roamingConsortiumOIs, that.roamingConsortiumOIs);
+    }
+
+    public static final Creator<HomeSP> CREATOR =
+        new Creator<HomeSP>() {
+            @Override
+            public HomeSP createFromParcel(Parcel in) {
+                HomeSP homeSp = new HomeSP();
+                homeSp.fqdn = in.readString();
+                homeSp.friendlyName = in.readString();
+                homeSp.roamingConsortiumOIs = in.createLongArray();
+                return homeSp;
+            }
+
+            @Override
+            public HomeSP[] newArray(int size) {
+                return new HomeSP[size];
+            }
+        };
+}
diff --git a/wifi/tests/assets/pps/PerProviderSubscription.xml b/wifi/tests/assets/pps/PerProviderSubscription.xml
new file mode 100644
index 0000000..53d38ad
--- /dev/null
+++ b/wifi/tests/assets/pps/PerProviderSubscription.xml
@@ -0,0 +1,80 @@
+<MgmtTree xmlns="syncml:dmddf1.2">
+  <VerDTD>1.2</VerDTD>
+  <Node>
+    <NodeName>PerProviderSubscription</NodeName>
+    <RTProperties>
+      <Type>
+        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
+      </Type>
+    </RTProperties>
+    <Node>
+      <NodeName>i001</NodeName>
+      <Node>
+        <NodeName>HomeSP</NodeName>
+        <Node>
+          <NodeName>FriendlyName</NodeName>
+          <Value>Century House</Value>
+        </Node>
+        <Node>
+          <NodeName>FQDN</NodeName>
+          <Value>mi6.co.uk</Value>
+        </Node>
+        <Node>
+          <NodeName>RoamingConsortiumOI</NodeName>
+          <Value>112233,445566</Value>
+        </Node>
+      </Node>
+      <Node>
+        <NodeName>Credential</NodeName>
+        <Node>
+          <NodeName>Realm</NodeName>
+          <Value>shaken.stirred.com</Value>
+        </Node>
+        <Node>
+          <NodeName>UsernamePassword</NodeName>
+          <Node>
+            <NodeName>Username</NodeName>
+            <Value>james</Value>
+          </Node>
+          <Node>
+            <NodeName>Password</NodeName>
+            <Value>Ym9uZDAwNw==</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPMethod</NodeName>
+            <Node>
+              <NodeName>EAPType</NodeName>
+              <Value>21</Value>
+            </Node>
+            <Node>
+              <NodeName>InnerMethod</NodeName>
+              <Value>MS-CHAP-V2</Value>
+            </Node>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>DigitalCertificate</NodeName>
+          <Node>
+            <NodeName>CertificateType</NodeName>
+            <Value>x509v3</Value>
+          </Node>
+          <Node>
+            <NodeName>CertSHA256FingerPrint</NodeName>
+            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>SIM</NodeName>
+          <Node>
+            <NodeName>IMSI</NodeName>
+            <Value>imsi</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPType</NodeName>
+            <Value>24</Value>
+          </Node>
+        </Node>
+      </Node>
+    </Node>
+  </Node>
+</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml b/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml
new file mode 100644
index 0000000..e13eb2a
--- /dev/null
+++ b/wifi/tests/assets/pps/PerProviderSubscription_DuplicateHomeSP.xml
@@ -0,0 +1,95 @@
+<MgmtTree xmlns="syncml:dmddf1.2">
+  <VerDTD>1.2</VerDTD>
+  <Node>
+    <NodeName>PerProviderSubscription</NodeName>
+    <RTProperties>
+      <Type>
+        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
+      </Type>
+    </RTProperties>
+    <Node>
+      <NodeName>i001</NodeName>
+      <Node>
+        <NodeName>HomeSP</NodeName>
+        <Node>
+          <NodeName>FriendlyName</NodeName>
+          <Value>Century House</Value>
+        </Node>
+        <Node>
+          <NodeName>FQDN</NodeName>
+          <Value>mi6.co.uk</Value>
+        </Node>
+        <Node>
+          <NodeName>RoamingConsortiumOI</NodeName>
+          <Value>112233,445566</Value>
+        </Node>
+      </Node>
+      <Node>
+        <NodeName>HomeSP</NodeName>
+        <Node>
+          <NodeName>FriendlyName</NodeName>
+          <Value>Century House</Value>
+        </Node>
+        <Node>
+          <NodeName>FQDN</NodeName>
+          <Value>mi6.co.uk</Value>
+        </Node>
+        <Node>
+          <NodeName>RoamingConsortiumOI</NodeName>
+          <Value>112233,445566</Value>
+        </Node>
+      </Node>
+      <Node>
+        <NodeName>Credential</NodeName>
+        <Node>
+          <NodeName>Realm</NodeName>
+          <Value>shaken.stirred.com</Value>
+        </Node>
+        <Node>
+          <NodeName>UsernamePassword</NodeName>
+          <Node>
+            <NodeName>Username</NodeName>
+            <Value>james</Value>
+          </Node>
+          <Node>
+            <NodeName>Password</NodeName>
+            <Value>Ym9uZDAwNw==</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPMethod</NodeName>
+            <Node>
+              <NodeName>EAPType</NodeName>
+              <Value>21</Value>
+            </Node>
+            <Node>
+              <NodeName>InnerMethod</NodeName>
+              <Value>MS-CHAP-V2</Value>
+            </Node>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>DigitalCertificate</NodeName>
+          <Node>
+            <NodeName>CertificateType</NodeName>
+            <Value>x509v3</Value>
+          </Node>
+          <Node>
+            <NodeName>CertSHA256FingerPrint</NodeName>
+            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>SIM</NodeName>
+          <Node>
+            <NodeName>IMSI</NodeName>
+            <Value>imsi</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPType</NodeName>
+            <Value>24</Value>
+          </Node>
+        </Node>
+      </Node>
+    </Node>
+  </Node>
+</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml b/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml
new file mode 100644
index 0000000..8719ffa
--- /dev/null
+++ b/wifi/tests/assets/pps/PerProviderSubscription_DuplicateValue.xml
@@ -0,0 +1,81 @@
+<MgmtTree xmlns="syncml:dmddf1.2">
+  <VerDTD>1.2</VerDTD>
+  <Node>
+    <NodeName>PerProviderSubscription</NodeName>
+    <RTProperties>
+      <Type>
+        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
+      </Type>
+    </RTProperties>
+    <Node>
+      <NodeName>i001</NodeName>
+      <Node>
+        <NodeName>HomeSP</NodeName>
+        <Node>
+          <NodeName>FriendlyName</NodeName>
+          <Value>Century House</Value>
+          <Value>Century House</Value>
+        </Node>
+        <Node>
+          <NodeName>FQDN</NodeName>
+          <Value>mi6.co.uk</Value>
+        </Node>
+        <Node>
+          <NodeName>RoamingConsortiumOI</NodeName>
+          <Value>112233,445566</Value>
+        </Node>
+      </Node>
+      <Node>
+        <NodeName>Credential</NodeName>
+        <Node>
+          <NodeName>Realm</NodeName>
+          <Value>shaken.stirred.com</Value>
+        </Node>
+        <Node>
+          <NodeName>UsernamePassword</NodeName>
+          <Node>
+            <NodeName>Username</NodeName>
+            <Value>james</Value>
+          </Node>
+          <Node>
+            <NodeName>Password</NodeName>
+            <Value>Ym9uZDAwNw==</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPMethod</NodeName>
+            <Node>
+              <NodeName>EAPType</NodeName>
+              <Value>21</Value>
+            </Node>
+            <Node>
+              <NodeName>InnerMethod</NodeName>
+              <Value>MS-CHAP-V2</Value>
+            </Node>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>DigitalCertificate</NodeName>
+          <Node>
+            <NodeName>CertificateType</NodeName>
+            <Value>x509v3</Value>
+          </Node>
+          <Node>
+            <NodeName>CertSHA256FingerPrint</NodeName>
+            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>SIM</NodeName>
+          <Node>
+            <NodeName>IMSI</NodeName>
+            <Value>imsi</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPType</NodeName>
+            <Value>24</Value>
+          </Node>
+        </Node>
+      </Node>
+    </Node>
+  </Node>
+</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml b/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml
new file mode 100644
index 0000000..c761237
--- /dev/null
+++ b/wifi/tests/assets/pps/PerProviderSubscription_InvalidName.xml
@@ -0,0 +1,80 @@
+<MgmtTree xmlns="syncml:dmddf1.2">
+  <VerDTD>1.2</VerDTD>
+  <Node>
+    <NodeName>PerProviderSubscription</NodeName>
+    <RTProperties>
+      <Type>
+        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
+      </Type>
+    </RTProperties>
+    <Node>
+      <NodeName>i001</NodeName>
+      <Node>
+        <NodeName>HomeSP</NodeName>
+        <Node>
+          <NodeName>FriendName</NodeName>
+          <Value>Century House</Value>
+        </Node>
+        <Node>
+          <NodeName>FQDN</NodeName>
+          <Value>mi6.co.uk</Value>
+        </Node>
+        <Node>
+          <NodeName>RoamingConsortiumOI</NodeName>
+          <Value>112233,445566</Value>
+        </Node>
+      </Node>
+      <Node>
+        <NodeName>Credential</NodeName>
+        <Node>
+          <NodeName>Realm</NodeName>
+          <Value>shaken.stirred.com</Value>
+        </Node>
+        <Node>
+          <NodeName>UsernamePassword</NodeName>
+          <Node>
+            <NodeName>Username</NodeName>
+            <Value>james</Value>
+          </Node>
+          <Node>
+            <NodeName>Password</NodeName>
+            <Value>Ym9uZDAwNw==</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPMethod</NodeName>
+            <Node>
+              <NodeName>EAPType</NodeName>
+              <Value>21</Value>
+            </Node>
+            <Node>
+              <NodeName>InnerMethod</NodeName>
+              <Value>MS-CHAP-V2</Value>
+            </Node>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>DigitalCertificate</NodeName>
+          <Node>
+            <NodeName>CertificateType</NodeName>
+            <Value>x509v3</Value>
+          </Node>
+          <Node>
+            <NodeName>CertSHA256FingerPrint</NodeName>
+            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>SIM</NodeName>
+          <Node>
+            <NodeName>IMSI</NodeName>
+            <Value>imsi</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPType</NodeName>
+            <Value>24</Value>
+          </Node>
+        </Node>
+      </Node>
+    </Node>
+  </Node>
+</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml b/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml
new file mode 100644
index 0000000..6b807af
--- /dev/null
+++ b/wifi/tests/assets/pps/PerProviderSubscription_InvalidNode.xml
@@ -0,0 +1,84 @@
+<MgmtTree xmlns="syncml:dmddf1.2">
+  <VerDTD>1.2</VerDTD>
+  <Node>
+    <NodeName>PerProviderSubscription</NodeName>
+    <RTProperties>
+      <Type>
+        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
+      </Type>
+    </RTProperties>
+    <Node>
+      <NodeName>i001</NodeName>
+      <Node>
+        <NodeName>HomeSP</NodeName>
+        <Node>
+          <NodeName>FriendlyName</NodeName>
+          <Value>Century House</Value>
+        </Node>
+        <Node>
+          <NodeName>FQDN</NodeName>
+          <Value>mi6.co.uk</Value>
+          <Node>
+            <NodeName>InvalidNode</NodeName>
+            <Value>Test</Value>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>RoamingConsortiumOI</NodeName>
+          <Value>112233,445566</Value>
+        </Node>
+      </Node>
+      <Node>
+        <NodeName>Credential</NodeName>
+        <Node>
+          <NodeName>Realm</NodeName>
+          <Value>shaken.stirred.com</Value>
+        </Node>
+        <Node>
+          <NodeName>UsernamePassword</NodeName>
+          <Node>
+            <NodeName>Username</NodeName>
+            <Value>james</Value>
+          </Node>
+          <Node>
+            <NodeName>Password</NodeName>
+            <Value>Ym9uZDAwNw==</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPMethod</NodeName>
+            <Node>
+              <NodeName>EAPType</NodeName>
+              <Value>21</Value>
+            </Node>
+            <Node>
+              <NodeName>InnerMethod</NodeName>
+              <Value>MS-CHAP-V2</Value>
+            </Node>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>DigitalCertificate</NodeName>
+          <Node>
+            <NodeName>CertificateType</NodeName>
+            <Value>x509v3</Value>
+          </Node>
+          <Node>
+            <NodeName>CertSHA256FingerPrint</NodeName>
+            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>SIM</NodeName>
+          <Node>
+            <NodeName>IMSI</NodeName>
+            <Value>imsi</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPType</NodeName>
+            <Value>24</Value>
+          </Node>
+        </Node>
+      </Node>
+    </Node>
+  </Node>
+</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml b/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml
new file mode 100644
index 0000000..ed06b47
--- /dev/null
+++ b/wifi/tests/assets/pps/PerProviderSubscription_MissingName.xml
@@ -0,0 +1,79 @@
+<MgmtTree xmlns="syncml:dmddf1.2">
+  <VerDTD>1.2</VerDTD>
+  <Node>
+    <NodeName>PerProviderSubscription</NodeName>
+    <RTProperties>
+      <Type>
+        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
+      </Type>
+    </RTProperties>
+    <Node>
+      <NodeName>i001</NodeName>
+      <Node>
+        <Node>
+          <NodeName>FriendlyName</NodeName>
+          <Value>Century House</Value>
+        </Node>
+        <Node>
+          <NodeName>FQDN</NodeName>
+          <Value>mi6.co.uk</Value>
+        </Node>
+        <Node>
+          <NodeName>RoamingConsortiumOI</NodeName>
+          <Value>112233,445566</Value>
+        </Node>
+      </Node>
+      <Node>
+        <NodeName>Credential</NodeName>
+        <Node>
+          <NodeName>Realm</NodeName>
+          <Value>shaken.stirred.com</Value>
+        </Node>
+        <Node>
+          <NodeName>UsernamePassword</NodeName>
+          <Node>
+            <NodeName>Username</NodeName>
+            <Value>james</Value>
+          </Node>
+          <Node>
+            <NodeName>Password</NodeName>
+            <Value>Ym9uZDAwNw==</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPMethod</NodeName>
+            <Node>
+              <NodeName>EAPType</NodeName>
+              <Value>21</Value>
+            </Node>
+            <Node>
+              <NodeName>InnerMethod</NodeName>
+              <Value>MS-CHAP-V2</Value>
+            </Node>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>DigitalCertificate</NodeName>
+          <Node>
+            <NodeName>CertificateType</NodeName>
+            <Value>x509v3</Value>
+          </Node>
+          <Node>
+            <NodeName>CertSHA256FingerPrint</NodeName>
+            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>SIM</NodeName>
+          <Node>
+            <NodeName>IMSI</NodeName>
+            <Value>imsi</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPType</NodeName>
+            <Value>24</Value>
+          </Node>
+        </Node>
+      </Node>
+    </Node>
+  </Node>
+</MgmtTree>
diff --git a/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml b/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml
new file mode 100644
index 0000000..f7e35dd
--- /dev/null
+++ b/wifi/tests/assets/pps/PerProviderSubscription_MissingValue.xml
@@ -0,0 +1,79 @@
+<MgmtTree xmlns="syncml:dmddf1.2">
+  <VerDTD>1.2</VerDTD>
+  <Node>
+    <NodeName>PerProviderSubscription</NodeName>
+    <RTProperties>
+      <Type>
+        <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
+      </Type>
+    </RTProperties>
+    <Node>
+      <NodeName>i001</NodeName>
+      <Node>
+        <NodeName>HomeSP</NodeName>
+        <Node>
+          <NodeName>FriendlyName</NodeName>
+        </Node>
+        <Node>
+          <NodeName>FQDN</NodeName>
+          <Value>mi6.co.uk</Value>
+        </Node>
+        <Node>
+          <NodeName>RoamingConsortiumOI</NodeName>
+          <Value>112233,445566</Value>
+        </Node>
+      </Node>
+      <Node>
+        <NodeName>Credential</NodeName>
+        <Node>
+          <NodeName>Realm</NodeName>
+          <Value>shaken.stirred.com</Value>
+        </Node>
+        <Node>
+          <NodeName>UsernamePassword</NodeName>
+          <Node>
+            <NodeName>Username</NodeName>
+            <Value>james</Value>
+          </Node>
+          <Node>
+            <NodeName>Password</NodeName>
+            <Value>Ym9uZDAwNw==</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPMethod</NodeName>
+            <Node>
+              <NodeName>EAPType</NodeName>
+              <Value>21</Value>
+            </Node>
+            <Node>
+              <NodeName>InnerMethod</NodeName>
+              <Value>MS-CHAP-V2</Value>
+            </Node>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>DigitalCertificate</NodeName>
+          <Node>
+            <NodeName>CertificateType</NodeName>
+            <Value>x509v3</Value>
+          </Node>
+          <Node>
+            <NodeName>CertSHA256FingerPrint</NodeName>
+            <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
+          </Node>
+        </Node>
+        <Node>
+          <NodeName>SIM</NodeName>
+          <Node>
+            <NodeName>IMSI</NodeName>
+            <Value>imsi</Value>
+          </Node>
+          <Node>
+            <NodeName>EAPType</NodeName>
+            <Value>24</Value>
+          </Node>
+        </Node>
+      </Node>
+    </Node>
+  </Node>
+</MgmtTree>
diff --git a/wifi/tests/assets/pps/README.txt b/wifi/tests/assets/pps/README.txt
new file mode 100644
index 0000000..369c0a9
--- /dev/null
+++ b/wifi/tests/assets/pps/README.txt
@@ -0,0 +1,7 @@
+PerProviderSubscription.xml - valid PPS XML file
+PerProviderSubscription_DuplicateHomeSP.xml - containing multiple HomeSP node
+PerProviderSubscription_DuplicateValue.xml - FriendlyName node contains multiple Value
+PerProviderSubscription_MissingValue.xml - FriendlyName node is missing Value
+PerProviderSubscription_MissingName.xml - HomeSP node is missing NodeName
+PerProviderSubscription_InvalidNode.xml - FQDN node contains both Value and a child node
+PerProviderSubscription_InvalidName.xml - FriendlyName node have a typo in its name
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
new file mode 100644
index 0000000..be11f0e
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.net.wifi.hotspot2;
+
+import static org.junit.Assert.assertTrue;
+
+import android.net.wifi.hotspot2.pps.Credential;
+import android.net.wifi.hotspot2.pps.HomeSP;
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.hotspot2.PasspointConfiguration}.
+ */
+@SmallTest
+public class PasspointConfigurationTest {
+
+    private static HomeSP createHomeSp() {
+        HomeSP homeSp = new HomeSP();
+        homeSp.fqdn = "fqdn";
+        homeSp.friendlyName = "friendly name";
+        homeSp.roamingConsortiumOIs = new long[] {0x55, 0x66};
+        return homeSp;
+    }
+
+    private static Credential createCredential() {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        cred.userCredential = null;
+        cred.certCredential = null;
+        cred.simCredential = null;
+        cred.caCertificate = null;
+        cred.clientCertificateChain = null;
+        cred.clientPrivateKey = null;
+        return cred;
+    }
+
+    private static void verifyParcel(PasspointConfiguration writeConfig) throws Exception {
+        Parcel parcel = Parcel.obtain();
+        writeConfig.writeToParcel(parcel, 0);
+
+        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
+        PasspointConfiguration readConfig =
+                PasspointConfiguration.CREATOR.createFromParcel(parcel);
+        assertTrue(readConfig.equals(writeConfig));
+    }
+
+    @Test
+    public void verifyParcelWithDefault() throws Exception {
+        verifyParcel(new PasspointConfiguration());
+    }
+
+    @Test
+    public void verifyParcelWithHomeSPAndCredential() throws Exception {
+        PasspointConfiguration config = new PasspointConfiguration();
+        config.homeSp = createHomeSp();
+        config.credential = createCredential();
+        verifyParcel(config);
+    }
+
+    @Test
+    public void verifyParcelWithHomeSPOnly() throws Exception {
+        PasspointConfiguration config = new PasspointConfiguration();
+        config.homeSp = createHomeSp();
+        verifyParcel(config);
+    }
+
+    @Test
+    public void verifyParcelWithCredentialOnly() throws Exception {
+        PasspointConfiguration config = new PasspointConfiguration();
+        config.credential = createCredential();
+        verifyParcel(config);
+    }
+}
\ No newline at end of file
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java
new file mode 100644
index 0000000..10b0267
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.hotspot2.omadm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.net.wifi.hotspot2.omadm.PPSMOParser;
+import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.pps.Credential;
+import android.net.wifi.hotspot2.pps.HomeSP;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+/**
+ * Unit tests for {@link android.net.wifi.hotspot2.omadm.PPSMOParser}.
+ */
+@SmallTest
+public class PPSMOParserTest {
+    private static final String VALID_PPS_MO_XML_FILE = "assets/pps/PerProviderSubscription.xml";
+    private static final String PPS_MO_XML_FILE_DUPLICATE_HOMESP =
+            "assets/pps/PerProviderSubscription_DuplicateHomeSP.xml";
+    private static final String PPS_MO_XML_FILE_DUPLICATE_VALUE =
+            "assets/pps/PerProviderSubscription_DuplicateValue.xml";
+    private static final String PPS_MO_XML_FILE_MISSING_VALUE =
+            "assets/pps/PerProviderSubscription_MissingValue.xml";
+    private static final String PPS_MO_XML_FILE_MISSING_NAME =
+            "assets/pps/PerProviderSubscription_MissingName.xml";
+    private static final String PPS_MO_XML_FILE_INVALID_NODE =
+            "assets/pps/PerProviderSubscription_InvalidNode.xml";
+    private static final String PPS_MO_XML_FILE_INVALID_NAME =
+            "assets/pps/PerProviderSubscription_InvalidName.xml";
+
+    /**
+     * Read the content of the given resource file into a String.
+     *
+     * @param filename String name of the file
+     * @return String
+     * @throws IOException
+     */
+    private String loadResourceFile(String filename) throws IOException {
+        InputStream in = getClass().getClassLoader().getResourceAsStream(filename);
+        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+        StringBuilder builder = new StringBuilder();
+        String line;
+        while ((line = reader.readLine()) != null) {
+            builder.append(line).append("\n");
+        }
+
+        return builder.toString();
+    }
+
+    /**
+     * Generate a {@link PasspointConfiguration} that matches the configuration specified in the
+     * XML file {@link #VALID_PPS_MO_XML_FILE}.
+     *
+     * @return {@link PasspointConfiguration}
+     */
+    private PasspointConfiguration generateConfigurationFromPPSMOTree() {
+        PasspointConfiguration config = new PasspointConfiguration();
+
+        // HomeSP configuration.
+        config.homeSp = new HomeSP();
+        config.homeSp.friendlyName = "Century House";
+        config.homeSp.fqdn = "mi6.co.uk";
+        config.homeSp.roamingConsortiumOIs = new long[] {0x112233L, 0x445566L};
+
+        // Credential configuration.
+        config.credential = new Credential();
+        config.credential.realm = "shaken.stirred.com";
+        config.credential.userCredential = new Credential.UserCredential();
+        config.credential.userCredential.username = "james";
+        config.credential.userCredential.password = "Ym9uZDAwNw==";
+        config.credential.userCredential.eapType = 21;
+        config.credential.userCredential.nonEapInnerMethod = "MS-CHAP-V2";
+        config.credential.certCredential = new Credential.CertificateCredential();
+        config.credential.certCredential.certType = "x509v3";
+        config.credential.certCredential.certSha256FingerPrint = new byte[32];
+        Arrays.fill(config.credential.certCredential.certSha256FingerPrint, (byte)0x1f);
+        config.credential.simCredential = new Credential.SimCredential();
+        config.credential.simCredential.imsi = "imsi";
+        config.credential.simCredential.eapType = 24;
+        return config;
+    }
+
+    /**
+     * Parse and verify all supported fields under PPS MO tree (currently only fields under
+     * HomeSP and Credential subtree).
+     *
+     * @throws Exception
+     */
+    @Test
+    public void parseValidPPSMOTree() throws Exception {
+        String ppsMoTree = loadResourceFile(VALID_PPS_MO_XML_FILE);
+        PasspointConfiguration expectedConfig = generateConfigurationFromPPSMOTree();
+        PasspointConfiguration actualConfig = PPSMOParser.parseMOText(ppsMoTree);
+        assertTrue(actualConfig.equals(expectedConfig));
+    }
+
+    @Test
+    public void parseNullPPSMOTree() throws Exception {
+        assertEquals(null, PPSMOParser.parseMOText(null));
+    }
+
+    @Test
+    public void parseEmptyPPSMOTree() throws Exception {
+        assertEquals(null, PPSMOParser.parseMOText(new String()));
+    }
+
+    @Test
+    public void parsePPSMOTreeWithDuplicateHomeSP() throws Exception {
+        assertEquals(null, PPSMOParser.parseMOText(
+                loadResourceFile(PPS_MO_XML_FILE_DUPLICATE_HOMESP)));
+    }
+
+    @Test
+    public void parsePPSMOTreeWithDuplicateValue() throws Exception {
+        assertEquals(null, PPSMOParser.parseMOText(
+                loadResourceFile(PPS_MO_XML_FILE_DUPLICATE_VALUE)));
+    }
+
+    @Test
+    public void parsePPSMOTreeWithMissingValue() throws Exception {
+        assertEquals(null, PPSMOParser.parseMOText(
+                loadResourceFile(PPS_MO_XML_FILE_MISSING_VALUE)));
+    }
+
+    @Test
+    public void parsePPSMOTreeWithMissingName() throws Exception {
+        assertEquals(null, PPSMOParser.parseMOText(
+                loadResourceFile(PPS_MO_XML_FILE_MISSING_NAME)));
+    }
+
+    @Test
+    public void parsePPSMOTreeWithInvalidNode() throws Exception {
+        assertEquals(null, PPSMOParser.parseMOText(
+                loadResourceFile(PPS_MO_XML_FILE_INVALID_NODE)));
+    }
+
+    @Test
+    public void parsePPSMOTreeWithInvalidName() throws Exception {
+        assertEquals(null, PPSMOParser.parseMOText(
+                loadResourceFile(PPS_MO_XML_FILE_INVALID_NAME)));
+    }
+}
+
+
+
+
+
+
+
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java
new file mode 100644
index 0000000..c2dcec6
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.hotspot2.omadm;
+
+import static org.junit.Assert.assertTrue;
+
+import android.net.wifi.hotspot2.omadm.XMLNode;
+import android.net.wifi.hotspot2.omadm.XMLParser;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+
+/**
+ * Unit tests for {@link android.net.wifi.hotspot2.omadm.XMLParser}.
+ */
+@SmallTest
+public class XMLParserTest {
+    XMLParser mParser;
+
+    private static XMLNode createNode(XMLNode parent, String tag, String text) {
+        XMLNode node = new XMLNode(parent, tag);
+        node.addText(text);
+        if (parent != null)
+            parent.addChild(node);
+        node.close();
+        return node;
+    }
+
+    /**
+     * Setup before tests.
+     */
+    @Before
+    public void setUp() throws Exception {
+        mParser = new XMLParser();
+    }
+
+    @Test(expected = IOException.class)
+    public void parseNullXML() throws Exception {
+        mParser.parse(null);
+    }
+
+    @Test(expected = IOException.class)
+    public void parseEmptyXML() throws Exception {
+        mParser.parse(new String());
+    }
+
+    @Test(expected = SAXException.class)
+    public void parseMalformedXML() throws Exception {
+        String malformedXmlTree = "<root><child1>test1</child2></root>";
+        mParser.parse(malformedXmlTree);
+    }
+
+    @Test
+    public void parseValidXMLTree() throws Exception {
+        String xmlTree = "<root><child1>test1</child1><child2>test2</child2></root>";
+
+        // Construct the expected XML tree.
+        XMLNode expectedRoot = createNode(null, "root", "");
+        createNode(expectedRoot, "child1", "test1");
+        createNode(expectedRoot, "child2", "test2");
+
+        XMLNode actualRoot = mParser.parse(xmlTree);
+        assertTrue(actualRoot.equals(expectedRoot));
+    }
+}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
new file mode 100644
index 0000000..68ac4ef
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.net.wifi.hotspot2.pps;
+
+import static org.junit.Assert.assertTrue;
+
+import android.net.wifi.FakeKeys;
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.hotspot2.pps.CredentialTest}.
+ */
+@SmallTest
+public class CredentialTest {
+    private static Credential createCredential(Credential.UserCredential userCred,
+                                               Credential.CertificateCredential certCred,
+                                               Credential.SimCredential simCred,
+                                               X509Certificate caCert,
+                                               X509Certificate[] clientCertificateChain,
+                                               PrivateKey clientPrivateKey) {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        cred.userCredential = userCred;
+        cred.certCredential = certCred;
+        cred.simCredential = simCred;
+        cred.caCertificate = caCert;
+        cred.clientCertificateChain = clientCertificateChain;
+        cred.clientPrivateKey = clientPrivateKey;
+        return cred;
+    }
+
+    private static Credential createCredentialWithCertificateCredential() {
+        Credential.CertificateCredential certCred = new Credential.CertificateCredential();
+        certCred.certType = "x509v3";
+        certCred.certSha256FingerPrint = new byte[256];
+        return createCredential(null, certCred, null, FakeKeys.CA_CERT0,
+                new X509Certificate[] {FakeKeys.CLIENT_CERT}, FakeKeys.RSA_KEY1);
+    }
+
+    private static Credential createCredentialWithSimCredential() {
+        Credential.SimCredential simCred = new Credential.SimCredential();
+        simCred.imsi = "imsi";
+        simCred.eapType = 1;
+        return createCredential(null, null, simCred, null, null, null);
+    }
+
+    private static Credential createCredentialWithUserCredential() {
+        Credential.UserCredential userCred = new Credential.UserCredential();
+        userCred.username = "username";
+        userCred.password = "password";
+        userCred.eapType = 1;
+        userCred.nonEapInnerMethod = "MS-CHAP";
+        return createCredential(userCred, null, null, FakeKeys.CA_CERT0,
+                new X509Certificate[] {FakeKeys.CLIENT_CERT}, FakeKeys.RSA_KEY1);
+    }
+
+    private static void verifyParcel(Credential writeCred) {
+        Parcel parcel = Parcel.obtain();
+        writeCred.writeToParcel(parcel, 0);
+
+        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
+        Credential readCred = Credential.CREATOR.createFromParcel(parcel);
+        assertTrue(readCred.equals(writeCred));
+    }
+
+    @Test
+    public void verifyParcelWithDefault() throws Exception {
+        verifyParcel(new Credential());
+    }
+
+    @Test
+    public void verifyParcelWithCertificateCredential() throws Exception {
+        verifyParcel(createCredentialWithCertificateCredential());
+    }
+
+    @Test
+    public void verifyParcelWithSimCredential() throws Exception {
+        verifyParcel(createCredentialWithSimCredential());
+    }
+
+    @Test
+    public void verifyParcelWithUserCredential() throws Exception {
+        verifyParcel(createCredentialWithUserCredential());
+    }
+}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
new file mode 100644
index 0000000..0d2da64
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.net.wifi.hotspot2.pps;
+
+import static org.junit.Assert.assertTrue;
+
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.HashMap;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.hotspot2.pps.HomeSP}.
+ */
+@SmallTest
+public class HomeSPTest {
+    private static HomeSP createHomeSp() {
+        HomeSP homeSp = new HomeSP();
+        homeSp.fqdn = "fqdn";
+        homeSp.friendlyName = "friendly name";
+        homeSp.roamingConsortiumOIs = new long[] {0x55, 0x66};
+        return homeSp;
+    }
+
+    private static void verifyParcel(HomeSP writeHomeSp) throws Exception {
+        Parcel parcel = Parcel.obtain();
+        writeHomeSp.writeToParcel(parcel, 0);
+
+        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
+        HomeSP readHomeSp = HomeSP.CREATOR.createFromParcel(parcel);
+        assertTrue(readHomeSp.equals(writeHomeSp));
+    }
+
+    @Test
+    public void verifyParcelWithEmptyHomeSP() throws Exception {
+        verifyParcel(new HomeSP());
+    }
+
+    @Test
+    public void verifyParcelWithValidHomeSP() throws Exception {
+        verifyParcel(createHomeSp());
+    }
+}